diff --git a/pom.xml b/pom.xml
index 39edfed..26e8fb9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,12 +15,11 @@
2.0.12
- 2.15.0
+ 0.0.8
UTF-8
UTF-8
21
8022
- wachter
8023
${server.port} ${management.port}
@@ -36,6 +35,11 @@
dev.vality.geck
serializer
+
+ dev.vality
+ woody-http-bridge
+ ${woody-http-bridge.version}
+
@@ -83,11 +87,6 @@
-
- io.opentelemetry.instrumentation
- opentelemetry-spring-boot-starter
- ${otel.instrumentation.version}
-
jakarta.servlet
jakarta.servlet-api
@@ -112,11 +111,6 @@
spring-boot-starter-test
test
-
- io.opentelemetry
- opentelemetry-sdk-testing
- test
-
io.jsonwebtoken
jjwt-api
diff --git a/src/main/java/dev/vality/wachter/client/ProxyHeadersExtractor.java b/src/main/java/dev/vality/wachter/client/ProxyHeadersExtractor.java
index dce2b53..5135111 100644
--- a/src/main/java/dev/vality/wachter/client/ProxyHeadersExtractor.java
+++ b/src/main/java/dev/vality/wachter/client/ProxyHeadersExtractor.java
@@ -1,6 +1,6 @@
package dev.vality.wachter.client;
-import dev.vality.wachter.constants.TraceHeadersConstants;
+import dev.vality.woody.http.bridge.tracing.TraceHeadersConstants;
import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
import org.springframework.http.HttpHeaders;
diff --git a/src/main/java/dev/vality/wachter/client/WachterClient.java b/src/main/java/dev/vality/wachter/client/WachterClient.java
index b2764a1..804bb37 100644
--- a/src/main/java/dev/vality/wachter/client/WachterClient.java
+++ b/src/main/java/dev/vality/wachter/client/WachterClient.java
@@ -1,12 +1,13 @@
package dev.vality.wachter.client;
-import dev.vality.wachter.tracing.TraceContextHeadersExtractor;
-import dev.vality.wachter.tracing.TraceContextHeadersNormalizer;
+import dev.vality.woody.http.bridge.tracing.TraceContextExtractor;
+import dev.vality.woody.http.bridge.tracing.TraceContextHeadersNormalizer;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestClient;
@@ -26,7 +27,7 @@ public WachterClientResponse send(HttpServletRequest servletRequest, byte[] cont
var httpMethod = resolveMethod(servletRequest);
var proxyHeaders = ProxyHeadersExtractor.extractHeaders(servletRequest);
- var traceHeaders = TraceContextHeadersExtractor.extractHeaders();
+ var traceHeaders = TraceContextExtractor.extractHeaders();
var httpHeaders = new HttpHeaders();
proxyHeaders.forEach(httpHeaders::addAll);
@@ -59,4 +60,7 @@ private HttpMethod resolveMethod(HttpServletRequest servletRequest) {
return HttpMethod.POST;
}
}
+
+ public record WachterClientResponse(HttpStatusCode statusCode, HttpHeaders headers, byte[] body) {
+ }
}
diff --git a/src/main/java/dev/vality/wachter/client/WachterClientResponse.java b/src/main/java/dev/vality/wachter/client/WachterClientResponse.java
deleted file mode 100644
index c5a6f26..0000000
--- a/src/main/java/dev/vality/wachter/client/WachterClientResponse.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package dev.vality.wachter.client;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatusCode;
-
-public record WachterClientResponse(HttpStatusCode statusCode, HttpHeaders headers, byte[] body) {
-}
diff --git a/src/main/java/dev/vality/wachter/config/OtelConfig.java b/src/main/java/dev/vality/wachter/config/OtelConfig.java
deleted file mode 100644
index ee9dd89..0000000
--- a/src/main/java/dev/vality/wachter/config/OtelConfig.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package dev.vality.wachter.config;
-
-import dev.vality.wachter.config.properties.OtelConfigProperties;
-import io.opentelemetry.api.GlobalOpenTelemetry;
-import io.opentelemetry.api.OpenTelemetry;
-import io.opentelemetry.api.common.Attributes;
-import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
-import io.opentelemetry.context.propagation.ContextPropagators;
-import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
-import io.opentelemetry.sdk.OpenTelemetrySdk;
-import io.opentelemetry.sdk.resources.Resource;
-import io.opentelemetry.sdk.trace.SdkTracerProvider;
-import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
-import io.opentelemetry.sdk.trace.samplers.Sampler;
-import io.opentelemetry.semconv.ServiceAttributes;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.time.Duration;
-
-@Slf4j
-@Configuration
-@ConditionalOnProperty(value = "otel.enabled", havingValue = "true", matchIfMissing = true)
-@RequiredArgsConstructor
-public class OtelConfig {
-
- private final OtelConfigProperties otelConfigProperties;
-
- @Value("${spring.application.name}")
- private String applicationName;
-
- @Bean
- public OpenTelemetry openTelemetryConfig() {
- var resource = Resource.getDefault()
- .merge(Resource.create(Attributes.of(ServiceAttributes.SERVICE_NAME, applicationName)));
- var sdkTracerProvider = SdkTracerProvider.builder()
- .addSpanProcessor(BatchSpanProcessor.builder(OtlpHttpSpanExporter.builder()
- .setEndpoint(otelConfigProperties.getResource())
- .setTimeout(Duration.ofMillis(otelConfigProperties.getTimeout()))
- .build())
- .build())
- .setSampler(Sampler.alwaysOn())
- .setResource(resource)
- .build();
- var openTelemetrySdk = OpenTelemetrySdk.builder()
- .setTracerProvider(sdkTracerProvider)
- .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
- .build();
- registerGlobalOpenTelemetry(openTelemetrySdk);
- return openTelemetrySdk;
- }
-
- private static void registerGlobalOpenTelemetry(OpenTelemetry openTelemetry) {
- try {
- GlobalOpenTelemetry.set(openTelemetry);
- } catch (Throwable ex) {
- log.warn("Please initialize the ObservabilitySdk before starting the application", ex);
- GlobalOpenTelemetry.resetForTest();
- try {
- GlobalOpenTelemetry.set(openTelemetry);
- } catch (Throwable ex1) {
- log.warn("Unable to set GlobalOpenTelemetry", ex1);
- }
- }
- }
-}
diff --git a/src/main/java/dev/vality/wachter/config/WebConfig.java b/src/main/java/dev/vality/wachter/config/WebConfig.java
deleted file mode 100644
index 539c1f3..0000000
--- a/src/main/java/dev/vality/wachter/config/WebConfig.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package dev.vality.wachter.config;
-
-import dev.vality.wachter.tracing.WoodyTracingFilter;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Configuration
-@Slf4j
-public class WebConfig {
-
- @Value("${server.port}")
- private int serverPort;
-
- @Value("/${wachter.endpoint}")
- private String wachterEndpoint;
-
- @Bean
- public FilterRegistrationBean externalPortRestrictingFilter() {
- var filter = new OncePerRequestFilter() {
- @Override
- protected void doFilterInternal(HttpServletRequest request,
- HttpServletResponse response,
- FilterChain filterChain) throws ServletException, IOException {
- var requestPath = getRequestPath(request);
- if ((request.getLocalPort() == serverPort) && !requestPath.equals(wachterEndpoint)) {
- var status = HttpServletResponse.SC_NOT_FOUND;
- log.warn("<- Sent [redirecting {}]: Unknown address {}", status, requestPath);
- response.sendError(status, "Unknown address");
- return;
- }
- filterChain.doFilter(request, response);
- }
- };
-
- var filterRegistrationBean = new FilterRegistrationBean();
- filterRegistrationBean.setFilter(filter);
- filterRegistrationBean.setOrder(-100);
- filterRegistrationBean.setName("externalPortRestrictingFilter");
- filterRegistrationBean.addUrlPatterns("/*");
- return filterRegistrationBean;
- }
-
- @Bean
- public FilterRegistrationBean woodyTracingFilter() {
- var registrationBean = new FilterRegistrationBean<>(new WoodyTracingFilter(serverPort, wachterEndpoint));
- registrationBean.setOrder(-50);
- registrationBean.setName("woodyTracingFilter");
- registrationBean.addUrlPatterns(wachterEndpoint);
- return registrationBean;
- }
-
- public static String getRequestPath(HttpServletRequest request) {
- var servletPath = request.getServletPath();
- if (servletPath != null && !servletPath.isBlank()) {
- return servletPath;
- }
- var requestPath = request.getRequestURI();
- if (requestPath != null && !requestPath.isBlank()) {
- return requestPath;
- }
- return "";
- }
-}
diff --git a/src/main/java/dev/vality/wachter/config/properties/HttpClientProperties.java b/src/main/java/dev/vality/wachter/config/properties/HttpClientProperties.java
deleted file mode 100644
index be4695f..0000000
--- a/src/main/java/dev/vality/wachter/config/properties/HttpClientProperties.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package dev.vality.wachter.config.properties;
-
-import jakarta.validation.constraints.NotNull;
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.validation.annotation.Validated;
-
-@Getter
-@Setter
-@Validated
-@Configuration
-@ConfigurationProperties("http-client")
-public class HttpClientProperties {
-
- @NotNull
- private int maxTotalPooling;
-
- @NotNull
- private int defaultMaxPerRoute;
-
- @NotNull
- private int socketTimeout;
-
- @NotNull
- private int connectionRequestTimeout;
-
- @NotNull
- private int connectTimeout;
-
-}
diff --git a/src/main/java/dev/vality/wachter/config/properties/OtelConfigProperties.java b/src/main/java/dev/vality/wachter/config/properties/OtelConfigProperties.java
deleted file mode 100644
index 407339b..0000000
--- a/src/main/java/dev/vality/wachter/config/properties/OtelConfigProperties.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package dev.vality.wachter.config.properties;
-
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-@Getter
-@Setter
-@Component
-@ConfigurationProperties(prefix = "otel")
-public class OtelConfigProperties {
-
- private String resource;
- private Long timeout;
-
-}
diff --git a/src/main/java/dev/vality/wachter/config/properties/WachterProperties.java b/src/main/java/dev/vality/wachter/config/properties/WachterProperties.java
index 80af146..6aece91 100644
--- a/src/main/java/dev/vality/wachter/config/properties/WachterProperties.java
+++ b/src/main/java/dev/vality/wachter/config/properties/WachterProperties.java
@@ -27,5 +27,4 @@ public static class Service {
private String url;
}
-
}
diff --git a/src/main/java/dev/vality/wachter/constants/RequestAttributeNames.java b/src/main/java/dev/vality/wachter/constants/RequestAttributeNames.java
deleted file mode 100644
index a8a58eb..0000000
--- a/src/main/java/dev/vality/wachter/constants/RequestAttributeNames.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package dev.vality.wachter.constants;
-
-public final class RequestAttributeNames {
-
- public static final String NORMALIZED_WOODY_HEADERS = "wachter.normalizedWoodyHeaders";
-
- private RequestAttributeNames() {
- }
-}
diff --git a/src/main/java/dev/vality/wachter/constants/TraceHeadersConstants.java b/src/main/java/dev/vality/wachter/constants/TraceHeadersConstants.java
deleted file mode 100644
index 2fc46af..0000000
--- a/src/main/java/dev/vality/wachter/constants/TraceHeadersConstants.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package dev.vality.wachter.constants;
-
-import dev.vality.woody.api.trace.context.metadata.user.UserIdentityEmailExtensionKit;
-import dev.vality.woody.api.trace.context.metadata.user.UserIdentityIdExtensionKit;
-import dev.vality.woody.api.trace.context.metadata.user.UserIdentityRealmExtensionKit;
-import dev.vality.woody.api.trace.context.metadata.user.UserIdentityUsernameExtensionKit;
-import dev.vality.woody.thrift.impl.http.transport.THttpHeader;
-
-public class TraceHeadersConstants {
-
- public static final String WOODY_PREFIX = "woody.";
- public static final String WOODY_TRACE_ID = THttpHeader.TRACE_ID.getKey();
- public static final String WOODY_SPAN_ID = THttpHeader.SPAN_ID.getKey();
- public static final String WOODY_PARENT_ID = THttpHeader.PARENT_ID.getKey();
- public static final String WOODY_DEADLINE = THttpHeader.DEADLINE.getKey();
- public static final String WOODY_ERROR_CLASS = THttpHeader.ERROR_CLASS.getKey();
- public static final String WOODY_ERROR_REASON = THttpHeader.ERROR_REASON.getKey();
- public static final String WOODY_META_PREFIX = THttpHeader.META.getKey();
- public static final String WOODY_META_ID = WOODY_META_PREFIX + WoodyMetaHeaders.ID;
- public static final String WOODY_META_USERNAME = WOODY_META_PREFIX + WoodyMetaHeaders.USERNAME;
- public static final String WOODY_META_EMAIL = WOODY_META_PREFIX + WoodyMetaHeaders.EMAIL;
- public static final String WOODY_META_REALM = WOODY_META_PREFIX + WoodyMetaHeaders.REALM;
- public static final String WOODY_META_REQUEST_ID = WOODY_META_PREFIX + WoodyMetaHeaders.X_REQUEST_ID;
- public static final String WOODY_META_REQUEST_DEADLINE =
- WOODY_META_PREFIX + WoodyMetaHeaders.X_REQUEST_DEADLINE;
- public static final String WOODY_META_REQUEST_INVOICE_ID =
- WOODY_META_PREFIX + WoodyMetaHeaders.X_INVOICE_ID;
-
- public static final String OTEL_TRACE_PARENT = THttpHeader.TRACE_PARENT.getKey();
- public static final String OTEL_TRACE_STATE = THttpHeader.TRACE_STATE.getKey();
-
- public static final class ExternalHeaders {
-
- public static final String X_REQUEST_ID = "X-Request-ID";
- public static final String X_REQUEST_DEADLINE = "X-Request-Deadline";
- public static final String X_INVOICE_ID = "X-Invoice-ID";
- public static final String X_WOODY_PREFIX = "x-woody-";
- public static final String X_WOODY_TRACE_ID = X_WOODY_PREFIX + "trace-id";
- public static final String X_WOODY_SPAN_ID = X_WOODY_PREFIX + "span-id";
- public static final String X_WOODY_PARENT_ID = X_WOODY_PREFIX + "parent-id";
- public static final String X_WOODY_DEADLINE = X_WOODY_PREFIX + "deadline";
- public static final String X_WOODY_ERROR_CLASS = X_WOODY_PREFIX + "error-class";
- public static final String X_WOODY_ERROR_REASON = X_WOODY_PREFIX + "error-reason";
- public static final String X_WOODY_META_PREFIX = X_WOODY_PREFIX + "meta-";
- public static final String X_WOODY_META_ID = X_WOODY_META_PREFIX + XWoodyMetaHeaders.ID;
- public static final String X_WOODY_META_USERNAME = X_WOODY_META_PREFIX + XWoodyMetaHeaders.USERNAME;
- public static final String X_WOODY_META_EMAIL = X_WOODY_META_PREFIX + XWoodyMetaHeaders.EMAIL;
- public static final String X_WOODY_META_REALM = X_WOODY_META_PREFIX + XWoodyMetaHeaders.REALM;
-
- public static final class XWoodyMetaHeaders {
-
- public static final String USER_IDENTITY_PREFIX = "user-identity-";
- public static final String ID = USER_IDENTITY_PREFIX + "id";
- public static final String USERNAME = USER_IDENTITY_PREFIX + "username";
- public static final String EMAIL = USER_IDENTITY_PREFIX + "email";
- public static final String REALM = USER_IDENTITY_PREFIX + "realm";
-
- }
- }
-
- public static final class WoodyMetaHeaders {
-
- public static final String USER_IDENTITY_PREFIX = "user-identity.";
- public static final String ID = UserIdentityIdExtensionKit.KEY;
- public static final String USERNAME = UserIdentityUsernameExtensionKit.KEY;
- public static final String EMAIL = UserIdentityEmailExtensionKit.KEY;
- public static final String REALM = UserIdentityRealmExtensionKit.KEY;
- public static final String X_REQUEST_ID = USER_IDENTITY_PREFIX + ExternalHeaders.X_REQUEST_ID;
- public static final String X_REQUEST_DEADLINE = USER_IDENTITY_PREFIX + ExternalHeaders.X_REQUEST_DEADLINE;
- public static final String X_INVOICE_ID = USER_IDENTITY_PREFIX + ExternalHeaders.X_INVOICE_ID;
-
- }
-}
diff --git a/src/main/java/dev/vality/wachter/security/JwtTokenDetailsExtractor.java b/src/main/java/dev/vality/wachter/security/JwtTokenDetailsExtractor.java
deleted file mode 100644
index 78510d7..0000000
--- a/src/main/java/dev/vality/wachter/security/JwtTokenDetailsExtractor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package dev.vality.wachter.security;
-
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.jwt.JwtClaimNames;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
-
-import java.util.List;
-import java.util.Optional;
-
-public final class JwtTokenDetailsExtractor {
-
- private static final String PREFERRED_USERNAME = "preferred_username";
- private static final String EMAIL = "email";
- private static final String ISSUER = "iss";
-
- private JwtTokenDetailsExtractor() {
- }
-
- public static Optional extractFromContext(Authentication authentication) {
- if (!(authentication instanceof JwtAuthenticationToken jwtAuthentication)) {
- return Optional.empty();
- }
- var token = jwtAuthentication.getToken();
- return Optional.of(new JwtTokenDetails(
- token.getClaimAsString(JwtClaimNames.SUB),
- token.getClaimAsString(PREFERRED_USERNAME),
- token.getClaimAsString(EMAIL),
- extractRealm(token),
- jwtAuthentication.getAuthorities().stream()
- .map(GrantedAuthority::getAuthority)
- .toList()
- ));
- }
-
- private static String extractRealm(Jwt token) {
- var issuer = token.getClaimAsString(ISSUER);
- if (issuer == null || issuer.isBlank()) {
- return null;
- }
- var lastSlash = issuer.lastIndexOf('/');
- if (lastSlash < 0) {
- return issuer;
- }
- return issuer.substring(lastSlash);
- }
-
- public record JwtTokenDetails(String subject,
- String preferredUsername,
- String email,
- String realm,
- List roles) {
- }
-}
diff --git a/src/main/java/dev/vality/wachter/service/WachterService.java b/src/main/java/dev/vality/wachter/service/WachterService.java
index 08d78b3..af0d40e 100644
--- a/src/main/java/dev/vality/wachter/service/WachterService.java
+++ b/src/main/java/dev/vality/wachter/service/WachterService.java
@@ -1,11 +1,10 @@
package dev.vality.wachter.service;
import dev.vality.wachter.client.WachterClient;
-import dev.vality.wachter.client.WachterClientResponse;
import dev.vality.wachter.mapper.ServiceMapper;
import dev.vality.wachter.security.AccessData;
import dev.vality.wachter.security.AccessService;
-import dev.vality.wachter.security.JwtTokenDetailsExtractor;
+import dev.vality.woody.http.bridge.util.JwtTokenDetailsExtractor;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@@ -15,6 +14,8 @@
import java.io.ByteArrayOutputStream;
+import static dev.vality.wachter.client.WachterClient.WachterClientResponse;
+
@RequiredArgsConstructor
@Service
public class WachterService {
diff --git a/src/main/java/dev/vality/wachter/tracing/TraceContextHeadersExtractor.java b/src/main/java/dev/vality/wachter/tracing/TraceContextHeadersExtractor.java
deleted file mode 100644
index 70f496b..0000000
--- a/src/main/java/dev/vality/wachter/tracing/TraceContextHeadersExtractor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package dev.vality.wachter.tracing;
-
-import dev.vality.woody.api.trace.context.TraceContext;
-import io.opentelemetry.api.GlobalOpenTelemetry;
-import io.opentelemetry.context.propagation.TextMapSetter;
-import lombok.experimental.UtilityClass;
-import lombok.extern.slf4j.Slf4j;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import static dev.vality.wachter.constants.TraceHeadersConstants.*;
-
-@Slf4j
-@UtilityClass
-public class TraceContextHeadersExtractor {
-
- public Map extractHeaders() {
- var traceData = Objects.requireNonNull(TraceContext.getCurrentTraceData(),
- "TraceData should be present in TraceContext");
- var otelSpan = Objects.requireNonNull(traceData.getOtelSpan(),
- "OTel span should be attached to TraceData");
- if (!otelSpan.getSpanContext().isValid()) {
- throw new IllegalStateException("SpanContext must be valid");
- }
-
- var span = traceData.getActiveSpan().getSpan();
- var headers = new HashMap();
- putIfNotNull(headers, WOODY_TRACE_ID, span.getTraceId());
- putIfNotNull(headers, WOODY_SPAN_ID, span.getId());
- putIfNotNull(headers, WOODY_PARENT_ID, span.getParentId());
- putIfNotNull(headers, WOODY_DEADLINE,
- Optional.ofNullable(span.getDeadline()).map(Instant::toString).orElse(null));
- var customMetadata = traceData.getActiveSpan().getCustomMetadata();
- customMetadata.getKeys()
- .forEach(s -> putIfNotNull(headers, WOODY_META_PREFIX + s, customMetadata.getValue(s)));
- GlobalOpenTelemetry.getPropagators()
- .getTextMapPropagator()
- .inject(traceData.getOtelContext(), headers, MAP_SETTER);
- return headers;
- }
-
- private void putIfNotNull(Map headers,
- String key,
- String value) {
- if (value != null && !value.isEmpty()) {
- headers.put(key, value);
- }
- }
-
- private static final TextMapSetter