Skip to content

Commit

Permalink
feat: added full impl workspace details endpoint (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
JordenReuter authored Feb 23, 2024
1 parent ed592d0 commit 344511f
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 13 deletions.
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,19 @@
<skipCache>true</skipCache>
</configuration>
</execution>
<execution>
<id>product-store-svc-external-v1</id>
<phase>generate-resources</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://raw.githubusercontent.com/onecx/onecx-product-store-svc/main/src/main/openapi/onecx-product-store-v1.yaml</url>
<outputDirectory>target/tmp/openapi</outputDirectory>
<outputFileName>onecx-product-store-svc-v1.yaml</outputFileName>
<skipCache>true</skipCache>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.tkit.onecx.permission.bff.rs.controllers;

import java.util.Arrays;
import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
Expand All @@ -10,9 +13,14 @@
import org.tkit.quarkus.log.cdi.LogService;

import gen.org.tkit.onecx.permission.bff.rs.internal.WorkspaceApiService;
import gen.org.tkit.onecx.permission.bff.rs.internal.model.WorkspaceDetailsDTO;
import gen.org.tkit.onecx.permission.client.api.ProductExternalApi;
import gen.org.tkit.onecx.permission.client.api.WorkspaceExternalApi;
import gen.org.tkit.onecx.permission.client.model.Product;
import gen.org.tkit.onecx.permission.client.model.Workspace;
import gen.org.tkit.onecx.product.store.client.api.ProductsApi;
import gen.org.tkit.onecx.product.store.client.model.ProductItemLoadSearchCriteria;
import gen.org.tkit.onecx.product.store.client.model.ProductsLoadResult;

@ApplicationScoped
@Transactional(value = Transactional.TxType.NOT_SUPPORTED)
Expand All @@ -27,6 +35,10 @@ public class WorkspaceRestController implements WorkspaceApiService {
@Inject
ProductExternalApi productClient;

@RestClient
@Inject
ProductsApi productStoreClient;

@Inject
WorkspaceMapper mapper;

Expand All @@ -43,4 +55,32 @@ public Response getAllWorkspaceNames() {
return Response.status(response.getStatus()).entity(response.readEntity(String[].class)).build();
}
}

@Override
public Response getDetailsByWorkspaceName(String workspaceName) {
try (Response response = workspaceClient.getWorkspaceByName(workspaceName)) {
WorkspaceDetailsDTO workspaceDetails;
List<String> productNames;
List<String> workspaceRoles;
ProductsLoadResult productsLoadResult;
var workspaceResponse = response.readEntity(Workspace.class);
workspaceRoles = workspaceResponse.getWorkspaceRoles().stream().toList();

//get products of workspace
try (Response wsProductsResponse = productClient.getProducts(workspaceName)) {
//list of product names registered in workspace
productNames = Arrays.stream(wsProductsResponse.readEntity(Product[].class))
.map(Product::getProductName).toList();

//get mfe and ms for each product by name from product-store
ProductItemLoadSearchCriteria mfeAndMsCriteria = new ProductItemLoadSearchCriteria();
mfeAndMsCriteria.setProductNames(productNames);
try (Response productStoreResponse = productStoreClient.loadProductsByCriteria(mfeAndMsCriteria)) {
productsLoadResult = productStoreResponse.readEntity(ProductsLoadResult.class);
}
workspaceDetails = mapper.map(workspaceRoles, productsLoadResult);
}
return Response.status(Response.Status.OK).entity(workspaceDetails).build();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
package org.tkit.onecx.permission.bff.rs.mappers;

import java.util.List;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper;

import gen.org.tkit.onecx.permission.bff.rs.internal.model.ProductDTO;
import gen.org.tkit.onecx.permission.bff.rs.internal.model.ProductDetailsDTO;
import gen.org.tkit.onecx.permission.bff.rs.internal.model.WorkspaceDetailsDTO;
import gen.org.tkit.onecx.permission.client.model.Product;
import gen.org.tkit.onecx.product.store.client.model.ProductsAbstract;
import gen.org.tkit.onecx.product.store.client.model.ProductsLoadResult;

@Mapper(uses = { OffsetDateTimeMapper.class })
public interface WorkspaceMapper {
ProductDTO[] map(Product[] products);

ProductDTO map(Product product);

@Mapping(target = "removeMsItem", ignore = true)
@Mapping(target = "removeMfeItem", ignore = true)
@Mapping(target = "productName", source = "name")
@Mapping(target = "ms", source = "microservices")
@Mapping(target = "mfe", source = "microfrontends")
ProductDetailsDTO map(ProductsAbstract productsAbstract);

List<ProductDetailsDTO> map(List<ProductsAbstract> productsAbstracts);

default WorkspaceDetailsDTO map(List<String> workspaceRoles, ProductsLoadResult productsLoadResult) {
WorkspaceDetailsDTO workspaceDetailsDTO = new WorkspaceDetailsDTO();
workspaceDetailsDTO.setWorkspaceRoles(workspaceRoles);
workspaceDetailsDTO.setProducts(map(productsLoadResult.getStream()));
return workspaceDetailsDTO;
}
}
70 changes: 58 additions & 12 deletions src/main/openapi/openapi-bff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/RolePageResult'
$ref: '#/components/schemas/RolePageResult'
400:
description: Bad request
content:
Expand Down Expand Up @@ -174,9 +172,7 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PermissionPageResult'
$ref: '#/components/schemas/PermissionPageResult'
400:
description: Bad request
content:
Expand Down Expand Up @@ -205,9 +201,7 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AssignmentPageResult'
$ref: '#/components/schemas/AssignmentPageResult'
400:
description: Bad request
content:
Expand Down Expand Up @@ -316,9 +310,7 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ApplicationPageResult'
$ref: '#/components/schemas/ApplicationPageResult'
400:
description: Bad request
content:
Expand Down Expand Up @@ -367,6 +359,29 @@ paths:
type: array
items:
$ref: '#/components/schemas/Product'
/workspaces/{workspaceName}/details:
get:
x-onecx:
permissions:
permission:
- read
tags:
- workspace
description: get detailed information to all workspace related products and roles
operationId: getDetailsByWorkspaceName
parameters:
- name: workspaceName
in: path
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/WorkspaceDetails'
components:
schemas:
CreateRoleRequest:
Expand Down Expand Up @@ -655,6 +670,37 @@ components:
type: string
baseUrl:
type: string
WorkspaceDetails:
type: object
properties:
workspaceRoles:
type: array
items:
type: string
products:
type: array
items:
$ref: '#/components/schemas/ProductDetails'
ProductDetails:
type: object
properties:
productName:
type: string
mfe:
type: array
items:
$ref: '#/components/schemas/MfeMsAbstract'
ms:
type: array
items:
$ref: '#/components/schemas/MfeMsAbstract'
MfeMsAbstract:
type: object
properties:
appName:
type: string
appId:
type: string
OffsetDateTime:
format: date-time
type: string
Expand Down
9 changes: 8 additions & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ org.eclipse.microprofile.rest.client.propagateHeaders=apm-principal-token
# PROD
%prod.quarkus.rest-client.onecx_permission_svc.url=http://onecx-permission-svc:8080
%prod.quarkus.rest-client.onecx_workspace_svc.url=http://onecx-workspace-svc:8080
%prod.quarkus.rest-client.onecx_product_store_svc.url=http://onecx-product-store-svc:8080
%prod.quarkus.oidc-client.client-id=${quarkus.application.name}

# DEV
%dev.quarkus.rest-client.onecx_workspace_svc.url=${quarkus.mockserver.endpoint}
%dev.quarkus.rest-client.onecx_permission_svc.url=${quarkus.mockserver.endpoint}
%dev.quarkus.rest-client.onecx_product_store_svc.url=${quarkus.mockserver.endpoint}

%dev.quarkus.oidc-client.auth-server-url=${quarkus.oidc.auth-server-url}
%dev.quarkus.oidc-client.client-id=${quarkus.oidc.client-id}
Expand All @@ -37,7 +39,11 @@ quarkus.openapi-generator.codegen.spec.onecx_workspace_svc_v1_yaml.config-key=on
quarkus.openapi-generator.codegen.spec.onecx_workspace_svc_v1_yaml.base-package=gen.org.tkit.onecx.permission.client
quarkus.openapi-generator.codegen.spec.onecx_workspace_svc_v1_yaml.return-response=true
quarkus.openapi-generator.codegen.spec.onecx_workspace_svc_v1_yaml.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;

# product-store client
quarkus.openapi-generator.codegen.spec.onecx_product_store_svc_v1_yaml.config-key=onecx_product_store_svc
quarkus.openapi-generator.codegen.spec.onecx_product_store_svc_v1_yaml.base-package=gen.org.tkit.onecx.product.store.client
quarkus.openapi-generator.codegen.spec.onecx_product_store_svc_v1_yaml.return-response=true
quarkus.openapi-generator.codegen.spec.onecx_product_store_svc_v1_yaml.additional-api-type-annotations=@org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
# INTEGRATION TEST
quarkus.test.integration-test-profile=test

Expand All @@ -52,6 +58,7 @@ quarkus.test.integration-test-profile=test
%test.onecx.permissions.product-name=applications
%test.quarkus.rest-client.onecx_permission_svc.url=${quarkus.mockserver.endpoint}
%test.quarkus.rest-client.onecx_workspace_svc.url=${quarkus.mockserver.endpoint}
%test.quarkus.rest-client.onecx_product_store_svc.url=${quarkus.mockserver.endpoint}
%test.tkit.rs.context.token.header-param=apm-principal-token
%test.tkit.rs.context.token.enabled=false
%test.quarkus.rest-client.onecx_permission_svc.providers=io.quarkus.oidc.client.reactive.filter.OidcClientRequestReactiveFilter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.core.Response;
Expand All @@ -17,7 +19,10 @@
import org.tkit.onecx.permission.bff.rs.controllers.WorkspaceRestController;

import gen.org.tkit.onecx.permission.bff.rs.internal.model.ProductDTO;
import gen.org.tkit.onecx.permission.bff.rs.internal.model.WorkspaceDetailsDTO;
import gen.org.tkit.onecx.permission.client.model.Product;
import gen.org.tkit.onecx.permission.client.model.Workspace;
import gen.org.tkit.onecx.product.store.client.model.*;
import io.quarkiverse.mockserver.test.InjectMockServerClient;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
Expand Down Expand Up @@ -93,4 +98,98 @@ void getAllProductsByWorkspaceNameTest() {
Assertions.assertEquals(2, Arrays.stream(output).toList().size());
}

@Test
void getDetailsByWorkspaceNameTest() {

String workspaceName = "test-workspace";
Workspace workspace = new Workspace();
workspace.name("test-workspace").workspaceRoles(Set.of("role1", "role2"));

// create mock rest endpoint
mockServerClient
.when(request().withPath("/v1/workspaces/name/" + workspaceName).withMethod(HttpMethod.GET))
.withId(MOCKID)
.respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode())
.withBody(JsonBody.json(workspace)));

List<Product> productsOfWorkspace = new ArrayList<>();
Product product1 = new Product();
product1.productName("product1");
Product product2 = new Product();
product2.productName("product2");
productsOfWorkspace.add(product1);
productsOfWorkspace.add(product2);

// create mock rest endpoint
mockServerClient
.when(request().withPath("/v1/workspaces/" + workspaceName + "/products").withMethod(HttpMethod.GET))
.withId("MOCKID2")
.respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode())
.withBody(JsonBody.json(productsOfWorkspace)));

List<String> productNames = List.of("product1", "product2");
ProductItemLoadSearchCriteria criteria = new ProductItemLoadSearchCriteria();
criteria.setProductNames(productNames);

ProductsLoadResult result = new ProductsLoadResult();

ProductsAbstract productsAbstract1 = new ProductsAbstract();
productsAbstract1.setName("product1");
MicrofrontendAbstract mfe1 = new MicrofrontendAbstract();
mfe1.appId("mfe1").appName("mfe1");
MicroserviceAbstract ms1 = new MicroserviceAbstract();
ms1.appId("ms1").appName("ms1");
productsAbstract1.setMicrofrontends(List.of(mfe1));
productsAbstract1.setMicroservices(List.of(ms1));

ProductsAbstract productsAbstract2 = new ProductsAbstract();
productsAbstract2.setName("product2");
MicrofrontendAbstract mfe2 = new MicrofrontendAbstract();
mfe2.appId("mfe2").appName("mfe2");
MicroserviceAbstract ms2 = new MicroserviceAbstract();
ms2.appId("ms2").appName("ms2");
productsAbstract2.setMicrofrontends(List.of(mfe2));
productsAbstract2.setMicroservices(List.of(ms2));

result.setStream(List.of(productsAbstract1, productsAbstract2));
result.setTotalElements(2L);
result.setNumber(0);
result.setSize(2);
result.setTotalPages(1L);

// create mock rest endpoint
mockServerClient
.when(request().withPath("/v1/products/load").withMethod(HttpMethod.POST)
.withBody(JsonBody.json(criteria)))
.withId("MOCKID3")
.respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode())
.withBody(JsonBody.json(result)));

var output = given()
.when()
.auth().oauth2(keycloakClient.getAccessToken(ADMIN))
.header(APM_HEADER_PARAM, ADMIN)
.pathParam("workspaceName", workspaceName)
.get("/{workspaceName}/details")
.then()
.statusCode(Response.Status.OK.getStatusCode())
.extract().as(WorkspaceDetailsDTO.class);

Assertions.assertNotNull(output);
Assertions.assertEquals(2, output.getProducts().size());
Assertions.assertTrue(output.getWorkspaceRoles().contains("role1"));
Assertions.assertTrue(output.getWorkspaceRoles().contains("role2"));
Assertions.assertEquals(1, output.getProducts().get(0).getMfe().size());
Assertions.assertEquals(1, output.getProducts().get(0).getMs().size());
Assertions.assertNotNull(output.getProducts().get(0).getMfe().get(0).getAppId());

Assertions.assertEquals(1, output.getProducts().get(1).getMfe().size());
Assertions.assertEquals(1, output.getProducts().get(1).getMs().size());
Assertions.assertNotNull(output.getProducts().get(1).getMs().get(0).getAppId());

mockServerClient.clear(MOCKID);
mockServerClient.clear("MOCKID2");
mockServerClient.clear("MOCKID3");
}

}

0 comments on commit 344511f

Please sign in to comment.