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

feat(eventssearch): implement search as query param #623

Merged
merged 2 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 7 additions & 5 deletions HTTP_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ The handler-specific descriptions below describe how each handler populates the
| What you want to do | Which handler you should use |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------|
| **Recordings in Target JVMs** | |
| Search event types that can be produced by a target JVM | [`TargetEventsSearchGetHandler`](#TargetEventsSearchGetHandler) |
| List or search event types that can be produced by a target JVM | [`TargetEventsGetHandler`](#TargetEventsGetHandler) |
| Get a list of recording options for a target JVM | [`TargetRecordingOptionsListGetHandler`](#TargetRecordingOptionsListGetHandler) |
| Create a snapshot recording in a target JVM | [`TargetSnapshotPostHandler`](#TargetSnapshotPostHandler-1) |
| **Automated Rules** | |
Expand All @@ -1254,20 +1254,22 @@ The handler-specific descriptions below describe how each handler populates the

### Recordings in Target JVMs

* #### `TargetEventsSearchGetHandler`
* #### `TargetEventsGetHandler`

###### synopsis
Returns a list of event types that can be produced by a target JVM,
where the event name, category, label, etc. matches the given query.

###### request
`GET /api/v2/targets/:targetId/eventsSearch/:query`
`GET /api/v2/targets/:targetId/events[?q=searchQuery]`

`targetId` - The location of the target JVM to connect to,
in the form of a `service:rmi:jmx://` JMX Service URL, or `hostname:port`.
Should use percent-encoding.

`query` - The search query.
`q` - The search query. Event names, IDs, categories, and descriptions will
be searched for case-insensitive substring matches of the supplied query. If
this parameter is omitted or blank then all events will be returned.

###### response
`200` - The result is a JSON array of event objects.
Expand All @@ -1293,7 +1295,7 @@ The handler-specific descriptions below describe how each handler populates the

###### example
```
$ curl localhost:8181/api/v2/targets/localhost/eventsSearch/javaerrorthrow
$ curl localhost:8181/api/v2/targets/localhost/events?q=javaerrorthrow
{"meta":{"type":"application/json","status":"OK"},"data":{"result":[{"name":"Java Error","typeId":"jdk.JavaErrorThrow","description":"An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored","category":["Java Application"],"options":{"enabled":{"name":"Enabled","description":"Record event","defaultValue":"false"},"threshold":{"name":"Threshold","description":"Record event with duration above or equal to threshold","defaultValue":"0ns[ns]"},"stackTrace":{"name":"Stack Trace","description":"Record stack traces","defaultValue":"false"}}}]}}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ abstract RequestHandler bindTargetRecordingOptionsListGetHandler(

@Binds
@IntoSet
abstract RequestHandler bindTargetEventsSearchGetHandler(TargetEventsSearchGetHandler handler);
abstract RequestHandler bindTargetEventsGetHandler(TargetEventsGetHandler handler);

@Provides
@Singleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@

import com.google.gson.Gson;
import io.vertx.core.http.HttpMethod;
import org.apache.commons.lang3.StringUtils;

class TargetEventsSearchGetHandler
extends AbstractV2RequestHandler<List<SerializableEventTypeInfo>> {
class TargetEventsGetHandler extends AbstractV2RequestHandler<List<SerializableEventTypeInfo>> {

private final TargetConnectionManager targetConnectionManager;

@Inject
TargetEventsSearchGetHandler(
TargetEventsGetHandler(
AuthManager auth, TargetConnectionManager targetConnectionManager, Gson gson) {
super(auth, gson);
this.targetConnectionManager = targetConnectionManager;
Expand All @@ -85,7 +85,7 @@ public HttpMethod httpMethod() {

@Override
public String path() {
return basePath() + "targets/:targetId/eventsSearch/:query";
return basePath() + "targets/:targetId/events";
}

@Override
Expand All @@ -104,13 +104,14 @@ public IntermediateResponse<List<SerializableEventTypeInfo>> handle(RequestParam
return targetConnectionManager.executeConnectedTask(
getConnectionDescriptorFromParams(params),
connection -> {
String query = params.getPathParams().get("query");
String q = params.getQueryParams().get("q");
List<SerializableEventTypeInfo> matchingEvents =
connection.getService().getAvailableEventTypes().stream()
.filter(
event ->
eventMatchesSearchTerm(
event, query.toLowerCase()))
StringUtils.isBlank(q)
|| eventMatchesSearchTerm(
event, q.toLowerCase()))
.map(SerializableEventTypeInfo::new)
.collect(Collectors.toList());
return new IntermediateResponse<List<SerializableEventTypeInfo>>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class TargetEventsSearchGetHandlerTest {
class TargetEventsGetHandlerTest {

TargetEventsSearchGetHandler handler;
TargetEventsGetHandler handler;
@Mock AuthManager auth;
@Mock TargetConnectionManager targetConnectionManager;
@Mock Logger logger;
Expand All @@ -83,7 +83,7 @@ class TargetEventsSearchGetHandlerTest {

@BeforeEach
void setup() {
this.handler = new TargetEventsSearchGetHandler(auth, targetConnectionManager, gson);
this.handler = new TargetEventsGetHandler(auth, targetConnectionManager, gson);
}

@Test
Expand All @@ -94,7 +94,7 @@ void shouldHandleGETRequest() {
@Test
void shouldHandleCorrectPath() {
MatcherAssert.assertThat(
handler.path(), Matchers.equalTo("/api/v2/targets/:targetId/eventsSearch/:query"));
handler.path(), Matchers.equalTo("/api/v2/targets/:targetId/events"));
}

@Test
Expand All @@ -111,8 +111,8 @@ void shouldHandleNoMatches() throws Exception {

RequestParameters params =
new RequestParameters(
Map.of("targetId", "foo:9091", "query", "foo"),
MultiMap.caseInsensitiveMultiMap(),
Map.of("targetId", "foo:9091"),
MultiMap.caseInsensitiveMultiMap().set("q", "foo"),
MultiMap.caseInsensitiveMultiMap(),
MultiMap.caseInsensitiveMultiMap(),
Set.of(),
Expand Down Expand Up @@ -179,8 +179,8 @@ void shouldHandleMatches() throws Exception {

RequestParameters params =
new RequestParameters(
Map.of("targetId", "foo:9091", "query", "foo"),
MultiMap.caseInsensitiveMultiMap(),
Map.of("targetId", "foo:9091"),
MultiMap.caseInsensitiveMultiMap().set("q", "foo"),
MultiMap.caseInsensitiveMultiMap(),
MultiMap.caseInsensitiveMultiMap(),
Set.of(),
Expand Down
33 changes: 28 additions & 5 deletions src/test/java/itest/TargetEventsGetIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class TargetEventsGetIT extends StandardSelfTest {
static final String EVENT_REQ_URL =
String.format("/api/v1/targets/%s/events", SELF_REFERENCE_TARGET_ID);
static final String SEARCH_REQ_URL =
String.format("/api/v2/targets/%s/eventsSearch", SELF_REFERENCE_TARGET_ID);
String.format("/api/v2/targets/%s/events", SELF_REFERENCE_TARGET_ID);

@Test
public void testGetTargetEventsReturnsListOfEvents() throws Exception {
Expand All @@ -80,10 +80,33 @@ public void testGetTargetEventsReturnsListOfEvents() throws Exception {
}

@Test
public void testGetTargetEventsSearchReturnsRequestedEvents() throws Exception {
public void testGetTargetEventsV2WithNoQueryReturnsListOfEvents() throws Exception {
CompletableFuture<JsonObject> getResponse = new CompletableFuture<>();
webClient
.get(String.format("%s/WebServerRequest", SEARCH_REQ_URL))
.get(SEARCH_REQ_URL)
.send(
ar -> {
if (assertRequestStatus(ar, getResponse)) {
MatcherAssert.assertThat(
ar.result().statusCode(), Matchers.equalTo(200));
MatcherAssert.assertThat(
ar.result().getHeader(HttpHeaders.CONTENT_TYPE.toString()),
Matchers.equalTo(HttpMimeType.JSON.mime()));
getResponse.complete(ar.result().bodyAsJsonObject());
}
});

MatcherAssert.assertThat(getResponse.get().size(), Matchers.greaterThan(0));
MatcherAssert.assertThat(
getResponse.get().getJsonObject("data").getJsonArray("result").size(),
Matchers.greaterThan(0));
}

@Test
public void testGetTargetEventsV2WithQueryReturnsRequestedEvents() throws Exception {
CompletableFuture<JsonObject> getResponse = new CompletableFuture<>();
webClient
.get(String.format("%s?q=WebServerRequest", SEARCH_REQ_URL))
andrewazores marked this conversation as resolved.
Show resolved Hide resolved
.send(
ar -> {
if (assertRequestStatus(ar, getResponse)) {
Expand Down Expand Up @@ -140,10 +163,10 @@ public void testGetTargetEventsSearchReturnsRequestedEvents() throws Exception {
}

@Test
public void testGetTargetEventsSearchReturnsEmptyListWhenNoEventsMatch() throws Exception {
public void testGetTargetEventsV2WithQueryReturnsEmptyListWhenNoEventsMatch() throws Exception {
CompletableFuture<JsonObject> getResponse = new CompletableFuture<>();
webClient
.get(String.format("%s/thisEventDoesNotExist", SEARCH_REQ_URL))
.get(String.format("%s?q=thisEventDoesNotExist", SEARCH_REQ_URL))
.send(
ar -> {
if (assertRequestStatus(ar, getResponse)) {
Expand Down