Skip to content

Commit e2427b7

Browse files
committed
feat: implement backend for creating portal navigation items.
1 parent 85d1413 commit e2427b7

File tree

45 files changed

+2275
-242
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2275
-242
lines changed

gravitee-apim-rest-api/gravitee-apim-rest-api-automation/gravitee-apim-rest-api-automation-rest/src/test/java/io/gravitee/apim/rest/api/automation/spring/ResourceContextConfiguration.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@
101101
import io.gravitee.apim.core.plugin.crud_service.PolicyPluginCrudService;
102102
import io.gravitee.apim.core.plugin.domain_service.EndpointConnectorPluginDomainService;
103103
import io.gravitee.apim.core.policy.domain_service.PolicyValidationDomainService;
104+
import io.gravitee.apim.core.portal_page.domain_service.CreatePortalNavigationItemValidatorService;
105+
import io.gravitee.apim.core.portal_page.use_case.CreatePortalNavigationItemUseCase;
104106
import io.gravitee.apim.core.portal_page.use_case.GetPortalPageContentUseCase;
105107
import io.gravitee.apim.core.portal_page.use_case.ListPortalNavigationItemsUseCase;
106108
import io.gravitee.apim.core.promotion.service_provider.CockpitPromotionServiceProvider;
@@ -856,6 +858,16 @@ public CreatePromotionUseCase createPromotionUseCase() {
856858
return mock(CreatePromotionUseCase.class);
857859
}
858860

861+
@Bean
862+
public CreatePortalNavigationItemUseCase createPortalNavigationItemUseCase() {
863+
return mock(CreatePortalNavigationItemUseCase.class);
864+
}
865+
866+
@Bean
867+
public CreatePortalNavigationItemValidatorService createPortalNavigationItemValidatorService() {
868+
return mock(CreatePortalNavigationItemValidatorService.class);
869+
}
870+
859871
@Bean
860872
public ListPortalNavigationItemsUseCase listPortalNavigationItemsUseCase() {
861873
return mock(ListPortalNavigationItemsUseCase.class);

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/GraviteeManagementV2Application.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.ThrowableMapper;
2525
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.UnrecognizedPropertyExceptionMapper;
2626
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.ValidationExceptionMapper;
27+
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.domain.ConflictDomainExceptionMapper;
2728
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.domain.NotAllowedDomainExceptionMapper;
2829
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.domain.NotFoundDomainExceptionMapper;
2930
import io.gravitee.rest.api.management.v2.rest.exceptionMapper.domain.TechnicalDomainExceptionMapper;
@@ -106,6 +107,7 @@ public GraviteeManagementV2Application() {
106107
register(TechnicalDomainExceptionMapper.class);
107108
register(NotAllowedDomainExceptionMapper.class);
108109
register(NotFoundDomainExceptionMapper.class);
110+
register(ConflictDomainExceptionMapper.class);
109111

110112
register(CommaSeparatedQueryParamConverterProvider.class);
111113

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright © 2015 The Gravitee team (http://gravitee.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.gravitee.rest.api.management.v2.rest.exceptionMapper.domain;
17+
18+
import io.gravitee.apim.core.exception.ConflictDomainException;
19+
import io.gravitee.rest.api.management.v2.rest.model.Error;
20+
import jakarta.ws.rs.core.MediaType;
21+
import jakarta.ws.rs.core.Response;
22+
import java.util.Map;
23+
24+
public class ConflictDomainExceptionMapper extends AbstractDomainExceptionMapper<ConflictDomainException> {
25+
26+
@Override
27+
public Response toResponse(ConflictDomainException exception) {
28+
return Response.status(Response.Status.CONFLICT)
29+
.type(MediaType.APPLICATION_JSON_TYPE)
30+
.entity(conflictDomainError(exception))
31+
.build();
32+
}
33+
34+
private Error conflictDomainError(ConflictDomainException exception) {
35+
return new Error()
36+
.httpStatus(Response.Status.CONFLICT.getStatusCode())
37+
.message(exception.getMessage())
38+
.parameters(exception.getId() != null ? Map.of("id", exception.getId()) : null);
39+
}
40+
}

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/exceptionMapper/domain/NotFoundDomainExceptionMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ private Error notFoundDomainError(NotFoundDomainException nfe) {
3333
return new Error()
3434
.httpStatus(Response.Status.NOT_FOUND.getStatusCode())
3535
.message(nfe.getMessage())
36-
.parameters(Map.of("id", nfe.getId()));
36+
.parameters(nfe.getId() != null ? Map.of("id", nfe.getId()) : null);
3737
}
3838
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright © 2015 The Gravitee team (http://gravitee.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.gravitee.rest.api.management.v2.rest.mapper;
17+
18+
import io.gravitee.apim.core.exception.TechnicalDomainException;
19+
import io.gravitee.apim.core.portal_page.model.PortalNavigationItemId;
20+
import io.gravitee.rest.api.management.v2.rest.model.BaseCreatePortalNavigationItem;
21+
import io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationFolder;
22+
import io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationLink;
23+
import io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationPage;
24+
import io.gravitee.rest.api.management.v2.rest.model.PortalNavigationItem;
25+
import java.util.List;
26+
import java.util.UUID;
27+
import org.mapstruct.Mapper;
28+
import org.mapstruct.Mapping;
29+
import org.mapstruct.factory.Mappers;
30+
31+
@Mapper
32+
public interface PortalNavigationItemsMapper {
33+
PortalNavigationItemsMapper INSTANCE = Mappers.getMapper(PortalNavigationItemsMapper.class);
34+
35+
@Mapping(target = "type", constant = "PAGE")
36+
@Mapping(
37+
target = "configuration",
38+
expression = "java(new io.gravitee.rest.api.management.v2.rest.model.PortalNavigationPageAllOfConfiguration().portalPageContentId(page.getPortalPageContentId().id()))"
39+
)
40+
io.gravitee.rest.api.management.v2.rest.model.PortalNavigationPage map(
41+
io.gravitee.apim.core.portal_page.model.PortalNavigationPage page
42+
);
43+
44+
@Mapping(target = "type", constant = "FOLDER")
45+
io.gravitee.rest.api.management.v2.rest.model.PortalNavigationFolder map(
46+
io.gravitee.apim.core.portal_page.model.PortalNavigationFolder folder
47+
);
48+
49+
@Mapping(target = "type", constant = "LINK")
50+
@Mapping(
51+
target = "configuration",
52+
expression = "java(new io.gravitee.rest.api.management.v2.rest.model.PortalNavigationLinkAllOfConfiguration().url(link.getUrl()))"
53+
)
54+
io.gravitee.rest.api.management.v2.rest.model.PortalNavigationLink map(
55+
io.gravitee.apim.core.portal_page.model.PortalNavigationLink link
56+
);
57+
58+
default List<PortalNavigationItem> map(List<io.gravitee.apim.core.portal_page.model.PortalNavigationItem> items) {
59+
return items.stream().map(this::map).toList();
60+
}
61+
62+
default PortalNavigationItem map(io.gravitee.apim.core.portal_page.model.PortalNavigationItem portalNavigationItem) {
63+
return switch (portalNavigationItem) {
64+
case io.gravitee.apim.core.portal_page.model.PortalNavigationFolder folder -> new PortalNavigationItem(map(folder));
65+
case io.gravitee.apim.core.portal_page.model.PortalNavigationPage page -> new PortalNavigationItem(map(page));
66+
case io.gravitee.apim.core.portal_page.model.PortalNavigationLink link -> new PortalNavigationItem(map(link));
67+
};
68+
}
69+
70+
@Mapping(
71+
target = "contentId",
72+
expression = "java(page.getContentId() == null ? null : io.gravitee.apim.core.portal_page.model.PortalPageContentId.of(page.getContentId().toString()))"
73+
)
74+
io.gravitee.apim.core.portal_page.model.CreatePortalNavigationItem map(
75+
io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationPage page
76+
);
77+
78+
io.gravitee.apim.core.portal_page.model.CreatePortalNavigationItem map(
79+
io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationFolder folder
80+
);
81+
82+
@Mapping(target = "url", expression = "java(link.getUrl().toString())")
83+
io.gravitee.apim.core.portal_page.model.CreatePortalNavigationItem map(
84+
io.gravitee.rest.api.management.v2.rest.model.CreatePortalNavigationLink link
85+
);
86+
87+
default io.gravitee.apim.core.portal_page.model.CreatePortalNavigationItem map(
88+
BaseCreatePortalNavigationItem createPortalNavigationItem
89+
) {
90+
return switch (createPortalNavigationItem) {
91+
case CreatePortalNavigationFolder folder -> map(folder);
92+
case CreatePortalNavigationPage page -> map(page);
93+
case CreatePortalNavigationLink link -> map(link);
94+
default -> throw new TechnicalDomainException(
95+
String.format("Unknown PortalNavigationItem class %s", createPortalNavigationItem.getClass().getSimpleName())
96+
);
97+
};
98+
}
99+
100+
default PortalNavigationItemId map(UUID id) {
101+
return id == null ? null : PortalNavigationItemId.of(id.toString());
102+
}
103+
104+
default String map(io.gravitee.apim.core.portal_page.model.PortalNavigationItemId id) {
105+
return id != null ? id.json() : null;
106+
}
107+
}

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/mapper/PortalNavigationMapper.java

Lines changed: 0 additions & 66 deletions
This file was deleted.

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/resource/environment/PortalNavigationItemsResource.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import io.gravitee.apim.core.portal_page.model.PortalArea;
1919
import io.gravitee.apim.core.portal_page.model.PortalNavigationItemId;
20+
import io.gravitee.apim.core.portal_page.use_case.CreatePortalNavigationItemUseCase;
2021
import io.gravitee.apim.core.portal_page.use_case.ListPortalNavigationItemsUseCase;
2122
import io.gravitee.common.http.MediaType;
22-
import io.gravitee.rest.api.management.v2.rest.mapper.PortalNavigationMapper;
23+
import io.gravitee.rest.api.management.v2.rest.mapper.PortalNavigationItemsMapper;
24+
import io.gravitee.rest.api.management.v2.rest.model.BaseCreatePortalNavigationItem;
2325
import io.gravitee.rest.api.management.v2.rest.model.PortalNavigationItemsResponse;
2426
import io.gravitee.rest.api.management.v2.rest.resource.AbstractResource;
2527
import io.gravitee.rest.api.model.permissions.RolePermission;
@@ -28,20 +30,32 @@
2830
import io.gravitee.rest.api.rest.annotation.Permissions;
2931
import io.gravitee.rest.api.service.common.GraviteeContext;
3032
import jakarta.inject.Inject;
33+
import jakarta.validation.Valid;
34+
import jakarta.validation.constraints.NotNull;
35+
import jakarta.ws.rs.Consumes;
3136
import jakarta.ws.rs.DefaultValue;
3237
import jakarta.ws.rs.GET;
38+
import jakarta.ws.rs.POST;
3339
import jakarta.ws.rs.Produces;
3440
import jakarta.ws.rs.QueryParam;
41+
import jakarta.ws.rs.core.Response;
3542
import java.util.Optional;
43+
import lombok.extern.slf4j.Slf4j;
3644

3745
/**
3846
* @author GraviteeSource Team
3947
*/
48+
@Slf4j
4049
public class PortalNavigationItemsResource extends AbstractResource {
4150

51+
@Inject
52+
private CreatePortalNavigationItemUseCase createPortalNavigationItemUseCase;
53+
4254
@Inject
4355
private ListPortalNavigationItemsUseCase listPortalNavigationItemsUseCase;
4456

57+
private final PortalNavigationItemsMapper mapper = PortalNavigationItemsMapper.INSTANCE;
58+
4559
@GET
4660
@Produces(MediaType.APPLICATION_JSON)
4761
@Permissions({ @Permission(value = RolePermission.ENVIRONMENT_DOCUMENTATION, acls = RolePermissionAction.READ) })
@@ -59,6 +73,24 @@ public PortalNavigationItemsResponse getPortalNavigationItems(
5973
)
6074
);
6175

62-
return new PortalNavigationItemsResponse().items(PortalNavigationMapper.INSTANCE.map(result.items()));
76+
return new PortalNavigationItemsResponse().items(mapper.map(result.items()));
77+
}
78+
79+
@POST
80+
@Permissions({ @Permission(value = RolePermission.ENVIRONMENT_DOCUMENTATION, acls = { RolePermissionAction.UPDATE }) })
81+
@Consumes(MediaType.APPLICATION_JSON)
82+
@Produces(MediaType.APPLICATION_JSON)
83+
public Response createPortalNavigationItem(@Valid @NotNull final BaseCreatePortalNavigationItem createPortalNavigationItem) {
84+
final var executionContext = GraviteeContext.getExecutionContext();
85+
86+
final var output = createPortalNavigationItemUseCase.execute(
87+
new CreatePortalNavigationItemUseCase.Input(
88+
executionContext.getOrganizationId(),
89+
executionContext.getEnvironmentId(),
90+
mapper.map(createPortalNavigationItem)
91+
)
92+
);
93+
94+
return Response.created(this.getLocationHeader(output.item().getId().toString())).entity(mapper.map(output.item())).build();
6395
}
6496
}

gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/java/io/gravitee/rest/api/management/v2/rest/resource/installation/EnvironmentResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public InstancesResource getInstancesResource() {
116116
}
117117

118118
@Path("/portal-navigation-items")
119-
public PortalNavigationItemsResource getPortalNavigationItemResource() {
119+
public PortalNavigationItemsResource getPortalNavigationItemsResource() {
120120
return resourceContext.getResource(PortalNavigationItemsResource.class);
121121
}
122122

0 commit comments

Comments
 (0)