OwnerProductResource { @ApiOperation(notes = "Removes a Product", value = "deleteProduct") @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("/{product_id}") @Transactional public void deleteProduct( @PathParam("owner_key") String ownerKey, @PathParam("product_id") String productId) { Owner owner = this.getOwnerByKey(ownerKey); Product product = this.fetchProduct(owner, productId); if (product.isLocked()) { throw new ForbiddenException(i18n.tr("product \"{0}\" is locked", product.getId())); } if (this.productCurator.productHasSubscriptions(owner, product)) { throw new BadRequestException( i18n.tr("Product with ID \"{0}\" cannot be deleted while subscriptions exist.", productId)); } this.productManager.removeProduct(owner, product); } @Inject  OwnerProductResource(Configuration config, I18n i18n, OwnerCurator ownerCurator,
        OwnerContentCurator ownerContentCurator, OwnerProductCurator ownerProductCurator,
        ProductCertificateCurator productCertCurator, ProductCurator productCurator,
        ProductManager productManager, ModelTranslator translator, JobManager jobManager); @ApiOperation(notes = "Retrieves a list of Products", value = "List Products for an Owner", response = ProductDTO.class, responseContainer = "list") @GET @Produces(MediaType.APPLICATION_JSON) CandlepinQuery<ProductDTO> listProducts(
        @Verify(Owner.class) @PathParam("owner_key") String ownerKey,
        @QueryParam("product") List<String> productIds); @ApiOperation(notes = "Retrieves a single Product", value = "getProduct") @ApiResponses({ @ApiResponse(code = 404, message = "") }) @GET @Path("/{product_id}") @Produces(MediaType.APPLICATION_JSON) ProductDTO getProduct(
        @Verify(Owner.class) @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId); @ApiOperation(notes = "Retrieves a Certificate for a Product", value = "getProductCertificate") @ApiResponses({ @ApiResponse(code = 404, message = "") }) @GET @Path("/{product_id}/certificate") @Produces(MediaType.APPLICATION_JSON) @Transactional ProductCertificateDTO getProductCertificate(
        @PathParam("owner_key") String ownerKey,
        @ApiParam(name = "productId", required = true, value = "Numeric product identifier")
        @PathParam("product_id") String productId); @ApiOperation(notes = "Creates a Product. Returns either the new created Product or " + "the Product that already existed.", value = "createProduct") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Transactional ProductDTO createProduct(
        @PathParam("owner_key") String ownerKey,
        ProductDTO dto); @ApiOperation(notes = "Updates a Product", value = "updateProduct") @ApiResponses({ @ApiResponse(code = 400, message = "") }) @PUT @Path("/{product_id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Transactional ProductDTO updateProduct(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @ApiParam(name = "update", required = true) ProductDTO update); @ApiOperation(notes = "Adds one or more Content entities to a Product", value = "addBatchContent") @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{product_id}/batch_content") @Transactional ProductDTO addBatchContent(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @ApiParam(name = "contentMap", required = true) Map<String, Boolean> contentMap); @ApiOperation(notes = "Adds a single Content to a Product", value = "addContent") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) @Path("/{product_id}/content/{content_id}") @Transactional ProductDTO addContent(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @PathParam("content_id") String contentId,
        @QueryParam("enabled") Boolean enabled); @ApiOperation(notes = "Adds one or more Content entities to a Product", value = "addBatchContent") @DELETE @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{product_id}/batch_content") @Transactional ProductDTO removeBatchContent(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @ApiParam(name = "content", required = true) List<String> contentIds); @ApiOperation(notes = "Removes a single Content from a Product", value = "removeContent") @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("/{product_id}/content/{content_id}") @Transactional ProductDTO removeContent(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @PathParam("content_id") String contentId); @ApiOperation(notes = "Removes a Product", value = "deleteProduct") @ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 404, message = "") }) @DELETE @Produces(MediaType.APPLICATION_JSON) @Path("/{product_id}") @Transactional void deleteProduct(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId); @ApiOperation(notes = "Refreshes Pools by Product", value = "refreshPoolsForProduct") @PUT @Path("/{product_id}/subscriptions") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.WILDCARD) @Transactional AsyncJobStatusDTO refreshPoolsForProduct(
        @PathParam("owner_key") String ownerKey,
        @PathParam("product_id") String productId,
        @QueryParam("lazy_regen") @DefaultValue("true") boolean lazyRegen);  }
@Test public void testDeleteProductWithSubscriptions() { OwnerCurator oc = mock(OwnerCurator.class); OwnerProductCurator opc = mock(OwnerProductCurator.class); ProductCurator pc = mock(ProductCurator.class); I18n i18n = I18nFactory.getI18n(getClass(), Locale.US, I18nFactory.FALLBACK); OwnerProductResource pr = new OwnerProductResource( config, i18n, oc, null, opc, null, pc, null, this.modelTranslator, this.jobManager); Owner o = mock(Owner.class); Product p = mock(Product.class); when(oc.getByKey(eq("owner"))).thenReturn(o); when(opc.getProductById(eq(o), eq("10"))).thenReturn(p); Set<Subscription> subs = new HashSet<>(); Subscription s = mock(Subscription.class); subs.add(s); when(pc.productHasSubscriptions(eq(o), eq(p))).thenReturn(true); assertThrows(BadRequestException.class, () -> pr.deleteProduct("owner", "10")); }