diff options
author | 2024-10-20 20:15:17 +0200 | |
---|---|---|
committer | 2024-10-21 14:15:36 +0200 | |
commit | 8cb2c97c400b30fb71a89aefaf19f247b450d49f (patch) | |
tree | 204e69a9a0843e0d1f8182b71752b8a83da24af4 /src/main | |
parent | d261bec9ccd72b8268cec06033169b38917ab9bd (diff) |
Clean up babel GenerateArtifactsService
- rename GenerateArtifactsService to Controller
- move request logging into central request filter
- move request authentication into central request filter
- constructor-inject gson to avoid creating the mapper on each request
Issue-ID: AAI-4021
Change-Id: Ifb95644858ddf4b3364e08291d1685da469edd71
Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/org/onap/aai/babel/JerseyConfiguration.java | 7 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/config/MappingConfig.java | 36 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/filters/AuthenticationRequestFilter.java | 72 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/filters/LoggingRequestFilter.java | 85 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/logging/LogHelper.java | 5 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/request/RequestHeaders.java | 6 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/service/GenerateArtifactsController.java (renamed from src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java) | 2 | ||||
-rw-r--r-- | src/main/java/org/onap/aai/babel/service/GenerateArtifactsControllerImpl.java (renamed from src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java) | 97 | ||||
-rw-r--r-- | src/main/resources/babel-beans.xml | 3 |
9 files changed, 235 insertions, 78 deletions
diff --git a/src/main/java/org/onap/aai/babel/JerseyConfiguration.java b/src/main/java/org/onap/aai/babel/JerseyConfiguration.java index 16a7aa0..84cda4d 100644 --- a/src/main/java/org/onap/aai/babel/JerseyConfiguration.java +++ b/src/main/java/org/onap/aai/babel/JerseyConfiguration.java @@ -22,7 +22,7 @@ package org.onap.aai.babel; import javax.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; -import org.onap.aai.babel.service.GenerateArtifactsServiceImpl; +import org.onap.aai.babel.service.GenerateArtifactsControllerImpl; import org.onap.aai.babel.service.InfoService; import org.springframework.context.annotation.Configuration; @@ -31,8 +31,9 @@ import org.springframework.context.annotation.Configuration; public class JerseyConfiguration extends ResourceConfig { public JerseyConfiguration() { - register(GenerateArtifactsServiceImpl.class); - register(InfoService.class); + packages("org.onap.aai.babel"); + // register(GenerateArtifactsControllerImpl.class); + // register(InfoService.class); } } diff --git a/src/main/java/org/onap/aai/babel/config/MappingConfig.java b/src/main/java/org/onap/aai/babel/config/MappingConfig.java new file mode 100644 index 0000000..321f86e --- /dev/null +++ b/src/main/java/org/onap/aai/babel/config/MappingConfig.java @@ -0,0 +1,36 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.babel.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +@Configuration +public class MappingConfig { + + @Bean + public Gson gson() { + return new GsonBuilder().disableHtmlEscaping().create(); + } +} diff --git a/src/main/java/org/onap/aai/babel/filters/AuthenticationRequestFilter.java b/src/main/java/org/onap/aai/babel/filters/AuthenticationRequestFilter.java new file mode 100644 index 0000000..deeafb0 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/filters/AuthenticationRequestFilter.java @@ -0,0 +1,72 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.babel.filters; + +import org.onap.aai.auth.AAIMicroServiceAuth; +import org.onap.aai.auth.AAIMicroServiceAuthCore.HTTP_METHODS; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.logging.LogHelper; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.Provider; +import javax.ws.rs.core.PathSegment; +import javax.ws.rs.core.Response; + +import java.io.IOException; +import java.util.List; + +@Slf4j +@Component +@Provider +@RequiredArgsConstructor +public class AuthenticationRequestFilter implements ContainerRequestFilter { + + private static final LogHelper applicationLogger = LogHelper.INSTANCE; + private final AAIMicroServiceAuth authService; + private final HttpServletRequest servletRequest; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + List<PathSegment> pathSegments = requestContext.getUriInfo().getPathSegments(); + String lastPathSegment = pathSegments.isEmpty() ? "" : pathSegments.get(pathSegments.size() - 1).getPath(); + + try { + HTTP_METHODS method = HTTP_METHODS.valueOf(requestContext.getMethod()); + boolean authorized = authService.validateRequest(null, servletRequest, + method, lastPathSegment); + if (!authorized) { + requestContext.abortWith(Response.status(Status.FORBIDDEN).build()); + } + } catch (Exception e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + applicationLogger.logAuditError(e); + requestContext.abortWith(Response.status(Status.FORBIDDEN).build()); + // log.warn("Authorization skipped for method: {}", requestContext.getMethod()); + } + } +} diff --git a/src/main/java/org/onap/aai/babel/filters/LoggingRequestFilter.java b/src/main/java/org/onap/aai/babel/filters/LoggingRequestFilter.java new file mode 100644 index 0000000..9699be4 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/filters/LoggingRequestFilter.java @@ -0,0 +1,85 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aai.babel.filters; + +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.logging.LogHelper; +import org.onap.aai.babel.logging.LogHelper.MdcParameter; +import org.onap.aai.babel.request.RequestHeaders; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.MultivaluedMap; + +import java.io.IOException; +import java.util.UUID; + +@Component +public class LoggingRequestFilter implements ContainerRequestFilter { + + private static final LogHelper applicationLogger = LogHelper.INSTANCE; + + @Autowired + private HttpServletRequest servletRequest; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + UriInfo uriInfo = requestContext.getUriInfo(); + String requestBody = requestContext.getEntityStream().toString(); + MultivaluedMap<String, String> headers = requestContext.getHeaders(); + applicationLogger.startAudit(headers, servletRequest); + applicationLogger.info(ApplicationMsgs.BABEL_REQUEST_PAYLOAD, + "Received request: " + headers + requestBody); + applicationLogger.debug(String.format( + "Received request. UriInfo \"%s\", HttpHeaders \"%s\", ServletRequest \"%s\", Request \"%s\"", uriInfo, + headers, servletRequest, requestBody)); + + // Additional name/value pairs according to EELF guidelines + applicationLogger.setContextValue("Protocol", "https"); + applicationLogger.setContextValue("Method", requestContext.getMethod()); + applicationLogger.setContextValue("Path", uriInfo.getPath()); + applicationLogger.setContextValue("Query", uriInfo.getPathParameters().toString()); + + RequestHeaders requestHeaders = new RequestHeaders(headers); + applicationLogger.info(ApplicationMsgs.BABEL_REQUEST_PAYLOAD, requestHeaders.toString()); + + String requestId = requestHeaders.getCorrelationId(); + if (requestId == null || !isRequestIDValid(requestId)) { + requestId = UUID.randomUUID().toString(); + applicationLogger.info(ApplicationMsgs.MISSING_REQUEST_ID, requestId); + applicationLogger.setContextValue(MdcParameter.REQUEST_ID, requestId); + } + + } + + private boolean isRequestIDValid(String requestId) { + try { + UUID.fromString(requestId); + } catch (IllegalArgumentException e) { + return false; + } + return true; + } +} diff --git a/src/main/java/org/onap/aai/babel/logging/LogHelper.java b/src/main/java/org/onap/aai/babel/logging/LogHelper.java index 19ee25b..f96aff0 100644 --- a/src/main/java/org/onap/aai/babel/logging/LogHelper.java +++ b/src/main/java/org/onap/aai/babel/logging/LogHelper.java @@ -32,6 +32,7 @@ import java.util.function.Consumer; import javax.servlet.ServletRequest; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response.Status; import org.apache.commons.lang3.time.StopWatch; @@ -158,7 +159,7 @@ public enum LogHelper implements Logger { * @param headers raw HTTP headers * @param servletRequest the request */ - public void startAudit(final HttpHeaders headers, ServletRequest servletRequest) { + public void startAudit(final MultivaluedMap<String, String> headers, ServletRequest servletRequest) { auditStopwatch = new StopWatch(); auditStopwatch.start(); @@ -170,7 +171,7 @@ public enum LogHelper implements Logger { RequestHeaders requestHeaders = new RequestHeaders(headers); requestId = Optional.ofNullable(requestHeaders.getCorrelationId()); serviceInstanceId = requestHeaders.getInstanceId(); - partnerName = Optional.ofNullable(headers.getHeaderString(Headers.FROM_APP_ID)); + partnerName = Optional.ofNullable(headers.getFirst(Headers.FROM_APP_ID)); } String clientHost = null; diff --git a/src/main/java/org/onap/aai/babel/request/RequestHeaders.java b/src/main/java/org/onap/aai/babel/request/RequestHeaders.java index 1850d62..19d5425 100644 --- a/src/main/java/org/onap/aai/babel/request/RequestHeaders.java +++ b/src/main/java/org/onap/aai/babel/request/RequestHeaders.java @@ -23,6 +23,7 @@ package org.onap.aai.babel.request; import java.util.Optional; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedMap; /** Bean to represent the ECOMP request/transaction IDs required for EELF logging. */ public class RequestHeaders { @@ -42,6 +43,11 @@ public class RequestHeaders { instanceId = headers.getHeaderString(RequestHeaders.HEADER_SERVICE_INSTANCE_ID); transactionId = headers.getHeaderString(RequestHeaders.HEADER_X_TRANSACTION_ID); } + public RequestHeaders(MultivaluedMap<String, String> headers) { + requestId = headers.getFirst(RequestHeaders.HEADER_REQUEST_ID); + instanceId = headers.getFirst(RequestHeaders.HEADER_SERVICE_INSTANCE_ID); + transactionId = headers.getFirst(RequestHeaders.HEADER_X_TRANSACTION_ID); + } public String getRequestId() { return requestId; diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsController.java index 734bb1a..67fc865 100644 --- a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java +++ b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsController.java @@ -37,7 +37,7 @@ import org.onap.aai.auth.AAIAuthException; @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @FunctionalInterface -public interface GenerateArtifactsService { +public interface GenerateArtifactsController { @POST @Path("/generateArtifacts") diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsControllerImpl.java index 544d782..189aaf3 100644 --- a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java +++ b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsControllerImpl.java @@ -24,10 +24,11 @@ package org.onap.aai.babel.service; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; + +import lombok.RequiredArgsConstructor; + import java.util.Base64; import java.util.List; -import java.util.UUID; -import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.*; import javax.ws.rs.core.Response.Status; @@ -44,81 +45,44 @@ import org.onap.aai.babel.logging.ApplicationMsgs; import org.onap.aai.babel.logging.LogHelper; import org.onap.aai.babel.logging.LogHelper.MdcParameter; import org.onap.aai.babel.logging.LogHelper.StatusCode; -import org.onap.aai.babel.request.RequestHeaders; import org.onap.aai.babel.service.data.BabelArtifact; import org.onap.aai.babel.service.data.BabelRequest; import org.onap.aai.babel.util.RequestValidationException; import org.onap.aai.babel.util.RequestValidator; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Controller; /** * Generate SDC Artifacts by passing in a CSAR payload, Artifact Name and Artifact version. * */ -@Service -public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { - private static final LogHelper applicationLogger = LogHelper.INSTANCE; +@Controller +@RequiredArgsConstructor +public class GenerateArtifactsControllerImpl implements GenerateArtifactsController { - private AAIMicroServiceAuth aaiMicroServiceAuth; - - /** - * @param authorization - * the auth module - */ - @Inject - public GenerateArtifactsServiceImpl(final AAIMicroServiceAuth authorization) { - this.aaiMicroServiceAuth = authorization; - } + private static final LogHelper applicationLogger = LogHelper.INSTANCE; + private final Gson gson; - /* - * (non-Javadoc) - * - * @see org.onap.aai.babel.service.GenerateArtifactsService#generateArtifacts(javax.ws.rs.core.UriInfo, - * javax.ws.rs.core.HttpHeaders, javax.servlet.http.HttpServletRequest, java.lang.String) - */ @Override public Response generateArtifacts(UriInfo uriInfo, HttpHeaders headers, HttpServletRequest servletRequest, String requestBody) { - applicationLogger.startAudit(headers, servletRequest); - applicationLogger.info(ApplicationMsgs.BABEL_REQUEST_PAYLOAD, - "Received request: " + headers.getRequestHeaders() + requestBody); - applicationLogger.debug(String.format( - "Received request. UriInfo \"%s\", HttpHeaders \"%s\", ServletRequest \"%s\", Request \"%s\"", uriInfo, - headers, servletRequest, requestBody)); - - // Additional name/value pairs according to EELF guidelines - applicationLogger.setContextValue("Protocol", "https"); - applicationLogger.setContextValue("Method", "POST"); - applicationLogger.setContextValue("Path", uriInfo.getPath()); - applicationLogger.setContextValue("Query", uriInfo.getPathParameters().toString()); - - RequestHeaders requestHeaders = new RequestHeaders(headers); - applicationLogger.info(ApplicationMsgs.BABEL_REQUEST_PAYLOAD, requestHeaders.toString()); - - String requestId = requestHeaders.getCorrelationId(); - if (requestId == null || !isRequestIDValid(requestId)) { - requestId = UUID.randomUUID().toString(); - applicationLogger.info(ApplicationMsgs.MISSING_REQUEST_ID, requestId); - applicationLogger.setContextValue(MdcParameter.REQUEST_ID, requestId); - } - Response response; - try { + // try { // Get last URI path segment to use for authentication - List<PathSegment> pathSegments = uriInfo.getPathSegments(); - String lastPathSegment = pathSegments.isEmpty() ? "" : pathSegments.get(pathSegments.size() - 1).getPath(); - - boolean authorized = aaiMicroServiceAuth.validateRequest(headers, servletRequest, - AAIMicroServiceAuthCore.HTTP_METHODS.POST, lastPathSegment); - - response = authorized ? generateArtifacts(requestBody) - : buildResponse(Status.UNAUTHORIZED, "User not authorized to perform the operation."); - } catch (AAIAuthException e) { - applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); - applicationLogger.logAuditError(e); - return buildResponse(Status.INTERNAL_SERVER_ERROR, - "Error while processing request. Please check the Babel service logs for more details.\n"); - } + // List<PathSegment> pathSegments = uriInfo.getPathSegments(); + // String lastPathSegment = pathSegments.isEmpty() ? "" : pathSegments.get(pathSegments.size() - 1).getPath(); + + // boolean authorized = aaiMicroServiceAuth.validateRequest(headers, servletRequest, + // AAIMicroServiceAuthCore.HTTP_METHODS.POST, lastPathSegment); + + response = generateArtifacts(requestBody); + // response = authorized ? generateArtifacts(requestBody) + // : buildResponse(Status.UNAUTHORIZED, "User not authorized to perform the operation."); + // } catch (AAIAuthException e) { + // applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + // applicationLogger.logAuditError(e); + // return buildResponse(Status.INTERNAL_SERVER_ERROR, + // "Error while processing request. Please check the Babel service logs for more details.\n"); + // } StatusCode statusDescription; int statusCode = response.getStatus(); @@ -133,15 +97,6 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { return response; } - private boolean isRequestIDValid(String requestId) { - try { - UUID.fromString(requestId); - } catch (IllegalArgumentException e) { - return false; - } - return true; - } - /** * Generate XML model artifacts from request body. * @@ -156,8 +111,6 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { Response response; try { - Gson gson = new GsonBuilder().disableHtmlEscaping().create(); - BabelRequest babelRequest = gson.fromJson(requestBody, BabelRequest.class); new RequestValidator().validateRequest(babelRequest); byte[] csarFile = Base64.getDecoder().decode(babelRequest.getCsar()); diff --git a/src/main/resources/babel-beans.xml b/src/main/resources/babel-beans.xml index e979a2e..ab784c8 100644 --- a/src/main/resources/babel-beans.xml +++ b/src/main/resources/babel-beans.xml @@ -30,4 +30,7 @@ <constructor-arg ref="babelAuthConfig" /> </bean> + <!-- <bean id="gson" class="com.google.gson.Gson"> + </bean> --> + </beans> |