diff --git a/cloud/cloud-api-lib/src/main/java/org/webpieces/ctx/api/ClientServiceConfig.java b/cloud/cloud-api-lib/src/main/java/org/webpieces/ctx/api/ClientServiceConfig.java index 86dad8856..dc7b49405 100644 --- a/cloud/cloud-api-lib/src/main/java/org/webpieces/ctx/api/ClientServiceConfig.java +++ b/cloud/cloud-api-lib/src/main/java/org/webpieces/ctx/api/ClientServiceConfig.java @@ -16,7 +16,17 @@ public ClientServiceConfig(HeaderCtxList hcl, String serversName){ this(hcl, null, serversName); } public ClientServiceConfig(HeaderCtxList hcl, List successExceptions, String serviceName){ + if(hcl == null) { + throw new IllegalArgumentException("Pass in a non-null hcl param please. We need the class still to determine which jar the application is in." + + " This will be deprecated in the future"); + } this.hcl = hcl; + if(hcl.listHeaderCtxPairs() != null) { + throw new IllegalArgumentException("listHeaderCtxPairs() must return null AND add this instead -> \n" + + "Multibinder htmlTagCreators = Multibinder.newSetBinder(binder, AddPlatformHeaders.class);\n" + + "htmlTagCreators.addBinding().to(CompanyHeaders.class);\n\n" + + "We now use binders instead so plugins can add headers they need"); + } this.successExceptions = successExceptions; this.serversName = serviceName; } diff --git a/cloud/cloud-api-lib/src/main/java/org/webpieces/microsvc/server/api/HeaderTranslation.java b/cloud/cloud-api-lib/src/main/java/org/webpieces/microsvc/server/api/HeaderTranslation.java new file mode 100644 index 000000000..b159727fc --- /dev/null +++ b/cloud/cloud-api-lib/src/main/java/org/webpieces/microsvc/server/api/HeaderTranslation.java @@ -0,0 +1,38 @@ +package org.webpieces.microsvc.server.api; + +import org.webpieces.ctx.api.ClientServiceConfig; +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.Context; +import org.webpieces.util.context.PlatformHeaders; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class HeaderTranslation { + + private final List listHeaders; + + @Inject + public HeaderTranslation( + Set addPlatformHeaders, + ClientServiceConfig config + ) { + listHeaders = new ArrayList<>(); + for(AddPlatformHeaders add : addPlatformHeaders) { + Class clazz = add.platformHeadersToAdd(); + PlatformHeaders[] enumConstants = clazz.getEnumConstants(); + List list = Arrays.asList(enumConstants); + listHeaders.addAll(list); + } + + Context.checkForDuplicates(listHeaders); + } + + public List getHeaders() { + return listHeaders; + } + +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/AddGcpAuthHeaders.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/AddGcpAuthHeaders.java new file mode 100644 index 000000000..61e792078 --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/AddGcpAuthHeaders.java @@ -0,0 +1,12 @@ +package org.webpieces.microsvc.client.api; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddGcpAuthHeaders implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return GcpAuthHeader.class; + } + +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/Authentication.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/Authentication.java new file mode 100644 index 000000000..55fe62e4a --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/Authentication.java @@ -0,0 +1,10 @@ +package org.webpieces.microsvc.client.api; + +import org.webpieces.util.context.Context; + +public interface Authentication { + public Object setupMagic(); + + public void resetMagic(Object state); + +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthHeader.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthHeader.java new file mode 100644 index 000000000..1a22805fc --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthHeader.java @@ -0,0 +1,57 @@ +package org.webpieces.microsvc.client.api; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +/** + * + */ +public enum GcpAuthHeader implements PlatformHeaders { + + AUTH_TOKEN("Authorization", null, false, true), + METADATA_FLAVOR("Metadata-Flavor", null, false, false); + + private final String headerName; + private final String logKey; + private final boolean isLog; + private final boolean isSecure; + + GcpAuthHeader(String headerName, String logKey, boolean isLog, boolean isSecure) { + this.headerName = headerName; + this.logKey = logKey; + this.isLog = isLog; + this.isSecure = isSecure; + } + + + @Override + public String getHeaderName() { + return headerName; + } + + @Override + public String getLoggerMDCKey() { + return logKey; + } + + @Override + public boolean isWantLogged() { + return isLog; + } + + @Override + public boolean isWantTransferred() { + return headerName != null; + } + + @Override + public boolean isSecured() { + return isSecure; + } + + @Override + public boolean isDimensionForMetrics() { + return false; + } + +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthentication.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthentication.java new file mode 100644 index 000000000..bfeccd353 --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/GcpAuthentication.java @@ -0,0 +1,82 @@ +package org.webpieces.microsvc.client.api; + +import org.webpieces.microsvc.client.impl.Endpoint; +import org.webpieces.microsvc.client.impl.HttpsJsonClient; +import org.webpieces.util.HostWithPort; +import org.webpieces.util.SneakyThrow; +import org.webpieces.util.context.Context; +import org.webpieces.util.futures.XFuture; + +import javax.inject.Inject; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +public class GcpAuthentication implements Authentication { + + private final HttpsJsonClient jsonClient; + private final Method method; + private long expiresAtSeconds = 0; + private String accessToken; + + @Inject + public GcpAuthentication( + HttpsJsonClient jsonClient + ) { + this.jsonClient = jsonClient; + + try { + method = GcpAuthentication.class.getDeclaredMethod("fetchToken"); + } catch (NoSuchMethodException e) { + throw SneakyThrow.sneak(e); + } + } + + @Override + public Object setupMagic() { + String previousSetting = Context.getMagic(GcpAuthHeader.AUTH_TOKEN); + + String accessToken = fetchToken(); + Context.putMagic(GcpAuthHeader.AUTH_TOKEN, "Bearer "+accessToken); + + return previousSetting; + } + + private synchronized String fetchToken() { + long secondsEpochNow = System.currentTimeMillis() / 1000; + if(secondsEpochNow < expiresAtSeconds) + return accessToken; + + try { + Context.putMagic(GcpAuthHeader.METADATA_FLAVOR, "Google"); + HostWithPort host = new HostWithPort("metadata.google.internal", 80); + Endpoint endpoint = new Endpoint(host, "GET", "/computeMetadata/v1/instance/service-accounts/default/token"); + + XFuture mapXFuture = jsonClient.sendHttpRequest(method, null, endpoint, TokenResponse.class, true); + TokenResponse map = null; + try { + map = mapXFuture.get(20, TimeUnit.SECONDS); + } catch (Exception e) { + throw SneakyThrow.sneak(e); + } + accessToken = map.getAccessToken(); + expiresAtSeconds = secondsEpochNow + map.getExpiresIn() - 30; //subtract 30 seconds so we renew before it expires + + return accessToken; + } finally { + Context.removeMagic(GcpAuthHeader.METADATA_FLAVOR); + } + } + + @Override + public void resetMagic(Object state) { + //restore to previous state or if state was null, remove magic.. + if(state == null) { + Context.removeMagic(GcpAuthHeader.AUTH_TOKEN); + return; + } + + String previousSetting = (String) state; + Context.putMagic(GcpAuthHeader.AUTH_TOKEN, previousSetting); + } + +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/RESTClientCreator.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/RESTClientCreator.java index db114fad5..3eaeddcc2 100644 --- a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/RESTClientCreator.java +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/RESTClientCreator.java @@ -22,19 +22,29 @@ public RESTClientCreator(Provider wrapperProvider) this.wrapperProvider = wrapperProvider; } + public T createAuthClient(Class apiInterface, HostWithPort addr, Authentication auth) { + return createClient(apiInterface, addr, false, false, auth); + } + public T createClient(Class apiInterface, HostWithPort addr) { - return createClient(apiInterface, addr, false, false); + return createClient(apiInterface, addr, false, false, null); } public T createClientPubsub(Class apiInterface, HostWithPort addr) { - return createClient(apiInterface, addr, true, false); + return createClient(apiInterface, addr, true, false, null); } public T createClientHttp(Class apiInterface, HostWithPort addr) { - return createClient(apiInterface, addr, false, true); + return createClient(apiInterface, addr, false, true, null); } - public T createClient(Class apiInterface, HostWithPort addr, boolean createForPubSub, boolean forHttp) { + public T createClient( + Class apiInterface, + HostWithPort addr, + boolean createForPubSub, + boolean forHttp, + Authentication authentication + ) { //quick DNS check or fail try { @@ -45,7 +55,7 @@ public T createClient(Class apiInterface, HostWithPort addr, boolean crea HttpsJsonClientInvokeHandler invokeHandler = wrapperProvider.get(); boolean hasUrlParams = apiInterface.getAnnotation(NotEvolutionProof.class) != null; - invokeHandler.initialize(addr, hasUrlParams, forHttp); + invokeHandler.initialize(addr, hasUrlParams, forHttp, authentication); boolean forceVoid = false; if(createForPubSub) diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/TokenResponse.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/TokenResponse.java new file mode 100644 index 000000000..7621f8d16 --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/api/TokenResponse.java @@ -0,0 +1,44 @@ +package org.webpieces.microsvc.client.api; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class TokenResponse { + /* + { + "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAi85nHq39HE3C2LTrCARA", + "expires_in":3599, + "token_type":"Bearer" + } + */ + + @JsonProperty("access_token") + private String accessToken; + @JsonProperty("expires_in") + private Long expiresIn; + @JsonProperty("token_type") + private String tokenType; + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public Long getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(Long expiresIn) { + this.expiresIn = expiresIn; + } + + public String getTokenType() { + return tokenType; + } + + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/EmptyAuth.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/EmptyAuth.java new file mode 100644 index 000000000..99318681f --- /dev/null +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/EmptyAuth.java @@ -0,0 +1,14 @@ +package org.webpieces.microsvc.client.impl; + +import org.webpieces.microsvc.client.api.Authentication; + +public class EmptyAuth implements Authentication { + @Override + public Object setupMagic() { + return null; + } + + @Override + public void resetMagic(Object state) { + } +} diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClient.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClient.java index 20f8fa88e..a6b7f9ea0 100644 --- a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClient.java +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClient.java @@ -23,9 +23,11 @@ import org.webpieces.http2client.api.dto.FullResponse; import org.webpieces.httpparser.api.common.KnownHeaderName; import org.webpieces.microsvc.client.api.ClientSSLEngineFactory; +import org.webpieces.microsvc.server.api.HeaderTranslation; import org.webpieces.util.HostWithPort; import org.webpieces.plugin.json.JacksonJsonConverter; import org.webpieces.plugin.json.JsonError; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.Context; import org.webpieces.util.context.PlatformHeaders; import org.webpieces.util.exceptions.NioClosedChannelException; @@ -79,26 +81,22 @@ public HttpsJsonClient( FutureHelper futureUtil, ScheduledExecutorService schedulerSvc, Masker masker, - MeterRegistry metrics + MeterRegistry metrics, + HeaderTranslation translation ) { this.sslFactory = sslFactory; - if(clientServiceConfig.getHcl() == null) - throw new IllegalArgumentException("clientServiceConfig.getHcl() cannot be null and was"); - this.serversName = clientServiceConfig.getServersName(); this.metrics = metrics; - List listHeaders = clientServiceConfig.getHcl().listHeaderCtxPairs(); - this.jsonMapper = jsonMapper; this.client = client; this.futureUtil = futureUtil; this.schedulerSvc = schedulerSvc; this.masker = masker; - Context.checkForDuplicates(listHeaders); + List headers = translation.getHeaders(); - for(PlatformHeaders header : listHeaders) { + for(PlatformHeaders header : headers) { if(header.isSecured()) { secureList.add(header.getHeaderName()); } @@ -110,6 +108,10 @@ public HttpsJsonClient( } + private Enum something() { + return null; + } + private void cancel(Http2Socket clientSocket) { try { @@ -237,7 +239,7 @@ private XFuture sendAndTranslate(Method method, HostWithPort apiAddress, //Creating a gauage in micrometer will have micrometer thread keep a reference to object forever. //It is very important to do this lazy or we add a new AtomicInteger on every api call if it //already exists instead of ONCE PR API CLASS (we do not even do once per method yet, though we could) - public AtomicInteger computeLazyToAvoidOOM(String key, AtomicInteger existing, Iterable tags) { + private AtomicInteger computeLazyToAvoidOOM(String key, AtomicInteger existing, Iterable tags) { if(existing == null) { existing = new AtomicInteger(0); metrics.gauge("webpieces.requests.inflight", tags, existing, (c) -> c.get()); @@ -245,7 +247,7 @@ public AtomicInteger computeLazyToAvoidOOM(String key, AtomicInteger existing, I return existing; } - public XFuture send(Iterable tags, AtomicInteger inFlightCounter, Http2Socket socket, FullRequest request) { + private XFuture send(Iterable tags, AtomicInteger inFlightCounter, Http2Socket socket, FullRequest request) { XFuture send = socket.send(request); //in an ideal world, we would use the async send which can notify us when 'write' is done so it is out the door, but diff --git a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClientInvokeHandler.java b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClientInvokeHandler.java index 4f8d3ba15..c79a6afb5 100644 --- a/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClientInvokeHandler.java +++ b/cloud/generate-httpclient/src/main/java/org/webpieces/microsvc/client/impl/HttpsJsonClientInvokeHandler.java @@ -3,6 +3,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.webpieces.ctx.api.HttpMethod; +import org.webpieces.microsvc.client.api.Authentication; import org.webpieces.util.HostWithPort; import org.webpieces.recorder.impl.EndpointInfo; import org.webpieces.recorder.impl.TestCaseRecorder; @@ -35,6 +36,7 @@ public class HttpsJsonClientInvokeHandler implements InvocationHandler { private HostWithPort addr; private boolean hasUrlParams; private boolean forHttp; + private Authentication authentication; @Inject public HttpsJsonClientInvokeHandler(HttpsJsonClient clientHelper, ClientAssertions clientAssertions) { @@ -42,14 +44,27 @@ public HttpsJsonClientInvokeHandler(HttpsJsonClient clientHelper, ClientAssertio this.clientAssertions = clientAssertions; } - public void initialize(HostWithPort addr, boolean hasUrlParams, boolean forHttp) { + public void initialize(HostWithPort addr, boolean hasUrlParams, boolean forHttp, Authentication authentication) { this.addr = addr; this.hasUrlParams = hasUrlParams; this.forHttp = forHttp; + this.authentication = authentication; + if(this.authentication == null) + this.authentication = new EmptyAuth(); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object state = authentication.setupMagic(); + try { + return invokeImpl(proxy, method, args); + } finally { + authentication.resetMagic(state); + } + } + + private Object invokeImpl(Object proxy, Method method, Object[] args) throws Throwable { + if(args == null) args = new Object[0]; //avoid needing to deal with null here diff --git a/cloud/generate-httpclient/src/test/java/org/webpieces/googlecloud/storage/biz/HeadersCtx.java b/cloud/generate-httpclient/src/test/java/org/webpieces/googlecloud/storage/biz/HeadersCtx.java index fef1fb897..1471bbbec 100644 --- a/cloud/generate-httpclient/src/test/java/org/webpieces/googlecloud/storage/biz/HeadersCtx.java +++ b/cloud/generate-httpclient/src/test/java/org/webpieces/googlecloud/storage/biz/HeadersCtx.java @@ -9,6 +9,6 @@ public class HeadersCtx implements HeaderCtxList { @Override public List listHeaderCtxPairs() { - return new ArrayList<>(); + return null; } } diff --git a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/api/LogExceptionFilter.java b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/api/LogExceptionFilter.java index 4be27cfa4..a8387c428 100644 --- a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/api/LogExceptionFilter.java +++ b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/api/LogExceptionFilter.java @@ -44,11 +44,11 @@ public class LogExceptionFilter extends RouteFilter { public LogExceptionFilter( IgnoreExceptions exceptionCheck, Masker masker, - ClientServiceConfig clientServiceConfig + HeaderTranslation translation ) { this.exceptionCheck = exceptionCheck; this.masker = masker; - List listHeaders = clientServiceConfig.getHcl().listHeaderCtxPairs(); + List listHeaders = translation.getHeaders(); for(PlatformHeaders header : listHeaders) { if(header.isSecured()) { diff --git a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/HeaderToRequestStateFilter.java b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/HeaderToRequestStateFilter.java index 57cd668e2..a6eb0dd59 100644 --- a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/HeaderToRequestStateFilter.java +++ b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/HeaderToRequestStateFilter.java @@ -7,6 +7,7 @@ import org.webpieces.ctx.api.ClientServiceConfig; import org.webpieces.ctx.api.Current; import org.webpieces.microsvc.server.api.HeaderCtxList; +import org.webpieces.microsvc.server.api.HeaderTranslation; import org.webpieces.recorder.impl.TestCaseHolder; import org.webpieces.router.api.controller.actions.Action; import org.webpieces.router.api.routes.MethodMeta; @@ -23,15 +24,13 @@ public class HeaderToRequestStateFilter extends RouteFilter { private static final Logger log = LoggerFactory.getLogger(HeaderToRequestStateFilter.class); private final Set transferKeys = new HashSet<>(); - private HeaderCtxList headerCtxList; @Inject - public HeaderToRequestStateFilter(ClientServiceConfig config) { - headerCtxList = config.getHcl(); - List platformHeaders = headerCtxList.listHeaderCtxPairs(); - Context.checkForDuplicates(platformHeaders); + public HeaderToRequestStateFilter( + HeaderTranslation translation + ) { + List headers = translation.getHeaders(); - List headers = headerCtxList.listHeaderCtxPairs(); for (PlatformHeaders contextKey : headers) { if (!contextKey.isWantTransferred()) continue; diff --git a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/MDCFilter.java b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/MDCFilter.java index 2e021fda1..6e810d0ca 100644 --- a/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/MDCFilter.java +++ b/cloud/server-scaffolding/src/main/java/org/webpieces/microsvc/server/impl/filters/MDCFilter.java @@ -3,6 +3,7 @@ import org.slf4j.MDC; import org.webpieces.ctx.api.ClientServiceConfig; import org.webpieces.microsvc.server.api.HeaderCtxList; +import org.webpieces.microsvc.server.api.HeaderTranslation; import org.webpieces.router.api.controller.actions.Action; import org.webpieces.router.api.routes.MethodMeta; import org.webpieces.router.api.routes.RouteFilter; @@ -13,6 +14,7 @@ import org.webpieces.util.futures.XFuture; import javax.inject.Inject; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,12 +25,22 @@ public class MDCFilter extends RouteFilter { private FutureHelper futureUtil; - private HeaderCtxList headerCollector; + + private List loggerHeaders = new ArrayList<>(); @Inject - public MDCFilter(FutureHelper futureUtil, ClientServiceConfig config) { + public MDCFilter( + FutureHelper futureUtil, + HeaderTranslation translation + ) { this.futureUtil = futureUtil; - headerCollector = config.getHcl(); + List headers = translation.getHeaders(); + + for(PlatformHeaders h : headers) { + if(h.isWantLogged()) { + loggerHeaders.add(h); + } + } } @Override @@ -40,15 +52,11 @@ public XFuture filter(MethodMeta meta, Service nextF Set keys = new HashSet<>(); try { - List headersCtx = headerCollector.listHeaderCtxPairs(); - for (PlatformHeaders key : headersCtx) { - if (!key.isWantLogged()) { - continue; - } - + for (PlatformHeaders key : loggerHeaders) { String magic = Context.getMagic(key); if (magic != null) { MDC.put(key.getLoggerMDCKey(), magic); + keys.add(key.getLoggerMDCKey()); } } diff --git a/core/core-future/src/main/java/org/webpieces/microsvc/api/AddMicroSvcHeaders.java b/core/core-future/src/main/java/org/webpieces/microsvc/api/AddMicroSvcHeaders.java new file mode 100644 index 000000000..0e045915c --- /dev/null +++ b/core/core-future/src/main/java/org/webpieces/microsvc/api/AddMicroSvcHeaders.java @@ -0,0 +1,11 @@ +package org.webpieces.microsvc.api; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddMicroSvcHeaders implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return MicroSvcHeader.class; + } +} diff --git a/core/core-future/src/main/java/org/webpieces/microsvc/api/MicroSvcHeader.java b/core/core-future/src/main/java/org/webpieces/microsvc/api/MicroSvcHeader.java index cfacdf26a..aa54f9b0e 100644 --- a/core/core-future/src/main/java/org/webpieces/microsvc/api/MicroSvcHeader.java +++ b/core/core-future/src/main/java/org/webpieces/microsvc/api/MicroSvcHeader.java @@ -1,5 +1,6 @@ package org.webpieces.microsvc.api; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.Context; import org.webpieces.util.context.PlatformHeaders; diff --git a/core/core-future/src/main/java/org/webpieces/util/context/AddPlatformHeaders.java b/core/core-future/src/main/java/org/webpieces/util/context/AddPlatformHeaders.java new file mode 100644 index 000000000..5b27fcc39 --- /dev/null +++ b/core/core-future/src/main/java/org/webpieces/util/context/AddPlatformHeaders.java @@ -0,0 +1,7 @@ +package org.webpieces.util.context; + +public interface AddPlatformHeaders { + + public Class platformHeadersToAdd(); + +} diff --git a/core/core-future/src/main/java/org/webpieces/util/context/Context.java b/core/core-future/src/main/java/org/webpieces/util/context/Context.java index bc2781c6b..ccb6243cd 100644 --- a/core/core-future/src/main/java/org/webpieces/util/context/Context.java +++ b/core/core-future/src/main/java/org/webpieces/util/context/Context.java @@ -34,11 +34,18 @@ public synchronized static void checkForDuplicates(List platfor existingFromMdc = mdcKeyToHeader.get(header.getLoggerMDCKey()); if(existingFromHeader != null) { - throw new IllegalArgumentException("Duplicate in Platform headers not allowed. key=" - +header.getHeaderName()+" exists in "+tuple(existingFromHeader)+" and in "+tuple(header)); + if(header.getLoggerMDCKey() != existingFromHeader.getLoggerMDCKey()) + throw new IllegalStateException("header="+tuple(header)+" and header="+tuple(existingFromHeader)+" define the same header " + + "but they define getLoggerMDCKey differently. remove one of the plugins or modules to remove one of these headers or redine th header to match"); + compareHeader(header, existingFromHeader); + continue; // no need to add duplicate, they are the same } else if(existingFromMdc != null) { - throw new IllegalArgumentException("Duplicate in Platform headers not allowed. key=" - +header.getHeaderName()+" exists in "+tuple(existingFromMdc)+" and in "+tuple(header)); + if(header.getHeaderName() != existingFromHeader.getHeaderName()) + throw new IllegalStateException("header="+tuple(header)+" and header="+tuple(existingFromHeader)+" define the same mdc key " + + "but they define getHeaderName() differently. remove one of the plugins or modules to remove one of these headers or redine th header to match"); + compareHeader(header, existingFromMdc); + + continue; //no need to add duplicate, they are the same } headerKeyToHeader.put(header.getHeaderName(), header); @@ -46,8 +53,18 @@ public synchronized static void checkForDuplicates(List platfor } } + private static void compareHeader(PlatformHeaders header, PlatformHeaders existingFromHeader) { + if(header.isWantLogged() != existingFromHeader.isWantLogged() + || header.isDimensionForMetrics() != existingFromHeader.isDimensionForMetrics() + || header.isSecured() != existingFromHeader.isSecured() + || header.isWantTransferred() != existingFromHeader.isWantTransferred() + ) + throw new IllegalStateException("header="+tuple(header)+" and header="+tuple(existingFromHeader)+" define the same header " + + "but they define their properties differently. remove one of the plugins or modules to remove one of these headers or redine th header to match"); + } + private static String tuple(PlatformHeaders header) { - return header.getHeaderName()+"/"+header.getLoggerMDCKey(); + return header.getClass()+"."+header; } public static T get(String key) { diff --git a/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/impl/GCPTaskClient.java b/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/impl/GCPTaskClient.java index de7c9ef34..8db37b0b7 100644 --- a/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/impl/GCPTaskClient.java +++ b/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/impl/GCPTaskClient.java @@ -8,6 +8,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; +import org.webpieces.microsvc.server.api.HeaderTranslation; import org.webpieces.util.HostWithPort; import org.webpieces.util.SneakyThrow; import org.slf4j.Logger; @@ -45,19 +46,14 @@ public class GCPTaskClient { public GCPTaskClient( GCPCloudTaskConfig config, CloudTasksClient cloudTasksClient, - ClientServiceConfig clientServiceConfig, - Masker masker + Masker masker, + HeaderTranslation translation ) { this.config = config; this.cloudTasksClient = cloudTasksClient; this.masker = masker; - if(clientServiceConfig.getHcl() == null) - throw new IllegalArgumentException("clientServiceConfig.getHcl() cannot be null and was"); - - List listHeaders = clientServiceConfig.getHcl().listHeaderCtxPairs(); - - Context.checkForDuplicates(listHeaders); + List listHeaders = translation.getHeaders(); for(PlatformHeaders header : listHeaders) { if(header.isSecured()) diff --git a/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/localimpl/HttpClientWrapper.java b/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/localimpl/HttpClientWrapper.java index 7cd76b9c0..cf4c05345 100644 --- a/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/localimpl/HttpClientWrapper.java +++ b/googlecloud/cloud-tasks/src/main/java/org/webpieces/googlecloud/cloudtasks/localimpl/HttpClientWrapper.java @@ -20,6 +20,7 @@ import org.webpieces.http2client.api.dto.FullResponse; import org.webpieces.httpparser.api.common.KnownHeaderName; import org.webpieces.microsvc.client.api.ClientSSLEngineFactory; +import org.webpieces.microsvc.server.api.HeaderTranslation; import org.webpieces.util.HostWithPort; import org.webpieces.util.security.Masker; import org.webpieces.util.context.Context; @@ -59,22 +60,17 @@ public class HttpClientWrapper { @Inject public HttpClientWrapper( ClientSSLEngineFactory sslFactory, - ClientServiceConfig clientServiceConfig, Http2Client client, FutureHelper futureUtil, - Masker masker + Masker masker, + HeaderTranslation translation ) { this.sslFactory = sslFactory; this.client = client; this.futureUtil = futureUtil; this.masker = masker; - if(clientServiceConfig.getHcl() == null) - throw new IllegalArgumentException("clientServiceConfig.getHcl() cannot be null and was"); - - List listHeaders = clientServiceConfig.getHcl().listHeaderCtxPairs(); - - Context.checkForDuplicates(listHeaders); + List listHeaders = translation.getHeaders(); for(PlatformHeaders header : listHeaders) { if(header.isSecured()) diff --git a/googlecloud/cloud-tasks/src/test/java/org/webpieces/googlecloud/cloudtasks/HeadersCtx.java b/googlecloud/cloud-tasks/src/test/java/org/webpieces/googlecloud/cloudtasks/HeadersCtx.java index d676eec1c..6771c4975 100644 --- a/googlecloud/cloud-tasks/src/test/java/org/webpieces/googlecloud/cloudtasks/HeadersCtx.java +++ b/googlecloud/cloud-tasks/src/test/java/org/webpieces/googlecloud/cloudtasks/HeadersCtx.java @@ -9,6 +9,6 @@ public class HeadersCtx implements HeaderCtxList { @Override public List listHeaderCtxPairs() { - return new ArrayList<>(); + return null; } } diff --git a/googlecloud/logging/src/main/java/org/webpieces/googlecloud/logging/SingletonHeaderList.java b/googlecloud/logging/src/main/java/org/webpieces/googlecloud/logging/SingletonHeaderList.java deleted file mode 100644 index a1cba0af9..000000000 --- a/googlecloud/logging/src/main/java/org/webpieces/googlecloud/logging/SingletonHeaderList.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.webpieces.googlecloud.logging; - -import org.webpieces.microsvc.server.api.HeaderCtxList; -import org.webpieces.util.context.PlatformHeaders; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -public class SingletonHeaderList implements HeaderCtxList { - - private static SingletonHeaderList singleton; - private AtomicReference> headersList = new AtomicReference<>(new ArrayList<>()); - - @Override - public List listHeaderCtxPairs() { - return headersList.get(); - } - - private void setHeaderCtxList(List headers) { - headersList.set(headers); - } - - public synchronized static void initialize(List headers) { - List result = new ArrayList<>(); - for(PlatformHeaders h : headers) { - if(h.isWantLogged()) { - result.add(h); - } - } - SingletonHeaderList singleton1 = getSingleton(); - singleton1.setHeaderCtxList(result); - } - - public synchronized static SingletonHeaderList getSingleton() { - if(singleton == null) - singleton = new SingletonHeaderList(); - return singleton; - } - -} diff --git a/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/AddAuthHeader.java b/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/AddAuthHeader.java new file mode 100644 index 000000000..d81279bc7 --- /dev/null +++ b/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/AddAuthHeader.java @@ -0,0 +1,12 @@ +package org.webpieces.googleauth.impl; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddAuthHeader implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return AuthHeader.class; + } + +} diff --git a/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/GoogleAuthModule.java b/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/GoogleAuthModule.java index f2daff790..b8fb7700e 100644 --- a/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/GoogleAuthModule.java +++ b/googlecloud/plugin-google-auth/src/main/java/org/webpieces/googleauth/impl/GoogleAuthModule.java @@ -8,10 +8,9 @@ import org.webpieces.googleauth.client.api.AuthApi; import org.webpieces.googleauth.api.GoogleAuthConfig; import org.webpieces.microsvc.client.api.RESTClientCreator; -import org.webpieces.router.api.extensions.BodyContentBinder; import org.webpieces.util.HostWithPort; import org.webpieces.util.cmdline2.Arguments; -import org.webpieces.util.context.PlatformHeaders; +import org.webpieces.util.context.AddPlatformHeaders; import javax.inject.Singleton; import java.util.function.Supplier; @@ -38,8 +37,8 @@ public GoogleAuthModule(Arguments args, GoogleAuthConfig authRouteIdSet, Class headerBinder = Multibinder.newSetBinder(binder, PlatformHeaders.class); - headerBinder.addBinding().toInstance(AuthHeader.AUTH_TOKEN); + Multibinder htmlTagCreators = Multibinder.newSetBinder(binder, AddPlatformHeaders.class); + htmlTagCreators.addBinding().to(AddAuthHeader.class); binder.bind(AuthApiConfig.class).toInstance( new AuthApiConfig(callbackUrl.get(), authClientId.get(), authClientSecret.get())); diff --git a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java new file mode 100644 index 000000000..8120cd9bd --- /dev/null +++ b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java @@ -0,0 +1,11 @@ +package webpiecesxxxxxpackage.base; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddCompanyHeaders implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return CompanyHeaders.class; + } +} diff --git a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java index 38c24dc87..992ef0370 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java @@ -23,6 +23,7 @@ import com.google.inject.multibindings.Multibinder; import org.webpieces.util.cmdline2.Arguments; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.ClientAssertions; import webpiecesxxxxxpackage.Server; import webpiecesxxxxxpackage.db.DbCredentials; @@ -86,6 +87,9 @@ public void configure(Binder binder) { Multibinder uriBinder = Multibinder.newSetBinder(binder, Startable.class); uriBinder.addBinding().to(PopulateDatabase.class); + Multibinder headers = Multibinder.newSetBinder(binder, AddPlatformHeaders.class); + headers.addBinding().to(AddCompanyHeaders.class); + Multibinder conversionBinder = Multibinder.newSetBinder(binder, ObjectStringConverter.class); conversionBinder.addBinding().to(EducationEnum.WebConverter.class); conversionBinder.addBinding().to(RoleEnum.WebConverter.class); diff --git a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java index d49da66f7..bc8dace75 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java @@ -4,10 +4,7 @@ import org.webpieces.microsvc.api.MicroSvcHeader; import org.webpieces.microsvc.server.api.HeaderCtxList; import org.webpieces.util.context.PlatformHeaders; -import webpiecesxxxxxpackage.Server; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class HeadersCtx implements HeaderCtxList { @@ -16,12 +13,8 @@ public static ClientServiceConfig createConfig(String appName) { return new ClientServiceConfig(new HeadersCtx(), appName); } + @Override public List listHeaderCtxPairs() { - List list = new ArrayList<>(); - CompanyHeaders[] values = CompanyHeaders.values(); - MicroSvcHeader[] values1 = MicroSvcHeader.values(); - list.addAll(Arrays.asList(values)); - list.addAll(Arrays.asList(values1)); - return list; + return null; } } diff --git a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java index c2e6fed6e..4bb65df2b 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateBasic/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java @@ -9,11 +9,14 @@ import org.slf4j.LoggerFactory; import org.webpieces.ctx.api.ClientServiceConfig; import org.webpieces.util.HostWithPort; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.Context; -import org.webpieces.util.futures.Logging; +import org.webpieces.util.context.PlatformHeaders; import org.webpieces.webserver.api.ServerConfig; import org.webpieces.webserver.test.http2.CompanyApiTest; import webpiecesxxxxxpackage.Server; +import webpiecesxxxxxpackage.base.AddCompanyHeaders; +import webpiecesxxxxxpackage.base.CompanyHeaders; import webpiecesxxxxxpackage.base.HeadersCtx; import webpiecesxxxxxpackage.json.ExampleRestAPI; import webpiecesxxxxxpackage.json.SearchApi; @@ -21,7 +24,7 @@ import webpiecesxxxxxpackage.mock.MockRemoteService; import webpiecesxxxxxpackage.service.RemoteService; -import java.net.InetSocketAddress; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -88,6 +91,13 @@ protected ClientServiceConfig getConfig() { return HeadersCtx.createConfig(Server.APP_NAME); } + @Override + protected List fetchEnums() { + List classes = super.fetchEnums(); + classes.add(new AddCompanyHeaders()); + return classes; + } + private class AppOverridesModule implements Module { @Override public void configure(Binder binder) { diff --git a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java new file mode 100644 index 000000000..a859d2b31 --- /dev/null +++ b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/AddCompanyHeaders.java @@ -0,0 +1,11 @@ +package webpiecesxxxxxpackage.base; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddCompanyHeaders implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return PlatformHeaders.class; + } +} diff --git a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java index 7c5bde4c1..19d53bb6b 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/GuiceModule.java @@ -24,6 +24,7 @@ import com.google.inject.multibindings.Multibinder; import org.webpieces.util.cmdline2.Arguments; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.ClientAssertions; import webpiecesxxxxxpackage.db.DbCredentials; import webpiecesxxxxxpackage.deleteme.remoteapi.RemoteApi; @@ -74,7 +75,10 @@ public void configure(Binder binder) { //all modules have access to adding their own Startable objects to be run on server startup Multibinder uriBinder = Multibinder.newSetBinder(binder, Startable.class); uriBinder.addBinding().to(PopulateDatabase.class); - + + Multibinder headers = Multibinder.newSetBinder(binder, AddPlatformHeaders.class); + headers.addBinding().to(AddCompanyHeaders.class); + //Must bind a SimpleStorage for plugins to read/save data and render their html pages binder.bind(SimpleStorage.class).to(SimpleStorageImpl.class).asEagerSingleton(); diff --git a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java index d49da66f7..d101af72c 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/main/java/webpiecesxxxxxpackage/base/HeadersCtx.java @@ -1,13 +1,9 @@ package webpiecesxxxxxpackage.base; import org.webpieces.ctx.api.ClientServiceConfig; -import org.webpieces.microsvc.api.MicroSvcHeader; import org.webpieces.microsvc.server.api.HeaderCtxList; import org.webpieces.util.context.PlatformHeaders; -import webpiecesxxxxxpackage.Server; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class HeadersCtx implements HeaderCtxList { @@ -17,11 +13,6 @@ public static ClientServiceConfig createConfig(String appName) { } public List listHeaderCtxPairs() { - List list = new ArrayList<>(); - CompanyHeaders[] values = CompanyHeaders.values(); - MicroSvcHeader[] values1 = MicroSvcHeader.values(); - list.addAll(Arrays.asList(values)); - list.addAll(Arrays.asList(values1)); - return list; + return null; } } diff --git a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java index 9d994ee25..5cb18cf50 100644 --- a/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java +++ b/webserver-templates/webpiecesServerBuilder/TemplateJsonMicroSvc/production/src/test/java/webpiecesxxxxxpackage/framework/FeatureTest.java @@ -9,17 +9,21 @@ import org.slf4j.LoggerFactory; import org.webpieces.ctx.api.ClientServiceConfig; import org.webpieces.util.HostWithPort; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.Context; +import org.webpieces.util.context.PlatformHeaders; import org.webpieces.webserver.api.ServerConfig; import org.webpieces.webserver.test.http2.CompanyApiTest; import webpiecesxxxxxpackage.Server; +import webpiecesxxxxxpackage.base.AddCompanyHeaders; +import webpiecesxxxxxpackage.base.CompanyHeaders; import webpiecesxxxxxpackage.base.HeadersCtx; import webpiecesxxxxxpackage.deleteme.api.SaveApi; import webpiecesxxxxxpackage.mock.JavaCache; import webpiecesxxxxxpackage.mock.MockRemoteService; import webpiecesxxxxxpackage.deleteme.remoteapi.RemoteApi; -import java.net.InetSocketAddress; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -93,4 +97,11 @@ public void configure(Binder binder) { protected ClientServiceConfig getConfig() { return HeadersCtx.createConfig(Server.APP_NAME); } + + @Override + protected List fetchEnums() { + List classes = super.fetchEnums(); + classes.add(new AddCompanyHeaders()); + return classes; + } } diff --git a/webserver/http-auth0login/src/main/java/org/webpieces/auth0/impl/AddAuth0Headers.java b/webserver/http-auth0login/src/main/java/org/webpieces/auth0/impl/AddAuth0Headers.java new file mode 100644 index 000000000..c3928f70c --- /dev/null +++ b/webserver/http-auth0login/src/main/java/org/webpieces/auth0/impl/AddAuth0Headers.java @@ -0,0 +1,12 @@ +package org.webpieces.auth0.impl; + +import org.webpieces.util.context.AddPlatformHeaders; +import org.webpieces.util.context.PlatformHeaders; + +public class AddAuth0Headers implements AddPlatformHeaders { + @Override + public Class platformHeadersToAdd() { + return Auth0Header.class; + } + +} diff --git a/webserver/http-router/src/main/java/org/webpieces/router/impl/WebpiecesToAppBindingModule.java b/webserver/http-router/src/main/java/org/webpieces/router/impl/WebpiecesToAppBindingModule.java index 2c41f7d02..311b86912 100644 --- a/webserver/http-router/src/main/java/org/webpieces/router/impl/WebpiecesToAppBindingModule.java +++ b/webserver/http-router/src/main/java/org/webpieces/router/impl/WebpiecesToAppBindingModule.java @@ -3,6 +3,8 @@ import java.util.concurrent.ScheduledExecutorService; import org.webpieces.ctx.api.extension.HtmlTagCreator; +import org.webpieces.microsvc.api.AddMicroSvcHeaders; +import org.webpieces.microsvc.api.MicroSvcHeader; import org.webpieces.router.api.PlatformInjector; import org.webpieces.router.api.extensions.BodyContentBinder; import org.webpieces.router.api.extensions.EntityLookup; @@ -17,6 +19,7 @@ import com.google.inject.multibindings.Multibinder; import io.micrometer.core.instrument.MeterRegistry; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.PlatformHeaders; public class WebpiecesToAppBindingModule implements Module { @@ -52,7 +55,8 @@ public void configure(Binder binder) { Multibinder.newSetBinder(binder, BodyContentBinder.class); Multibinder.newSetBinder(binder, ObjectStringConverter.class); Multibinder.newSetBinder(binder, HtmlTagCreator.class); - Multibinder.newSetBinder(binder, PlatformHeaders.class); + Multibinder platformHeaders = Multibinder.newSetBinder(binder, AddPlatformHeaders.class); + platformHeaders.addBinding().to(AddMicroSvcHeaders.class); //special case so the notFound controller can inspect and list all routes in a web page //OR some client application can inject and introspect all web routes as well diff --git a/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/CompanyApiTest.java b/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/CompanyApiTest.java index e85f05e3f..eca2acffd 100644 --- a/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/CompanyApiTest.java +++ b/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/CompanyApiTest.java @@ -4,6 +4,7 @@ import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; +import com.google.inject.multibindings.Multibinder; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.slf4j.Logger; @@ -11,18 +12,24 @@ import org.slf4j.bridge.SLF4JBridgeHandler; import org.webpieces.ctx.api.ClientServiceConfig; import org.webpieces.http2client.api.Http2Client; +import org.webpieces.microsvc.api.AddMicroSvcHeaders; +import org.webpieces.microsvc.api.MicroSvcHeader; import org.webpieces.microsvc.client.api.HttpsConfig; import org.webpieces.microsvc.client.api.RESTClientCreator; import org.webpieces.plugin.json.ConverterConfig; import org.webpieces.util.HostWithPort; +import org.webpieces.util.context.AddPlatformHeaders; import org.webpieces.util.context.ClientAssertions; import org.webpieces.util.context.Context; import org.webpieces.util.SneakyThrow; +import org.webpieces.util.context.PlatformHeaders; import org.webpieces.webserver.test.Asserts; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -83,6 +90,11 @@ public void configure(Binder binder) { binder.bind(MeterRegistry.class).toInstance(new SimpleMeterRegistry()); + Multibinder headers = Multibinder.newSetBinder(binder, AddPlatformHeaders.class); + for(AddPlatformHeaders ph : fetchEnums()) { + headers.addBinding().toInstance(ph); + } + binder.bind(ClientAssertions.class).toInstance(new ClientAssertions() { @Override public void throwIfCannotGoRemote() { @@ -93,6 +105,12 @@ public void throwIfCannotGoRemote() { } } + protected List fetchEnums() { + List list = new ArrayList<>(); + list.add(new AddMicroSvcHeaders()); + return list; + } + public T createRestClient(Class apiOfService) { if(!initialized) throw new IllegalStateException("call initialize method first"); diff --git a/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/EmptyHeaderList.java b/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/EmptyHeaderList.java index a098501fc..cff9a3b67 100644 --- a/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/EmptyHeaderList.java +++ b/webserver/http-webserver-test/src/main/java/org/webpieces/webserver/test/http2/EmptyHeaderList.java @@ -9,6 +9,6 @@ public class EmptyHeaderList implements HeaderCtxList { @Override public List listHeaderCtxPairs() { - return new ArrayList<>(); + return null; } } diff --git a/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyHcl.java b/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyHcl.java new file mode 100644 index 000000000..7322d9163 --- /dev/null +++ b/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyHcl.java @@ -0,0 +1,13 @@ +package org.webpieces.webserver; + +import org.webpieces.microsvc.server.api.HeaderCtxList; +import org.webpieces.util.context.PlatformHeaders; + +import java.util.List; + +public class EmptyHcl implements HeaderCtxList { + @Override + public List listHeaderCtxPairs() { + return null; + } +} diff --git a/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyModule.java b/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyModule.java index 674ca734f..c4ce4aaad 100644 --- a/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyModule.java +++ b/webserver/http-webserver/src/test/java/org/webpieces/webserver/EmptyModule.java @@ -18,7 +18,7 @@ public void configure(Binder binder) { binder.bind(SimpleStorage.class).toInstance(new EmptyStorage()); binder.bind(ApplicationContext.class).toInstance(new ApplicationContextImpl()); - ClientServiceConfig config = new ClientServiceConfig(null, "deansTestSvc"); + ClientServiceConfig config = new ClientServiceConfig(new EmptyHcl(), "deansTestSvc"); binder.bind(ClientServiceConfig.class).toInstance(config); binder.bind(SSLEngineFactory.class).to(SSLEngineFactoryWebServerTesting.class);