Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,26 @@ public class ProjectCreationCommandBuilder {

private final ProjectExistenceService projectExistenceService;

public ProjectCreationCommand build(CreateProjectRequest request, ClientAppEntity clientApp) {
public ProjectCreationCommand buildForCreation(CreateProjectRequest request, ClientAppEntity clientApp) {
ClientAppProjectFlavorEntity flavor = resolveFlavor(request, clientApp);
String projectKey = resolveProjectKey(request.getProjectKey(), flavor);

return build(request, flavor, projectKey, clientApp);
}

public ProjectCreationCommand buildForRegistration(CreateProjectRequest request, ClientAppEntity clientApp) {
ClientAppProjectFlavorEntity flavor = resolveFlavor(request, clientApp);
String projectKey = resolveProjectKeyForRegistration(request.getProjectKey(), flavor);

return build(request, flavor, projectKey, clientApp);
}

private ProjectCreationCommand build(CreateProjectRequest request, ClientAppProjectFlavorEntity flavor, String projectKey, ClientAppEntity clientApp) {
String projectFlavor = firstNonBlank(request.getProjectFlavor(), flavor.getName());
String configurationItem = firstNonBlank(request.getConfigurationItem(), flavor.getConfigItem());
String owner = firstNonBlank(request.getOwner(), flavor.getProjectOwner());
String x2account = firstNonBlank(request.getX2OdsAccount(), flavor.getServiceAccount());
String location = firstNonBlank(request.getLocation(), flavor.getLocation());
String projectKey = resolveProjectKey(request.getProjectKey(), flavor);
String projectName = resolveProjectName(request.getProjectName(), projectKey);
String projectDescription = firstNonBlank(request.getProjectDescription(), "project " + projectFlavor);

Expand Down Expand Up @@ -131,6 +142,26 @@ private String resolveProjectKey(String existingProjectKey, ClientAppProjectFlav
}
}

private String resolveProjectKeyForRegistration(String existingProjectKey, ClientAppProjectFlavorEntity flavor) {
try {
if (Strings.isNotEmpty(existingProjectKey)) {
if (!projectExistenceService.isProjectFoundInCollection(existingProjectKey)) {
return existingProjectKey;
}

throw new ProjectAlreadyExistsException(ErrorKey.PROJECT_ALREADY_EXISTS);
}

String pattern = flavor.getProjectKeyPattern();

return generateProjectKeyService.generateProjectKey(pattern);
} catch (ProjectKeyGenerationException e) {
throw new ProjectCreationException("Error generating the project key", e);
} catch (ProjectExistenceServiceException e) {
throw new ProjectCreationException("Error checking if the generated key exists: " + e.getMessage(), e);
}
}

private boolean isAllowedConfigItem(String configurationItem, ClientAppProjectFlavorEntity flavor) {
String[] allowedConfigItems = flavor.getAllowedConfigItems();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ public CreateProjectResponse createProject(CreateProjectRequest request, UUID cl

ClientAppEntity clientApp = clientAppService.findByClientId(clientId);

ProjectCreationCommand command = projectCreationCommandBuilder.build(request, clientApp);

ProjectCreationCommand command;
ProjectResponse project;

if (Boolean.TRUE.equals(request.getRegistrationOnly())) {
command = projectCreationCommandBuilder.buildForRegistration(request, clientApp);
project = registerProject(command);
} else {
command = projectCreationCommandBuilder.buildForCreation(request, clientApp);
project = createNewProject(command);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void tear_down() throws Exception {
}

@Test
void build_resolves_defaults_from_flavor_when_request_fields_are_missing() throws ProjectExistenceServiceException {
void build_for_creation_resolves_defaults_from_flavor_when_request_fields_are_missing() throws ProjectExistenceServiceException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");
Expand All @@ -59,7 +59,7 @@ void build_resolves_defaults_from_flavor_when_request_fields_are_missing() throw

when(projectExistenceService.isProjectFound("KEY01")).thenReturn(false);

ProjectCreationCommand result = sut.build(request, clientApp);
ProjectCreationCommand result = sut.buildForCreation(request, clientApp);

assertEquals("DLSS", result.getProjectFlavor());
assertEquals("CI-001", result.getConfigurationItem());
Expand All @@ -69,84 +69,84 @@ void build_resolves_defaults_from_flavor_when_request_fields_are_missing() throw
}

@Test
void build_resolves_flavor_from_configuration_item_when_flavor_is_not_provided() throws ProjectExistenceServiceException {
void build_for_creation_resolves_flavor_from_configuration_item_when_flavor_is_not_provided() throws ProjectExistenceServiceException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request(null, "CI-001", "KEY01");

when(projectExistenceService.isProjectFound("KEY01")).thenReturn(false);

ProjectCreationCommand result = sut.build(request, clientApp);
ProjectCreationCommand result = sut.buildForCreation(request, clientApp);

assertEquals("DLSS", result.getProjectFlavor());
assertEquals("CI-001", result.getConfigurationItem());
}

@Test
void build_generates_project_key_when_request_project_key_is_null() throws ProjectExistenceServiceException, org.opendevstack.apiservice.serviceproject.exception.ProjectKeyGenerationException {
void build_for_creation_generates_project_key_when_request_project_key_is_null() throws ProjectExistenceServiceException, org.opendevstack.apiservice.serviceproject.exception.ProjectKeyGenerationException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, null);

when(generateProjectKeyService.generateProjectKey("DLSS%06d")).thenReturn("DLSS000001");
when(projectExistenceService.isProjectFound("DLSS000001")).thenReturn(false);

ProjectCreationCommand result = sut.build(request, clientApp);
ProjectCreationCommand result = sut.buildForCreation(request, clientApp);

assertEquals("DLSS000001", result.getProjectKey());
verify(generateProjectKeyService).generateProjectKey("DLSS%06d");
}

@Test
void build_throws_project_already_exists_exception_when_project_key_already_exists() throws ProjectExistenceServiceException {
void build_for_creation_throws_project_already_exists_exception_when_project_key_already_exists() throws ProjectExistenceServiceException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");

when(projectExistenceService.isProjectFound("KEY01")).thenReturn(true);

ProjectAlreadyExistsException ex = assertThrows(ProjectAlreadyExistsException.class,
() -> sut.build(request, clientApp));
() -> sut.buildForCreation(request, clientApp));
assertEquals(ErrorKey.PROJECT_ALREADY_EXISTS, ex.getErrorKey());
}

@Test
void build_throws_validation_exception_when_flavor_and_config_item_are_missing() {
void build_for_creation_throws_validation_exception_when_flavor_and_config_item_are_missing() {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request(null, null, "KEY01");

ProjectValidationException ex = assertThrows(ProjectValidationException.class,
() -> sut.build(request, clientApp));
() -> sut.buildForCreation(request, clientApp));
assertEquals(ErrorKey.BAD_REQUEST_FLAVOR_CONFIG_ITEM, ex.getErrorKey());
}

@Test
void build_throws_validation_exception_when_configuration_item_matches_multiple_flavors() {
void build_for_creation_throws_validation_exception_when_configuration_item_matches_multiple_flavors() {
ClientAppEntity clientApp = build_client_app(List.of(
build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1"),
build_flavor("AMP", "CI-001", new String[] {}, "eu", "owner2")));
CreateProjectRequest request = build_request(null, "CI-001", "KEY01");

ProjectValidationException ex = assertThrows(ProjectValidationException.class,
() -> sut.build(request, clientApp));
() -> sut.buildForCreation(request, clientApp));
assertEquals(ErrorKey.INVALID_CONFIG_ITEM, ex.getErrorKey());
}

@Test
void build_throws_project_key_generation_exception_when_generation_fails() throws Exception {
void build_for_creation_throws_project_key_generation_exception_when_generation_fails() throws Exception {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, null);

when(generateProjectKeyService.generateProjectKey("DLSS%06d"))
.thenThrow(new org.opendevstack.apiservice.serviceproject.exception.ProjectKeyGenerationException("fail"));

assertThrows(ProjectCreationException.class, () -> sut.build(request, clientApp));
assertThrows(ProjectCreationException.class, () -> sut.buildForCreation(request, clientApp));
}

@Test
void build_throws_project_already_exists_exception_when_project_name_already_exists() throws Exception {
void build_for_creation_throws_project_already_exists_exception_when_project_name_already_exists() throws Exception {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");
Expand All @@ -155,11 +155,11 @@ void build_throws_project_already_exists_exception_when_project_name_already_exi
when(projectExistenceService.isProjectFound("KEY01")).thenReturn(false);
when(projectExistenceService.isProjectFoundByName("Existing Project")).thenReturn(true);

assertThrows(ProjectAlreadyExistsException.class, () -> sut.build(request, clientApp));
assertThrows(ProjectAlreadyExistsException.class, () -> sut.buildForCreation(request, clientApp));
}

@Test
void build_throws_project_creation_exception_when_project_name_check_fails() throws Exception {
void build_for_creation_throws_project_creation_exception_when_project_name_check_fails() throws Exception {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");
Expand All @@ -169,7 +169,39 @@ void build_throws_project_creation_exception_when_project_name_check_fails() thr
when(projectExistenceService.isProjectFoundByName("Any Project"))
.thenThrow(new ProjectExistenceServiceException("lookup failed"));

assertThrows(ProjectCreationException.class, () -> sut.build(request, clientApp));
assertThrows(ProjectCreationException.class, () -> sut.buildForCreation(request, clientApp));
}

@Test
void build_for_registration_resolves_defaults_from_flavor_when_request_fields_are_missing() throws ProjectExistenceServiceException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");
request.setOwner(null);
request.setLocation(null);

when(projectExistenceService.isProjectFoundInCollection("KEY01")).thenReturn(false);

ProjectCreationCommand result = sut.buildForRegistration(request, clientApp);

assertEquals("DLSS", result.getProjectFlavor());
assertEquals("CI-001", result.getConfigurationItem());
assertEquals("owner1", result.getOwner());
assertEquals("eu", result.getLocation());
assertEquals("KEY01", result.getProjectKey());
}

@Test
void build_for_registration_throws_project_already_exists_exception_when_project_key_already_exists() throws ProjectExistenceServiceException {
ClientAppProjectFlavorEntity flavor = build_flavor("DLSS", "CI-001", new String[] {}, "eu", "owner1");
ClientAppEntity clientApp = build_client_app(List.of(flavor));
CreateProjectRequest request = build_request("DLSS", null, "KEY01");

when(projectExistenceService.isProjectFoundInCollection("KEY01")).thenReturn(true);

ProjectAlreadyExistsException ex = assertThrows(ProjectAlreadyExistsException.class,
() -> sut.buildForRegistration(request, clientApp));
assertEquals(ErrorKey.PROJECT_ALREADY_EXISTS, ex.getErrorKey());
}

private CreateProjectRequest build_request(String flavor, String configItem, String projectKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void create_project_returns_success_response_when_automation_is_successful() {
apiResponse.setProjectFlavor("DLSS");

when(clientAppService.findByClientId(CLIENT_ID)).thenReturn(clientApp);
when(projectCreationCommandBuilder.build(request, clientApp)).thenReturn(command);
when(projectCreationCommandBuilder.buildForCreation(request, clientApp)).thenReturn(command);
when(projectMapper.toServiceRequest(command)).thenReturn(serviceRequest);
when(projectService.saveProject(serviceRequest)).thenReturn(projectResponse);
when(automationParametersMapper.toWorkflowParameters(command, "11111111-1111-1111-1111-111111111111"))
Expand All @@ -114,7 +114,7 @@ void create_project_returns_success_response_when_automation_is_successful() {

assertEquals("Pending", result.getStatus());
assertEquals("DLSS", result.getProjectFlavor());
verify(projectCreationCommandBuilder).build(request, clientApp);
verify(projectCreationCommandBuilder).buildForCreation(request, clientApp);
verify(projectMapper).toServiceRequest(command);
verify(automationParametersMapper)
.toWorkflowParameters(command, "11111111-1111-1111-1111-111111111111");
Expand All @@ -139,7 +139,7 @@ void create_project_with_registrationOnly_returns_success_response_when_automati
apiResponse.setProjectFlavor("REGULAR");

when(clientAppService.findByClientId(CLIENT_ID)).thenReturn(clientApp);
when(projectCreationCommandBuilder.build(request, clientApp)).thenReturn(command);
when(projectCreationCommandBuilder.buildForRegistration(request, clientApp)).thenReturn(command);
when(projectMapper.toServiceRequest(command)).thenReturn(serviceRequest);
when(projectService.saveProject(serviceRequest)).thenReturn(projectResponse);
when(projectCreationResponseMapper.toSuccessResponse(command, projectResponse)).thenReturn(apiResponse);
Expand All @@ -148,7 +148,7 @@ void create_project_with_registrationOnly_returns_success_response_when_automati

assertEquals("Running", result.getStatus());
assertEquals("REGULAR", result.getProjectFlavor());
verify(projectCreationCommandBuilder).build(request, clientApp);
verify(projectCreationCommandBuilder).buildForRegistration(request, clientApp);
verify(projectMapper).toServiceRequest(command);
verify(automationParametersMapper, never())
.toWorkflowParameters(command, "11111111-1111-1111-1111-111111111111");
Expand All @@ -164,7 +164,7 @@ void create_project_throws_project_creation_exception_when_automation_is_not_suc
"DLSS01", "name", "desc", "DLSS", "CI-001", "eu", "x2test", "owner", CLIENT_ID);

when(clientAppService.findByClientId(CLIENT_ID)).thenReturn(clientApp);
when(projectCreationCommandBuilder.build(request, clientApp)).thenReturn(command);
when(projectCreationCommandBuilder.buildForCreation(request, clientApp)).thenReturn(command);
when(projectMapper.toServiceRequest(command)).thenReturn(new ProjectRequest());
when(projectService.saveProject(any(ProjectRequest.class)))
.thenReturn(ProjectResponse.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ public interface ProjectExistenceService {
boolean isProjectFound(String projectKey) throws ProjectExistenceServiceException;

boolean isProjectFoundByName(String projecName) throws ProjectExistenceServiceException;

boolean isProjectFoundInCollection(String projectKey) throws ProjectExistenceServiceException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public boolean isProjectFoundByName(String projecName) throws ProjectExistenceSe
return !projectService.findProjectsByName(projecName).isEmpty();
}

@Override
public boolean isProjectFoundInCollection(String projectKey) throws ProjectExistenceServiceException {
return existsInCollection(projectKey);
}

private boolean existsInCollection(String projectKey) {
return projectService.getProject(projectKey) != null;
}
Expand Down
Loading