ProductResource { @ApiOperation(notes = "Refreshes Pools by Product", value = "refreshPoolsForProduct", response = AsyncJobStatusDTO.class, responseContainer = "List") @PUT @Path("/subscriptions") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) public Stream<AsyncJobStatusDTO> refreshPoolsForProduct( @ApiParam(value = "Multiple product UUIDs", required = true) @QueryParam("product") List<String> productUuids, @QueryParam("lazy_regen") @DefaultValue("true") Boolean lazyRegen) throws JobException { if (productUuids.isEmpty()) { throw new BadRequestException(i18n.tr("No product IDs specified")); } if (config.getBoolean(ConfigProperties.STANDALONE)) { log.warn("Ignoring refresh pools request due to standalone config."); return null; } ResultIterator<Owner> iterator = this.ownerCurator.getOwnersWithProducts(productUuids).iterate(); List<JobConfig> jobConfigs = new LinkedList<>(); while (iterator.hasNext()) { JobConfig config = RefreshPoolsJob.createJobConfig() .setOwner(iterator.next()) .setLazyRegeneration(lazyRegen); jobConfigs.add(config); } iterator.close(); List<AsyncJobStatus> statuses = new LinkedList<>(); for (JobConfig config : jobConfigs) { try { statuses.add(this.jobManager.queueJob(config)); } catch (Exception e) { statuses.add(new AsyncJobStatus() .setName(RefreshPoolsJob.JOB_NAME) .setState(AsyncJobStatus.JobState.FAILED) .setJobResult(e.toString())); } } return statuses.stream().map( this.translator.getStreamMapper(AsyncJobStatus.class, AsyncJobStatusDTO.class)); } @Inject  ProductResource(ProductCurator productCurator, OwnerCurator ownerCurator,
        ProductCertificateCurator productCertCurator, Configuration config, I18n i18n,
        ModelTranslator translator, JobManager jobManager); @ApiOperation(notes = "Retrieves a single Product", value = "getProduct") @ApiResponses({ @ApiResponse(code = 404, message = "") }) @GET @Path("/{product_uuid}") @Produces(MediaType.APPLICATION_JSON) @SecurityHole ProductDTO getProduct(@PathParam("product_uuid") String productUuid); @ApiOperation(notes = "Retreives a Certificate for a Product", value = "getProductCertificate") @ApiResponses({ @ApiResponse(code = 404, message = "") }) @GET @Path("/{product_uuid}/certificate") @Produces(MediaType.APPLICATION_JSON) @SecurityHole ProductCertificateDTO getProductCertificate(
        @PathParam("product_uuid") String productUuid); @ApiOperation(notes = "Creates a Product. Returns either the new created " + "Product or the Product that already existed. @deprecated Use per-org" + " version", value = "createProduct") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Deprecated ProductDTO createProduct(ProductDTO product); @ApiOperation(notes = "Updates a Product @deprecated Use per-org version", value = "updateProduct") @ApiResponses({ @ApiResponse(code = 400, message = "") }) @PUT @Path("/{product_uuid}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) @Deprecated ProductDTO updateProduct(
        @PathParam("product_uuid") String productUuid,
        @ApiParam(name = "product", required = true) ProductDTO product); @ApiOperation(notes = "Adds Content to a Product Batch mode @deprecated Use per-org version", value = "addBatchContent") @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{product_uuid}/batch_content") @Deprecated ProductDTO addBatchContent(
        @PathParam("product_uuid") String productUuid,
        Map<String, Boolean> contentMap); @ApiOperation(notes = "Adds Content to a Product. Single mode @deprecated Use " + "per-org version", value = "addContent") @ApiResponses({ }) @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) @Path("/{product_uuid}/content/{content_id}") @Deprecated ProductDTO addContent(
        @PathParam("product_uuid") String productUuid,
        @PathParam("content_id") String contentId,
        @QueryParam("enabled") Boolean enabled); @ApiOperation(notes = "Removes Content from a Product @deprecated Use per-org version", value = "removeContent") @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("/{product_uuid}/content/{content_id}") @Deprecated void removeContent(
        @PathParam("product_uuid") String productUuid,
        @PathParam("content_id") String contentId); @ApiOperation(notes = "Removes a Product @deprecated Use per-org version", value = "deleteProduct") @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("/{product_uuid}") @Deprecated void deleteProduct(
        @PathParam("product_uuid") String productUuid); @ApiOperation(notes = "Retrieves a list of Owners by Product", value = "getProductOwners", response = OwnerDTO.class, responseContainer = "list") @ApiResponses({ @ApiResponse(code = 400, message = "") }) @GET @Path("/owners") @Produces(MediaType.APPLICATION_JSON) CandlepinQuery<OwnerDTO> getProductOwners(
        @ApiParam(value = "Multiple product UUIDs", required = true)
        @QueryParam("product") List<String> productUuids); @ApiOperation(notes = "Refreshes Pools by Product", value = "refreshPoolsForProduct", response = AsyncJobStatusDTO.class, responseContainer = "List") @PUT @Path("/subscriptions") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) Stream<AsyncJobStatusDTO> refreshPoolsForProduct(
        @ApiParam(value = "Multiple product UUIDs", required = true)
        @QueryParam("product") List<String> productUuids,
        @QueryParam("lazy_regen") @DefaultValue("true") Boolean lazyRegen);  }
@Test public void testRefreshPoolsByProduct() throws JobException { Configuration config = new MapConfiguration(this.config); config.setProperty(ConfigProperties.STANDALONE, "false"); ProductResource productResource = new ProductResource(this.productCurator, this.ownerCurator, this.productCertificateCurator, config, this.i18n, this.modelTranslator, this.jobManager); this.setupDBForOwnerProdTests(); List<AsyncJobStatusDTO> jobs = productResource.refreshPoolsForProduct(Arrays.asList("p1"), true) .collect(Collectors.toList()); assertNotNull(jobs); assertEquals(2, jobs.size()); this.verifyRefreshPoolsJobsWereQueued(jobs); }
@Test public void testRefreshPoolsByProductForMultipleProducts() throws JobException { Configuration config = new MapConfiguration(this.config); config.setProperty(ConfigProperties.STANDALONE, "false"); ProductResource productResource = new ProductResource(this.productCurator, this.ownerCurator, this.productCertificateCurator, config, this.i18n, this.modelTranslator, this.jobManager); this.setupDBForOwnerProdTests(); List<AsyncJobStatusDTO> jobs = productResource .refreshPoolsForProduct(Arrays.asList("p1", "p2"), false) .collect(Collectors.toList()); assertNotNull(jobs); assertEquals(3, jobs.size()); this.verifyRefreshPoolsJobsWereQueued(jobs); }
@Test public void testRefreshPoolsByProductWithoutLazyOffload() throws JobException { Configuration config = new MapConfiguration(this.config); config.setProperty(ConfigProperties.STANDALONE, "false"); ProductResource productResource = new ProductResource(this.productCurator, this.ownerCurator, this.productCertificateCurator, config, this.i18n, this.modelTranslator, this.jobManager); this.setupDBForOwnerProdTests(); List<AsyncJobStatusDTO> jobs = productResource.refreshPoolsForProduct(Arrays.asList("p3"), false) .collect(Collectors.toList()); assertNotNull(jobs); assertEquals(1, jobs.size()); this.verifyRefreshPoolsJobsWereQueued(jobs); }
@Test public void testRefreshPoolsByProductWithBadProductId() throws JobException { Configuration config = new MapConfiguration(this.config); config.setProperty(ConfigProperties.STANDALONE, "false"); ProductResource productResource = new ProductResource(this.productCurator, this.ownerCurator, this.productCertificateCurator, config, this.i18n, this.modelTranslator, this.jobManager); this.setupDBForOwnerProdTests(); List<AsyncJobStatusDTO> jobs = productResource.refreshPoolsForProduct(Arrays.asList("nope"), false) .collect(Collectors.toList()); assertNotNull(jobs); assertEquals(0, jobs.size()); }
@Test public void testRefreshPoolsByProductInputValidation() { assertThrows(BadRequestException.class, () -> productResource.refreshPoolsForProduct(new LinkedList<>(), true) ); }
@Test public void testRefreshPoolsByProductJobQueueingErrorsShouldBeHandled() throws JobException { Configuration config = new MapConfiguration(this.config); config.setProperty(ConfigProperties.STANDALONE, "false"); JobManager jobManager = mock(JobManager.class); AsyncJobStatus status1 = new AsyncJobStatus(); status1.setName(RefreshPoolsJob.JOB_NAME); status1.setState(AsyncJobStatus.JobState.CREATED); status1.setState(AsyncJobStatus.JobState.QUEUED); when(jobManager.queueJob(anyObject())) .thenReturn(status1) .thenThrow(new JobConfigValidationException("a job config validation error happened!")); ProductResource productResource = new ProductResource(this.productCurator, this.ownerCurator, this.productCertificateCurator, config, this.i18n, this.modelTranslator, jobManager); this.setupDBForOwnerProdTests(); List<AsyncJobStatusDTO> jobs = null; try { jobs = productResource.refreshPoolsForProduct(Arrays.asList("p1"), true) .collect(Collectors.toList()); } catch (Exception e) { fail("A validation exception when trying to queue a job should be handled " + "by the endpoint, not thrown!"); } assertNotNull(jobs); assertEquals(2, jobs.size()); AsyncJobStatusDTO statusDTO1 = jobs.get(0); assertEquals(RefreshPoolsJob.JOB_NAME, statusDTO1.getName()); assertEquals(AsyncJobStatus.JobState.CREATED.toString(), statusDTO1.getState()); assertEquals(AsyncJobStatus.JobState.CREATED.toString(), statusDTO1.getPreviousState()); assertEquals(Integer.valueOf(0), statusDTO1.getAttempts()); assertEquals(Integer.valueOf(1), statusDTO1.getMaxAttempts()); AsyncJobStatusDTO statusDTO2 = jobs.get(1); assertEquals(RefreshPoolsJob.JOB_NAME, statusDTO2.getName()); assertEquals(AsyncJobStatus.JobState.FAILED.toString(), statusDTO2.getState()); assertEquals(AsyncJobStatus.JobState.CREATED.toString(), statusDTO2.getPreviousState()); assertEquals(Integer.valueOf(0), statusDTO2.getAttempts()); assertEquals(Integer.valueOf(1), statusDTO2.getMaxAttempts()); }