Skip to content

Commit eb89e19

Browse files
pujaganidiemol
andauthored
[grid] Add new session request queue size endpoint and GraphQL support (#9030)
* [grid] Add new session request queue size endpoint and GraphQL support * [grid] Remove unused imports from GraphQL classes. Fix assert for NewSessionQueuer tests. Co-authored-by: Diego Molina <[email protected]>
1 parent 34b27b5 commit eb89e19

17 files changed

+182
-21
lines changed

java/server/src/org/openqa/selenium/grid/commands/Hub.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,11 @@ protected Handlers createHandlers(Config config) {
165165
handler.addHandler(distributor);
166166

167167
Router router = new Router(tracer, clientFactory, sessions, queuer, distributor);
168-
GraphqlHandler graphqlHandler = new GraphqlHandler(tracer, distributor, serverOptions.getExternalUri());
168+
GraphqlHandler graphqlHandler = new GraphqlHandler(
169+
tracer,
170+
distributor,
171+
queuer,
172+
serverOptions.getExternalUri());
169173
HttpHandler readinessCheck = req -> {
170174
boolean ready = router.isReady() && bus.isReady();
171175
return new HttpResponse()

java/server/src/org/openqa/selenium/grid/commands/Standalone.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ protected Handlers createHandlers(Config config) {
175175
.setContent(Contents.utf8String("Standalone is " + ready));
176176
};
177177

178-
GraphqlHandler graphqlHandler = new GraphqlHandler(tracer, distributor, serverOptions.getExternalUri());
178+
GraphqlHandler graphqlHandler = new GraphqlHandler(
179+
tracer,
180+
distributor,
181+
queuer,
182+
serverOptions.getExternalUri());
179183

180184
Routable ui;
181185
URL uiRoot = getClass().getResource("/javascript/grid-ui/build");

java/server/src/org/openqa/selenium/grid/graphql/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ java_library(
1818
"//java/client/src/org/openqa/selenium/remote",
1919
"//java/server/src/org/openqa/selenium/grid/data",
2020
"//java/server/src/org/openqa/selenium/grid/distributor",
21+
"//java/server/src/org/openqa/selenium/grid/sessionqueue",
2122
artifact("com.google.guava:guava"),
2223
artifact("com.graphql-java:graphql-java"),
2324
],

java/server/src/org/openqa/selenium/grid/graphql/GraphqlHandler.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import graphql.schema.idl.SchemaParser;
3030
import graphql.schema.idl.TypeDefinitionRegistry;
3131
import org.openqa.selenium.grid.distributor.Distributor;
32+
import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;
3233
import org.openqa.selenium.internal.Require;
3334
import org.openqa.selenium.json.Json;
3435
import org.openqa.selenium.remote.http.Contents;
@@ -68,12 +69,15 @@ public class GraphqlHandler implements HttpHandler {
6869
public static final Json JSON = new Json();
6970
private final Tracer tracer;
7071
private final Distributor distributor;
72+
private final NewSessionQueuer newSessionQueuer;
7173
private final URI publicUri;
7274
private final GraphQL graphQl;
7375

7476

75-
public GraphqlHandler(Tracer tracer, Distributor distributor, URI publicUri) {
77+
public GraphqlHandler(Tracer tracer, Distributor distributor, NewSessionQueuer newSessionQueuer,
78+
URI publicUri) {
7679
this.distributor = Require.nonNull("Distributor", distributor);
80+
this.newSessionQueuer = Require.nonNull("NewSessionQueuer", newSessionQueuer);
7781
this.publicUri = Require.nonNull("Uri", publicUri);
7882
this.tracer = Require.nonNull("Tracer", tracer);
7983

@@ -169,7 +173,7 @@ private RuntimeWiring buildRuntimeWiring() {
169173
.scalar(Types.Uri)
170174
.scalar(Types.Url)
171175
.type("GridQuery", typeWiring -> typeWiring
172-
.dataFetcher("grid", new GridData(distributor, publicUri))
176+
.dataFetcher("grid", new GridData(distributor, newSessionQueuer, publicUri))
173177
.dataFetcher("session", new SessionData(distributor)))
174178
.build();
175179
}

java/server/src/org/openqa/selenium/grid/graphql/Grid.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.openqa.selenium.grid.data.NodeStatus;
2525
import org.openqa.selenium.grid.data.Slot;
2626
import org.openqa.selenium.grid.distributor.Distributor;
27+
import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;
2728
import org.openqa.selenium.internal.Require;
2829

2930
import java.net.URI;
@@ -37,10 +38,12 @@ public class Grid {
3738

3839
private final URI uri;
3940
private final Supplier<DistributorStatus> distributorStatus;
41+
private final NewSessionQueuer newSessionQueuer;
4042

41-
public Grid(Distributor distributor, URI uri) {
43+
public Grid(Distributor distributor, NewSessionQueuer newSessionQueuer, URI uri) {
4244
Require.nonNull("Distributor", distributor);
4345
this.uri = Require.nonNull("Grid's public URI", uri);
46+
this.newSessionQueuer = Require.nonNull("NewSessionQueuer", newSessionQueuer);
4447
this.distributorStatus = Suppliers.memoize(distributor::getStatus);
4548
}
4649

@@ -96,4 +99,8 @@ public int getTotalSlots() {
9699
public int getUsedSlots() {
97100
return getSessionCount();
98101
}
102+
103+
public int getSessionQueueSize() {
104+
return newSessionQueuer.getQueueSize();
105+
}
99106
}

java/server/src/org/openqa/selenium/grid/graphql/GridData.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,24 @@
2020
import graphql.schema.DataFetcher;
2121
import graphql.schema.DataFetchingEnvironment;
2222
import org.openqa.selenium.grid.distributor.Distributor;
23+
import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;
2324
import org.openqa.selenium.internal.Require;
2425

2526
import java.net.URI;
2627

2728
public class GridData implements DataFetcher {
2829
private final Distributor distributor;
30+
private final NewSessionQueuer newSessionQueuer;
2931
private final URI publicUri;
3032

31-
public GridData(Distributor distributor, URI publicUri) {
33+
public GridData(Distributor distributor, NewSessionQueuer newSessionQueuer, URI publicUri) {
3234
this.distributor = Require.nonNull("Distributor", distributor);
3335
this.publicUri = Require.nonNull("Grid's public URI", publicUri);
36+
this.newSessionQueuer = Require.nonNull("NewSessionQueuer", newSessionQueuer);
3437
}
3538

3639
@Override
3740
public Object get(DataFetchingEnvironment environment) {
38-
return new Grid(distributor, publicUri);
41+
return new Grid(distributor, newSessionQueuer, publicUri);
3942
}
4043
}

java/server/src/org/openqa/selenium/grid/graphql/selenium-grid-schema.graphqls

+1
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ type Grid {
4747
totalSlots: Int
4848
usedSlots: Int
4949
sessionCount: Int!
50+
sessionQueueSize: Int!
5051
}

java/server/src/org/openqa/selenium/grid/router/httpd/RouterServer.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ protected Handlers createHandlers(Config config) {
133133
distributorUrl,
134134
secret);
135135

136-
GraphqlHandler graphqlHandler = new GraphqlHandler(tracer, distributor, serverOptions.getExternalUri());
136+
GraphqlHandler graphqlHandler = new GraphqlHandler(
137+
tracer,
138+
distributor,
139+
queuer,
140+
serverOptions.getExternalUri());
137141

138142
Route handler = Route.combine(
139143
new Router(tracer, clientFactory, sessions, queuer, distributor).with(networkOptions.getSpecComplianceChecks()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.grid.sessionqueue;
19+
20+
import com.google.common.collect.ImmutableMap;
21+
import org.openqa.selenium.internal.Require;
22+
import org.openqa.selenium.remote.http.HttpHandler;
23+
import org.openqa.selenium.remote.http.HttpRequest;
24+
import org.openqa.selenium.remote.http.HttpResponse;
25+
import org.openqa.selenium.remote.tracing.Span;
26+
import org.openqa.selenium.remote.tracing.Tracer;
27+
28+
import static org.openqa.selenium.remote.http.Contents.asJson;
29+
import static org.openqa.selenium.remote.tracing.HttpTracing.newSpanAsChildOf;
30+
import static org.openqa.selenium.remote.tracing.Tags.HTTP_REQUEST;
31+
import static org.openqa.selenium.remote.tracing.Tags.HTTP_RESPONSE;
32+
33+
class GetNewSessionQueueSize implements HttpHandler {
34+
35+
private final Tracer tracer;
36+
private final NewSessionQueuer newSessionQueuer;
37+
38+
GetNewSessionQueueSize(Tracer tracer, NewSessionQueuer newSessionQueuer) {
39+
this.tracer = Require.nonNull("Tracer", tracer);
40+
this.newSessionQueuer = Require.nonNull("New Session Queuer", newSessionQueuer);
41+
}
42+
43+
@Override
44+
public HttpResponse execute(HttpRequest req) {
45+
try (Span span = newSpanAsChildOf(tracer, req, "sessionqueue.size")) {
46+
HTTP_REQUEST.accept(span, req);
47+
48+
int value = newSessionQueuer.getQueueSize();
49+
50+
span.setAttribute("request.retry", value);
51+
52+
HttpResponse response = new HttpResponse()
53+
.setContent(asJson(ImmutableMap.of("value", value)));
54+
55+
HTTP_RESPONSE.accept(span, response);
56+
57+
return response;
58+
}
59+
}
60+
}
61+

java/server/src/org/openqa/selenium/grid/sessionqueue/NewSessionQueue.java

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public abstract class NewSessionQueue implements HasReadyState {
4848

4949
public abstract int clear();
5050

51+
public abstract int getQueueSize();
52+
5153
public void addRequestHeaders(HttpRequest request, RequestId reqId) {
5254
long timestamp = Instant.now().getEpochSecond();
5355
request.addHeader(SESSIONREQUEST_TIMESTAMP_HEADER, Long.toString(timestamp));

java/server/src/org/openqa/selenium/grid/sessionqueue/NewSessionQueuer.java

+5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ protected NewSessionQueuer(Tracer tracer, Secret registrationSecret) {
6363
RequiresSecretFilter requiresSecret = new RequiresSecretFilter(registrationSecret);
6464

6565
routes = combine(
66+
6667
post("/session")
6768
.to(() -> this::addToQueue),
6869
post("/se/grid/newsessionqueuer/session")
@@ -73,6 +74,8 @@ protected NewSessionQueuer(Tracer tracer, Secret registrationSecret) {
7374
get("/se/grid/newsessionqueuer/session/{requestId}")
7475
.to(params -> new RemoveFromSessionQueue(tracer, this, requestIdFrom(params)))
7576
.with(requiresSecret),
77+
get("/se/grid/newsessionqueuer/queue/size")
78+
.to(() -> new GetNewSessionQueueSize(tracer, this)),
7679
delete("/se/grid/newsessionqueuer/queue")
7780
.to(() -> new ClearSessionQueue(tracer, this))
7881
.with(requiresSecret));
@@ -122,6 +125,8 @@ public void validateSessionRequest(HttpRequest request) {
122125

123126
public abstract int clearQueue();
124127

128+
public abstract int getQueueSize();
129+
125130
@Override
126131
public boolean matches(HttpRequest req) {
127132
return routes.matches(req);

java/server/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public boolean isReady() {
8888
return bus.isReady();
8989
}
9090

91+
@Override
9192
@ManagedAttribute(name = "NewSessionQueueSize")
9293
public int getQueueSize() {
9394
Lock readLock = lock.readLock();

java/server/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueuer.java

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ public int clearQueue() {
9191
return sessionRequests.clear();
9292
}
9393

94+
@Override
95+
public int getQueueSize() {
96+
return sessionRequests.getQueueSize();
97+
}
98+
9499
@Override
95100
public boolean isReady() {
96101
return bus.isReady();

java/server/src/org/openqa/selenium/grid/sessionqueue/remote/RemoteNewSessionQueuer.java

+9
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,15 @@ public int clearQueue() {
129129
return Values.get(response, Integer.class);
130130
}
131131

132+
@Override
133+
public int getQueueSize() {
134+
HttpRequest upstream =
135+
new HttpRequest(GET, "/se/grid/newsessionqueuer/queue/size");
136+
HttpTracing.inject(tracer, tracer.getCurrentContext(), upstream);
137+
HttpResponse response = client.execute(upstream);
138+
return Values.get(response, Integer.class);
139+
}
140+
132141
@Override
133142
public boolean isReady() {
134143
try {

0 commit comments

Comments
 (0)