Skip to content

Commit 8ef5671

Browse files
authored
OWLS-102313 Add filtering by regular expression (#211)
1 parent f62f0c4 commit 8ef5671

19 files changed

+880
-226
lines changed

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ queries:
3636
type: WebAppComponentRuntime
3737
prefix: webapp_config_
3838
key: name
39+
includedKeyValues: "abc_.*"
40+
excludedKeyValues: "abc_12.*"
3941
values: [deploymentState, contextRoot, sourceInfo, openSessionsHighCount]
4042
stringValues:
4143
status: [deployed, undeployed]
@@ -60,14 +62,16 @@ Note that if unable to contact the REST API using the inferred host and port, th
6062
The `query` field is more complex. Each query consists of a hierarchy of the [MBeans](https://docs.oracle.com/middleware/12213/wls/WLMBR/core/index.html), starting relative to `ServerRuntimes`.
6163
Within each section, there are a number of options:
6264

63-
| Name | Description |
64-
|----------------|----------------------------------------------------------------------------------------------------------------------------------------|
65-
| `key` | The name of the attribute to use as a key for qualifiers in the output. |
66-
| `keyName` | The name to use for the key in the qualifier; defaults to the name of the attribute. |
67-
| `prefix` | A prefix to use for all the metrics gathered from the current level. |
68-
| `values` | The attributes for which metrics are to be output. If not specified and a prefix is defined, all values on the MBean will be selected. |
69-
| `type` | A filter for subtypes. If specified, only those objects whose `type` attribute matches will be collected. |
70-
| `stringValues` | A map of string-valued metric names to a list of case-insensitive possible values. They will be converted to indexes of that list. |
65+
| Name | Description |
66+
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------|
67+
| `key` | The name of the attribute to use as a key for qualifiers in the output. |
68+
| `includedKeyValues` | An optional filter. If specified, only entries whose key value matches the specified [regular expression](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html) will generate metrics. |
69+
| `excludedKeyValues` | An optional filter. If specified, entries whose key value matches the specified regular expression will NOT generate metrics. |
70+
| `keyName` | The name to use for the key in the qualifier; defaults to the name of the attribute. |
71+
| `prefix` | A prefix to use for all the metrics gathered from the current level. |
72+
| `values` | The attributes for which metrics are to be output. If not specified and a prefix is defined, all values on the MBean will be selected. |
73+
| `type` | A filter for subtypes. If specified, only those objects whose `type` attribute matches will be collected. |
74+
| `stringValues` | A map of string-valued metric names to a list of case-insensitive possible values. They will be converted to indexes of that list. |
7175

7276
Note that all fields other than the above, will be interpreted as collections of values.
7377

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
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;
55

6+
import com.google.gson.JsonObject;
7+
import com.google.gson.JsonParser;
8+
import com.oracle.wls.exporter.domain.MBeanSelector;
9+
610
import java.io.IOException;
711
import java.io.OutputStream;
12+
import java.util.Collections;
813
import java.util.Locale;
914
import java.util.Map;
1015
import java.util.TreeMap;
1116

12-
import com.oracle.wls.exporter.domain.MBeanSelector;
13-
1417
import static com.oracle.wls.exporter.domain.MapUtils.isNullOrEmptyString;
1518
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
1619

@@ -48,15 +51,15 @@ private void displayMetrics(WebClient webClient, MetricsStream metricsStream) th
4851
private void displayMetrics(WebClient webClient, MetricsStream metricsStream, MBeanSelector selector) throws IOException {
4952
try {
5053
Map<String, Object> metrics = getMetrics(webClient, selector);
51-
if (metrics != null)
54+
if (!metrics.isEmpty())
5255
sort(metrics).forEach(metricsStream::printMetric);
5356
} catch (RestQueryException e) {
5457
metricsStream.println(
5558
withCommentMarkers("REST service was unable to handle this query and returned a " + HTTP_BAD_REQUEST + "\n"
5659
+ selector.getPrintableRequest()));
5760
} catch (AuthenticationChallengeException e) { // don't add a message for this case
5861
throw e;
59-
} catch (IOException | RuntimeException | Error e) {
62+
} catch (IOException | RuntimeException e) {
6063
WlsRestExchanges.addExchange(getQueryUrl(selector), selector.getRequest(), e.toString());
6164
throw e;
6265
}
@@ -71,18 +74,31 @@ private static String withCommentMarkers(String string) {
7174

7275
private Map<String, Object> getMetrics(WebClient webClient, MBeanSelector selector) throws IOException {
7376
String jsonResponse = requestMetrics(webClient, selector);
74-
if (isNullOrEmptyString(jsonResponse)) return null;
77+
if (isNullOrEmptyString(jsonResponse)) return Collections.emptyMap();
7578

7679
return LiveConfiguration.scrapeMetrics(selector, jsonResponse);
7780
}
7881

7982
private String requestMetrics(WebClient webClient, MBeanSelector selector) throws IOException {
80-
String url = getQueryUrl(selector);
81-
String jsonResponse = webClient.withUrl(url).doPostRequest(selector.getRequest());
83+
if (selector.needsNewKeys()) refreshKeys(webClient, selector);
84+
85+
final String url = getQueryUrl(selector);
86+
final String jsonResponse = webClient.withUrl(url).doPostRequest(selector.getRequest());
8287
WlsRestExchanges.addExchange(url, selector.getRequest(), jsonResponse);
8388
return jsonResponse;
8489
}
8590

91+
private void refreshKeys(WebClient webClient, MBeanSelector selector) throws IOException {
92+
final String url = getQueryUrl(selector);
93+
final String keyResponse = webClient.withUrl(url).doPostRequest(selector.getKeyRequest());
94+
WlsRestExchanges.addExchange(url, selector.getKeyRequest(), keyResponse);
95+
selector.offerKeys(toJsonObject(keyResponse));
96+
}
97+
98+
private static JsonObject toJsonObject(String response) {
99+
return JsonParser.parseString(response).getAsJsonObject();
100+
}
101+
86102
private TreeMap<String, Object> sort(Map<String, Object> metrics) {
87103
return new TreeMap<>(metrics);
88104
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ public long getLatestConfigurationTimestamp() {
227227
}
228228

229229
@Override
230-
public void shareConfiguration(String configuration) {}
230+
public void shareConfiguration(String configuration) {
231+
// do nothing
232+
}
231233

232234
@Override
233235
public ConfigurationUpdate getUpdate() {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public WebClientException(String message) {
1717
super(formatMessage(message, args), cause);
1818
}
1919

20+
WebClientException(String message, Object... args) {
21+
super(formatMessage(message, args));
22+
}
23+
2024
private static String formatMessage(String message, Object... args) {
2125
return String.format(message, args);
2226
}

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
* @author Russell Gold
2525
*/
26-
public class ExporterConfig {
26+
public class ExporterConfig implements MetricsProcessor {
2727
public static final String DOMAIN_NAME_PROPERTY = "DOMAIN";
2828

2929
private static final String QUERY_SYNC = "query_sync";
@@ -88,16 +88,17 @@ public Map<String, Object> scrapeMetrics(MBeanSelector selector, JsonObject resp
8888
MetricsScraper scraper = new MetricsScraper(getGlobalQualifiers());
8989
scraper.setMetricNameSnakeCase(metricsNameSnakeCase);
9090
Map<String, Object> metrics = scraper.scrape(selector, response);
91-
selector.processMetrics(metrics, this::processMetrics);
91+
selector.postProcessMetrics(metrics, this);
9292
return metrics;
9393
}
9494

9595
private String getGlobalQualifiers() {
9696
return Optional.ofNullable(domainName).map(n->String.format(DOMAIN_NAME_QUALIFIER, n)).orElse("");
9797
}
9898

99-
private void processMetrics(Map<String, String> metrics) {
100-
domainName = metrics.get(QueryType.DOMAIN_KEY);
99+
@Override
100+
public void updateConfiguration(Map<String, Object> metrics) {
101+
Optional.ofNullable((String) metrics.remove("name")).ifPresent(n-> domainName = n);
101102
}
102103

103104
/**
@@ -317,14 +318,14 @@ private void appendQueryToString(StringBuilder sb, MBeanSelector query) {
317318
List<String> selectorKeys = new ArrayList<>(query.getNestedSelectors().keySet());
318319
for (String selectorKey : selectorKeys) {
319320
sb.append(indent).append(selectorKey).append(":\n");
320-
query.getNestedSelectors().get(selectorKey).appendNestedQuery(sb, " ");
321+
query.getNestedSelectors().get(selectorKey).appendAsNestedQuery(sb, " ");
321322
indent = " ";
322323
}
323324
}
324325

325326
private String formatQuery(MBeanSelector query) {
326327
StringBuilder sb = new StringBuilder();
327-
query.appendNestedQuery(sb, " ");
328+
query.appendAsNestedQuery(sb, " ");
328329
sb.replace(0, 1, "-");
329330
return sb.toString();
330331
}

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

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
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;
5+
56
import java.util.ArrayList;
67
import java.util.Arrays;
78
import java.util.HashMap;
9+
import java.util.List;
810
import java.util.Map;
11+
import java.util.Set;
12+
13+
import com.google.gson.Gson;
14+
import com.google.gson.JsonArray;
15+
import com.google.gson.JsonObject;
916

1017
/**
1118
* A class which Gson can convert to a JSON string for a WLS REST query. The REST API specifies that each
@@ -16,15 +23,16 @@
1623
*/
1724
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
1825
class JsonQuerySpec {
19-
private final String[] links = new String[0];
20-
private ArrayList<String> fields = null;
21-
private Map<String,JsonQuerySpec> children = null;
26+
private List<String> fields = null;
27+
private Map<String, JsonQuerySpec> children = null;
28+
private String keyName = null;
29+
private List<String> selectedKeys = null;
2230

2331
/**
2432
* Specifies the name of any mbean values which should be retrieved.
2533
* @param newFields the field names to add to any previous defined
2634
*/
27-
void addFields(String ... newFields) {
35+
void addFields(String... newFields) {
2836
if (fields == null) fields = new ArrayList<>();
2937
fields.addAll(Arrays.asList(newFields));
3038
}
@@ -39,4 +47,38 @@ void addChild(String name, JsonQuerySpec child) {
3947
children = new HashMap<>();
4048
children.put(name, child);
4149
}
50+
51+
void setFilter(String keyName, Set<String> selectedKeys) {
52+
this.keyName = keyName;
53+
this.selectedKeys = new ArrayList<>(selectedKeys);
54+
}
55+
56+
String toJson(Gson gson) {
57+
return gson.toJson(toJsonObject());
58+
}
59+
60+
JsonObject toJsonObject() {
61+
final JsonObject result = new JsonObject();
62+
63+
result.add("links", new JsonArray());
64+
if (fields != null) result.add("fields", asStringArray(fields));
65+
if (keyName != null) result.add(keyName, asStringArray(selectedKeys));
66+
if (children != null) asChildObject(result);
67+
68+
return result;
69+
}
70+
71+
JsonArray asStringArray(List<String> values) {
72+
final JsonArray result = new JsonArray();
73+
values.forEach(result::add);
74+
return result;
75+
}
76+
77+
private void asChildObject(JsonObject result) {
78+
final JsonObject nesting = new JsonObject();
79+
result.add("children", nesting);
80+
for (Map.Entry<String, JsonQuerySpec> entry : children.entrySet()) {
81+
nesting.add(entry.getKey(), entry.getValue().toJsonObject());
82+
}
83+
}
4284
}

0 commit comments

Comments
 (0)