diff options
Diffstat (limited to 'vid-app-common/src/main')
-rw-r--r-- | vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseRequestIdFilter.java (renamed from vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseEcompRequestIdFilter.java) | 98 | ||||
-rw-r--r-- | vid-app-common/src/main/java/org/onap/vid/logging/Headers.kt | 20 |
2 files changed, 90 insertions, 28 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseEcompRequestIdFilter.java b/vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseRequestIdFilter.java index 37622a215..c0fc96e03 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseEcompRequestIdFilter.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/filter/PromiseRequestIdFilter.java @@ -21,10 +21,18 @@ package org.onap.vid.controller.filter; -import com.google.common.collect.ImmutableList; -import org.apache.commons.lang3.StringUtils; -import org.springframework.web.filter.GenericFilterBean; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; +import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID; +import com.google.common.collect.ImmutableList; +import java.io.IOException; +import java.util.Collections; +import java.util.Enumeration; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.regex.Pattern; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -33,18 +41,28 @@ import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.UUID; - -import static org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID; +import javax.validation.constraints.NotNull; +import org.onap.vid.logging.Headers; +import org.springframework.web.filter.GenericFilterBean; @WebFilter(urlPatterns = "/*") -public class PromiseEcompRequestIdFilter extends GenericFilterBean { - +public class PromiseRequestIdFilter extends GenericFilterBean { + + // The wrapped request is guaranteed to have the transaction id as the value + // of the header PROMISED_HEADER_NAME. + // PROMISED_HEADER_NAME is set to ECOMP_REQUEST_ID as long as + // org.onap.portalsdk...UserUtils.getRequestId() is using the header + // "X-ECOMP-RequestID". + private static final String PROMISED_HEADER_NAME = ECOMP_REQUEST_ID; private static final String REQUEST_ID_RESPONSE_HEADER = ECOMP_REQUEST_ID + "-echo"; + private static final Pattern uuidRegex = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", Pattern.CASE_INSENSITIVE); + + private final Headers headers; + + public PromiseRequestIdFilter(Headers headers) { + this.headers = headers; + } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) @@ -54,7 +72,7 @@ public class PromiseEcompRequestIdFilter extends GenericFilterBean { request = wrapIfNeeded(request); if (response instanceof HttpServletResponse) { - final String actualRequestId = ((HttpServletRequest) request).getHeader(ECOMP_REQUEST_ID); + final String actualRequestId = ((HttpServletRequest) request).getHeader(PROMISED_HEADER_NAME); ((HttpServletResponse) response).addHeader(REQUEST_ID_RESPONSE_HEADER, actualRequestId); } } @@ -62,30 +80,54 @@ public class PromiseEcompRequestIdFilter extends GenericFilterBean { chain.doFilter(request, response); } - public static ServletRequest wrapIfNeeded(ServletRequest request) { + public ServletRequest wrapIfNeeded(ServletRequest request) { final HttpServletRequest httpRequest = (HttpServletRequest) request; - final String originalRequestId = httpRequest.getHeader(ECOMP_REQUEST_ID); - if (StringUtils.isEmpty(originalRequestId) || !verifyAndValidateUuid(originalRequestId)) { - request = new PromiseEcompRequestIdRequestWrapper(httpRequest); + final String highestPriorityHeader = highestPriorityHeader(httpRequest); + final String originalRequestId = httpRequest.getHeader(highestPriorityHeader); + + if (isWrapNeeded(highestPriorityHeader, originalRequestId)) { + // Copy originalRequestId to the promised header value + request = new PromiseRequestIdRequestWrapper(httpRequest, toUuidOrElse(originalRequestId, UUID::randomUUID)); } return request; } - public static boolean verifyAndValidateUuid(String value) - { - String uuidRegex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"; - return value.matches(uuidRegex); + private boolean verifyAndValidateUuid(String value) { + return isNotEmpty(value) && uuidRegex.matcher(value).matches(); } - private static class PromiseEcompRequestIdRequestWrapper extends HttpServletRequestWrapper { + private boolean isWrapNeeded(String highestPriorityHeader, String originalRequestId) { + boolean headerExistsAndValid = + equalsIgnoreCase(highestPriorityHeader, PROMISED_HEADER_NAME) && verifyAndValidateUuid(originalRequestId); + + return !headerExistsAndValid; + } + + UUID toUuidOrElse(String uuid, Supplier<UUID> uuidSupplier) { + if (verifyAndValidateUuid(uuid)) { + try { + return UUID.fromString(uuid); + } catch (IllegalArgumentException e) { + return uuidSupplier.get(); + } + } else { + return uuidSupplier.get(); + } + } + + String highestPriorityHeader(HttpServletRequest httpRequest) { + return defaultIfNull(headers.highestPriorityHeader(httpRequest), PROMISED_HEADER_NAME); + } + + private static class PromiseRequestIdRequestWrapper extends HttpServletRequestWrapper { private final UUID requestId; - PromiseEcompRequestIdRequestWrapper(HttpServletRequest request) { + PromiseRequestIdRequestWrapper(HttpServletRequest request, @NotNull UUID requestId) { super(request); - requestId = UUID.randomUUID(); + this.requestId = requestId; } @Override @@ -106,18 +148,18 @@ public class PromiseEcompRequestIdFilter extends GenericFilterBean { @Override public Enumeration<String> getHeaderNames() { - if (null == super.getHeader(ECOMP_REQUEST_ID)) { - return Collections.enumeration(ImmutableList.<String>builder() - .add(ECOMP_REQUEST_ID) + if (null == super.getHeader(PROMISED_HEADER_NAME)) { + return Collections.enumeration(ImmutableList.<String>builder() + .add(PROMISED_HEADER_NAME) .addAll(Collections.list(super.getHeaderNames())) .build()); - } + } return super.getHeaderNames(); } private boolean isRequestIdHeaderName(String name) { - return ECOMP_REQUEST_ID.equalsIgnoreCase(name); + return equalsIgnoreCase(name, PROMISED_HEADER_NAME); } } } diff --git a/vid-app-common/src/main/java/org/onap/vid/logging/Headers.kt b/vid-app-common/src/main/java/org/onap/vid/logging/Headers.kt new file mode 100644 index 000000000..cc5ebf38c --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/logging/Headers.kt @@ -0,0 +1,20 @@ +package org.onap.vid.logging + +import org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID +import org.springframework.stereotype.Component +import javax.servlet.http.HttpServletRequest + +@Component +class Headers { + fun prioritizedRequestIdHeaders() = listOf( + "X-ONAP-RequestID", + "X-RequestID", + "X-TransactionID", + ECOMP_REQUEST_ID + ) + + fun highestPriorityHeader(httpRequest: HttpServletRequest): String? { + val headers = httpRequest.headerNames.asSequence().toSet().map { it.toUpperCase() } + return prioritizedRequestIdHeaders().firstOrNull { headers.contains(it.toUpperCase()) } + } +} |