How to use RequestId class of org.openqa.selenium.grid.data package

Best Selenium code snippet using org.openqa.selenium.grid.data.RequestId

Source:GraphqlHandlerTest.java Github

copy

Full Screen

...27import org.openqa.selenium.grid.data.CreateSessionRequest;28import org.openqa.selenium.grid.data.CreateSessionResponse;29import org.openqa.selenium.grid.data.DefaultSlotMatcher;30import org.openqa.selenium.grid.data.NewSessionRequestEvent;31import org.openqa.selenium.grid.data.RequestId;32import org.openqa.selenium.grid.data.Session;33import org.openqa.selenium.grid.data.Slot;34import org.openqa.selenium.grid.distributor.Distributor;35import org.openqa.selenium.grid.distributor.local.LocalDistributor;36import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;37import org.openqa.selenium.grid.node.ActiveSession;38import org.openqa.selenium.grid.node.Node;39import org.openqa.selenium.grid.node.SessionFactory;40import org.openqa.selenium.grid.node.local.LocalNode;41import org.openqa.selenium.grid.security.Secret;42import org.openqa.selenium.grid.sessionmap.SessionMap;43import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;44import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;45import org.openqa.selenium.grid.data.SessionRequest;46import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;47import org.openqa.selenium.grid.testing.TestSessionFactory;48import org.openqa.selenium.internal.Either;49import org.openqa.selenium.json.Json;50import org.openqa.selenium.remote.http.Contents;51import org.openqa.selenium.remote.http.HttpClient;52import org.openqa.selenium.remote.http.HttpHandler;53import org.openqa.selenium.remote.http.HttpRequest;54import org.openqa.selenium.remote.http.HttpResponse;55import org.openqa.selenium.remote.tracing.DefaultTestTracer;56import org.openqa.selenium.remote.tracing.Tracer;57import org.openqa.selenium.support.ui.FluentWait;58import org.openqa.selenium.support.ui.Wait;59import java.net.URI;60import java.net.URISyntaxException;61import java.time.Duration;62import java.time.Instant;63import java.util.Collections;64import java.util.Map;65import java.util.Set;66import java.util.UUID;67import java.util.concurrent.CountDownLatch;68import java.util.concurrent.atomic.AtomicInteger;69import static java.util.Collections.singletonList;70import static java.util.Collections.singletonMap;71import static java.util.concurrent.TimeUnit.SECONDS;72import static org.assertj.core.api.Assertions.assertThat;73import static org.assertj.core.api.Assertions.fail;74import static org.assertj.core.api.InstanceOfAssertFactories.LIST;75import static org.assertj.core.api.InstanceOfAssertFactories.MAP;76import static org.openqa.selenium.json.Json.MAP_TYPE;77import static org.openqa.selenium.remote.Dialect.OSS;78import static org.openqa.selenium.remote.Dialect.W3C;79import static org.openqa.selenium.remote.http.HttpMethod.GET;80public class GraphqlHandlerTest {81 private static final Json JSON = new Json();82 private final Secret registrationSecret = new Secret("stilton");83 private final URI publicUri = new URI("http://example.com/grid-o-matic");84 private final String version = "4.0.0";85 private final Wait<Object> wait = new FluentWait<>(new Object()).withTimeout(Duration.ofSeconds(5));86 private Distributor distributor;87 private NewSessionQueue queue;88 private Tracer tracer;89 private EventBus events;90 private ImmutableCapabilities caps;91 private ImmutableCapabilities stereotype;92 private SessionRequest sessionRequest;93 public GraphqlHandlerTest() throws URISyntaxException {94 }95 @Before96 public void setupGrid() {97 tracer = DefaultTestTracer.createTracer();98 events = new GuavaEventBus();99 HttpClient.Factory clientFactory = HttpClient.Factory.createDefault();100 SessionMap sessions = new LocalSessionMap(tracer, events);101 stereotype = new ImmutableCapabilities("browserName", "cheese");102 caps = new ImmutableCapabilities("browserName", "cheese");103 sessionRequest = new SessionRequest(104 new RequestId(UUID.randomUUID()),105 Instant.now(),106 Set.of(OSS, W3C),107 Set.of(caps),108 Map.of(),109 Map.of());110 queue = new LocalNewSessionQueue(111 tracer,112 events,113 new DefaultSlotMatcher(),114 Duration.ofSeconds(2),115 Duration.ofSeconds(2),116 registrationSecret);117 distributor = new LocalDistributor(118 tracer,119 events,120 clientFactory,121 sessions,122 queue,123 new DefaultSlotSelector(),124 registrationSecret,125 Duration.ofMinutes(5),126 false);127 }128 @Test129 public void shouldBeAbleToGetGridUri() {130 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);131 Map<String, Object> topLevel = executeQuery(handler, "{ grid { uri } }");132 assertThat(topLevel).isEqualTo(133 singletonMap(134 "data", singletonMap(135 "grid", singletonMap(136 "uri", publicUri.toString()))));137 }138 @Test139 public void shouldBeAbleToGetGridVersion() {140 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);141 Map<String, Object> topLevel = executeQuery(handler, "{ grid { version } }");142 assertThat(topLevel).isEqualTo(143 singletonMap(144 "data", singletonMap(145 "grid", singletonMap(146 "version", version))));147 }148 private void continueOnceAddedToQueue(SessionRequest request) {149 // Add to the queue in the background150 CountDownLatch latch = new CountDownLatch(1);151 events.addListener(NewSessionRequestEvent.listener(id -> latch.countDown()));152 new Thread(() -> {153 queue.addToQueue(request);154 }).start();155 try {156 assertThat(latch.await(5, SECONDS)).isTrue();157 } catch (InterruptedException e) {158 Thread.currentThread().interrupt();159 throw new RuntimeException(e);160 }161 }162 @Test163 public void shouldBeAbleToGetSessionQueueSize() throws URISyntaxException {164 SessionRequest request = new SessionRequest(165 new RequestId(UUID.randomUUID()),166 Instant.now(),167 Set.of(W3C),168 Set.of(caps),169 Map.of(),170 Map.of());171 continueOnceAddedToQueue(request);172 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);173 Map<String, Object> topLevel = executeQuery(handler, "{ grid { sessionQueueSize } }");174 assertThat(topLevel).isEqualTo(175 singletonMap(176 "data", singletonMap(177 "grid", singletonMap(178 "sessionQueueSize", 1L))));179 }180 @Test181 public void shouldBeAbleToGetSessionQueueRequests() throws URISyntaxException {182 SessionRequest request = new SessionRequest(183 new RequestId(UUID.randomUUID()),184 Instant.now(),185 Set.of(W3C),186 Set.of(caps),187 Map.of(),188 Map.of());189 continueOnceAddedToQueue(request);190 GraphqlHandler handler = new GraphqlHandler(tracer, distributor, queue, publicUri, version);191 Map<String, Object> topLevel = executeQuery(handler,192 "{ sessionsInfo { sessionQueueRequests } }");193 assertThat(topLevel).isEqualTo(194 singletonMap(195 "data", singletonMap(196 "sessionsInfo", singletonMap(197 "sessionQueueRequests", singletonList(JSON.toJson(caps))))));...

Full Screen

Full Screen

Source:LocalNewSessionQueueTest.java Github

copy

Full Screen

...30import org.openqa.selenium.grid.data.CreateSessionResponse;31import org.openqa.selenium.grid.data.DefaultSlotMatcher;32import org.openqa.selenium.grid.data.NewSessionRejectedEvent;33import org.openqa.selenium.grid.data.NewSessionRequestEvent;34import org.openqa.selenium.grid.data.RequestId;35import org.openqa.selenium.grid.data.Session;36import org.openqa.selenium.grid.data.SessionRequestCapability;37import org.openqa.selenium.grid.security.Secret;38import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;39import org.openqa.selenium.grid.data.SessionRequest;40import org.openqa.selenium.grid.sessionqueue.remote.RemoteNewSessionQueue;41import org.openqa.selenium.grid.testing.PassthroughHttpClient;42import org.openqa.selenium.internal.Debug;43import org.openqa.selenium.internal.Either;44import org.openqa.selenium.json.Json;45import org.openqa.selenium.remote.SessionId;46import org.openqa.selenium.remote.http.Contents;47import org.openqa.selenium.remote.http.HttpClient;48import org.openqa.selenium.remote.http.HttpResponse;49import org.openqa.selenium.remote.tracing.DefaultTestTracer;50import org.openqa.selenium.remote.tracing.Tracer;51import java.net.URI;52import java.net.URISyntaxException;53import java.time.Duration;54import java.time.Instant;55import java.util.Collection;56import java.util.LinkedHashSet;57import java.util.List;58import java.util.Map;59import java.util.Optional;60import java.util.Set;61import java.util.UUID;62import java.util.concurrent.Callable;63import java.util.concurrent.CountDownLatch;64import java.util.concurrent.ExecutionException;65import java.util.concurrent.ExecutorService;66import java.util.concurrent.Executors;67import java.util.concurrent.Future;68import java.util.concurrent.TimeoutException;69import java.util.concurrent.atomic.AtomicBoolean;70import java.util.concurrent.atomic.AtomicInteger;71import java.util.concurrent.atomic.AtomicReference;72import java.util.function.Supplier;73import java.util.stream.Collectors;74import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;75import static java.net.HttpURLConnection.HTTP_OK;76import static java.nio.charset.StandardCharsets.UTF_8;77import static java.util.concurrent.TimeUnit.SECONDS;78import static org.assertj.core.api.Assertions.assertThat;79import static org.assertj.core.api.Assertions.fail;80import static org.junit.Assert.assertEquals;81import static org.junit.Assert.assertFalse;82import static org.junit.Assert.assertNotEquals;83import static org.junit.Assert.assertTrue;84import static org.openqa.selenium.remote.Dialect.W3C;85import static org.openqa.selenium.testing.Safely.safelyCall;86@RunWith(Parameterized.class)87public class LocalNewSessionQueueTest {88 @ClassRule89 public static Timeout classTimeout = new Timeout(60, SECONDS);90 private static final Json JSON = new Json();91 private static final Capabilities CAPS = new ImmutableCapabilities("browserName", "cheese");92 private static final Secret REGISTRATION_SECRET = new Secret("secret");93 private static final Instant LONG_AGO = Instant.parse("2007-01-03T21:49:10.00Z"); // Go check the git log94 private final NewSessionQueue queue;95 private final LocalNewSessionQueue localQueue;96 private final EventBus bus;97 private final SessionRequest sessionRequest;98 static class TestData {99 public final EventBus bus;100 public final LocalNewSessionQueue localQueue;101 public final NewSessionQueue queue;102 public TestData(EventBus bus, LocalNewSessionQueue localQueue, NewSessionQueue queue) {103 this.bus = bus;104 this.localQueue = localQueue;105 this.queue = queue;106 }107 }108 public LocalNewSessionQueueTest(Supplier<TestData> supplier) {109 TestData testData = supplier.get();110 this.bus = testData.bus;111 this.queue = testData.queue;112 this.localQueue = testData.localQueue;113 this.sessionRequest = new SessionRequest(114 new RequestId(UUID.randomUUID()),115 Instant.now(),116 Set.of(W3C),117 Set.of(CAPS),118 Map.of(),119 Map.of());120 }121 @Parameterized.Parameters122 public static Collection<Supplier<TestData>> createQueues() {123 Tracer tracer = DefaultTestTracer.createTracer();124 Set<Supplier<TestData>> toReturn = new LinkedHashSet<>();125 // Note: this method is called only once, so if we want each test to126 // be isolated, everything that they use has to be created via the127 // supplier. In particular, a shared event bus will cause weird128 // failures to happen.129 toReturn.add(() -> {130 EventBus bus = new GuavaEventBus();131 LocalNewSessionQueue local = new LocalNewSessionQueue(132 tracer,133 bus,134 new DefaultSlotMatcher(),135 Duration.ofSeconds(1),136 Duration.ofSeconds(Debug.isDebugging() ? 9999 : 5),137 REGISTRATION_SECRET);138 return new TestData(bus, local, local);139 });140 toReturn.add(() -> {141 EventBus bus = new GuavaEventBus();142 LocalNewSessionQueue local = new LocalNewSessionQueue(143 tracer,144 bus,145 new DefaultSlotMatcher(),146 Duration.ofSeconds(1),147 Duration.ofSeconds(Debug.isDebugging() ? 9999 : 5),148 REGISTRATION_SECRET);149 HttpClient client = new PassthroughHttpClient(local);150 return new TestData(bus, local, new RemoteNewSessionQueue(tracer, client, REGISTRATION_SECRET));151 });152 return toReturn;153 }154 @After155 public void shutdownQueue() {156 safelyCall(localQueue::close);157 }158 @Test159 public void shouldBeAbleToAddToQueueAndGetValidResponse() {160 AtomicBoolean isPresent = new AtomicBoolean(false);161 bus.addListener(NewSessionRequestEvent.listener(reqId -> {162 isPresent.set(true);163 Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome");164 SessionId sessionId = new SessionId("123");165 Session session =166 new Session(167 sessionId,168 URI.create("http://example.com"),169 CAPS,170 capabilities,171 Instant.now());172 CreateSessionResponse sessionResponse = new CreateSessionResponse(173 session,174 JSON.toJson(175 ImmutableMap.of(176 "value", ImmutableMap.of(177 "sessionId", sessionId,178 "capabilities", capabilities)))179 .getBytes(UTF_8));180 queue.complete(reqId, Either.right(sessionResponse));181 }));182 HttpResponse httpResponse = queue.addToQueue(sessionRequest);183 assertThat(isPresent.get()).isTrue();184 assertEquals(httpResponse.getStatus(), HTTP_OK);185 }186 @Test187 public void shouldBeAbleToAddToQueueAndGetErrorResponse() {188 bus.addListener(NewSessionRequestEvent.listener(reqId ->189 queue.complete(reqId, Either.left(new SessionNotCreatedException("Error")))));190 HttpResponse httpResponse = queue.addToQueue(sessionRequest);191 assertEquals(httpResponse.getStatus(), HTTP_INTERNAL_ERROR);192 }193 @Test194 public void shouldBeAbleToRemoveFromQueue() {195 Optional<SessionRequest> httpRequest = queue.remove(new RequestId(UUID.randomUUID()));196 assertFalse(httpRequest.isPresent());197 }198 @Test199 public void shouldBeClearQueue() {200 RequestId requestId = new RequestId(UUID.randomUUID());201 localQueue.injectIntoQueue(sessionRequest);202 int count = queue.clearQueue();203 assertEquals(count, 1);204 assertFalse(queue.remove(requestId).isPresent());205 }206 @Test207 public void shouldBeAbleToGetQueueContents() {208 localQueue.injectIntoQueue(sessionRequest);209 List<Set<Capabilities>> response = queue.getQueueContents()210 .stream()211 .map(SessionRequestCapability::getDesiredCapabilities)212 .collect(Collectors.toList());213 assertThat(response).hasSize(1);214 assertEquals(Set.of(CAPS), response.get(0));215 }216 @Test217 public void shouldBeClearQueueAndFireRejectedEvent() throws InterruptedException {218 AtomicBoolean result = new AtomicBoolean(false);219 RequestId requestId = sessionRequest.getRequestId();220 CountDownLatch latch = new CountDownLatch(1);221 bus.addListener(222 NewSessionRejectedEvent.listener(223 response -> {224 result.set(response.getRequestId().equals(requestId));225 latch.countDown();226 }));227 localQueue.injectIntoQueue(sessionRequest);228 queue.remove(requestId);229 queue.retryAddToQueue(sessionRequest);230 int count = queue.clearQueue();231 assertThat(latch.await(2, SECONDS)).isTrue();232 assertThat(result.get()).isTrue();233 assertEquals(count, 1);234 assertFalse(queue.remove(requestId).isPresent());235 }236 @Test237 public void removingARequestIdThatDoesNotExistInTheQueueShouldNotBeAnError() {238 localQueue.injectIntoQueue(sessionRequest);239 Optional<SessionRequest> httpRequest = queue.remove(new RequestId(UUID.randomUUID()));240 assertFalse(httpRequest.isPresent());241 }242 @Test243 public void shouldBeAbleToAddAgainToQueue() {244 localQueue.injectIntoQueue(sessionRequest);245 Optional<SessionRequest> removed = queue.remove(sessionRequest.getRequestId());246 assertThat(removed).isPresent();247 boolean added = queue.retryAddToQueue(sessionRequest);248 assertTrue(added);249 }250 @Test251 public void shouldBeAbleToRetryRequest() {252 AtomicBoolean isPresent = new AtomicBoolean(false);253 AtomicBoolean retrySuccess = new AtomicBoolean(false);254 AtomicInteger count = new AtomicInteger(0);255 bus.addListener(256 NewSessionRequestEvent.listener(257 reqId -> {258 // Keep a count of event fired259 count.incrementAndGet();260 Optional<SessionRequest> sessionRequest = this.queue.remove(reqId);261 isPresent.set(sessionRequest.isPresent());262 if (count.get() == 1) {263 retrySuccess.set(queue.retryAddToQueue(sessionRequest.get()));264 }265 // Only if it was retried after an interval, the count is 2266 if (count.get() == 2) {267 ImmutableCapabilities capabilities =268 new ImmutableCapabilities("browserName", "edam");269 try {270 SessionId sessionId = new SessionId("123");271 Session session =272 new Session(273 sessionId,274 new URI("http://example.com"),275 CAPS,276 capabilities,277 Instant.now());278 CreateSessionResponse sessionResponse =279 new CreateSessionResponse(280 session,281 JSON.toJson(282 ImmutableMap.of(283 "value",284 ImmutableMap.of(285 "sessionId", sessionId,286 "capabilities", capabilities)))287 .getBytes(UTF_8));288 queue.complete(reqId, Either.right(sessionResponse));289 } catch (URISyntaxException e) {290 throw new RuntimeException(e);291 }292 }293 }));294 HttpResponse httpResponse = queue.addToQueue(sessionRequest);295 assertThat(isPresent.get()).isTrue();296 assertThat(retrySuccess.get()).isTrue();297 assertEquals(httpResponse.getStatus(), HTTP_OK);298 }299 @Test(timeout = 5000)300 public void shouldBeAbleToHandleMultipleSessionRequestsAtTheSameTime() {301 bus.addListener(NewSessionRequestEvent.listener(reqId -> {302 queue.remove(reqId);303 ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");304 try {305 SessionId sessionId = new SessionId(UUID.randomUUID());306 Session session =307 new Session(308 sessionId,309 new URI("http://example.com"),310 CAPS,311 capabilities,312 Instant.now());313 CreateSessionResponse sessionResponse = new CreateSessionResponse(314 session,315 JSON.toJson(316 ImmutableMap.of(317 "value", ImmutableMap.of(318 "sessionId", sessionId,319 "capabilities", capabilities)))320 .getBytes(UTF_8));321 queue.complete(reqId, Either.right(sessionResponse));322 } catch (URISyntaxException e) {323 queue.complete(reqId, Either.left(new SessionNotCreatedException(e.getMessage())));324 }325 }));326 ExecutorService executor = Executors.newFixedThreadPool(2);327 Callable<HttpResponse> callable = () -> {328 SessionRequest sessionRequest = new SessionRequest(329 new RequestId(UUID.randomUUID()),330 Instant.now(),331 Set.of(W3C),332 Set.of(CAPS),333 Map.of(),334 Map.of());335 return queue.addToQueue(sessionRequest);336 };337 Future<HttpResponse> firstRequest = executor.submit(callable);338 Future<HttpResponse> secondRequest = executor.submit(callable);339 try {340 HttpResponse firstResponse = firstRequest.get(30, SECONDS);341 HttpResponse secondResponse = secondRequest.get(30, SECONDS);342 String firstResponseContents = Contents.string(firstResponse);343 String secondResponseContents = Contents.string(secondResponse);344 assertEquals(firstResponse.getStatus(), HTTP_OK);345 assertEquals(secondResponse.getStatus(), HTTP_OK);346 assertNotEquals(firstResponseContents, secondResponseContents);347 } catch (InterruptedException | ExecutionException | TimeoutException e) {348 fail("Could not create session");349 }350 executor.shutdown();351 }352 @Test(timeout = 5000)353 public void shouldBeAbleToTimeoutARequestOnRetry() {354 final SessionRequest request = new SessionRequest(355 new RequestId(UUID.randomUUID()),356 LONG_AGO,357 Set.of(W3C),358 Set.of(CAPS),359 Map.of(),360 Map.of());361 AtomicInteger count = new AtomicInteger();362 bus.addListener(NewSessionRejectedEvent.listener(reqId -> {363 count.incrementAndGet();364 }));365 HttpResponse httpResponse = queue.addToQueue(request);366 assertEquals(1, count.get());367 assertEquals(HTTP_INTERNAL_ERROR, httpResponse.getStatus());368 }369 @Test(timeout = 10000)370 public void shouldBeAbleToTimeoutARequestOnRemove() throws InterruptedException {371 AtomicReference<RequestId> isPresent = new AtomicReference<>();372 CountDownLatch latch = new CountDownLatch(1);373 bus.addListener(374 NewSessionRejectedEvent.listener(375 response -> {376 isPresent.set(response.getRequestId());377 latch.countDown();378 }));379 SessionRequest sessionRequest = new SessionRequest(380 new RequestId(UUID.randomUUID()),381 LONG_AGO,382 Set.of(W3C),383 Set.of(CAPS),384 Map.of(),385 Map.of());386 localQueue.injectIntoQueue(sessionRequest);387 queue.remove(sessionRequest.getRequestId());388 assertThat(latch.await(4, SECONDS)).isTrue();389 assertThat(isPresent.get()).isEqualTo(sessionRequest.getRequestId());390 }391 @Test(timeout = 5000)392 public void shouldBeAbleToClearQueueAndRejectMultipleRequests() {393 ExecutorService executor = Executors.newFixedThreadPool(2);394 Callable<HttpResponse> callable = () -> {395 SessionRequest sessionRequest = new SessionRequest(396 new RequestId(UUID.randomUUID()),397 Instant.now(),398 Set.of(W3C),399 Set.of(CAPS),400 Map.of(),401 Map.of());402 return queue.addToQueue(sessionRequest);403 };404 Future<HttpResponse> firstRequest = executor.submit(callable);405 Future<HttpResponse> secondRequest = executor.submit(callable);406 int count = 0;407 while (count < 2) {408 count += queue.clearQueue();409 }410 try {411 HttpResponse firstResponse = firstRequest.get(30, SECONDS);412 HttpResponse secondResponse = secondRequest.get(30, SECONDS);413 assertEquals(firstResponse.getStatus(), HTTP_INTERNAL_ERROR);414 assertEquals(secondResponse.getStatus(), HTTP_INTERNAL_ERROR);415 } catch (InterruptedException | ExecutionException | TimeoutException e) {416 fail("Could not create session");417 }418 executor.shutdownNow();419 }420 @Test421 public void shouldBeAbleToReturnTheNextAvailableEntryThatMatchesAStereotype() {422 SessionRequest expected = new SessionRequest(423 new RequestId(UUID.randomUUID()),424 Instant.now(),425 Set.of(W3C),426 Set.of(new ImmutableCapabilities("browserName", "cheese", "se:kind", "smoked")),427 Map.of(),428 Map.of());429 localQueue.injectIntoQueue(expected);430 localQueue.injectIntoQueue(new SessionRequest(431 new RequestId(UUID.randomUUID()),432 Instant.now(),433 Set.of(W3C),434 Set.of(new ImmutableCapabilities("browserName", "peas", "se:kind", "mushy")),435 Map.of(),436 Map.of()));437 Optional<SessionRequest> returned = queue.getNextAvailable(438 Set.of(new ImmutableCapabilities("browserName", "cheese")));439 assertThat(returned).isEqualTo(Optional.of(expected));440 }441 @Test442 public void shouldNotReturnANextAvailableEntryThatDoesNotMatchTheStereotypes() {443 // Note that this is basically the same test as getting the entry444 // from queue, but we've cleverly reversed the entries, so the one445 // that doesn't match should be first in the queue.446 localQueue.injectIntoQueue(new SessionRequest(447 new RequestId(UUID.randomUUID()),448 Instant.now(),449 Set.of(W3C),450 Set.of(new ImmutableCapabilities("browserName", "peas", "se:kind", "mushy")),451 Map.of(),452 Map.of()));453 SessionRequest expected = new SessionRequest(454 new RequestId(UUID.randomUUID()),455 Instant.now(),456 Set.of(W3C),457 Set.of(new ImmutableCapabilities("browserName", "cheese", "se:kind", "smoked")),458 Map.of(),459 Map.of());460 localQueue.injectIntoQueue(expected);461 Optional<SessionRequest> returned = queue.getNextAvailable(462 Set.of(new ImmutableCapabilities("browserName", "cheese")));463 assertThat(returned).isEqualTo(Optional.of(expected));464 }465}...

Full Screen

Full Screen

Source:LocalDistributor.java Github

copy

Full Screen

...38import org.openqa.selenium.grid.data.NodeHeartBeatEvent;39import org.openqa.selenium.grid.data.NodeId;40import org.openqa.selenium.grid.data.NodeStatus;41import org.openqa.selenium.grid.data.NodeStatusEvent;42import org.openqa.selenium.grid.data.RequestId;43import org.openqa.selenium.grid.data.Slot;44import org.openqa.selenium.grid.data.SlotId;45import org.openqa.selenium.grid.distributor.Distributor;46import org.openqa.selenium.grid.distributor.config.DistributorOptions;47import org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector;48import org.openqa.selenium.grid.log.LoggingOptions;49import org.openqa.selenium.grid.node.HealthCheck;50import org.openqa.selenium.grid.node.Node;51import org.openqa.selenium.grid.node.remote.RemoteNode;52import org.openqa.selenium.grid.security.Secret;53import org.openqa.selenium.grid.security.SecretOptions;54import org.openqa.selenium.grid.server.EventBusOptions;55import org.openqa.selenium.grid.server.NetworkOptions;56import org.openqa.selenium.grid.sessionmap.SessionMap;57import org.openqa.selenium.grid.sessionmap.config.SessionMapOptions;58import org.openqa.selenium.grid.sessionqueue.NewSessionQueuer;59import org.openqa.selenium.grid.sessionqueue.config.NewSessionQueuerOptions;60import org.openqa.selenium.internal.Either;61import org.openqa.selenium.internal.Require;62import org.openqa.selenium.remote.http.HttpClient;63import org.openqa.selenium.remote.http.HttpRequest;64import org.openqa.selenium.remote.tracing.AttributeKey;65import org.openqa.selenium.remote.tracing.EventAttribute;66import org.openqa.selenium.remote.tracing.EventAttributeValue;67import org.openqa.selenium.remote.tracing.Span;68import org.openqa.selenium.remote.tracing.Tracer;69import org.openqa.selenium.status.HasReadyState;70import java.time.Duration;71import java.util.ArrayList;72import java.util.HashMap;73import java.util.List;74import java.util.Map;75import java.util.Optional;76import java.util.Queue;77import java.util.Set;78import java.util.concurrent.ConcurrentHashMap;79import java.util.concurrent.ConcurrentLinkedQueue;80import java.util.concurrent.Executors;81import java.util.concurrent.ScheduledExecutorService;82import java.util.concurrent.ThreadFactory;83import java.util.concurrent.TimeUnit;84import java.util.concurrent.locks.Lock;85import java.util.concurrent.locks.ReadWriteLock;86import java.util.concurrent.locks.ReentrantReadWriteLock;87import java.util.logging.Level;88import java.util.logging.Logger;89import static com.google.common.collect.ImmutableSet.toImmutableSet;90import static org.openqa.selenium.grid.data.Availability.DOWN;91import static org.openqa.selenium.grid.data.Availability.DRAINING;92import static org.openqa.selenium.remote.tracing.HttpTracing.newSpanAsChildOf;93public class LocalDistributor extends Distributor {94 private static final Logger LOG = Logger.getLogger(LocalDistributor.class.getName());95 private final Tracer tracer;96 private final EventBus bus;97 private final HttpClient.Factory clientFactory;98 private final SessionMap sessions;99 private final Secret registrationSecret;100 private final Regularly hostChecker = new Regularly("distributor host checker");101 private final Map<NodeId, Runnable> allChecks = new HashMap<>();102 private final Queue<RequestId> requestIds = new ConcurrentLinkedQueue<>();103 private final ScheduledExecutorService executorService;104 private final Duration healthcheckInterval;105 private final ReadWriteLock lock = new ReentrantReadWriteLock(/* fair */ true);106 private final GridModel model;107 private final Map<NodeId, Node> nodes;108 private final NewSessionQueuer sessionRequests;109 public LocalDistributor(110 Tracer tracer,111 EventBus bus,112 HttpClient.Factory clientFactory,113 SessionMap sessions,114 NewSessionQueuer sessionRequests,115 Secret registrationSecret,116 Duration healthcheckInterval) {117 super(tracer, clientFactory, new DefaultSlotSelector(), sessions, registrationSecret);118 this.tracer = Require.nonNull("Tracer", tracer);119 this.bus = Require.nonNull("Event bus", bus);120 this.clientFactory = Require.nonNull("HTTP client factory", clientFactory);121 this.sessions = Require.nonNull("Session map", sessions);122 this.model = new GridModel(bus);123 this.nodes = new ConcurrentHashMap<>();124 this.sessionRequests = Require.nonNull("New Session Request Queue", sessionRequests);125 this.registrationSecret = Require.nonNull("Registration secret", registrationSecret);126 this.healthcheckInterval = Require.nonNull("Health check interval", healthcheckInterval);127 bus.addListener(NodeStatusEvent.listener(this::register));128 bus.addListener(NodeStatusEvent.listener(model::refresh));129 bus.addListener(NodeHeartBeatEvent.listener(nodeStatus -> {130 if (nodes.containsKey(nodeStatus.getId())) {131 model.touch(nodeStatus.getId());132 } else {133 register(nodeStatus);134 }135 }));136 bus.addListener(NodeDrainComplete.listener(this::remove));137 bus.addListener(NewSessionRequestEvent.listener(requestIds::offer));138 Regularly regularly = new Regularly("Local Distributor");139 regularly.submit(model::purgeDeadNodes, Duration.ofSeconds(30), Duration.ofSeconds(30));140 Thread shutdownHook = new Thread(this::callExecutorShutdown);141 Runtime.getRuntime().addShutdownHook(shutdownHook);142 NewSessionRunnable runnable = new NewSessionRunnable();143 ThreadFactory threadFactory = r -> {144 Thread thread = new Thread(r);145 thread.setName("New Session Creation");146 thread.setDaemon(true);147 return thread;148 };149 executorService = Executors.newSingleThreadScheduledExecutor(threadFactory);150 executorService.scheduleAtFixedRate(runnable, 0, 1000, TimeUnit.MILLISECONDS);151 }152 public static Distributor create(Config config) {153 Tracer tracer = new LoggingOptions(config).getTracer();154 EventBus bus = new EventBusOptions(config).getEventBus();155 DistributorOptions distributorOptions = new DistributorOptions(config);156 HttpClient.Factory clientFactory = new NetworkOptions(config).getHttpClientFactory(tracer);157 SessionMap sessions = new SessionMapOptions(config).getSessionMap();158 SecretOptions secretOptions = new SecretOptions(config);159 NewSessionQueuer sessionRequests =160 new NewSessionQueuerOptions(config).getSessionQueuer(161 "org.openqa.selenium.grid.sessionqueue.remote.RemoteNewSessionQueuer");162 return new LocalDistributor(163 tracer,164 bus,165 clientFactory,166 sessions,167 sessionRequests,168 secretOptions.getRegistrationSecret(),169 distributorOptions.getHealthCheckInterval());170 }171 @Override172 public boolean isReady() {173 try {174 return ImmutableSet.of(bus, sessions).parallelStream()175 .map(HasReadyState::isReady)176 .reduce(true, Boolean::logicalAnd);177 } catch (RuntimeException e) {178 return false;179 }180 }181 private void register(NodeStatus status) {182 Require.nonNull("Node", status);183 Lock writeLock = lock.writeLock();184 writeLock.lock();185 try {186 if (nodes.containsKey(status.getId())) {187 return;188 }189 Set<Capabilities> capabilities = status.getSlots().stream()190 .map(Slot::getStereotype)191 .map(ImmutableCapabilities::copyOf)192 .collect(toImmutableSet());193 // A new node! Add this as a remote node, since we've not called add194 RemoteNode remoteNode = new RemoteNode(195 tracer,196 clientFactory,197 status.getId(),198 status.getUri(),199 registrationSecret,200 capabilities);201 add(remoteNode);202 } finally {203 writeLock.unlock();204 }205 }206 @Override207 public LocalDistributor add(Node node) {208 Require.nonNull("Node", node);209 LOG.info(String.format("Added node %s at %s.", node.getId(), node.getUri()));210 nodes.put(node.getId(), node);211 model.add(node.getStatus());212 // Extract the health check213 Runnable runnableHealthCheck = asRunnableHealthCheck(node);214 allChecks.put(node.getId(), runnableHealthCheck);215 hostChecker.submit(runnableHealthCheck, healthcheckInterval, Duration.ofSeconds(30));216 bus.fire(new NodeAddedEvent(node.getId()));217 return this;218 }219 private Runnable asRunnableHealthCheck(Node node) {220 HealthCheck healthCheck = node.getHealthCheck();221 NodeId id = node.getId();222 return () -> {223 HealthCheck.Result result;224 try {225 result = healthCheck.check();226 } catch (Exception e) {227 LOG.log(Level.WARNING, "Unable to process node " + id, e);228 result = new HealthCheck.Result(DOWN, "Unable to run healthcheck. Assuming down");229 }230 Lock writeLock = lock.writeLock();231 writeLock.lock();232 try {233 model.setAvailability(id, result.getAvailability());234 } finally {235 writeLock.unlock();236 }237 };238 }239 @Override240 public boolean drain(NodeId nodeId) {241 Node node = nodes.get(nodeId);242 if (node == null) {243 LOG.info("Asked to drain unregistered node " + nodeId);244 return false;245 }246 Lock writeLock = lock.writeLock();247 writeLock.lock();248 try {249 node.drain();250 model.setAvailability(nodeId, DRAINING);251 } finally {252 writeLock.unlock();253 }254 return node.isDraining();255 }256 public void remove(NodeId nodeId) {257 Lock writeLock = lock.writeLock();258 writeLock.lock();259 try {260 model.remove(nodeId);261 Runnable runnable = allChecks.remove(nodeId);262 if (runnable != null) {263 hostChecker.remove(runnable);264 }265 } finally {266 writeLock.unlock();267 }268 }269 @Override270 public DistributorStatus getStatus() {271 Lock readLock = this.lock.readLock();272 readLock.lock();273 try {274 return new DistributorStatus(model.getSnapshot());275 } finally {276 readLock.unlock();277 }278 }279 @Beta280 public void refresh() {281 List<Runnable> allHealthChecks = new ArrayList<>();282 Lock readLock = this.lock.readLock();283 readLock.lock();284 try {285 allHealthChecks.addAll(allChecks.values());286 } finally {287 readLock.unlock();288 }289 allHealthChecks.parallelStream().forEach(Runnable::run);290 }291 @Override292 protected Set<NodeStatus> getAvailableNodes() {293 Lock readLock = this.lock.readLock();294 readLock.lock();295 try {296 return model.getSnapshot().stream()297 .filter(node -> !DOWN.equals(node.getAvailability()))298 .collect(toImmutableSet());299 } finally {300 readLock.unlock();301 }302 }303 @Override304 protected Either<SessionNotCreatedException, CreateSessionResponse> reserve(SlotId slotId, CreateSessionRequest request) {305 Require.nonNull("Slot ID", slotId);306 Require.nonNull("New Session request", request);307 Lock writeLock = this.lock.writeLock();308 writeLock.lock();309 try {310 Node node = nodes.get(slotId.getOwningNodeId());311 if (node == null) {312 return Either.left(new RetrySessionRequestException(313 "Unable to find node. Try a different node"));314 }315 model.reserve(slotId);316 Either<WebDriverException, CreateSessionResponse> response = node.newSession(request);317 if (response.isRight()) {318 model.setSession(slotId, response.right().getSession());319 return Either.right(response.right());320 } else {321 model.setSession(slotId, null);322 WebDriverException exception = response.left();323 if (exception instanceof RetrySessionRequestException) {324 return Either.left(new RetrySessionRequestException(exception.getMessage()));325 } else {326 return Either.left(new SessionNotCreatedException(exception.getMessage()));327 }328 }329 } finally {330 writeLock.unlock();331 }332 }333 public void callExecutorShutdown() {334 LOG.info("Shutting down Distributor executor service");335 executorService.shutdownNow();336 }337 public class NewSessionRunnable implements Runnable {338 @Override339 public void run() {340 Lock writeLock = lock.writeLock();341 writeLock.lock();342 try {343 if (!requestIds.isEmpty()) {344 Set<NodeStatus> availableNodes = ImmutableSet.copyOf(getAvailableNodes());345 boolean hasCapacity = availableNodes.stream()346 .anyMatch(NodeStatus::hasCapacity);347 if (hasCapacity) {348 RequestId reqId = requestIds.poll();349 if (reqId != null) {350 Optional<HttpRequest> optionalHttpRequest = sessionRequests.remove(reqId);351 // Check if polling the queue did not return null352 if (optionalHttpRequest.isPresent()) {353 handleNewSessionRequest(optionalHttpRequest.get(), reqId);354 } else {355 fireSessionRejectedEvent(356 "Unable to poll request from the new session request queue.",357 reqId);358 }359 }360 }361 }362 } finally {363 writeLock.unlock();364 }365 }366 private void handleNewSessionRequest(HttpRequest sessionRequest, RequestId reqId) {367 try (Span span = newSpanAsChildOf(tracer, sessionRequest, "distributor.poll_queue")) {368 Map<String, EventAttributeValue> attributeMap = new HashMap<>();369 attributeMap.put(370 AttributeKey.LOGGER_CLASS.getKey(),371 EventAttribute.setValue(getClass().getName()));372 span.setAttribute(AttributeKey.REQUEST_ID.getKey(), reqId.toString());373 attributeMap.put(374 AttributeKey.REQUEST_ID.getKey(),375 EventAttribute.setValue(reqId.toString()));376 attributeMap.put("request", EventAttribute.setValue(sessionRequest.toString()));377 Either<SessionNotCreatedException, CreateSessionResponse> response =378 newSession(sessionRequest);379 if (response.isRight()) {380 CreateSessionResponse sessionResponse = response.right();381 NewSessionResponse newSessionResponse =382 new NewSessionResponse(383 reqId,384 sessionResponse.getSession(),385 sessionResponse.getDownstreamEncodedResponse());386 bus.fire(new NewSessionResponseEvent(newSessionResponse));387 } else {388 SessionNotCreatedException exception = response.left();389 if (exception instanceof RetrySessionRequestException) {390 boolean retried = sessionRequests.retryAddToQueue(sessionRequest, reqId);391 attributeMap.put("request.retry_add", EventAttribute.setValue(retried));392 span.addEvent("Retry adding to front of queue. No slot available.", attributeMap);393 if (!retried) {394 span.addEvent("Retry adding to front of queue failed.", attributeMap);395 fireSessionRejectedEvent(exception.getMessage(), reqId);396 }397 } else {398 fireSessionRejectedEvent(exception.getMessage(), reqId);399 }400 }401 }402 }403 private void fireSessionRejectedEvent(String message, RequestId reqId) {404 bus.fire(405 new NewSessionRejectedEvent(new NewSessionErrorResponse(reqId, message)));406 }407 }408}...

Full Screen

Full Screen

Source:NewSessionQueuerTest.java Github

copy

Full Screen

...27import org.openqa.selenium.grid.data.NewSessionRejectedEvent;28import org.openqa.selenium.grid.data.NewSessionRequestEvent;29import org.openqa.selenium.grid.data.NewSessionResponse;30import org.openqa.selenium.grid.data.NewSessionResponseEvent;31import org.openqa.selenium.grid.data.RequestId;32import org.openqa.selenium.grid.data.Session;33import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueue;34import org.openqa.selenium.grid.sessionqueue.local.LocalNewSessionQueuer;35import org.openqa.selenium.grid.sessionqueue.remote.RemoteNewSessionQueuer;36import org.openqa.selenium.grid.testing.PassthroughHttpClient;37import org.openqa.selenium.json.Json;38import org.openqa.selenium.remote.NewSessionPayload;39import org.openqa.selenium.remote.SessionId;40import org.openqa.selenium.remote.http.Contents;41import org.openqa.selenium.remote.http.HttpClient;42import org.openqa.selenium.remote.http.HttpMethod;43import org.openqa.selenium.remote.http.HttpRequest;44import org.openqa.selenium.remote.http.HttpResponse;45import org.openqa.selenium.remote.tracing.DefaultTestTracer;46import org.openqa.selenium.remote.tracing.Tracer;47import java.io.IOException;48import java.io.UncheckedIOException;49import java.net.URI;50import java.net.URISyntaxException;51import java.time.Duration;52import java.time.Instant;53import java.util.Optional;54import java.util.UUID;55import java.util.concurrent.Callable;56import java.util.concurrent.ExecutionException;57import java.util.concurrent.ExecutorService;58import java.util.concurrent.Executors;59import java.util.concurrent.Future;60import java.util.concurrent.TimeUnit;61import java.util.concurrent.TimeoutException;62import java.util.concurrent.atomic.AtomicBoolean;63import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;64import static java.net.HttpURLConnection.HTTP_OK;65import static java.nio.charset.StandardCharsets.UTF_8;66import static org.assertj.core.api.Assertions.assertThat;67import static org.assertj.core.api.Assertions.fail;68import static org.junit.Assert.assertEquals;69import static org.junit.Assert.assertFalse;70import static org.junit.Assert.assertNotEquals;71import static org.junit.Assert.assertTrue;72import static org.openqa.selenium.remote.http.Contents.utf8String;73import static org.openqa.selenium.remote.http.HttpMethod.POST;74public class NewSessionQueuerTest {75 private LocalNewSessionQueuer local;76 private RemoteNewSessionQueuer remote;77 private EventBus bus;78 private ImmutableCapabilities caps;79 private NewSessionPayload payload;80 private HttpRequest request;81 private static int count = 0;82 private static final Json JSON = new Json();83 private static int sessionTimeout = 5;84 private NewSessionQueue sessionQueue;85 @Before86 public void setUp() {87 Tracer tracer = DefaultTestTracer.createTracer();88 caps = new ImmutableCapabilities("browserName", "chrome");89 bus = new GuavaEventBus();90 sessionQueue = new LocalNewSessionQueue(tracer, bus, Duration.ofSeconds(1));91 local = new LocalNewSessionQueuer(tracer, bus, sessionQueue);92 HttpClient client = new PassthroughHttpClient(local);93 remote = new RemoteNewSessionQueuer(tracer, client);94 payload = NewSessionPayload.create(caps);95 request = createRequest(payload, POST, "/session");96 }97 @Test98 public void shouldBeAbleToAddToQueueAndGetValidResponse() {99 AtomicBoolean isPresent = new AtomicBoolean(false);100 bus.addListener(NewSessionRequestEvent.listener(reqId -> {101 Optional<HttpRequest> sessionRequest = this.local.remove();102 isPresent.set(sessionRequest.isPresent());103 Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome");104 try {105 SessionId sessionId = new SessionId("123");106 Session session =107 new Session(108 sessionId,109 new URI("http://example.com"),110 caps,111 capabilities,112 Instant.now());113 CreateSessionResponse sessionResponse = new CreateSessionResponse(114 session,115 JSON.toJson(116 ImmutableMap.of(117 "value", ImmutableMap.of(118 "sessionId", sessionId,119 "capabilities", capabilities)))120 .getBytes(UTF_8));121 NewSessionResponse newSessionResponse =122 new NewSessionResponse(reqId, sessionResponse.getSession(),123 sessionResponse.getDownstreamEncodedResponse());124 bus.fire(new NewSessionResponseEvent(newSessionResponse));125 } catch (URISyntaxException e) {126 bus.fire(127 new NewSessionRejectedEvent(128 new NewSessionErrorResponse(new RequestId(UUID.randomUUID()), "Error")));129 }130 }));131 HttpResponse httpResponse = local.addToQueue(request);132 assertThat(isPresent.get()).isTrue();133 assertEquals(httpResponse.getStatus(), HTTP_OK);134 }135 @Test136 public void shouldBeAbleToAddToQueueAndGetErrorResponse() {137 AtomicBoolean isPresent = new AtomicBoolean(false);138 bus.addListener(NewSessionRequestEvent.listener(reqId -> {139 Optional<HttpRequest> sessionRequest = this.local.remove();140 isPresent.set(sessionRequest.isPresent());141 bus.fire(142 new NewSessionRejectedEvent(143 new NewSessionErrorResponse(reqId, "Error")));144 }));145 HttpResponse httpResponse = local.addToQueue(request);146 assertThat(isPresent.get()).isTrue();147 assertEquals(httpResponse.getStatus(), HTTP_INTERNAL_ERROR);148 }149 @Test150 public void shouldBeAbleToAddToQueueRemotelyAndGetErrorResponse() {151 AtomicBoolean isPresent = new AtomicBoolean(false);152 bus.addListener(NewSessionRequestEvent.listener(reqId -> {153 Optional<HttpRequest> sessionRequest = this.remote.remove();154 isPresent.set(sessionRequest.isPresent());155 bus.fire(156 new NewSessionRejectedEvent(157 new NewSessionErrorResponse(reqId, "Could not poll the queue")));158 }));159 HttpResponse httpResponse = remote.addToQueue(request);160 assertThat(isPresent.get()).isTrue();161 assertEquals(httpResponse.getStatus(), HTTP_INTERNAL_ERROR);162 }163 @Test164 public void shouldBeAbleToRemoveFromQueue() {165 Optional<HttpRequest> httpRequest = local.remove();166 assertFalse(httpRequest.isPresent());167 }168 @Test169 public void shouldBeClearQueue() {170 RequestId requestId = new RequestId(UUID.randomUUID());171 sessionQueue.offerLast(request, requestId);172 int count = local.clearQueue();173 assertEquals(count, 1);174 assertFalse(local.remove().isPresent());175 }176 @Test177 public void shouldBeClearQueueRemotely() {178 RequestId requestId = new RequestId(UUID.randomUUID());179 sessionQueue.offerLast(request, requestId);180 int count = remote.clearQueue();181 assertEquals(count, 1);182 assertFalse(remote.remove().isPresent());183 }184 @Test185 public void shouldBeClearQueueAndFireRejectedEvent() {186 AtomicBoolean result = new AtomicBoolean(false);187 RequestId requestId = new RequestId(UUID.randomUUID());188 bus.addListener(NewSessionRejectedEvent.listener(response ->189 result.set(response.getRequestId()190 .equals(requestId))));191 sessionQueue.offerLast(request, requestId);192 int count = remote.clearQueue();193 assertThat(result.get()).isTrue();194 assertEquals(count, 1);195 assertFalse(remote.remove().isPresent());196 }197 @Test198 public void shouldBeAbleToRemoveFromQueueRemotely() {199 Optional<HttpRequest> httpRequest = remote.remove();200 assertFalse(httpRequest.isPresent());201 }202 @Test203 public void shouldBeAbleToAddAgainToQueue() {204 boolean added = local.retryAddToQueue(request, new RequestId(UUID.randomUUID()));205 assertTrue(added);206 }207 @Test208 public void shouldBeAbleToAddAgainToQueueRemotely() {209 HttpRequest request = createRequest(payload, POST, "/se/grid/newsessionqueuer/session");210 boolean added = remote.retryAddToQueue(request, new RequestId(UUID.randomUUID()));211 assertTrue(added);212 }213 @Test214 public void shouldBeAbleToRetryRequest() {215 AtomicBoolean isPresent = new AtomicBoolean(false);216 AtomicBoolean retrySuccess = new AtomicBoolean(false);217 bus.addListener(NewSessionRequestEvent.listener(reqId -> {218 // Keep a count of event fired219 count++;220 Optional<HttpRequest> sessionRequest = this.remote.remove();221 isPresent.set(sessionRequest.isPresent());222 if (count == 1) {223 retrySuccess.set(remote.retryAddToQueue(sessionRequest.get(), reqId));224 }225 // Only if it was retried after an interval, the count is 2226 if (count == 2) {227 ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");228 try {229 SessionId sessionId = new SessionId("123");230 Session session =231 new Session(232 sessionId,233 new URI("http://example.com"),234 caps,235 capabilities,236 Instant.now());237 CreateSessionResponse sessionResponse = new CreateSessionResponse(238 session,239 JSON.toJson(240 ImmutableMap.of(241 "value", ImmutableMap.of(242 "sessionId", sessionId,243 "capabilities", capabilities)))244 .getBytes(UTF_8));245 NewSessionResponse newSessionResponse =246 new NewSessionResponse(reqId, sessionResponse.getSession(),247 sessionResponse.getDownstreamEncodedResponse());248 bus.fire(new NewSessionResponseEvent(newSessionResponse));249 } catch (URISyntaxException e) {250 bus.fire(251 new NewSessionRejectedEvent(252 new NewSessionErrorResponse(new RequestId(UUID.randomUUID()), "Error")));253 }254 }255 }));256 HttpResponse httpResponse = remote.addToQueue(request);257 assertThat(isPresent.get()).isTrue();258 assertThat(retrySuccess.get()).isTrue();259 assertEquals(httpResponse.getStatus(), HTTP_OK);260 }261 @Test262 public void shouldBeAbleToHandleMultipleSessionRequestsAtTheSameTime() {263 bus.addListener(NewSessionRequestEvent.listener(reqId -> {264 Optional<HttpRequest> sessionRequest = this.local.remove();265 ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");266 try {267 SessionId sessionId = new SessionId(UUID.randomUUID());268 Session session =269 new Session(270 sessionId,271 new URI("http://example.com"),272 caps,273 capabilities,274 Instant.now());275 CreateSessionResponse sessionResponse = new CreateSessionResponse(276 session,277 JSON.toJson(278 ImmutableMap.of(279 "value", ImmutableMap.of(280 "sessionId", sessionId,281 "capabilities", capabilities)))282 .getBytes(UTF_8));283 NewSessionResponse newSessionResponse =284 new NewSessionResponse(reqId, sessionResponse.getSession(),285 sessionResponse.getDownstreamEncodedResponse());286 bus.fire(new NewSessionResponseEvent(newSessionResponse));287 } catch (URISyntaxException e) {288 bus.fire(289 new NewSessionRejectedEvent(290 new NewSessionErrorResponse(new RequestId(UUID.randomUUID()), "Error")));291 }292 }));293 ExecutorService executor = Executors.newFixedThreadPool(2);294 Callable<HttpResponse> callable = () -> remote.addToQueue(request);295 Future<HttpResponse> firstRequest = executor.submit(callable);296 Future<HttpResponse> secondRequest = executor.submit(callable);297 try {298 HttpResponse firstResponse = firstRequest.get(30, TimeUnit.SECONDS);299 HttpResponse secondResponse = secondRequest.get(30, TimeUnit.SECONDS);300 String firstResponseContents = Contents.string(firstResponse);301 String secondResponseContents = Contents.string(secondResponse);302 assertEquals(firstResponse.getStatus(), HTTP_OK);303 assertEquals(secondResponse.getStatus(), HTTP_OK);304 assertNotEquals(firstResponseContents, secondResponseContents);...

Full Screen

Full Screen

Source:LocalNewSessionQueue.java Github

copy

Full Screen

...7import org.openqa.selenium.grid.data.CreateSessionResponse;8import org.openqa.selenium.grid.data.NewSessionErrorResponse;9import org.openqa.selenium.grid.data.NewSessionRejectedEvent;10import org.openqa.selenium.grid.data.NewSessionRequestEvent;11import org.openqa.selenium.grid.data.RequestId;12import org.openqa.selenium.grid.data.SessionRequest;13import org.openqa.selenium.grid.data.SessionRequestCapability;14import org.openqa.selenium.grid.data.TraceSessionRequest;15import org.openqa.selenium.grid.data.SlotMatcher;16import org.openqa.selenium.grid.distributor.config.DistributorOptions;17import org.openqa.selenium.grid.jmx.JMXHelper;18import org.openqa.selenium.grid.jmx.ManagedAttribute;19import org.openqa.selenium.grid.jmx.ManagedService;20import org.openqa.selenium.grid.log.LoggingOptions;21import org.openqa.selenium.grid.security.Secret;22import org.openqa.selenium.grid.security.SecretOptions;23import org.openqa.selenium.grid.server.EventBusOptions;24import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;25import org.openqa.selenium.grid.sessionqueue.config.SessionRequestOptions;26import org.openqa.selenium.internal.Either;27import org.openqa.selenium.internal.Require;28import org.openqa.selenium.remote.http.Contents;29import org.openqa.selenium.remote.http.HttpResponse;30import org.openqa.selenium.remote.tracing.Span;31import org.openqa.selenium.remote.tracing.TraceContext;32import org.openqa.selenium.remote.tracing.Tracer;33import java.io.Closeable;34import java.io.IOException;35import java.time.Duration;36import java.time.Instant;37import java.util.Collections;38import java.util.Deque;39import java.util.Iterator;40import java.util.List;41import java.util.Map;42import java.util.Optional;43import java.util.Set;44import java.util.concurrent.ConcurrentHashMap;45import java.util.concurrent.ConcurrentLinkedDeque;46import java.util.concurrent.CountDownLatch;47import java.util.concurrent.Executors;48import java.util.concurrent.ScheduledExecutorService;49import java.util.concurrent.locks.Lock;50import java.util.concurrent.locks.ReadWriteLock;51import java.util.concurrent.locks.ReentrantReadWriteLock;52import java.util.function.Predicate;53import java.util.stream.Collectors;54import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;55import static java.util.concurrent.TimeUnit.MILLISECONDS;56/**57 * An in-memory implementation of the list of new session requests.58 * <p>59 * The lifecycle of a request can be described as:60 * <ol>61 * <li>User adds an item on to the queue using {@link #addToQueue(SessionRequest)}. This62 * will block until the request completes in some way.63 * <li>After being added, a {@link NewSessionRequestEvent} is fired. Listeners should use64 * this as an indication to call {@link #remove(RequestId)} to get the session request.65 * <li>If the session request is completed, then {@link #complete(RequestId, Either)} must66 * be called. This will not only ensure that {@link #addToQueue(SessionRequest)}67 * returns, but will also fire a {@link NewSessionRejectedEvent} if the session was68 * rejected. Positive completions of events are assumed to be notified on the event bus69 * by other listeners.70 * <li>If the request cannot be handled right now, call71 * {@link #retryAddToQueue(SessionRequest)} to return the session request to the front72 * of the queue.73 * </ol>74 * <p>75 * There is a background thread that will reap {@link SessionRequest}s that have timed out.76 * This means that a request can either complete by a listener calling77 * {@link #complete(RequestId, Either)} directly, or by being reaped by the thread.78 */79@ManagedService(objectName = "org.seleniumhq.grid:type=SessionQueue,name=LocalSessionQueue",80 description = "New session queue")81public class LocalNewSessionQueue extends NewSessionQueue implements Closeable {82 private final EventBus bus;83 private final SlotMatcher slotMatcher;84 private final Duration requestTimeout;85 private final Map<RequestId, Data> requests;86 private final Map<RequestId, TraceContext> contexts;87 private final Deque<SessionRequest> queue;88 private final ReadWriteLock lock = new ReentrantReadWriteLock();89 private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(r -> {90 Thread thread = new Thread(r);91 thread.setDaemon(true);92 thread.setName("Local New Session Queue");93 return thread;94 });95 public LocalNewSessionQueue(96 Tracer tracer,97 EventBus bus,98 SlotMatcher slotMatcher,99 Duration retryPeriod,100 Duration requestTimeout,101 Secret registrationSecret) {102 super(tracer, registrationSecret);103 this.slotMatcher = Require.nonNull("Slot matcher", slotMatcher);104 this.bus = Require.nonNull("Event bus", bus);105 Require.nonNull("Retry period", retryPeriod);106 if (retryPeriod.isNegative() || retryPeriod.isZero()) {107 throw new IllegalArgumentException("Retry period must be positive");108 }109 this.requestTimeout = Require.nonNull("Request timeout", requestTimeout);110 if (requestTimeout.isNegative() || requestTimeout.isZero()) {111 throw new IllegalArgumentException("Request timeout must be positive");112 }113 this.requests = new ConcurrentHashMap<>();114 this.queue = new ConcurrentLinkedDeque<>();115 this.contexts = new ConcurrentHashMap<>();116 service.scheduleAtFixedRate(this::timeoutSessions, retryPeriod.toMillis(), retryPeriod.toMillis(), MILLISECONDS);117 new JMXHelper().register(this);118 }119 public static NewSessionQueue create(Config config) {120 LoggingOptions loggingOptions = new LoggingOptions(config);121 Tracer tracer = loggingOptions.getTracer();122 EventBusOptions eventBusOptions = new EventBusOptions(config);123 SessionRequestOptions requestOptions = new SessionRequestOptions(config);124 SecretOptions secretOptions = new SecretOptions(config);125 SlotMatcher slotMatcher = new DistributorOptions(config).getSlotMatcher();126 return new LocalNewSessionQueue(127 tracer,128 eventBusOptions.getEventBus(),129 slotMatcher,130 requestOptions.getSessionRequestRetryInterval(),131 requestOptions.getSessionRequestTimeout(),132 secretOptions.getRegistrationSecret());133 }134 private void timeoutSessions() {135 Instant now = Instant.now();136 Lock readLock = lock.readLock();137 readLock.lock();138 Set<RequestId> ids;139 try {140 ids = requests.entrySet().stream()141 .filter(entry -> isTimedOut(now, entry.getValue()))142 .map(Map.Entry::getKey)143 .collect(Collectors.toSet());144 } finally {145 readLock.unlock();146 }147 Lock writeLock = lock.writeLock();148 try {149 for (RequestId id : ids) {150 failDueToTimeout(id);151 }152 } finally {153 writeLock.unlock();154 }155 }156 private boolean isTimedOut(Instant now, Data data) {157 return data.endTime.isBefore(now);158 }159 @Override160 public HttpResponse addToQueue(SessionRequest request) {161 Require.nonNull("New session request", request);162 Require.nonNull("Request id", request.getRequestId());163 TraceContext context = TraceSessionRequest.extract(tracer, request);164 try (Span span = context.createSpan("sessionqueue.add_to_queue")) {165 contexts.put(request.getRequestId(), context);166 Data data = injectIntoQueue(request);167 if (isTimedOut(Instant.now(), data)) {168 failDueToTimeout(request.getRequestId());169 }170 Either<SessionNotCreatedException, CreateSessionResponse> result;171 try {172 if (data.latch.await(requestTimeout.toMillis(), MILLISECONDS)) {173 result = data.result;174 } else {175 result = Either.left(new SessionNotCreatedException("New session request timed out"));176 }177 } catch (InterruptedException e) {178 Thread.currentThread().interrupt();179 result = Either.left(new SessionNotCreatedException("Interrupted when creating the session", e));180 } catch (RuntimeException e) {181 result = Either.left(new SessionNotCreatedException("An error occurred creating the session", e));182 }183 Lock writeLock = this.lock.writeLock();184 writeLock.lock();185 try {186 requests.remove(request.getRequestId());187 queue.remove(request);188 } finally {189 writeLock.unlock();190 }191 HttpResponse res = new HttpResponse();192 if (result.isRight()) {193 res.setContent(Contents.bytes(result.right().getDownstreamEncodedResponse()));194 } else {195 res.setStatus(HTTP_INTERNAL_ERROR)196 .setContent(Contents.asJson(Collections.singletonMap("value", result.left())));197 }198 return res;199 }200 }201 @VisibleForTesting202 Data injectIntoQueue(SessionRequest request) {203 Require.nonNull("Session request", request);204 Data data = new Data(request.getEnqueued());205 Lock writeLock = lock.writeLock();206 writeLock.lock();207 try {208 requests.put(request.getRequestId(), data);209 queue.addLast(request);210 } finally {211 writeLock.unlock();212 }213 bus.fire(new NewSessionRequestEvent(request.getRequestId()));214 return data;215 }216 @Override217 public boolean retryAddToQueue(SessionRequest request) {218 Require.nonNull("New session request", request);219 boolean added;220 TraceContext context = contexts.getOrDefault(request.getRequestId(), tracer.getCurrentContext());221 try (Span span = context.createSpan("sessionqueue.retry")) {222 Lock writeLock = lock.writeLock();223 writeLock.lock();224 try {225 if (!requests.containsKey(request.getRequestId())) {226 return false;227 }228 if (queue.contains(request)) {229 // No need to re-add this230 return true;231 } else {232 added = queue.offerFirst(request);233 }234 } finally {235 writeLock.unlock();236 }237 if (added) {238 bus.fire(new NewSessionRequestEvent(request.getRequestId()));239 }240 return added;241 }242 }243 @Override244 public Optional<SessionRequest> remove(RequestId reqId) {245 Require.nonNull("Request ID", reqId);246 Lock writeLock = lock.writeLock();247 writeLock.lock();248 try {249 Iterator<SessionRequest> iterator = queue.iterator();250 while (iterator.hasNext()) {251 SessionRequest req = iterator.next();252 if (reqId.equals(req.getRequestId())) {253 iterator.remove();254 return Optional.of(req);255 }256 }257 return Optional.empty();258 } finally {259 writeLock.unlock();260 }261 }262 @Override263 public Optional<SessionRequest> getNextAvailable(Set<Capabilities> stereotypes) {264 Require.nonNull("Stereotypes", stereotypes);265 Predicate<Capabilities> matchesStereotype =266 caps -> stereotypes.stream().anyMatch(stereotype -> slotMatcher.matches(stereotype, caps));267 Lock writeLock = lock.writeLock();268 writeLock.lock();269 try {270 Optional<SessionRequest> maybeRequest =271 queue.stream()272 .filter(req -> req.getDesiredCapabilities().stream().anyMatch(matchesStereotype))273 .findFirst();274 maybeRequest.ifPresent(req -> {275 this.remove(req.getRequestId());276 });277 return maybeRequest;278 } finally {279 writeLock.unlock();280 }281 }282 @Override283 public void complete(RequestId reqId, Either<SessionNotCreatedException, CreateSessionResponse> result) {284 Require.nonNull("New session request", reqId);285 Require.nonNull("Result", result);286 TraceContext context = contexts.getOrDefault(reqId, tracer.getCurrentContext());287 try (Span span = context.createSpan("sessionqueue.completed")) {288 Lock readLock = lock.readLock();289 readLock.lock();290 Data data;291 try {292 data = requests.get(reqId);293 } finally {294 readLock.unlock();295 }296 if (data == null) {297 return;298 }299 Lock writeLock = lock.writeLock();300 writeLock.lock();301 try {302 requests.remove(reqId);303 queue.removeIf(req -> reqId.equals(req.getRequestId()));304 contexts.remove(reqId);305 } finally {306 writeLock.unlock();307 }308 if (result.isLeft()) {309 bus.fire(new NewSessionRejectedEvent(new NewSessionErrorResponse(reqId, result.left().getMessage())));310 }311 data.setResult(result);312 }313 }314 @Override315 public int clearQueue() {316 Lock writeLock = lock.writeLock();317 writeLock.lock();318 try {319 int size = queue.size();320 queue.clear();321 requests.forEach((reqId, data) -> {322 data.setResult(Either.left(new SessionNotCreatedException("Request queue was cleared")));323 bus.fire(new NewSessionRejectedEvent(324 new NewSessionErrorResponse(reqId, "New session queue was forcibly cleared")));325 });326 requests.clear();327 return size;328 } finally {329 writeLock.unlock();330 }331 }332 @Override333 public List<SessionRequestCapability> getQueueContents() {334 Lock readLock = lock.readLock();335 readLock.lock();336 try {337 return queue.stream()338 .map(req ->339 new SessionRequestCapability(req.getRequestId(), req.getDesiredCapabilities()))340 .collect(Collectors.toList());341 } finally {342 readLock.unlock();343 }344 }345 @ManagedAttribute(name = "NewSessionQueueSize")346 public int getQueueSize() {347 return queue.size();348 }349 @Override350 public boolean isReady() {351 return true;352 }353 @Override354 public void close() throws IOException {355 service.shutdownNow();356 }357 private void failDueToTimeout(RequestId reqId) {358 complete(reqId, Either.left(new SessionNotCreatedException("Timed out creating session")));359 }360 private class Data {361 public final Instant endTime;362 public Either<SessionNotCreatedException, CreateSessionResponse> result;363 private boolean complete;364 private CountDownLatch latch = new CountDownLatch(1);365 public Data(Instant enqueued) {366 this.endTime = enqueued.plus(requestTimeout);367 this.result = Either.left(new SessionNotCreatedException("Session not created"));368 }369 public synchronized void setResult(Either<SessionNotCreatedException, CreateSessionResponse> result) {370 if (complete) {371 return;...

Full Screen

Full Screen

Source:GetNewSessionResponse.java Github

copy

Full Screen

...21import org.openqa.selenium.grid.data.NewSessionRejectedEvent;22import org.openqa.selenium.grid.data.NewSessionRequest;23import org.openqa.selenium.grid.data.NewSessionResponse;24import org.openqa.selenium.grid.data.NewSessionResponseEvent;25import org.openqa.selenium.grid.data.RequestId;26import org.openqa.selenium.internal.Require;27import org.openqa.selenium.remote.http.HttpRequest;28import org.openqa.selenium.remote.http.HttpResponse;29import org.openqa.selenium.remote.tracing.Tracer;30import java.util.Map;31import java.util.Optional;32import java.util.UUID;33import java.util.concurrent.ConcurrentHashMap;34import java.util.concurrent.CountDownLatch;35import java.util.logging.Level;36import java.util.logging.Logger;37import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;38import static org.openqa.selenium.remote.http.Contents.asJson;39import static org.openqa.selenium.remote.http.Contents.bytes;40public class GetNewSessionResponse {41 private static final Logger LOG = Logger.getLogger(GetNewSessionResponse.class.getName());42 private final EventBus bus;43 private final Tracer tracer;44 private final NewSessionQueue sessionRequests;45 private final Map<RequestId, NewSessionRequest> knownRequests = new ConcurrentHashMap<>();46 public GetNewSessionResponse(Tracer tracer, EventBus bus,47 NewSessionQueue sessionRequests) {48 this.tracer = Require.nonNull("Tracer", tracer);49 this.bus = Require.nonNull("Event bus", bus);50 this.sessionRequests = Require.nonNull("New Session Request Queue", sessionRequests);51 this.bus.addListener(NewSessionResponseEvent.listener(sessionResponse -> {52 try {53 this.setResponse(sessionResponse);54 } catch (Exception ignore) {55 // Ignore any exception. Do not want to block the eventbus thread.56 }57 }));58 this.bus.addListener(NewSessionRejectedEvent.listener(sessionResponse -> {59 try {60 this.setErrorResponse(sessionResponse);61 } catch (Exception ignore) {62 // Ignore any exception. Do not want to block the eventbus thread.63 }64 }));65 }66 private void setResponse(NewSessionResponse sessionResponse) {67 // Each thread will get its own CountDownLatch and it is stored in the Map using request id as the key.68 // EventBus thread will retrieve the same request and set it's response and unblock waiting request thread.69 RequestId id = sessionResponse.getRequestId();70 Optional<NewSessionRequest> sessionRequest = Optional.ofNullable(knownRequests.get(id));71 if (sessionRequest.isPresent()) {72 NewSessionRequest request = sessionRequest.get();73 request.setSessionResponse(74 new HttpResponse().setContent(bytes(sessionResponse.getDownstreamEncodedResponse())));75 request.getLatch().countDown();76 }77 }78 private void setErrorResponse(NewSessionErrorResponse sessionResponse) {79 RequestId id = sessionResponse.getRequestId();80 Optional<NewSessionRequest> sessionRequest = Optional.ofNullable(knownRequests.get(id));81 // There could be a situation where the session request in the queue is scheduled for retry.82 // Meanwhile the request queue is cleared.83 // This will fire a error response event and remove the request id from the knownRequests map.84 // Another error response event will be fired by the Distributor when the request is retried.85 // Since a response is already provided for the request, the event listener should not take any action.86 if (sessionRequest.isPresent()) {87 NewSessionRequest request = sessionRequest.get();88 request89 .setSessionResponse(new HttpResponse()90 .setStatus(HTTP_INTERNAL_ERROR)91 .setContent(asJson(92 ImmutableMap.of("message", sessionResponse.getMessage()))));93 request.getLatch().countDown();94 }95 }96 public HttpResponse add(HttpRequest request) {97 Require.nonNull("New Session request", request);98 CountDownLatch latch = new CountDownLatch(1);99 UUID uuid = UUID.randomUUID();100 RequestId requestId = new RequestId(uuid);101 NewSessionRequest requestIdentifier = new NewSessionRequest(requestId, latch);102 knownRequests.put(requestId, requestIdentifier);103 if (!sessionRequests.offerLast(request, requestId)) {104 return new HttpResponse()105 .setStatus(HTTP_INTERNAL_ERROR)106 .setContent(asJson(ImmutableMap.of("message",107 "Session request could not be created. Error while adding to the session queue.")));108 }109 try {110 // Block until response is received.111 // This will not wait indefinitely due to request timeout handled by the LocalDistributor.112 latch.await();113 HttpResponse res = requestIdentifier.getSessionResponse();114 return res;115 } catch (InterruptedException e) {116 LOG.log(Level.WARNING, "The thread waiting for new session response interrupted. {0}",117 e.getMessage());118 Thread.currentThread().interrupt();119 return new HttpResponse()120 .setStatus(HTTP_INTERNAL_ERROR)121 .setContent(asJson(ImmutableMap.of("message",122 "Session request could not be created. Error while processing the session request.")));123 } finally {124 removeRequest(requestId);125 }126 }127 private void removeRequest(RequestId id) {128 knownRequests.remove(id);129 }130}...

Full Screen

Full Screen

Source:NewSessionQueue.java Github

copy

Full Screen

...17package org.openqa.selenium.grid.sessionqueue;18import org.openqa.selenium.Capabilities;19import org.openqa.selenium.SessionNotCreatedException;20import org.openqa.selenium.grid.data.CreateSessionResponse;21import org.openqa.selenium.grid.data.RequestId;22import org.openqa.selenium.grid.data.SessionRequest;23import org.openqa.selenium.grid.data.SessionRequestCapability;24import org.openqa.selenium.grid.security.RequiresSecretFilter;25import org.openqa.selenium.grid.security.Secret;26import org.openqa.selenium.internal.Either;27import org.openqa.selenium.internal.Require;28import org.openqa.selenium.remote.http.HttpRequest;29import org.openqa.selenium.remote.http.HttpResponse;30import org.openqa.selenium.remote.http.Routable;31import org.openqa.selenium.remote.http.Route;32import org.openqa.selenium.remote.tracing.Tracer;33import org.openqa.selenium.status.HasReadyState;34import java.time.Instant;35import java.util.List;36import java.util.Map;37import java.util.Optional;38import java.util.Set;39import java.util.UUID;40import static org.openqa.selenium.remote.http.Route.combine;41import static org.openqa.selenium.remote.http.Route.delete;42import static org.openqa.selenium.remote.http.Route.get;43import static org.openqa.selenium.remote.http.Route.post;44public abstract class NewSessionQueue implements HasReadyState, Routable {45 protected final Tracer tracer;46 private final Route routes;47 protected NewSessionQueue(Tracer tracer, Secret registrationSecret) {48 this.tracer = Require.nonNull("Tracer", tracer);49 Require.nonNull("Registration secret", registrationSecret);50 RequiresSecretFilter requiresSecret = new RequiresSecretFilter(registrationSecret);51 routes = combine(52 post("/session")53 .to(() -> req -> {54 SessionRequest sessionRequest = new SessionRequest(55 new RequestId(UUID.randomUUID()),56 req,57 Instant.now()58 );59 return addToQueue(sessionRequest);60 }),61 post("/se/grid/newsessionqueue/session")62 .to(() -> new AddToSessionQueue(tracer, this))63 .with(requiresSecret),64 post("/se/grid/newsessionqueue/session/{requestId}/retry")65 .to(params -> new AddBackToSessionQueue(tracer, this, requestIdFrom(params)))66 .with(requiresSecret),67 post("/se/grid/newsessionqueue/session/{requestId}/failure")68 .to(params -> new SessionNotCreated(tracer, this, requestIdFrom(params)))69 .with(requiresSecret),70 post("/se/grid/newsessionqueue/session/{requestId}/success")71 .to(params -> new SessionCreated(tracer, this, requestIdFrom(params)))72 .with(requiresSecret),73 post("/se/grid/newsessionqueue/session/{requestId}")74 .to(params -> new RemoveFromSessionQueue(tracer, this, requestIdFrom(params)))75 .with(requiresSecret),76 post("/se/grid/newsessionqueue/session/next")77 .to(() -> new GetNextMatchingRequest(tracer, this))78 .with(requiresSecret),79 get("/se/grid/newsessionqueue/queue")80 .to(() -> new GetSessionQueue(tracer, this)),81 delete("/se/grid/newsessionqueue/queue")82 .to(() -> new ClearSessionQueue(tracer, this))83 .with(requiresSecret));84 }85 private RequestId requestIdFrom(Map<String, String> params) {86 return new RequestId(UUID.fromString(params.get("requestId")));87 }88 public abstract HttpResponse addToQueue(SessionRequest request);89 public abstract boolean retryAddToQueue(SessionRequest request);90 public abstract Optional<SessionRequest> remove(RequestId reqId);91 public abstract Optional<SessionRequest> getNextAvailable(Set<Capabilities> stereotypes);92 public abstract void complete(RequestId reqId, Either<SessionNotCreatedException, CreateSessionResponse> result);93 public abstract int clearQueue();94 public abstract List<SessionRequestCapability> getQueueContents();95 @Override96 public boolean matches(HttpRequest req) {97 return routes.matches(req);98 }99 @Override100 public HttpResponse execute(HttpRequest req) {101 return routes.execute(req);102 }103}...

Full Screen

Full Screen

Source:SessionCreated.java Github

copy

Full Screen

...15// specific language governing permissions and limitations16// under the License.17package org.openqa.selenium.grid.sessionqueue;18import org.openqa.selenium.grid.data.CreateSessionResponse;19import org.openqa.selenium.grid.data.RequestId;20import org.openqa.selenium.internal.Either;21import org.openqa.selenium.internal.Require;22import org.openqa.selenium.remote.http.Contents;23import org.openqa.selenium.remote.http.HttpHandler;24import org.openqa.selenium.remote.http.HttpRequest;25import org.openqa.selenium.remote.http.HttpResponse;26import org.openqa.selenium.remote.tracing.Span;27import org.openqa.selenium.remote.tracing.Tracer;28import java.io.UncheckedIOException;29import static org.openqa.selenium.remote.tracing.HttpTracing.newSpanAsChildOf;30import static org.openqa.selenium.remote.tracing.Tags.HTTP_REQUEST;31import static org.openqa.selenium.remote.tracing.Tags.HTTP_RESPONSE;32class SessionCreated implements HttpHandler {33 private final Tracer tracer;34 private final NewSessionQueue queue;35 private final RequestId requestId;36 public SessionCreated(Tracer tracer, NewSessionQueue queue, RequestId requestId) {37 this.tracer = Require.nonNull("Tracer", tracer);38 this.queue = Require.nonNull("New Session Queue", queue);39 this.requestId = Require.nonNull("Request ID", requestId);40 }41 @Override42 public HttpResponse execute(HttpRequest req) throws UncheckedIOException {43 try (Span span = newSpanAsChildOf(tracer, req, "sessionqueue.created_ok")) {44 HTTP_REQUEST.accept(span, req);45 CreateSessionResponse response = Contents.fromJson(req, CreateSessionResponse.class);46 queue.complete(requestId, Either.right(response));47 HttpResponse res = new HttpResponse();48 HTTP_RESPONSE.accept(span, res);49 return res;50 }...

Full Screen

Full Screen
copy
1==32551== Branches: 656,645,130 ( 656,609,208 cond + 35,922 ind)2==32551== Mispredicts: 169,556 ( 169,095 cond + 461 ind)3==32551== Mispred rate: 0.0% ( 0.0% + 1.2% )4
Full Screen
copy
1for (int i = 0; i < array.Length; ++i)2{3 // Use array[i]4}5
Full Screen
copy
1if (data[c] >= 128)2 sum += data[c];3
Full Screen

Selenium 4 Tutorial:

LambdaTest’s Selenium 4 tutorial is covering every aspects of Selenium 4 testing with examples and best practices. Here you will learn basics, such as how to upgrade from Selenium 3 to Selenium 4, to some advanced concepts, such as Relative locators and Selenium Grid 4 for Distributed testing. Also will learn new features of Selenium 4, such as capturing screenshots of specific elements, opening a new tab or window on the browser, and new protocol adoptions.

Chapters:

  1. Upgrading From Selenium 3 To Selenium 4?: In this chapter, learn in detail how to update Selenium 3 to Selenium 4 for Java binding. Also, learn how to upgrade while using different build tools such as Maven or Gradle and get comprehensive guidance for upgrading Selenium.

  2. What’s New In Selenium 4 & What’s Being Deprecated? : Get all information about new implementations in Selenium 4, such as W3S protocol adaption, Optimized Selenium Grid, and Enhanced Selenium IDE. Also, learn what is deprecated for Selenium 4, such as DesiredCapabilites and FindsBy methods, etc.

  3. Selenium 4 With Python: Selenium supports all major languages, such as Python, C#, Ruby, and JavaScript. In this chapter, learn how to install Selenium 4 for Python and the features of Python in Selenium 4, such as Relative locators, Browser manipulation, and Chrom DevTool protocol.

  4. Selenium 4 Is Now W3C Compliant: JSON Wireframe protocol is retiring from Selenium 4, and they are adopting W3C protocol to learn in detail about the advantages and impact of these changes.

  5. How To Use Selenium 4 Relative Locator? : Selenium 4 came with new features such as Relative Locators that allow constructing locators with reference and easily located constructors nearby. Get to know its different use cases with examples.

  6. Selenium Grid 4 Tutorial For Distributed Testing: Selenium Grid 4 allows you to perform tests over different browsers, OS, and device combinations. It also enables parallel execution browser testing, reads up on various features of Selenium Grid 4 and how to download it, and runs a test on Selenium Grid 4 with best practices.

  7. Selenium Video Tutorials: Binge on video tutorials on Selenium by industry experts to get step-by-step direction from automating basic to complex test scenarios with Selenium.

Selenium 101 certifications:

LambdaTest also provides certification for Selenium testing to accelerate your career in Selenium automation testing.

Run Selenium automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used methods in RequestId

Test Your Web Or Mobile Apps On 3000+ Browsers

Signup for free

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful