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 @@ -12,14 +12,14 @@ servers:
default: localhost:8080
description: Development environment
tags:
- name: ProjectComponents
- name: Project Components
description: API for managing project components

paths:
/projects/{projectId}/components/:
post:
tags:
- projectComponents
- Project Components
summary: Create a component in a project
operationId: createProjectComponent
description: Retrieves information about a specific component
Expand Down Expand Up @@ -61,7 +61,7 @@ paths:
/projects/{projectId}/components/{componentId}:
get:
tags:
- projectComponents
- Project Components
summary: Get component information
operationId: getProjectComponent
description: Retrieves information about a specific component
Expand Down
7 changes: 7 additions & 0 deletions api-project-component-v0/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.opendevstack.apiservice</groupId>
<artifactId>external-service-marketplace</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
Expand Down Expand Up @@ -89,6 +95,7 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ public static CreateComponentResponse error(String projectId) {
return response;
}

public static CreateComponentResponse entityCreated(String projectId, String componentName) {
public static CreateComponentResponse entityCreated(String projectId, String componentId) {
CreateComponentResponse response = new CreateComponentResponse();
response.setErrorCode(HttpStatus.CREATED.value());
response.setMessage(componentName + " component created successfully in project " + projectId);
response.setMessage(componentId + " component created successfully in project " + projectId);
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opendevstack.apiservice.project.api.ProjectComponentsApi;
import org.opendevstack.apiservice.project.facade.ComponentsFacade;
import org.opendevstack.apiservice.project.mapper.ComponentResponseMapper;
import org.opendevstack.apiservice.project.model.Component;
import org.opendevstack.apiservice.project.model.CreateComponentRequest;
import org.opendevstack.apiservice.project.model.CreateComponentResponse;
import org.opendevstack.apiservice.project.facade.ComponentsFacade;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/api/pub/v0")
public class ProjectComponentsController implements ProjectComponentsApi {

private final ComponentsFacade componentsFacade;
Expand All @@ -25,11 +27,12 @@ public class ProjectComponentsController implements ProjectComponentsApi {
public ResponseEntity<CreateComponentResponse> createProjectComponent(String projectId, CreateComponentRequest createComponentRequest) {
try {
Component component = componentsFacade.createProjectComponent(projectId, createComponentRequest);
log.info("Created component {} for project id {} and request {}", component, projectId, createComponentRequest);
if (component == null) {
log.error("Failed to create component for project '{}'", projectId);
return componentResponseMapper.toResponseEntity(ComponentsResponseFactory.error(projectId));
}
return componentResponseMapper.toResponseEntity(ComponentsResponseFactory.entityCreated(projectId, component.getName()));
return componentResponseMapper.toResponseEntity(ComponentsResponseFactory.entityCreated(projectId, component.getId()));
} catch (Exception e) {
log.error("Error while trying to create component for project '" + projectId + "': " + e.getMessage(), e);
return componentResponseMapper.toResponseEntity(ComponentsResponseFactory.error(projectId));
Expand All @@ -40,6 +43,7 @@ public ResponseEntity<CreateComponentResponse> createProjectComponent(String pro
public ResponseEntity<Component> getProjectComponent(String projectId, String componentId) {
try {
Component component = componentsFacade.getProjectComponent(projectId, componentId);
log.info("Retrieved component '{}' for project '{}': {}", componentId, projectId, component);
if (component == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,41 @@

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opendevstack.apiservice.externalservice.api.ExternalService;
import org.opendevstack.apiservice.externalservice.marketplace.model.CreateComponentParameter;
import org.opendevstack.apiservice.externalservice.marketplace.model.ProjectComponent;
import org.opendevstack.apiservice.externalservice.marketplace.service.MarketplaceService;
import org.opendevstack.apiservice.project.mapper.MarketplaceMapper;
import org.opendevstack.apiservice.project.model.Component;
import org.opendevstack.apiservice.project.model.CreateComponentRequest;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@AllArgsConstructor
@Slf4j
public class ComponentsFacade {

private final MarketplaceExternalServicePlaceholder marketplaceExternalService;

public Component getProjectComponent(String projectId, String componentId) {
return marketplaceExternalService.getProjectComponent(projectId, componentId);
}

public Component createProjectComponent(String projectId, CreateComponentRequest createComponentRequest) {
return marketplaceExternalService.createProjectComponent(projectId, createComponentRequest);
}

@Service
class MarketplaceExternalServicePlaceholder implements ExternalService {
private final MarketplaceService marketplaceExternalService;

@Override
public boolean isHealthy() {
return false;
}
private final MarketplaceMapper marketplaceMapper;

public Component getProjectComponent(String projectId, String componentId) {
log.info("Get component with id '" + componentId + "' for project '" + projectId + "'");
public Component getProjectComponent(String projectId, String componentId) {
ProjectComponent marketplaceComponent = marketplaceExternalService.getProjectComponent(projectId, componentId);
if (marketplaceComponent == null) {
log.info("Marketplace component with id {} not found", componentId);
return null;
}
return marketplaceMapper.mapMarketplaceComponentToV0Component(marketplaceComponent);
}

public Component createProjectComponent(String projectId, CreateComponentRequest createComponentRequest) {
log.info("Creating component for project '" + projectId + "'" + " with request: " + createComponentRequest);
public Component createProjectComponent(String projectId, CreateComponentRequest createComponentRequest) {
List<CreateComponentParameter> createComponentParameterList = marketplaceMapper.mapCreateComponentRequestToCreateComponentParameterList(createComponentRequest);
ProjectComponent marketplaceComponent = marketplaceExternalService.createProjectComponent(projectId, createComponentParameterList);
if (marketplaceComponent == null) {
log.error("Failed to create component in marketplace for project with id {}", projectId);
return null;
}
return marketplaceMapper.mapMarketplaceComponentToV0Component(marketplaceComponent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.opendevstack.apiservice.project.mapper;


import org.mapstruct.Mapper;
import org.opendevstack.apiservice.externalservice.marketplace.model.CreateComponentParameter;
import org.opendevstack.apiservice.externalservice.marketplace.model.ProjectComponent;
import org.opendevstack.apiservice.project.model.Component;
import org.opendevstack.apiservice.project.model.CreateComponentRequest;

import java.util.List;

@Mapper(componentModel = "spring")
public interface MarketplaceMapper {

default Component mapMarketplaceComponentToV0Component(ProjectComponent source) {
if (source == null) {
return null;
}
Component target = new Component();
target.setId(source.getComponentId());
target.setStatus(source.getStatus());
return target;
}

default List<CreateComponentParameter> mapCreateComponentRequestToCreateComponentParameterList(CreateComponentRequest createComponentRequest) {
return createComponentRequest.getParams().entrySet().stream()
.map(entry -> new CreateComponentParameter(entry.getKey(), "string", entry.getValue()))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void testCreateProjectComponent_whenSuccess_thenReturnOk() throws Exception {
Component testComponent = buildTestComponent();
String testProjectId = "testProjectId";
CreateComponentRequest testCreateComponentRequest = buildTestCreateComponentRequest();
CreateComponentResponse testServiceResponseSuccess = buildTestCreateComponentResponseSuccess(testComponent.getName(),
CreateComponentResponse testServiceResponseSuccess = buildTestCreateComponentResponseSuccess(testComponent.getId(),
testProjectId);

when(componentsFacade.createProjectComponent(anyString(), any(CreateComponentRequest.class)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,55 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mapstruct.factory.Mappers;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.opendevstack.apiservice.externalservice.marketplace.model.ProjectComponent;
import org.opendevstack.apiservice.externalservice.marketplace.service.MarketplaceService;
import org.opendevstack.apiservice.project.mapper.MarketplaceMapper;
import org.opendevstack.apiservice.project.model.Component;
import org.opendevstack.apiservice.project.model.CreateComponentRequest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import static org.opendevstack.apiservice.project.util.TestObjectsBuilder.buildTestComponent;
import static org.opendevstack.apiservice.project.util.TestObjectsBuilder.buildTestCreateComponentRequest;
import static org.opendevstack.apiservice.project.util.TestObjectsBuilder.buildTestMarketplaceComponent;

@ExtendWith(MockitoExtension.class)
class ComponentsServiceTest {
class ComponentsFacadeTest {

private final MarketplaceMapper marketplaceMapper = Mappers.getMapper(MarketplaceMapper.class);

@Mock
private ComponentsFacade.MarketplaceExternalServicePlaceholder marketPlaceExternalServicePlaceholder;
private MarketplaceService marketplaceExternalService;

private ComponentsFacade componentsFacade;

@BeforeEach
void setup() {
componentsFacade = new ComponentsFacade(marketPlaceExternalServicePlaceholder);
componentsFacade = new ComponentsFacade(marketplaceExternalService, marketplaceMapper);
}

@Test
void testGetProjectComponent_whenSuccess_thenReturnCorrectComponent() throws Exception {
Component testComponent = buildTestComponent();
ProjectComponent testComponent = buildTestMarketplaceComponent();

when(marketPlaceExternalServicePlaceholder.getProjectComponent(anyString(), eq("testId")))
when(marketplaceExternalService.getProjectComponent(anyString(), eq("testId")))
.thenReturn(testComponent);

Component retrievedComponent = componentsFacade.getProjectComponent("testId", "testId");
assertThat(retrievedComponent).isEqualTo(testComponent);
assertThat(retrievedComponent.getId()).isEqualTo(testComponent.getComponentId());
assertThat(retrievedComponent.getStatus()).isEqualTo(testComponent.getStatus());
}

@Test
void testGetProjectComponent_whenNoComponentFound_thenReturnNull() throws Exception {
when(marketPlaceExternalServicePlaceholder.getProjectComponent(anyString(), eq("testId")))
when(marketplaceExternalService.getProjectComponent(anyString(), eq("testId")))
.thenReturn(null);

Component retrievedComponent = componentsFacade.getProjectComponent("testId", "testId");
Expand All @@ -50,22 +60,23 @@ void testGetProjectComponent_whenNoComponentFound_thenReturnNull() throws Except

@Test
void testCreateProjectComponent_whenSuccess_thenReturnCorrectComponent() throws Exception {
Component testComponent = buildTestComponent();
ProjectComponent testComponent = buildTestMarketplaceComponent();
CreateComponentRequest testRequest = buildTestCreateComponentRequest();

when(marketPlaceExternalServicePlaceholder.createProjectComponent(anyString(), eq(testRequest)))
when(marketplaceExternalService.createProjectComponent(anyString(), any(List.class)))
.thenReturn(testComponent);

Component retrievedComponent = componentsFacade.createProjectComponent("testId", testRequest);
assertThat(retrievedComponent).isEqualTo(testComponent);
assertThat(retrievedComponent.getId()).isEqualTo(testComponent.getComponentId());
assertThat(retrievedComponent.getStatus()).isEqualTo(testComponent.getStatus());
}


@Test
void testCreateProjectComponent_whenFailure_thenReturnNull() throws Exception {
CreateComponentRequest testRequest = buildTestCreateComponentRequest();

when(marketPlaceExternalServicePlaceholder.createProjectComponent(anyString(), eq(testRequest)))
when(marketplaceExternalService.createProjectComponent(anyString(), any(List.class)))
.thenReturn(null);

Component retrievedComponent = componentsFacade.createProjectComponent("testId", testRequest);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.opendevstack.apiservice.project.util;

import org.opendevstack.apiservice.externalservice.marketplace.model.CreateComponentParameter;
import org.opendevstack.apiservice.externalservice.marketplace.model.ProjectComponent;
import org.opendevstack.apiservice.project.model.Component;
import org.opendevstack.apiservice.project.model.CreateComponentRequest;
import org.opendevstack.apiservice.project.model.CreateComponentResponse;
import org.springframework.http.HttpStatus;

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

public class TestObjectsBuilder {

private TestObjectsBuilder() {
Expand All @@ -19,17 +24,32 @@ public static Component buildTestComponent() {
return component;
}

public static ProjectComponent buildTestMarketplaceComponent() {
ProjectComponent component = new ProjectComponent();
component.setComponentId("testComponentId");
component.setCanBeDeleted(false);
component.setComponentUrl("http://test.component.url");
return component;
}

public static CreateComponentRequest buildTestCreateComponentRequest() {
CreateComponentRequest request = new CreateComponentRequest();
request.setName("testComponentName");
request.setProductId("testProductId");
return request;
}

public static CreateComponentResponse buildTestCreateComponentResponseSuccess(String componentName, String projectId) {
public static List<CreateComponentParameter> buildTestMarketplaceCreateComponentParameters() {
List<CreateComponentParameter> parameters = new ArrayList<>();
parameters.add(new CreateComponentParameter("name", "string", "testComponentName"));
parameters.add(new CreateComponentParameter("productId", "string", "testProductId"));
return parameters;
}

public static CreateComponentResponse buildTestCreateComponentResponseSuccess(String componentId, String projectId) {
CreateComponentResponse response = new CreateComponentResponse();
response.setErrorCode(HttpStatus.CREATED.value());
response.setMessage(componentName + " component created successfully in project " + projectId);
response.setMessage(componentId + " component created successfully in project " + projectId);
return response;
}

Expand Down
12 changes: 12 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.opendevstack.apiservice</groupId>
<artifactId>external-service-marketplace</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.opendevstack.apiservice</groupId>
<artifactId>api-project-users</artifactId>
Expand All @@ -121,6 +127,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.opendevstack.apiservice</groupId>
<artifactId>api-project-component-v0</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.opendevstack.apiservice</groupId>
<artifactId>api-project-platform</artifactId>
Expand Down
Loading
Loading