Skip to content

Commit

Permalink
feat: createSlots by list (#70)
Browse files Browse the repository at this point in the history
* feat: createSlots by list

* fixed api definition

* fix: sonar issue

* fix: sonar issue
  • Loading branch information
JordenReuter authored May 17, 2024
1 parent 72fed3c commit 056f7e4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
import org.tkit.onecx.workspace.domain.daos.SlotDAO;
import org.tkit.onecx.workspace.domain.daos.WorkspaceDAO;
import org.tkit.onecx.workspace.domain.models.Slot;
import org.tkit.onecx.workspace.rs.internal.mappers.InternalExceptionMapper;
import org.tkit.onecx.workspace.rs.internal.mappers.SlotMapper;
import org.tkit.quarkus.jpa.exceptions.ConstraintException;
Expand Down Expand Up @@ -50,12 +51,19 @@ public Response createSlot(CreateSlotRequestDTO createSlotRequestDTO) {
return Response.status(Response.Status.NOT_FOUND).build();
}

var slot = mapper.create(createSlotRequestDTO, workspace);
slot = dao.create(slot);
return Response
.created(uriInfo.getAbsolutePathBuilder().path(slot.getId()).build())
.entity(mapper.map(slot))
.build();
var slots = mapper.createList(createSlotRequestDTO, workspace);

var existingSlots = dao.findSlotsByWorkspaceId(workspace.getId()).stream().map(Slot::getName).toList();
slots.removeIf(slot -> existingSlots.contains(slot.getName()));
var createdSlots = dao.create(slots).toList();
if (!createdSlots.isEmpty()) {
return Response.status(Response.Status.CREATED)
.entity(mapper.map(createdSlots))
.build();
} else {
return Response.status(Response.Status.NO_CONTENT).build();
}

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public List<Item> getClasses() {
return List.of(
item(10, CreateSlotRequestDTO.class,
x -> CreateSlotRequestDTO.class.getSimpleName() + "["
+ ((CreateSlotRequestDTO) x).getName() + ","
+ ((CreateSlotRequestDTO) x).getSlots().size() + ","
+ ((CreateSlotRequestDTO) x).getWorkspaceId() + "]"),
item(10, UpdateSlotRequestDTO.class,
x -> UpdateSlotRequestDTO.class.getSimpleName() + "[" + ((UpdateSlotRequestDTO) x).getName()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.tkit.onecx.workspace.rs.internal.mappers;

import java.util.ArrayList;
import java.util.List;

import org.mapstruct.Mapper;
Expand All @@ -14,25 +15,6 @@
@Mapper(uses = { OffsetDateTimeMapper.class })
public interface SlotMapper {

default Slot create(CreateSlotRequestDTO dto, Workspace workspace) {
var role = create(dto);
role.setWorkspace(workspace);
return role;
}

@Mapping(target = "id", ignore = true)
@Mapping(target = "creationDate", ignore = true)
@Mapping(target = "creationUser", ignore = true)
@Mapping(target = "modificationDate", ignore = true)
@Mapping(target = "modificationUser", ignore = true)
@Mapping(target = "controlTraceabilityManual", ignore = true)
@Mapping(target = "modificationCount", ignore = true)
@Mapping(target = "persisted", ignore = true)
@Mapping(target = "tenantId", ignore = true)
@Mapping(target = "workspace", ignore = true)
@Mapping(target = "components", ignore = true)
Slot create(CreateSlotRequestDTO dto);

@Mapping(target = "removeComponentsItem", ignore = true)
SlotDTO map(Slot data);

Expand All @@ -53,4 +35,30 @@ default WorkspaceSlotsDTO create(List<Slot> slots) {
@Mapping(target = "workspace", ignore = true)
@Mapping(target = "workspaceId", ignore = true)
void update(UpdateSlotRequestDTO dto, @MappingTarget Slot slot);

default List<Slot> createList(CreateSlotRequestDTO createSlotRequestDTO, Workspace workspace) {
List<Slot> slots = new ArrayList<>();
createSlotRequestDTO.getSlots().forEach(createSlotDTO -> slots.add(map(createSlotDTO, workspace)));
return slots;
}

default Slot map(CreateSlotDTO createSlotDTO, Workspace workspace) {
var slot = map(createSlotDTO);
slot.setWorkspace(workspace);
return slot;
}

@Mapping(target = "workspaceId", ignore = true)
@Mapping(target = "workspace", ignore = true)
@Mapping(target = "tenantId", ignore = true)
@Mapping(target = "persisted", ignore = true)
@Mapping(target = "modificationUser", ignore = true)
@Mapping(target = "modificationDate", ignore = true)
@Mapping(target = "modificationCount", ignore = true)
@Mapping(target = "id", ignore = true)
@Mapping(target = "creationUser", ignore = true)
@Mapping(target = "creationDate", ignore = true)
@Mapping(target = "controlTraceabilityManual", ignore = true)
@Mapping(target = "components", ignore = true)
Slot map(CreateSlotDTO createSlotDTO);
}
18 changes: 11 additions & 7 deletions src/main/openapi/onecx-workspace-internal-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,12 @@ paths:
responses:
"201":
description: OK
headers:
Location:
required: true
schema:
type: string
format: url
content:
application/json:
schema:
$ref: '#/components/schemas/Slot'
type: array
items:
$ref: '#/components/schemas/Slot'
"400":
description: Bad request
content:
Expand Down Expand Up @@ -1397,6 +1393,14 @@ components:
properties:
workspaceId:
type: string
slots:
type: array
minItems: 1
items:
$ref: '#/components/schemas/CreateSlot'
CreateSlot:
type: object
properties:
name:
type: string
UpdateSlotRequest:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.tkit.onecx.workspace.rs.internal.controllers;

import static io.restassured.RestAssured.given;
import static jakarta.ws.rs.core.HttpHeaders.LOCATION;
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static jakarta.ws.rs.core.Response.Status.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.from;

import java.util.List;

import org.junit.jupiter.api.Test;
import org.tkit.onecx.workspace.rs.internal.mappers.InternalExceptionMapper;
import org.tkit.onecx.workspace.test.AbstractTest;
Expand All @@ -26,7 +27,7 @@ void createNewSlotTest() {

// create Role
var requestDTO = new CreateSlotRequestDTO();
requestDTO.setName("slot01");
requestDTO.setSlots(List.of(new CreateSlotDTO().name("slot01")));

given()
.when()
Expand All @@ -46,24 +47,23 @@ void createNewSlotTest() {

requestDTO.workspaceId("11-111");

var uri = given()
given()
.when()
.contentType(APPLICATION_JSON)
.body(requestDTO)
.post()
.then().statusCode(CREATED.getStatusCode())
.extract().header(LOCATION);
.then().statusCode(CREATED.getStatusCode());

var dto = given()
.contentType(APPLICATION_JSON)
.get(uri)
.get("/workspace/11-111")
.then()
.statusCode(OK.getStatusCode())
.extract()
.body().as(SlotDTO.class);
.body().as(WorkspaceSlotsDTO.class);

assertThat(dto).isNotNull()
.returns(requestDTO.getName(), from(SlotDTO::getName));
assertThat(dto).isNotNull();
assertThat(dto.getSlots()).hasSize(4);

// create Role without body
var exception = given()
Expand All @@ -77,22 +77,18 @@ void createNewSlotTest() {
assertThat(exception.getErrorCode()).isEqualTo(InternalExceptionMapper.TechnicalErrorKeys.CONSTRAINT_VIOLATIONS.name());
assertThat(exception.getDetail()).isEqualTo("createSlot.createSlotRequestDTO: must not be null");

// create Role with existing name
// create Slot with existing name, should skip
requestDTO = new CreateSlotRequestDTO();
requestDTO.setWorkspaceId("11-111");
requestDTO.setName("slot1");
requestDTO.setSlots(List.of(new CreateSlotDTO().name("slot1")));

exception = given().when()
given().when()
.contentType(APPLICATION_JSON)
.body(requestDTO)
.post()
.then()
.statusCode(BAD_REQUEST.getStatusCode())
.extract().as(ProblemDetailResponseDTO.class);
.statusCode(NO_CONTENT.getStatusCode());

assertThat(exception.getErrorCode()).isEqualTo("PERSIST_ENTITY_FAILED");
assertThat(exception.getDetail()).isEqualTo(
"could not execute statement [ERROR: duplicate key value violates unique constraint 'slot_workspace_name' Detail: Key (name, workspace_guid, tenant_id)=(slot1, 11-111, tenant-100) already exists.]");
}

@Test
Expand Down

0 comments on commit 056f7e4

Please sign in to comment.