Skip to content

Commit 325414a

Browse files
authored
Add messages endpoint to sidecar (#176)
* Add messages endpoint to sidecar * Address Sonar flagged security issue
1 parent e0b073a commit 325414a

File tree

10 files changed

+157
-86
lines changed

10 files changed

+157
-86
lines changed

wls-exporter-core/src/main/java/com/oracle/wls/exporter/AuthenticatedCall.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public abstract class AuthenticatedCall {
2424
private final UrlBuilder urlBuilder;
2525

2626

27-
public AuthenticatedCall(WebClientFactory webClientFactory, InvocationContext context) {
27+
protected AuthenticatedCall(WebClientFactory webClientFactory, InvocationContext context) {
2828
this.webClientFactory = webClientFactory;
2929
this.context = context;
3030
this.urlBuilder = context.createUrlBuilder();

wls-exporter-core/src/main/java/com/oracle/wls/exporter/ConfigurationCall.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter;
@@ -11,7 +11,7 @@
1111

1212
public abstract class ConfigurationCall extends AuthenticatedCall {
1313

14-
public ConfigurationCall(WebClientFactory webClientFactory, InvocationContext context) {
14+
protected ConfigurationCall(WebClientFactory webClientFactory, InvocationContext context) {
1515
super(webClientFactory, context);
1616
}
1717

@@ -40,7 +40,7 @@ private void authenticate(WebClient webClient) throws IOException {
4040

4141
abstract void reportUnableToUpdateConfiguration(InvocationContext context, ConfigurationException e) throws IOException;
4242

43-
static abstract class ConfigurationAction {
43+
abstract static class ConfigurationAction {
4444

4545
private ExporterConfig uploadedConfig;
4646

@@ -49,8 +49,8 @@ final void defineUploadedFile(InputStream inputStream) {
4949
uploadedConfig = ExporterConfig.loadConfig(inputStream);
5050
} catch (ConfigurationException e) {
5151
throw e;
52-
} catch (Throwable e) {
53-
throw new RuntimeException("Unable to understand specified configuration");
52+
} catch (Exception e) {
53+
throw new ConfigurationException("Unable to understand specified configuration");
5454
}
5555
}
5656

@@ -60,4 +60,6 @@ ExporterConfig getUploadedConfig() {
6060
return uploadedConfig;
6161
}
6262
}
63+
64+
6365
}

wls-exporter-core/src/main/java/com/oracle/wls/exporter/InvocationContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter;
@@ -71,7 +71,7 @@ public interface InvocationContext {
7171
void setResponseHeader(String name, String value);
7272

7373
/**
74-
* Updates the response with a status but does not close he response stream.
74+
* Updates the response with a status but does not close the response stream.
7575
* @param status an HTTP status code
7676
*/
7777
void setStatus(int status);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2022, Oracle and/or its affiliates.
2+
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
4+
package com.oracle.wls.exporter;
5+
6+
import java.io.IOException;
7+
import java.io.PrintStream;
8+
9+
public class MessagesCall extends AuthenticatedCall {
10+
11+
public MessagesCall(WebClientFactory webClientFactory, InvocationContext context) {
12+
super(webClientFactory, context);
13+
}
14+
15+
@Override
16+
protected void invoke(WebClient webClient, InvocationContext context) throws IOException {
17+
try (PrintStream out = context.getResponseStream()) {
18+
for (String message : WlsRestExchanges.getExchanges())
19+
out.println(message);
20+
}
21+
}
22+
}

wls-exporter-core/src/main/java/com/oracle/wls/exporter/WlsRestExchanges.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2022 Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter;
@@ -16,7 +16,10 @@ public class WlsRestExchanges {
1616
public static final int MAX_EXCHANGES = 5;
1717
private static final String TEMPLATE = "REQUEST to %s:%n%s%nREPLY:%n%s%n";
1818

19-
public static final Queue<String> exchanges = new ConcurrentLinkedDeque<>();
19+
private static final Queue<String> exchanges = new ConcurrentLinkedDeque<>();
20+
21+
private WlsRestExchanges() {
22+
}
2023

2124
/**
2225
* Returns a list of the most recent exchanges.

wls-exporter-core/src/main/java/com/oracle/wls/exporter/domain/ConfigurationException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2017, 2020, Oracle and/or its affiliates.
1+
// Copyright (c) 2017, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter.domain;
@@ -17,7 +17,7 @@ public class ConfigurationException extends RuntimeException {
1717
static final String NO_QUERY_SYNC_URL = "query_sync defined without url";
1818
private final List<String> context = new ArrayList<>();
1919

20-
ConfigurationException(String description) {
20+
public ConfigurationException(String description) {
2121
super(description);
2222
}
2323

wls-exporter-core/src/main/java/com/oracle/wls/exporter/webapp/MessagesServlet.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
// Copyright (c) 2019, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2019, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter.webapp;
55

66
import java.io.IOException;
7-
import javax.servlet.ServletOutputStream;
87
import javax.servlet.annotation.WebServlet;
98
import javax.servlet.http.HttpServlet;
109
import javax.servlet.http.HttpServletRequest;
1110
import javax.servlet.http.HttpServletResponse;
1211

13-
import com.oracle.wls.exporter.WlsRestExchanges;
12+
import com.oracle.wls.exporter.MessagesCall;
13+
import com.oracle.wls.exporter.ServletInvocationContext;
14+
import com.oracle.wls.exporter.WebClientFactory;
15+
import com.oracle.wls.exporter.WebClientFactoryImpl;
1416

1517
import static com.oracle.wls.exporter.WebAppConstants.MESSAGES_PAGE;
1618

@@ -20,11 +22,24 @@
2022
@WebServlet("/" + MESSAGES_PAGE)
2123
public class MessagesServlet extends HttpServlet {
2224

25+
private final WebClientFactory webClientFactory;
26+
27+
public MessagesServlet() {
28+
this(new WebClientFactoryImpl());
29+
}
30+
31+
public MessagesServlet(WebClientFactory webClientFactory) {
32+
this.webClientFactory = webClientFactory;
33+
}
34+
2335
@Override
2436
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
25-
try(ServletOutputStream out = resp.getOutputStream()) {
26-
for (String message : WlsRestExchanges.getExchanges())
27-
out.println(message);
37+
try {
38+
ServletUtils.setServer(req);
39+
MessagesCall call = new MessagesCall(webClientFactory, new ServletInvocationContext(req, resp));
40+
call.doWithAuthentication();
41+
} catch (IOException e) {
42+
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
2843
}
2944
}
3045

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2019, 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2019, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter.webapp;
@@ -9,6 +9,7 @@
99
import javax.servlet.annotation.WebServlet;
1010
import javax.servlet.http.HttpServlet;
1111

12+
import com.oracle.wls.exporter.WebClientFactoryStub;
1213
import com.oracle.wls.exporter.WlsRestExchanges;
1314
import org.hamcrest.Matcher;
1415
import org.junit.jupiter.api.BeforeEach;
@@ -27,83 +28,87 @@
2728
import static org.hamcrest.Matchers.is;
2829
import static org.hamcrest.Matchers.notNullValue;
2930

30-
public class MessagesServletTest {
31-
private static final int EXCESS_EXCHANGES = 3;
32-
private static final String URL = "http://localhost:7001";
33-
private final MessagesServlet servlet = new MessagesServlet();
34-
private final HttpServletRequestStub request = createGetRequest();
35-
private final HttpServletResponseStub response = createServletResponse();
31+
class MessagesServletTest {
3632

37-
@BeforeEach
38-
public void setUp() {
39-
WlsRestExchanges.clear();
40-
}
33+
private static final int EXCESS_EXCHANGES = 3;
34+
private static final String URL = "http://localhost:7001";
35+
private final WebClientFactoryStub factory = new WebClientFactoryStub();
36+
private final MessagesServlet servlet = new MessagesServlet(factory);
37+
private final HttpServletRequestStub request = createGetRequest();
38+
private final HttpServletResponseStub response = createServletResponse();
4139

42-
@Test
43-
public void diagnostics_isHttpServlet() {
44-
assertThat(servlet, instanceOf(HttpServlet.class));
45-
}
40+
@BeforeEach
41+
public void setUp() {
42+
WlsRestExchanges.clear();
43+
}
4644

47-
@Test
48-
public void servlet_isPublic() {
49-
assertThat(Modifier.isPublic(MessagesServlet.class.getModifiers()), is(true));
50-
}
45+
@Test
46+
void diagnostics_isHttpServlet() {
47+
assertThat(servlet, instanceOf(HttpServlet.class));
48+
}
5149

52-
@Test
53-
public void servlet_hasWebServletAnnotation() {
54-
assertThat(MessagesServlet.class.getAnnotation(WebServlet.class), notNullValue());
55-
}
50+
@Test
51+
void servlet_isPublic() {
52+
assertThat(Modifier.isPublic(MessagesServlet.class.getModifiers()), is(true));
53+
}
5654

57-
@Test
58-
public void servletAnnotationIndicatesMetricsPage() {
59-
WebServlet annotation = MessagesServlet.class.getAnnotation(WebServlet.class);
55+
@Test
56+
void servlet_hasWebServletAnnotation() {
57+
assertThat(MessagesServlet.class.getAnnotation(WebServlet.class), notNullValue());
58+
}
6059

61-
assertThat(annotation.value(), arrayContaining("/messages"));
62-
}
60+
@Test
61+
void servletAnnotationIndicatesMetricsPage() {
62+
WebServlet annotation = MessagesServlet.class.getAnnotation(WebServlet.class);
6363

64-
@Test
65-
public void afterExchangeAdded_retrieveExchange() {
66-
WlsRestExchanges.addExchange(URL, "request 1", "response1");
64+
assertThat(annotation.value(), arrayContaining("/messages"));
65+
}
6766

68-
assertThat(WlsRestExchanges.getExchanges(), hasItem(both(containsString("request 1")).and(containsString("response1"))));
69-
}
67+
@Test
68+
void afterExchangeAdded_retrieveExchange() {
69+
WlsRestExchanges.addExchange(URL, "request 1", "response1");
7070

71-
@Test
72-
public void afterMaximumExchangesAdded_retrieveAllExchanges() {
73-
IntStream.rangeClosed(1, MAX_EXCHANGES).forEach(this::addTestExchange);
71+
assertThat(WlsRestExchanges.getExchanges(),
72+
hasItem(both(containsString("request 1")).and(containsString("response1"))));
73+
}
7474

75-
assertThat(WlsRestExchanges.getExchanges(), contains(getExchangeMatchers(1, MAX_EXCHANGES)));
76-
}
75+
@Test
76+
void afterMaximumExchangesAdded_retrieveAllExchanges() {
77+
IntStream.rangeClosed(1, MAX_EXCHANGES).forEach(this::addTestExchange);
7778

78-
private void addTestExchange(int i) {
79-
WlsRestExchanges.addExchange(URL, "request " + i, "response " + i);
80-
}
79+
assertThat(WlsRestExchanges.getExchanges(), contains(getExchangeMatchers(1, MAX_EXCHANGES)));
80+
}
8181

82-
@SuppressWarnings("unchecked")
83-
private Matcher<String>[] getExchangeMatchers(int first, int last) {
84-
return IntStream.rangeClosed(first, last).mapToObj(this::getExchangeMatcher).toArray(Matcher[]::new);
85-
}
82+
private void addTestExchange(int i) {
83+
WlsRestExchanges.addExchange(URL, "request " + i, "response " + i);
84+
}
8685

87-
private Matcher<String> getExchangeMatcher(int i) {
88-
return containsString("request " + i);
89-
}
86+
@SuppressWarnings("unchecked")
87+
private Matcher<String>[] getExchangeMatchers(int first, int last) {
88+
return IntStream.rangeClosed(first, last).mapToObj(this::getExchangeMatcher).toArray(Matcher[]::new);
89+
}
9090

91-
@Test
92-
public void afterMoreThanMaximumExchangesAdded_retrieveLastMExchanges() {
93-
IntStream.rangeClosed(1, MAX_EXCHANGES+EXCESS_EXCHANGES).forEach(this::addTestExchange);
91+
private Matcher<String> getExchangeMatcher(int i) {
92+
return containsString("request " + i);
93+
}
9494

95-
assertThat(WlsRestExchanges.getExchanges(), contains(getExchangeMatchers(EXCESS_EXCHANGES+1, MAX_EXCHANGES+EXCESS_EXCHANGES)));
96-
}
95+
@Test
96+
void afterMoreThanMaximumExchangesAdded_retrieveLastMExchanges() {
97+
IntStream.rangeClosed(1, MAX_EXCHANGES + EXCESS_EXCHANGES).forEach(this::addTestExchange);
9798

98-
@Test
99-
public void whenServletInvoked_responseDisplaysRecentExchanges() throws IOException {
100-
IntStream.rangeClosed(1, MAX_EXCHANGES).forEach(this::addTestExchange);
99+
assertThat(WlsRestExchanges.getExchanges(),
100+
contains(getExchangeMatchers(EXCESS_EXCHANGES + 1, MAX_EXCHANGES + EXCESS_EXCHANGES)));
101+
}
101102

102-
servlet.doGet(request, response);
103+
@Test
104+
void whenServletInvoked_responseDisplaysRecentExchanges() throws IOException {
105+
IntStream.rangeClosed(1, MAX_EXCHANGES).forEach(this::addTestExchange);
103106

104-
assertThat(response.getHtml(), containsString("request 4"));
105-
}
107+
servlet.doGet(request, response);
106108

107-
// todo report last commit
108-
// todo diagnose classpath issues (all should be in the WAR)
109+
assertThat(response.getHtml(), containsString("request 4"));
110+
}
111+
112+
// todo report last commit
113+
// todo diagnose classpath issues (all should be in the WAR)
109114
}

wls-exporter-sidecar/src/main/java/com/oracle/wls/exporter/sidecar/MetricsService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2021, Oracle and/or its affiliates.
1+
// Copyright (c) 2021, 2022, Oracle and/or its affiliates.
22
// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
33

44
package com.oracle.wls.exporter.sidecar;
@@ -13,6 +13,7 @@
1313
import com.oracle.wls.exporter.ExporterCall;
1414
import com.oracle.wls.exporter.InvocationContext;
1515
import com.oracle.wls.exporter.LiveConfiguration;
16+
import com.oracle.wls.exporter.MessagesCall;
1617
import com.oracle.wls.exporter.WebClientFactory;
1718
import io.helidon.common.configurable.ThreadPoolSupplier;
1819
import io.helidon.webserver.Routing;
@@ -28,6 +29,7 @@ class MetricsService implements Service {
2829
private final AuthenticatedHandler metricsHandler = new AuthenticatedHandler(ExporterCall::new);
2930
private final AuthenticatedHandler configurationHandler = new AuthenticatedHandler(ConfigurationPutCall::new);
3031
private final MainHandler mainHandler = new MainHandler();
32+
private final AuthenticatedHandler messagesHandler = new AuthenticatedHandler(MessagesCall::new);
3133
private final int listenPort;
3234

3335
MetricsService(SidecarConfiguration configuration, WebClientFactory webClientFactory) {
@@ -48,6 +50,7 @@ public void update(Routing.Rules rules) {
4850
rules
4951
.get("/", mainHandler::dispatch)
5052
.get("/metrics", metricsHandler::dispatch)
53+
.get("/messages", messagesHandler::dispatch)
5154
.put("/configuration", configurationHandler::dispatch);
5255
}
5356

@@ -92,4 +95,5 @@ void invoke(InvocationContext context) throws IOException {
9295
context.close();
9396
}
9497
}
98+
9599
}

0 commit comments

Comments
 (0)