Skip to content

Commit

Permalink
feat: delete image by product delete (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenke authored Mar 5, 2024
1 parent 439e1f2 commit c1c5b51
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.tkit.quarkus.jpa.daos.AbstractDAO;
import org.tkit.quarkus.jpa.exceptions.DAOException;

import gen.org.tkit.onecx.image.rs.internal.model.RefTypeDTO;

@ApplicationScoped
@Transactional
public class ImageDAO extends AbstractDAO<Image> {
Expand Down Expand Up @@ -48,11 +50,29 @@ public void deleteQueryByRefId(String refId) throws DAOException {
}
}

@Transactional(value = Transactional.TxType.REQUIRED, rollbackOn = DAOException.class)
public void deleteQueryByRefIdAndRefType(String refId, RefTypeDTO refType) throws DAOException {
try {
var cq = deleteQuery();
var root = cq.from(Image.class);
var cb = this.getEntityManager().getCriteriaBuilder();

cq.where(cb.equal(root.get(Image_.REF_ID), refId));
cq.where(cb.equal(root.get(Image_.REF_TYPE), refType.toString()));
getEntityManager().createQuery(cq).executeUpdate();
getEntityManager().flush();
} catch (Exception e) {
throw handleConstraint(e, ErrorKeys.FAILED_TO_DELETE_BY_REF_ID_REF_TYPE_QUERY);
}
}

public enum ErrorKeys {

FAILED_TO_DELETE_BY_REF_ID_QUERY,

FIND_ENTITY_BY_REF_ID_REF_TYPE_FAILED,

FAILED_TO_DELETE_BY_REF_ID_REF_TYPE_QUERY

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ public class ImagesInternalRestController implements ImagesInternalApi {
@Inject
ImageMapper imageMapper;

@Override
public Response deleteImage(String refId, RefTypeDTO refType) {
imageDAO.deleteQueryByRefIdAndRefType(refId, refType);

return Response.status(Response.Status.NO_CONTENT).build();
}

@Override
@Transactional
public Response getImage(String refId, RefTypeDTO refType) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.tkit.onecx.product.store.rs.internal.controllers;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
Expand All @@ -15,7 +13,6 @@
import org.tkit.onecx.product.store.domain.daos.MicrofrontendDAO;
import org.tkit.onecx.product.store.domain.daos.MicroserviceDAO;
import org.tkit.onecx.product.store.domain.daos.ProductDAO;
import org.tkit.onecx.product.store.domain.models.Microfrontend;
import org.tkit.onecx.product.store.domain.models.Product;
import org.tkit.onecx.product.store.rs.internal.mappers.InternalExceptionMapper;
import org.tkit.onecx.product.store.rs.internal.mappers.ProductMapper;
Expand Down Expand Up @@ -63,15 +60,9 @@ public Response createProduct(CreateProductRequestDTO createProductDTO) {
}

@Override
@Transactional
public Response deleteProduct(String id) {
var product = dao.findById(id);
if (product != null) {
List<Microfrontend> productRelatedMfes = microfrontendDAO.loadByProductName(product.getName()).toList();
microfrontendDAO.delete(productRelatedMfes);
microserviceDAO.deleteByProductName(product.getName());
dao.deleteQueryById(id);
}
productService.deleteProduct(id);

return Response.noContent().build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.tkit.onecx.product.store.rs.internal.services;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;

import org.tkit.onecx.product.store.domain.daos.ImageDAO;
import org.tkit.onecx.product.store.domain.daos.MicrofrontendDAO;
import org.tkit.onecx.product.store.domain.daos.MicroserviceDAO;
import org.tkit.onecx.product.store.domain.daos.ProductDAO;
import org.tkit.onecx.product.store.domain.models.Microfrontend;
import org.tkit.onecx.product.store.domain.models.Product;

@ApplicationScoped
Expand All @@ -20,10 +24,28 @@ public class ProductService {
@Inject
ProductDAO productDAO;

@Inject
ImageDAO imageDAO;

@Transactional
public void updateProductAndRelatedMfeAndMs(String oldProductName, Product updateItem) {
microfrontendDAO.updateByProductName(oldProductName, updateItem.getName());
microserviceDAO.updateByProductName(oldProductName, updateItem.getName());
productDAO.update(updateItem);
}

@Transactional
public void deleteProduct(String id) {
var product = productDAO.findById(id);
if (product != null) {
List<Microfrontend> productRelatedMfes = microfrontendDAO.loadByProductName(product.getName()).toList();
microfrontendDAO.delete(productRelatedMfes);
microserviceDAO.deleteByProductName(product.getName());
productDAO.deleteQueryById(id);

// workaround for images
imageDAO.deleteQueryByRefId(product.getName());
}

}
}
29 changes: 29 additions & 0 deletions src/main/openapi/onecx-image-internal-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,35 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetailResponse'
delete:
tags:
- imagesInternal
description: delete Image
operationId: deleteImage
parameters:
- name: refId
in: path
required: true
schema:
type: string
- name: refType
in: path
required: true
schema:
$ref: "#/components/schemas/RefType"
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/ImageInfo'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetailResponse'
components:
schemas:
RefType:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.tkit.onecx.product.store.domain.daos;

import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.mockito.Mockito;
import org.tkit.onecx.product.store.AbstractTest;
import org.tkit.quarkus.jpa.exceptions.DAOException;

import gen.org.tkit.onecx.image.rs.internal.model.RefTypeDTO;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
class ImageDAOTest extends AbstractTest {
@Inject
ImageDAO dao;

@InjectMock
EntityManager em;

@BeforeEach
void beforeAll() {
Mockito.when(em.getCriteriaBuilder()).thenThrow(new RuntimeException("Test technical error exception"));
}

@Test
void methodExceptionTests() {
methodExceptionTests(() -> dao.deleteQueryByRefId("1"),
ImageDAO.ErrorKeys.FAILED_TO_DELETE_BY_REF_ID_QUERY);
methodExceptionTests(() -> dao.findByRefIdAndRefType(null, null),
ImageDAO.ErrorKeys.FIND_ENTITY_BY_REF_ID_REF_TYPE_FAILED);
methodExceptionTests(() -> dao.findByRefIdAndRefType(null, null),
ImageDAO.ErrorKeys.FIND_ENTITY_BY_REF_ID_REF_TYPE_FAILED);
methodExceptionTests(() -> dao.deleteQueryByRefIdAndRefType("1", RefTypeDTO.LOGO),
ImageDAO.ErrorKeys.FAILED_TO_DELETE_BY_REF_ID_REF_TYPE_QUERY);

}

void methodExceptionTests(Executable fn, Enum<?> key) {
var exc = Assertions.assertThrows(DAOException.class, fn);
Assertions.assertEquals(key, exc.key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,43 @@ void testMaxUploadSize() {
"uploadImage.contentLength: must be less than or equal to 110000");

}

@Test
void deleteImage() {

var refId = "productDeleteTest";
var refType = RefTypeDTO.LOGO;

given()
.pathParam("refId", refId)
.pathParam("refType", refType)
.when()
.body(FILE)
.contentType(MEDIA_TYPE_IMAGE_PNG)
.post()
.then()
.statusCode(CREATED.getStatusCode())
.extract()
.body().as(ImageInfoDTO.class);

var res = given()
.pathParam("refId", refId)
.pathParam("refType", refType)
.when()
.body(FILE)
.contentType(MEDIA_TYPE_IMAGE_PNG)
.delete()
.then()
.statusCode(NO_CONTENT.getStatusCode());

Assertions.assertNotNull(res);

given()
.contentType(APPLICATION_JSON)
.pathParam("refId", refId)
.pathParam("refType", refType)
.get()
.then()
.statusCode(NOT_FOUND.getStatusCode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@
import static jakarta.ws.rs.core.Response.Status.*;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.util.Objects;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.tkit.onecx.product.store.AbstractTest;
import org.tkit.quarkus.test.WithDBData;

import gen.org.tkit.onecx.image.rs.internal.model.ImageInfoDTO;
import gen.org.tkit.onecx.image.rs.internal.model.RefTypeDTO;
import gen.org.tkit.onecx.product.store.rs.internal.model.*;
import io.quarkus.test.junit.QuarkusTest;

Expand All @@ -18,6 +23,11 @@
@WithDBData(value = "data/test-internal.xml", deleteBeforeInsert = true, deleteAfterTest = true, rinseAndRepeat = true)
class ProductsInternalRestControllerTest extends AbstractTest {

private static final String MEDIA_TYPE_IMAGE_PNG = "image/png";

private static final File FILE = new File(
Objects.requireNonNull(ProductsInternalRestControllerTest.class.getResource("/images/Testimage.png")).getFile());

@Test
void createProductTest() {

Expand Down Expand Up @@ -123,6 +133,59 @@ void deleteProductTest() {
.statusCode(NO_CONTENT.getStatusCode());
}

@Test
void deleteProductTest_shouldDeleteImages() {
var refId = "productDeleteTest";
var refType = RefTypeDTO.LOGO;

// Create Product
var createProductDTO = new CreateProductRequestDTO();
createProductDTO.setName(refId);
createProductDTO.setVersion("test01");
createProductDTO.setBasePath("basePath");

var output = given()
.when()
.contentType(APPLICATION_JSON)
.body(createProductDTO)
.post("/internal/products")
.then()
.statusCode(CREATED.getStatusCode())
.extract()
.body().as(ProductDTO.class);

// Create Image
given()
.pathParam("refId", refId)
.pathParam("refType", refType)
.when()
.body(FILE)
.contentType(MEDIA_TYPE_IMAGE_PNG)
.post("/internal/images/{refId}/{refType}")
.then()
.statusCode(CREATED.getStatusCode())
.extract()
.body().as(ImageInfoDTO.class);

// delete product
var res = given()
.contentType(APPLICATION_JSON)
.pathParam("id", output.getId())
.delete("/internal/products/{id}")
.then()
.statusCode(NO_CONTENT.getStatusCode());

Assertions.assertNotNull(res);

given()
.contentType(APPLICATION_JSON)
.pathParam("refId", refId)
.pathParam("refType", refType)
.get("/internal/images/{refId}/{refType}")
.then()
.statusCode(NOT_FOUND.getStatusCode());
}

@Test
void getProductTest() {
var dto = given()
Expand Down

0 comments on commit c1c5b51

Please sign in to comment.