AssetExtractionService { public PollableFuture<Void> processAssetAsync( Long assetContentId, FilterConfigIdOverride filterConfigIdOverride, List<String> filterOptions, Long parentTaskId) throws UnsupportedAssetFilterTypeException, InterruptedException, AssetExtractionConflictException { ProcessAssetJobInput processAssetJobInput = new ProcessAssetJobInput(); processAssetJobInput.setAssetContentId(assetContentId); processAssetJobInput.setFilterConfigIdOverride(filterConfigIdOverride); processAssetJobInput.setFilterOptions(filterOptions); String pollableMessage = MessageFormat.format("Process asset content, id: {0}", assetContentId.toString()); QuartzJobInfo quartzJobInfo = QuartzJobInfo.newBuilder(ProcessAssetJob.class) .withInput(processAssetJobInput) .withMessage(pollableMessage) .withParentId(parentTaskId) .withExpectedSubTaskNumber(2) .build(); return quartzPollableTaskScheduler.scheduleJob(quartzJobInfo); }  PollableFuture<Asset> processAsset(
            Long assetContentId,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions,
            PollableTask currentTask); @Transactional @Pollable(message = "Extracting text units from asset") void performAssetExtraction(
            AssetExtraction assetExtraction,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions,
            List<String> md5sToSkip,
            @ParentTask PollableTask parentTask); boolean hasMoreActiveBranches(Asset asset, Branch branch); String getMergedContentMd5(List<AssetExtractionByBranch> sordedAssetExtractionByBranches); String getMergedFilterOptionsMd5(List<AssetExtractionByBranch> sordedAssetExtractionByBranches); AssetExtraction createAssetExtractionForMultipleBranches(Asset asset, PollableTask pollableTask); List<AssetExtractionByBranch> getSordedAssetExtractionByBranches(Asset asset); void deleteAssetBranch(Asset asset, String branchName); PollableFuture<Void> processAssetAsync(
            Long assetContentId,
            FilterConfigIdOverride filterConfigIdOverride,
            List<String> filterOptions,
            Long parentTaskId); @Retryable void markAssetExtractionAsLastSuccessful(Asset asset, AssetExtraction assetExtraction); @Transactional AssetExtraction createAssetExtraction(Asset asset, PollableTask pollableTask); @Transactional AssetExtraction createAssetExtraction(AssetContent assetContent, PollableTask pollableTask, List<String> filterOptions); AssetTextUnit createAssetTextUnit(AssetExtraction assetExtraction, String name, String content, String comment); @Transactional AssetTextUnit createAssetTextUnit(
            Long assetExtractionId,
            String name,
            String content,
            String comment,
            PluralForm pluralForm,
            String pluralFormOther,
            boolean doNotTranslate,
            Set<String> usages,
            Branch branch); static final String PRIMARY_BRANCH; }
@Test public void testProcessAssetShouldThrowIfUnsupportedAssetType() throws Exception { Repository repository = repositoryService.createRepository(testIdWatcher.getEntityName("repository")); Asset asset = assetService.createAsset(repository.getId(), "path/to/fake/file-with-unsupported.ext", false); AssetContent assetContent = assetContentService.createAssetContent(asset, "fake-content"); PollableFuture pollableTaskResult = assetExtractionService.processAssetAsync(assetContent.getId(), null, null, null); try { pollableTaskResult.get(); fail("An exception should have been thrown"); } catch (ExecutionException e) { Throwable originalException = e.getCause(); assertTrue(originalException instanceof PollableTaskException); logger.debug("\n===============\nThe exception thrown above is expected. Do not panic!\n===============\n"); } }