Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance bootup logging to include detailed rule information #1333

Merged
merged 35 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3d6ea17
Enhance bootup logging to include detailed rule information
t-burch Nov 5, 2024
f248c7c
Merge branch 'master' into #1297-bootup-api-info
t-burch Nov 5, 2024
8af3713
Merge branch 'master' into #1297-bootup-api-info
t-burch Nov 8, 2024
40c2293
improved logging
christiangoerdes Nov 20, 2024
28dd93d
Merge branch 'master' into #1297-bootup-api-info
predic8 Nov 22, 2024
62317e2
Names
predic8 Nov 22, 2024
92727fe
Started refactoring
predic8 Nov 22, 2024
308004b
Restructuring
predic8 Nov 25, 2024
3113060
.
t-burch Nov 25, 2024
18a860b
Add OpenAPI location formatting to RuleDisplayInfo
t-burch Nov 25, 2024
a064075
Merge branch 'master' into #1297-bootup-api-info
predic8 Nov 25, 2024
3b6e6cb
Add OpenAPI 3.1 references test class and update router setup
t-burch Nov 25, 2024
5e39309
Merge remote-tracking branch 'origin/master'
t-burch Dec 2, 2024
f9aba92
Merge remote-tracking branch 'origin/master'
t-burch Dec 6, 2024
5999769
Merge remote-tracking branch 'origin/master'
t-burch Dec 11, 2024
6c4ed31
Merge remote-tracking branch 'origin/master'
t-burch Dec 12, 2024
31ca34c
Merge remote-tracking branch 'origin/master'
t-burch Dec 16, 2024
3b4510b
Added more in-depth documentation and examples for ApiKeysInterceptor.
t-burch Dec 16, 2024
3e3662b
Merge remote-tracking branch 'origin/master'
t-burch Dec 16, 2024
932b106
Merge remote-tracking branch 'origin/master'
t-burch Dec 17, 2024
38b4a15
Merge remote-tracking branch 'origin/master'
t-burch Dec 18, 2024
8a7300f
Merge remote-tracking branch 'origin/master'
t-burch Dec 19, 2024
8efb821
Merge remote-tracking branch 'origin/master'
t-burch Dec 19, 2024
216f7aa
Merge remote-tracking branch 'origin/master'
t-burch Dec 19, 2024
14847c7
Merge remote-tracking branch 'origin/master'
t-burch Dec 19, 2024
9471b07
Merge remote-tracking branch 'origin/master'
t-burch Dec 20, 2024
a200cc1
Merge remote-tracking branch 'origin/master'
t-burch Dec 20, 2024
b37c282
Merge branch 'master' into #1297-bootup-api-info
t-burch Jan 6, 2025
cd5db79
Merge remote-tracking branch 'origin/master'
t-burch Jan 6, 2025
2ccd98d
Merge branch 'master' into #1297-bootup-api-info
t-burch Jan 6, 2025
d9c2fb2
After-Merge Fixes (Master 6.0.0)
t-burch Jan 6, 2025
d70556b
Renaming
t-burch Jan 6, 2025
6b98ea6
Refactor ProxyDisplayInfo class to simplify logging output and improv…
t-burch Jan 7, 2025
c832389
Implement OpenAPISpec and Rewrite cloning functionality
t-burch Jan 7, 2025
4f21f0d
Refactor test setup to use 'internal' method for API configuration in…
t-burch Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions core/src/main/java/com/predic8/membrane/core/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,13 @@ public void start() {

startJmx();

synchronized (lock) {
running = true;
}
synchronized (lock) {
running = true;
}

ProxyDisplayInfo.logInfosAboutStartedProxies(ruleManager);
log.info("{} {} up and running!", PRODUCT_NAME, VERSION);
}
}

private void startJmx() {
if (getBeanFactory() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ private void addOpenApisFromDirectory(Map<String, OpenAPIRecord> apiRecords, Ope
}
for (File file : files) {
log.info("Parsing spec {}", file);
OpenAPIRecord rec = create(spec, file);
OpenAPISpec fileSpec = spec.clone();
fileSpec.setLocation(spec.dir + "/" + file.getName());
OpenAPIRecord rec = create(fileSpec, file);
apiRecords.put(getUniqueId(apiRecords, rec), rec);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @description Reads an OpenAPI description and deploys an API with the information of it.
*/
@MCElement(name = "openapi", topLevel = false)
public class OpenAPISpec {
public class OpenAPISpec implements Cloneable {

public String location;
public String dir;
Expand All @@ -34,6 +34,17 @@ public class OpenAPISpec {
public YesNoOpenAPIOption validateSecurity = ASINOPENAPI;
private Rewrite rewrite = new Rewrite();

@Override
public OpenAPISpec clone() {
try {
OpenAPISpec clone = (OpenAPISpec) super.clone();
clone.rewrite = this.rewrite.clone();
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError("Should never happen", e);
}
}

public OpenAPISpec() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* @description
*/
@MCElement(name = "rewrite", topLevel = false)
public class Rewrite {
public class Rewrite implements Cloneable {

private static final Logger log = LoggerFactory.getLogger(Rewrite.class.getName());

Expand All @@ -45,6 +45,15 @@ public class Rewrite {

String basePath;

@Override
public Rewrite clone() {
try {
return (Rewrite) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError("Should never happen", e);
}
}

public JsonNode rewrite(OpenAPIRecord rec, Exchange exc, URIFactory uriFactory) throws URISyntaxException {
return rewriteOpenAPI3(exc, uriFactory, rec.node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.predic8.membrane.annot.*;
import com.predic8.membrane.core.util.*;
import org.apache.commons.lang3.StringUtils;

/**
* @description <p>Internal proxy that can only be invoked by other proxies within the gateway. An internal
Expand All @@ -26,7 +27,12 @@
public class InternalProxy extends AbstractServiceProxy implements NotPortOpeningProxy {

public InternalProxy() {
key = new ServiceProxyKey(0){};
key = new AbstractRuleKey(0,null) {
@Override
public String toString() {
return StringUtils.defaultIfEmpty(getPath(), "") + ":" + port;
}
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.predic8.membrane.core.proxies;

import com.predic8.membrane.core.*;
import com.predic8.membrane.core.openapi.serviceproxy.*;
import org.jetbrains.annotations.*;
import org.slf4j.*;

import java.util.*;

import static java.util.stream.Collectors.joining;

public class ProxyDisplayInfo {

private static final Logger log = LoggerFactory.getLogger(ProxyDisplayInfo.class.getName());
private static final int INDENT = 55;

public static void logInfosAboutStartedProxies(RuleManager manager) {
log.info("Started {} API{}:", manager.getRules().size(), (manager.getRules().size() > 1 ? "s" : ""));
manager.getRules().forEach(proxy ->
log.info(" {} {}{}{}", proxyDisplayName(proxy), proxyCustomName(proxy), getProxyKeyDisplayName(proxy), additionalProxyInfo(proxy))
);
}

private static String additionalProxyInfo(Proxy proxy) {
if (proxy instanceof APIProxy a) {
Map<String,OpenAPIRecord> recs = a.getApiRecords();
if (!recs.isEmpty()) {
return " using OpenAPI specifications:\n" + formatLocationInfo(recs);
}
} else if (proxy instanceof SOAPProxy s) {
return " using WSDL @ " + s.getWsdl();
}
return "";
}

private static String getProxyKeyDisplayName(Proxy proxy) {
return String.format("%s:%d%s",
getHost(proxy),
proxy.getKey().getPort(),
getPath(proxy));
}

private static @NotNull String getPath(Proxy proxy) {
String path = proxy.getKey().getPath();
return path != null ? path : "";
}

private static @Nullable String getHost(Proxy proxy) {
String host = proxy.getKey().getHost();
return Objects.equals(host, "*") ? getIP(proxy) : host;
}

private static @NotNull String getIP(Proxy proxy) {
String ip = proxy.getKey().getIp();
if (ip == null) {
return "0.0.0.0";
}
return ip;
}

private static String formatLocationInfo(Map<String, OpenAPIRecord> specs) {
return specs.entrySet().stream()
.map(e -> " ".repeat(INDENT) + "- \"%s\" @ %s".formatted(
e.getKey(),
e.getValue().getSpec().getLocation()
))
.collect(joining("\n"));
}

private static String proxyCustomName(Proxy proxy) {
if (Objects.equals(proxy.getName(), proxy.getKey().toString())) {
return "";
}
return "\"%s\" ".formatted(proxy.getName());
}

private static String proxyDisplayName(Proxy proxy) {
if (proxy instanceof APIProxy) {
return "API";
} else if (proxy instanceof ServiceProxy) {
return "ServiceProxy";
} else if (proxy instanceof SOAPProxy) {
return "SOAPProxy";
} else if (proxy instanceof InternalProxy) {
return "InternalProxy";
}
return "Proxy";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service:a");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(B, RESPONSE(C,ABORT,D), E,RETURN);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service:a");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(B, ABORT(C), D, ABORT);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.predic8.membrane.core.exchange.*;
import com.predic8.membrane.core.interceptor.*;
import com.predic8.membrane.core.openapi.serviceproxy.*;
import com.predic8.membrane.core.proxies.InternalProxy;
import org.junit.jupiter.api.*;

import java.util.*;
Expand Down Expand Up @@ -58,16 +59,28 @@ public void api(Consumer<TestAPIProxy> c) throws Exception {
router.getRuleManager().addProxyAndOpenPortIfNew(api);
}

protected String call() {
return given().post("http://localhost:2000/original-path").getBody().asString();
protected static class TestAPIProxy extends APIProxy {
public void add(Interceptor... i) {
getInterceptors().addAll(Arrays.asList(i));
}
}

protected static class TestAPIProxy extends APIProxy {
public void internal(Consumer<TestInternalProxy> c) throws Exception {
TestInternalProxy api = new TestInternalProxy();
c.accept(api);
router.getRuleManager().addProxyAndOpenPortIfNew(api);
}

protected static class TestInternalProxy extends InternalProxy {
public void add(Interceptor... i) {
getInterceptors().addAll(Arrays.asList(i));
}
}

protected String call() {
return given().post("http://localhost:2000/original-path").getBody().asString();
}

protected static class CaptureRoutingTestInterceptor extends AbstractInterceptor {

public String uri;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service://a");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(captureRoutingTestInterceptor);
api.add(B,RETURN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service://a/overwritten-path");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(captureRoutingTestInterceptor);
api.add(B,RETURN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service:a");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(B,REQUEST(C),RESPONSE(D),E,RETURN);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
a.getTarget().setUrl("service://b");
});

api(b -> {
internal(b -> {
b.setName("b");
b.add(B);
b.getTarget().setHost("localhost"); // Test also!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ protected void configure() throws Exception {
a.getTarget().setUrl("service://b");
});

api(b -> {
internal(b -> {
b.setName("b");
b.add(B);
b.getTarget().setUrl("service://c");
});

api(c -> {
internal(c -> {
c.setName("c");
c.add(C);
c.getTarget().setUrl("service://d");
});

api(d -> {
internal(d -> {
d.setName("d");
d.add(D,RETURN);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected void configure() throws Exception {
api.getTarget().setUrl("service:a");
});

api(api -> {
internal(api -> {
api.setName("a");
api.add(B,RETURN);
});
Expand Down
27 changes: 21 additions & 6 deletions distribution/conf/proxies.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,36 @@

<router>

<api port="2000">
<api port="2000" name="hello">
<path>/shop/v2</path>
<target host="api.predic8.de">
<ssl/>
</target>
</api>

<soapProxy wsdl="../../core/src/test/resources/ws/cities.wsdl">
<validator/>
</soapProxy>
<api port="2000" name="hello2">
<openapi location="https://api.predic8.de/shop/v2/api-docs" />
</api>

<api port="2001">
<sampleSoapService/>
<api port="2000" name="hello3">
<openapi dir="." />
</api>

<serviceProxy port="3000">
<target host="api.predic8.de">
<ssl/>
</target>
</serviceProxy>

<soapProxy port="4000" wsdl="https://www.predic8.de/city-service?wsdl">
</soapProxy>

<internalProxy name="wow">
<target host="api.predic8.de">
<ssl/>
</target>
</internalProxy>

</router>

</spring:beans>
Loading