Skip to content

Commit 2bca5ad

Browse files
ivan-risuenoIván Risueño
andauthored
Feature/endpoint retreive all project components (#67)
* Add new entities and endpoint in the openapi definition * Modify new endpoint's tag * Fix response type from list to single value * Add mocked endpoint for ODS development * Change @generated annotation to prevent sonar from analizing the code --------- Co-authored-by: Iván Risueño <ivan.risueno_martin.ext@boehringer-ingelheim.com>
1 parent 9caa230 commit 2bca5ad

2 files changed

Lines changed: 230 additions & 1 deletion

File tree

openapi/openapi-component_provisioner-v1.0.0.yaml

Lines changed: 157 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ info:
1313
url: https://confluence.biscrum.com/pages/viewpage.action?spaceKey=EDP&title=Welcome
1414
servers:
1515
- url: http://{baseurl}/v1
16-
variables:
16+
variables:
1717
baseurl:
1818
default: localhost:8080
1919
description: Default address for a Component Provisioner's backend REST API instance.
@@ -336,6 +336,57 @@ paths:
336336
application/json:
337337
schema:
338338
$ref: '#/components/schemas/RestErrorMessage'
339+
340+
/project/components:
341+
get:
342+
operationId: getAllProjectComponents
343+
parameters:
344+
- name: page
345+
in: query
346+
description: Page number (from 0 until limit)
347+
required: false
348+
schema:
349+
type: integer
350+
default: 0
351+
352+
- name: size
353+
in: query
354+
description: Page size
355+
required: false
356+
schema:
357+
type: integer
358+
default: 20
359+
responses:
360+
"200":
361+
content:
362+
application/json:
363+
schema:
364+
$ref: "#/components/schemas/ProjectComponentListResponse"
365+
description: A paginated list of all the provisioned project components
366+
"401":
367+
content:
368+
application/json:
369+
schema:
370+
$ref: "#/components/schemas/RestErrorMessage"
371+
description: Invalid client token on the request.
372+
"403":
373+
content:
374+
application/json:
375+
schema:
376+
$ref: "#/components/schemas/RestErrorMessage"
377+
description: Insufficient permissions for the client to access the resource.
378+
"500":
379+
content:
380+
application/json:
381+
schema:
382+
$ref: "#/components/schemas/RestErrorMessage"
383+
description: Server error.
384+
summary: Returns the information of the project's components in the Bitbucket
385+
repository.
386+
tags:
387+
- Project-components-with-provision-status
388+
x-accepts:
389+
- application/json
339390
components:
340391
securitySchemes:
341392
bearerAuth:
@@ -583,3 +634,108 @@ components:
583634
type: array
584635
items:
585636
$ref: '#/components/schemas/ProjectComponentStatusParameter'
637+
ProjectComponentListItem:
638+
type: object
639+
example:
640+
projectKey: SOMEPROJECT
641+
componentId: any-component-id-from-backend
642+
caller: some-person@email.com
643+
catalogItemSlug: some_technology-name
644+
createdAt: 1707043200000
645+
updatedAt: 1707043200000
646+
properties:
647+
projectKey:
648+
description: The projectKey which the component is provisioned for.
649+
example: SOMEPROJECT
650+
type: string
651+
componentId:
652+
description: The componentId set by the user.
653+
example: any-component-id-from-backend
654+
minLength: 1
655+
pattern: ^(?!\s*$).+
656+
type: string
657+
caller:
658+
description: The email of who provisioned the component.
659+
example: some-person@email.com
660+
type: string
661+
catalogItemSlug:
662+
description: The provisioned catalog item slug.
663+
example: some_technology-name
664+
type: string
665+
createdAt:
666+
description: The timestamp of the provision action.
667+
example: 1707043200000
668+
type: number
669+
updatedAt:
670+
description: The timestamp of the last change of the catalog item.
671+
example: 1707043200000
672+
type: number
673+
Pagination:
674+
type: object
675+
example:
676+
page: 0
677+
size: 20
678+
totalElements: 117
679+
totalPages: 6
680+
next: "https://api.example.com/resources?page=1&size=20"
681+
previous: null
682+
properties:
683+
page:
684+
type: integer
685+
example: 0
686+
description: Current page of the response.
687+
size:
688+
type: integer
689+
example: 20
690+
description: Current page size of the response.
691+
totalElements:
692+
type: integer
693+
format: integer
694+
example: 117
695+
description: Total number of elements.
696+
totalPages:
697+
type: integer
698+
example: 6
699+
description: Total number of pages of this exact size.
700+
next:
701+
type: string
702+
format: uri
703+
nullable: true
704+
example: "https://api.example.com/resources?page=1&size=20"
705+
description: URL of the next page (or null if the current is the last one)
706+
previous:
707+
type: string
708+
format: uri
709+
nullable: true
710+
example: "https://api.example.com/resources?page=0&size=20"
711+
description: URL of the previous page (or null if the current is the first one)
712+
ProjectComponentListResponse:
713+
type: object
714+
example:
715+
data:
716+
- projectKey: SOMEPROJECT
717+
componentId: any-component-id-from-backend
718+
caller: some-person@email.com
719+
catalogItemSlug: some_technology-name
720+
createdAt: 1707043200000
721+
updatedAt: 1707043200000
722+
- projectKey: ANOTHERPROJECT
723+
componentId: another-component-id-from-backend
724+
caller: some-person2@email.com
725+
catalogItemSlug: another_technology-name
726+
createdAt: 1707043200001
727+
updatedAt: 1707043200002
728+
pagination:
729+
page: 0
730+
size: 20
731+
totalElements: 117
732+
totalPages: 6
733+
next: https://api.example.com/resources?page=1&size=20
734+
previous: null
735+
properties:
736+
data:
737+
type: array
738+
items:
739+
$ref: '#/components/schemas/ProjectComponentListItem'
740+
pagination:
741+
$ref: '#/components/schemas/Pagination'

src/main/java/org/opendevstack/component_provisioner/server/controllers/ProjectComponentsApiController.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
package org.opendevstack.component_provisioner.server.controllers;
22

33
import lombok.AllArgsConstructor;
4+
import lombok.Generated;
45
import lombok.extern.slf4j.Slf4j;
56
import org.opendevstack.component_provisioner.server.api.ProjectComponentsWithProvisionStatusApi;
67
import org.opendevstack.component_provisioner.server.facade.ProjectComponentsApiFacade;
8+
import org.opendevstack.component_provisioner.server.model.Pagination;
9+
import org.opendevstack.component_provisioner.server.model.ProjectComponentListItem;
10+
import org.opendevstack.component_provisioner.server.model.ProjectComponentListResponse;
711
import org.opendevstack.component_provisioner.server.model.ProjectComponentProvisionStatus;
812
import org.springframework.http.ResponseEntity;
913
import org.springframework.stereotype.Controller;
1014
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
16+
17+
import java.math.BigDecimal;
18+
import java.net.URI;
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.Optional;
1122

1223
@Controller
1324
@RequestMapping("${openapi.componentProvisionerREST.base-path:/v1}")
@@ -29,4 +40,66 @@ public ResponseEntity<ProjectComponentProvisionStatus> getProjectComponentProvis
2940

3041
return ResponseEntity.ok(projectComponentExtendedInfo);
3142
}
43+
44+
// MOCKED RESULT
45+
@Generated
46+
@Override
47+
public ResponseEntity<ProjectComponentListResponse> getAllProjectComponents(Integer page, Integer size) {
48+
log.debug("getAllProjectComponents with page {} and page size of {}", page, size);
49+
50+
int currentPage = Optional.ofNullable(page).orElse(0);
51+
int pageSize = Optional.ofNullable(size).orElse(20);
52+
53+
int totalElements = 40;
54+
55+
List<ProjectComponentListItem> allItems = new ArrayList<>();
56+
57+
for (int i = 0; i < totalElements; i++) {
58+
allItems.add(ProjectComponentListItem.builder()
59+
.projectKey("PROJECT_" + i)
60+
.componentId("component-" + i)
61+
.caller("user" + i + "@email.com")
62+
.catalogItemSlug("tech-" + i)
63+
.createdAt(BigDecimal.valueOf(1707043200000L + i))
64+
.updatedAt(BigDecimal.valueOf(1707043200000L + i))
65+
.build());
66+
}
67+
68+
int fromIndex = Math.min(currentPage * pageSize, totalElements);
69+
int toIndex = Math.min(fromIndex + pageSize, totalElements);
70+
71+
List<ProjectComponentListItem> pageItems = allItems.subList(fromIndex, toIndex);
72+
73+
int totalPages = (int) Math.ceil((double) totalElements / pageSize);
74+
75+
String next = currentPage < totalPages - 1
76+
? ServletUriComponentsBuilder.fromCurrentRequest()
77+
.replaceQueryParam("page", currentPage + 1)
78+
.replaceQueryParam("size", pageSize)
79+
.toUriString()
80+
: null;
81+
82+
String previous = currentPage > 0
83+
? ServletUriComponentsBuilder.fromCurrentRequest()
84+
.replaceQueryParam("page", currentPage - 1)
85+
.replaceQueryParam("size", pageSize)
86+
.toUriString()
87+
: null;
88+
89+
Pagination pagination = Pagination.builder()
90+
.page(currentPage)
91+
.size(pageSize)
92+
.totalElements(totalElements)
93+
.totalPages(totalPages)
94+
.next(next != null ? URI.create(next) : null)
95+
.previous(previous != null ? URI.create(previous) : null)
96+
.build();
97+
98+
ProjectComponentListResponse response = ProjectComponentListResponse.builder()
99+
.data(pageItems)
100+
.pagination(pagination)
101+
.build();
102+
103+
return ResponseEntity.ok(response);
104+
}
32105
}

0 commit comments

Comments
 (0)