Skip to content

Commit

Permalink
fix: update modification count for rest-api (#20)
Browse files Browse the repository at this point in the history
* fix: update modification count for rest-api

* feat: update jpa model, fix rest api

* fix: sonar issues

* fix: sonar issues

* fix: sonar issues

* fix: sonar issues
  • Loading branch information
andrejpetras authored Feb 7, 2024
1 parent c29b118 commit ef959a9
Show file tree
Hide file tree
Showing 28 changed files with 427 additions and 235 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.tkit.onecx.workspace.domain.daos;

import static jakarta.persistence.criteria.JoinType.LEFT;
import static org.tkit.onecx.workspace.domain.models.MenuItem.MENU_ITEM_LOAD_ALL;
import static org.tkit.onecx.workspace.domain.models.MenuItem.MENU_ITEM_WORKSPACE_AND_TRANSLATIONS;

import java.util.List;
Expand Down Expand Up @@ -180,15 +181,32 @@ public MenuItem findById(Object id) throws DAOException {
}
}

public MenuItem loadById(Object id) throws DAOException {
try {
var cb = this.getEntityManager().getCriteriaBuilder();
var cq = cb.createQuery(MenuItem.class);
var root = cq.from(MenuItem.class);
cq.where(cb.equal(root.get(TraceableEntity_.ID), id));
return this.getEntityManager().createQuery(cq)
.setHint(HINT_LOAD_GRAPH,
this.getEntityManager().getEntityGraph(MENU_ITEM_LOAD_ALL))
.getSingleResult();
} catch (NoResultException nre) {
return null;
} catch (Exception e) {
throw new DAOException(MenuItemDAO.ErrorKeys.LOAD_ENTITY_BY_ID_FAILED, e, entityName, id);
}
}

public enum ErrorKeys {

FIND_ENTITY_BY_ID_FAILED,

LOAD_ENTITY_BY_ID_FAILED,
ERROR_UPDATE_MENU_ITEMS,
ERROR_LOAD_ALL_MENU_ITEMS_BY_WORKSPACE_ID,
ERROR_DELETE_ALL_MENU_ITEMS_BY_WORKSPACE_ID,
ERROR_LOAD_ALL_MENU_ITEMS_BY_WORKSPACE_NAME,
ERROR_LOAD_ALL_MENU_ITEM_BY_KEY,

ERROR_DELETE_ALL_MENU_ITEMS_BY_WORKSPACE_NAME_AND_APP_ID,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ public void deleteProductByWorkspaceId(String workspaceId) {
delete(products);
}

@Override
public Product findById(Object id) throws DAOException {
public Product loadById(Object id) throws DAOException {
try {
var cb = this.getEntityManager().getCriteriaBuilder();
var cq = cb.createQuery(Product.class);
var root = cq.from(Product.class);
root.fetch(Product_.WORKSPACE);
cq.where(cb.equal(root.get(TraceableEntity_.ID), id));
return this.getEntityManager().createQuery(cq).getSingleResult();
} catch (NoResultException nre) {
return null;
} catch (Exception e) {
throw this.handleConstraint(e, ProductDAO.ErrorKeys.FIND_ENTITY_BY_ID_FAILED);
throw this.handleConstraint(e, ProductDAO.ErrorKeys.LOAD_ENTITY_BY_ID_FAILED);
}
}

Expand All @@ -88,7 +88,7 @@ public Stream<Product> findByName(String name) throws DAOException {

public enum ErrorKeys {

FIND_ENTITY_BY_ID_FAILED,
LOAD_ENTITY_BY_ID_FAILED,

ERROR_DELETE_PRODUCT_ID,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
@NamedEntityGraph(name = MenuItem.MENU_ITEM_WORKSPACE_AND_TRANSLATIONS, attributeNodes = { @NamedAttributeNode("i18n"),
@NamedAttributeNode("workspace") })
@NamedEntityGraph(name = "MenuItem.loadById", includeAllAttributes = true, attributeNodes = { @NamedAttributeNode("i18n"),
@NamedAttributeNode("children") })
@NamedAttributeNode("children"), @NamedAttributeNode("workspace") })
@SuppressWarnings("squid:S2160")
public class MenuItem extends TraceableEntity {

public static final String MENU_ITEM_WORKSPACE_AND_TRANSLATIONS = "MenuItem.workspaceAndTranslations";

public static final String MENU_ITEM_LOAD_ALL = "MenuItem.loadById";

@TenantId
@Column(name = "TENANT_ID")
private String tenantId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@Table(name = "PRODUCT", uniqueConstraints = {
@UniqueConstraint(name = "PRODUCT_NAME_WORKSPACE_GUID", columnNames = { "PRODUCT_NAME", "WORKSPACE_GUID", "TENANT_ID" })
})
@NamedEntityGraph(name = "Product.loadById", includeAllAttributes = true, attributeNodes = { @NamedAttributeNode("workspace") })
@SuppressWarnings("squid:S2160")
public class Product extends TraceableEntity {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public class Workspace extends TraceableEntity {
@Column(name = "LOGO_URL")
private String logoUrl;

@OneToMany(mappedBy = "workspace")
@OneToMany(mappedBy = "workspace", fetch = LAZY)
private List<Product> products;

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ProductsExternalV1RestController implements ProductExternalV1Api {
ProductDAO productDAO;

@Override
public Response getProductsForWorkspaceId(String id) {
public Response getProducts(String id) {
var result = productDAO.getProductsForWorkspaceId(id);
return Response.ok(mapper.map(result)).build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.tkit.onecx.workspace.rs.external.v1.log;

import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;

import org.tkit.quarkus.log.cdi.LogParam;

import gen.org.tkit.onecx.workspace.rs.external.v1.model.WorkspaceSearchCriteriaDTOV1;

@ApplicationScoped
public class WorkspaceLogParam implements LogParam {

@Override
public List<Item> getClasses() {
return List.of(
item(10, WorkspaceSearchCriteriaDTOV1.class, x -> {
WorkspaceSearchCriteriaDTOV1 d = (WorkspaceSearchCriteriaDTOV1) x;
return WorkspaceSearchCriteriaDTOV1.class.getSimpleName() + "[" + d.getPageNumber() + "," + d.getPageSize()
+ "]";
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static org.jboss.resteasy.reactive.RestResponse.StatusCode.NOT_FOUND;

import java.util.*;
import java.util.stream.Collectors;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
Expand All @@ -21,6 +20,7 @@
import org.tkit.onecx.workspace.domain.models.MenuItem;
import org.tkit.onecx.workspace.rs.internal.mappers.InternalExceptionMapper;
import org.tkit.onecx.workspace.rs.internal.mappers.MenuItemMapper;
import org.tkit.onecx.workspace.rs.internal.services.MenuItemService;
import org.tkit.quarkus.jpa.exceptions.ConstraintException;
import org.tkit.quarkus.log.cdi.LogService;

Expand All @@ -47,6 +47,9 @@ public class MenuInternalRestController implements MenuInternalApi {
@Inject
WorkspaceDAO workspaceDAO;

@Inject
MenuItemService menuItemService;

@Override
@Transactional
public Response createMenuItemForWorkspace(String id, CreateMenuItemDTO menuItemDTO) {
Expand Down Expand Up @@ -122,67 +125,69 @@ public Response getMenuStructureForWorkspaceId(String id) {
}

@Override
@Transactional
public Response patchMenuItems(String id, List<MenuItemDTO> menuItemDTO) {
// create map of <ID, DTO>
Map<Object, MenuItemDTO> tmp = menuItemDTO.stream()
.collect(Collectors.toMap(MenuItemDTO::getId, x -> x));

public Response patchMenuItems(String id, UpdateMenuItemsRequestDTO updateMenuItemsRequestDTO) {
// list of IDs
List<Object> ids = new ArrayList<>(updateMenuItemsRequestDTO.getItems().keySet());
if (ids.isEmpty()) {
return Response.status(NOT_FOUND).build();
}
// load menu items
var items = dao.findByIds(Arrays.asList(tmp.keySet().toArray())).toList();
var items = dao.findByIds(ids).toList();
if (items.isEmpty()) {
return Response.status(NOT_FOUND).build();
}

if (items.size() != tmp.size()) {
if (items.size() != ids.size()) {
return Response.status(NOT_FOUND).entity("Menu Items specified in request body do not exist in db").build();
}

for (MenuItem item : items) {
MenuItemDTO dto = tmp.get(item.getId());

// update parent
updateParent(item, dto);

mapper.update(dto, item);
List<MenuItem> toUpdate = new ArrayList<>();
for (Map.Entry<String, UpdateMenuItemRequestDTO> entry : updateMenuItemsRequestDTO.getItems().entrySet()) {
var menuItem = update(entry.getKey(), entry.getValue());
toUpdate.add(menuItem);
}

var result = dao.update(items);
var result = dao.update(toUpdate);
return Response.ok(mapper.map(result)).build();
}

@Override
@Transactional
public Response updateMenuItem(String id, String menuItemId, MenuItemDTO menuItemDTO) {
var menuItem = dao.findById(menuItemId);
public Response updateMenuItem(String id, String menuItemId, UpdateMenuItemRequestDTO menuItemDTO) {
var menuItem = update(menuItemId, menuItemDTO);
if (menuItem == null) {
return Response.status(NOT_FOUND).build();
}

// update parent
updateParent(menuItem, menuItemDTO);

mapper.update(menuItemDTO, menuItem);

menuItem = dao.update(menuItem);

return Response.ok(mapper.map(menuItem)).build();
}

private MenuItem update(String menuItemId, UpdateMenuItemRequestDTO menuItemDTO) {
var result = menuItemService.updateMenuItem(menuItemId, menuItemDTO.getParentItemId());
if (result == null) {
return null;
}
var menuItem = result.getMenuItem();
mapper.update(menuItemDTO, menuItem);
if (result.isParentChange()) {
menuItem.setParent(result.getParent());
}
return menuItem;
}

@Override
@Transactional
public Response uploadMenuStructureForWorkspaceId(String id, WorkspaceMenuItemStructrueDTO menuItemStructrueDTO) {
public Response uploadMenuStructureForWorkspaceId(String id, WorkspaceMenuItemStructureDTO menuItemStructureDTO) {
var workspace = workspaceDAO.findById(id);
if (workspace == null) {
throw new ConstraintException("Given workspace does not exist", MenuItemErrorKeys.WORKSPACE_DOES_NOT_EXIST, null);
}

if (menuItemStructrueDTO.getMenuItems() == null || menuItemStructrueDTO.getMenuItems().isEmpty()) {
if (menuItemStructureDTO.getMenuItems() == null || menuItemStructureDTO.getMenuItems().isEmpty()) {
throw new ConstraintException("menuItems cannot be null", MenuItemErrorKeys.MENU_ITEMS_NULL, null);
}

List<MenuItem> items = new LinkedList<>();
mapper.recursiveMappingTreeStructure(menuItemStructrueDTO.getMenuItems(), workspace, null, items);
mapper.recursiveMappingTreeStructure(menuItemStructureDTO.getMenuItems(), workspace, null, items);

dao.deleteAllMenuItemsByWorkspaceId(id);
dao.create(items);
Expand All @@ -191,57 +196,6 @@ public Response uploadMenuStructureForWorkspaceId(String id, WorkspaceMenuItemSt

}

private void updateParent(MenuItem menuItem, MenuItemDTO dto) {

if (dto.getParentItemId() == null) {
menuItem.setParent(null);
return;
}

// check parent change
if (menuItem.getParent() != null && dto.getParentItemId().equals(menuItem.getParent().getId())) {
return;
}

// checking if request parent id is the same as current id
if (dto.getParentItemId().equals(menuItem.getId())) {
throw new ConstraintException("Menu Item " + menuItem.getId() + " id and parentItem id are the same",
MenuItemErrorKeys.PARENT_MENU_SAME_AS_MENU_ITEM, null);
}

// checking if parent exists
var parent = dao.findById(dto.getParentItemId());
if (parent == null) {
throw new ConstraintException("Parent menu item " + dto.getParentItemId() + " does not exists",
MenuItemErrorKeys.PARENT_MENU_DOES_NOT_EXIST, null);
} else {
// checking if parent exists in the same portal
if (!parent.getWorkspace().getId().equals(menuItem.getWorkspace().getId())) {
throw new ConstraintException("Parent menu item is assigned to different portal",
MenuItemErrorKeys.PARENT_ASSIGNED_TO_DIFFERENT_PORTAL, null);
}

// check for cycle
Set<String> children = new HashSet<>();
children(menuItem, children);
if (children.contains(parent.getId())) {
throw new ConstraintException(
"One of the items try to set one of its children to the new parent. Cycle dependency can not be created in tree structure",
MenuItemErrorKeys.CYCLE_DEPENDENCY, null);
}
}

// set new parent
menuItem.setParent(parent);
}

private void children(MenuItem menuItem, Set<String> result) {
menuItem.getChildren().forEach(c -> {
result.add(c.getId());
children(c, result);
});
}

@ServerExceptionMapper
public RestResponse<ProblemDetailResponseDTO> exception(ConstraintException ex) {
return exceptionMapper.exception(ex);
Expand All @@ -261,14 +215,9 @@ enum MenuItemErrorKeys {
WORKSPACE_DOES_NOT_EXIST,
PARENT_MENU_DOES_NOT_EXIST,

PARENT_MENU_SAME_AS_MENU_ITEM,
WORKSPACE_DIFFERENT,

MENU_ITEMS_NULL,

PARENT_ASSIGNED_TO_DIFFERENT_PORTAL,

CYCLE_DEPENDENCY

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,11 @@ public Response getProductsForWorkspaceId(String id) {
}

@Override
@Transactional
public Response updateProductById(String id, String productId, UpdateProductRequestDTO updateProductRequestDTO) {
var product = dao.findById(productId);
var product = dao.loadById(productId);
if (product == null) {
return Response.status(NOT_FOUND).build();
}

mapper.update(updateProductRequestDTO, product);
product = dao.update(product);
return Response.ok(mapper.map(product)).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public Response getWorkspace(String id) {
}

@Override
public Response getWorkspaceByName(String name) {
public Response findWorkspaceByName(String name) {
var item = dao.findByWorkspaceName(name);
if (item == null) {
return Response.status(Response.Status.NOT_FOUND).build();
Expand Down
Loading

0 comments on commit ef959a9

Please sign in to comment.