|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright The OpenTelemetry Authors | 
|  | 3 | + * SPDX-License-Identifier: Apache-2.0 | 
|  | 4 | + */ | 
|  | 5 | + | 
|  | 6 | +package io.opentelemetry.javaagent.instrumentation.play.v2_6; | 
|  | 7 | + | 
|  | 8 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.CAPTURE_HEADERS; | 
|  | 9 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.ERROR; | 
|  | 10 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.EXCEPTION; | 
|  | 11 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.INDEXED_CHILD; | 
|  | 12 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.QUERY_PARAM; | 
|  | 13 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.REDIRECT; | 
|  | 14 | +import static io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint.SUCCESS; | 
|  | 15 | + | 
|  | 16 | +import java.util.concurrent.CompletableFuture; | 
|  | 17 | +import java.util.concurrent.ExecutorService; | 
|  | 18 | +import java.util.concurrent.Executors; | 
|  | 19 | +import play.Mode; | 
|  | 20 | +import play.libs.concurrent.HttpExecution; | 
|  | 21 | +import play.mvc.Result; | 
|  | 22 | +import play.mvc.Results; | 
|  | 23 | +import play.routing.RoutingDsl; | 
|  | 24 | +import play.server.Server; | 
|  | 25 | +import scala.concurrent.ExecutionContextExecutor; | 
|  | 26 | + | 
|  | 27 | +class PlayAsyncServerTest extends PlayServerTest { | 
|  | 28 | + | 
|  | 29 | +  private static final ExecutorService executor = Executors.newCachedThreadPool(); | 
|  | 30 | + | 
|  | 31 | +  @Override | 
|  | 32 | +  protected Server setupServer() { | 
|  | 33 | +    ExecutionContextExecutor executionContextExecutor = HttpExecution.fromThread(executor); | 
|  | 34 | +    return Server.forRouter( | 
|  | 35 | +        Mode.TEST, | 
|  | 36 | +        port, | 
|  | 37 | +        components -> | 
|  | 38 | +            RoutingDsl.fromComponents(components) | 
|  | 39 | +                .GET(SUCCESS.getPath()) | 
|  | 40 | +                .routingAsync( | 
|  | 41 | +                    request -> | 
|  | 42 | +                        CompletableFuture.supplyAsync( | 
|  | 43 | +                            () -> | 
|  | 44 | +                                controller( | 
|  | 45 | +                                    SUCCESS, | 
|  | 46 | +                                    () -> Results.status(SUCCESS.getStatus(), SUCCESS.getBody())), | 
|  | 47 | +                            executionContextExecutor)) | 
|  | 48 | +                .GET(QUERY_PARAM.getPath()) | 
|  | 49 | +                .routingAsync( | 
|  | 50 | +                    request -> | 
|  | 51 | +                        CompletableFuture.supplyAsync( | 
|  | 52 | +                            () -> | 
|  | 53 | +                                controller( | 
|  | 54 | +                                    QUERY_PARAM, | 
|  | 55 | +                                    () -> | 
|  | 56 | +                                        Results.status( | 
|  | 57 | +                                            QUERY_PARAM.getStatus(), QUERY_PARAM.getBody())), | 
|  | 58 | +                            executionContextExecutor)) | 
|  | 59 | +                .GET(REDIRECT.getPath()) | 
|  | 60 | +                .routingAsync( | 
|  | 61 | +                    request -> | 
|  | 62 | +                        CompletableFuture.supplyAsync( | 
|  | 63 | +                            () -> controller(REDIRECT, () -> Results.found(REDIRECT.getBody())), | 
|  | 64 | +                            executionContextExecutor)) | 
|  | 65 | +                .GET(ERROR.getPath()) | 
|  | 66 | +                .routingAsync( | 
|  | 67 | +                    request -> | 
|  | 68 | +                        CompletableFuture.supplyAsync( | 
|  | 69 | +                            () -> | 
|  | 70 | +                                controller( | 
|  | 71 | +                                    ERROR, | 
|  | 72 | +                                    () -> Results.status(ERROR.getStatus(), ERROR.getBody())), | 
|  | 73 | +                            executionContextExecutor)) | 
|  | 74 | +                .GET(EXCEPTION.getPath()) | 
|  | 75 | +                .routingAsync( | 
|  | 76 | +                    request -> | 
|  | 77 | +                        CompletableFuture.supplyAsync( | 
|  | 78 | +                            () -> | 
|  | 79 | +                                controller( | 
|  | 80 | +                                    EXCEPTION, | 
|  | 81 | +                                    () -> { | 
|  | 82 | +                                      throw new IllegalArgumentException(EXCEPTION.getBody()); | 
|  | 83 | +                                    }), | 
|  | 84 | +                            executionContextExecutor)) | 
|  | 85 | +                .GET(CAPTURE_HEADERS.getPath()) | 
|  | 86 | +                .routingAsync( | 
|  | 87 | +                    request -> | 
|  | 88 | +                        CompletableFuture.supplyAsync( | 
|  | 89 | +                            () -> | 
|  | 90 | +                                controller( | 
|  | 91 | +                                    CAPTURE_HEADERS, | 
|  | 92 | +                                    () -> { | 
|  | 93 | +                                      Result result = | 
|  | 94 | +                                          Results.status( | 
|  | 95 | +                                              CAPTURE_HEADERS.getStatus(), | 
|  | 96 | +                                              CAPTURE_HEADERS.getBody()); | 
|  | 97 | +                                      return request | 
|  | 98 | +                                          .header("X-Test-Request") | 
|  | 99 | +                                          .map(value -> result.withHeader("X-Test-Response", value)) | 
|  | 100 | +                                          .orElse(result); | 
|  | 101 | +                                    }), | 
|  | 102 | +                            executionContextExecutor)) | 
|  | 103 | +                .GET(INDEXED_CHILD.getPath()) | 
|  | 104 | +                .routingAsync( | 
|  | 105 | +                    request -> { | 
|  | 106 | +                      String id = request.queryString("id").orElse(null); | 
|  | 107 | +                      return CompletableFuture.supplyAsync( | 
|  | 108 | +                          () -> | 
|  | 109 | +                              controller( | 
|  | 110 | +                                  INDEXED_CHILD, | 
|  | 111 | +                                  () -> { | 
|  | 112 | +                                    INDEXED_CHILD.collectSpanAttributes( | 
|  | 113 | +                                        name -> "id".equals(name) ? id : null); | 
|  | 114 | +                                    return Results.status( | 
|  | 115 | +                                        INDEXED_CHILD.getStatus(), INDEXED_CHILD.getBody()); | 
|  | 116 | +                                  }), | 
|  | 117 | +                          executionContextExecutor); | 
|  | 118 | +                    }) | 
|  | 119 | +                .build()); | 
|  | 120 | +  } | 
|  | 121 | + | 
|  | 122 | +  @Override | 
|  | 123 | +  protected void stopServer(Server server) { | 
|  | 124 | +    server.stop(); | 
|  | 125 | +    executor.shutdown(); | 
|  | 126 | +  } | 
|  | 127 | +} | 
0 commit comments