{"action":"created","comment":{"url":"https://api.github.com/repos/akka/akka/pulls/comments/65013366","id":65013366,"diff_hunk":"@@ -0,0 +1,788 @@\n+/*\n+ * Copyright (C) 2016-2016 Lightbend Inc. <http://www.lightbend.com>\n+ */\n+package docs.http.javadsl.server.directives;\n+\n+import akka.actor.ActorSystem;\n+import akka.dispatch.ExecutionContexts;\n+import akka.event.Logging;\n+import akka.event.LoggingAdapter;\n+import akka.http.impl.util.Util;\n+import akka.http.javadsl.model.ContentTypes;\n+import akka.http.javadsl.model.HttpEntities;\n+import akka.http.javadsl.model.HttpEntity;\n+import akka.http.javadsl.model.HttpMethods;\n+import akka.http.javadsl.model.HttpRequest;\n+import akka.http.javadsl.model.HttpResponse;\n+import akka.http.javadsl.model.ResponseEntity;\n+import akka.http.javadsl.model.StatusCodes;\n+import akka.http.javadsl.model.headers.RawHeader;\n+import akka.http.javadsl.model.headers.Server;\n+import akka.http.scaladsl.model.headers.ProductVersion;\n+import akka.http.scaladsl.settings.RoutingSettings;\n+import akka.http.javadsl.testkit.JUnitRouteTest;\n+import akka.http.javadsl.server.*;\n+import akka.japi.pf.PFBuilder;\n+import akka.stream.ActorMaterializer;\n+import akka.stream.ActorMaterializerSettings;\n+import akka.stream.javadsl.FileIO;\n+import akka.stream.javadsl.Sink;\n+import akka.stream.javadsl.Source;\n+import akka.util.ByteString;\n+import org.junit.Ignore;\n+import org.junit.Test;\n+import scala.concurrent.ExecutionContextExecutor;\n+\n+import java.nio.file.Paths;\n+import java.util.Arrays;\n+import java.util.Collections;\n+import java.util.Optional;\n+import java.util.concurrent.CompletableFuture;\n+import java.util.concurrent.CompletionStage;\n+import java.util.concurrent.Executors;\n+import java.util.function.Function;\n+import java.util.function.Predicate;\n+import java.util.function.Supplier;\n+\n+public class BasicDirectivesExamplesTest extends JUnitRouteTest {\n+\n+  @Test\n+  public void testExtract() {\n+    //#extract\n+    final Route route = extract(ctx -> ctx.getRequest().getUri().toString().length(), len ->\n+      complete(\"The length of the request URI is \" + len)\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/abcdef\"))\n+      .assertEntity(\"The length of the request URI is 25\");\n+    //#extract\n+  }\n+\n+  @Test\n+  public void testExtractLog() {\n+    //#extractLog\n+    final Route route = extractLog(log -> {\n+      log.debug(\"I'm logging things in much detail..!\");\n+      return complete(\"It's amazing!\");\n+    });\n+\n+    // tests:\n+\n+    testRoute(route).run(HttpRequest.GET(\"/abcdef\"))\n+      .assertEntity(\"It's amazing!\");\n+    //#extractLog\n+  }\n+\n+  @Test\n+  public void testWithMaterializer() {\n+    //#withMaterializer\n+    final ActorMaterializerSettings settings = ActorMaterializerSettings.create(system());\n+    final ActorMaterializer special = ActorMaterializer.create(settings, system(), \"special\");\n+\n+    final Route sample = path(\"sample\", () ->\n+      extractMaterializer(mat ->\n+        onSuccess(() ->\n+          // explicitly use the materializer:\n+          Source.single(\"Materialized by \" + mat.hashCode() + \"!\")\n+            .runWith(Sink.head(), mat), str -> complete(str)\n+        )\n+      )\n+    );\n+\n+    final Route route = route(\n+      pathPrefix(\"special\", () ->\n+        withMaterializer(special, () -> sample) // `special` materializer will be used\n+      ),\n+      sample // default materializer will be used\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"Materialized by \" + materializer().hashCode()+ \"!\");\n+    testRoute(route).run(HttpRequest.GET(\"/special/sample\"))\n+      .assertEntity(\"Materialized by \" + special.hashCode()+ \"!\");\n+    //#withMaterializer\n+  }\n+\n+  @Test\n+  public void testExtractMaterializer() {\n+    //#extractMaterializer\n+    final Route route = path(\"sample\", () ->\n+      extractMaterializer(mat ->\n+        onSuccess(() ->\n+          // explicitly use the materializer:\n+          Source.single(\"Materialized by \" + mat.hashCode() + \"!\")\n+            .runWith(Sink.head(), mat), str -> complete(str)\n+        )\n+      )\n+    ); // default materializer will be used\n+\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"Materialized by \" + materializer().hashCode()+ \"!\");\n+    //#extractMaterializer\n+  }\n+\n+  @Test\n+  public void testWithExecutionContext() {\n+    //#withExecutionContext\n+\n+    final ExecutionContextExecutor special =\n+      ExecutionContexts.fromExecutor(Executors.newFixedThreadPool(1));\n+\n+    final Route sample = path(\"sample\", () ->\n+      extractExecutionContext(executor ->\n+        onSuccess(() ->\n+          CompletableFuture.supplyAsync(() ->\n+            \"Run on \" + executor.hashCode() + \"!\", executor\n+          ), str -> complete(str)\n+        )\n+      )\n+    );\n+\n+    final Route route = route(\n+      pathPrefix(\"special\", () ->\n+        withExecutionContext(special, () -> sample) // `special` execution context will be used\n+      ),\n+      sample // default execution context will be used\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"Run on \" + system().dispatcher().hashCode() + \"!\");\n+    testRoute(route).run(HttpRequest.GET(\"/special/sample\"))\n+      .assertEntity(\"Run on \" + special.hashCode() + \"!\");\n+    //#withExecutionContext\n+  }\n+\n+  @Test\n+  public void testExtractExecutionContext() {\n+    //#extractExecutionContext\n+    final Route route = path(\"sample\", () ->\n+      extractExecutionContext(executor ->\n+        onSuccess(() ->\n+          CompletableFuture.supplyAsync(() ->\n+            \"Run on \" + executor.hashCode() + \"!\", executor // uses the `executor` ExecutionContext\n+          ), str -> complete(str)\n+        )\n+      )\n+    );\n+\n+    //tests:\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"Run on \" + system().dispatcher().hashCode() + \"!\");\n+    //#extractExecutionContext\n+  }\n+\n+  @Test\n+  public void testWithLog() {\n+    //#withLog\n+    final LoggingAdapter special = Logging.getLogger(system(), \"SpecialRoutes\");\n+\n+    final Route sample = path(\"sample\", () ->\n+      extractLog(log -> {\n+        final String msg = \"Logging using \" + log + \"!\";\n+        log.debug(msg);\n+        return complete(msg);\n+      }\n+      )\n+    );\n+\n+    final Route route = route(\n+      pathPrefix(\"special\", () ->\n+        withLog(special, () -> sample)\n+      ),\n+      sample\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"Logging using \" + system().log() + \"!\");\n+    testRoute(route).run(HttpRequest.GET(\"/special/sample\"))\n+      .assertEntity(\"Logging using \" + special + \"!\");\n+    //#withLog\n+  }\n+\n+  @Ignore(\"Ignore compile-only test\")\n+  @Test\n+  public void testWithSettings() {\n+    //#withSettings\n+    final RoutingSettings special =(RoutingSettings) RoutingSettings.create(system().settings().config()).withFileIODispatcher(\"special-io-dispatcher\");\n+\n+    final Route sample = path(\"sample\", () -> {\n+      // internally uses the configured fileIODispatcher: ContentTypes.APPLICATION_JSON, source\n+      final Source<ByteString, Object> source =\n+        FileIO.fromPath(Paths.get(\"example.json\")).mapMaterializedValue(completionStage -> (Object) completionStage);\n+      return complete(\n+        HttpResponse.create().withEntity(HttpEntities.create(ContentTypes.APPLICATION_JSON, source))\n+      );\n+    });\n+\n+    final Route route = get(() ->\n+      route(\n+        pathPrefix(\"special\", () ->\n+          withSettings(special, () -> sample) // `special` file-io-dispatcher will be used to read the file\n+        ),\n+        sample // default file-io-dispatcher will be used to read the file\n+      )\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/special/sample\"))\n+      .assertEntity(\"{}\");\n+    testRoute(route).run(HttpRequest.GET(\"/sample\"))\n+      .assertEntity(\"{}\");\n+    //#withSettings\n+  }\n+\n+  @Test\n+  public void testMapResponse() {\n+    //#mapResponse\n+    final Route route = mapResponse(\n+      response -> response.withStatus(StatusCodes.BAD_GATEWAY),\n+      () -> complete(\"abc\")\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/abcdef?ghi=12\"))\n+      .assertStatusCode(StatusCodes.BAD_GATEWAY);\n+    //#mapResponse\n+  }\n+\n+  class ApiRoute {\n+\n+    private ActorSystem _system = null;\n+\n+    private LoggingAdapter log = null;\n+\n+    private HttpEntity nullJsonEntity = HttpEntities.create(ContentTypes.APPLICATION_JSON, \"{}\");\n+\n+    public ApiRoute(ActorSystem system) {\n+      _system = system;\n+      log = Logging.getLogger(system, \"ApiRoutes\");\n+    }\n+\n+    private HttpResponse nonSuccessToEmptyJsonEntity(HttpResponse response) {\n+      if (response.status().isSuccess()) {\n+        return response;\n+      } else {\n+        log.warning(\"Dropping response entity since response status code was: \" + response.status());\n+        return response.withEntity((ResponseEntity) nullJsonEntity);\n+      }\n+    }\n+\n+    /** Wrapper for all of our JSON API routes */\n+    private Route apiRoute(Supplier<Route> innerRoutes) {\n+      return mapResponse(this::nonSuccessToEmptyJsonEntity, innerRoutes);\n+    }\n+  }\n+\n+  @Test\n+  public void testMapResponseAdvanced() {\n+    //#mapResponse-advanced\n+    final ApiRoute api = new ApiRoute(system());\n+\n+    final Route route = api.apiRoute(() ->\n+      get(() -> complete(StatusCodes.INTERNAL_SERVER_ERROR))\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertEntity(\"{}\");\n+    //#mapResponse-advanced\n+  }\n+\n+  @Test\n+  public void testMapRouteResult() {\n+    //#mapRouteResult\n+    // this directive is a joke, don't do that :-)\n+    final Route route = mapRouteResult(r -> {\n+      if (r instanceof akka.http.scaladsl.server.RouteResult.Complete) {\n+        final HttpResponse response = ((akka.http.scaladsl.server.RouteResult.Complete) r).getResponse();\n+        return new akka.http.scaladsl.server.RouteResult.Complete(\n+          (akka.http.scaladsl.model.HttpResponse) response.withStatus(200)\n+        );\n+      } else {\n+        return r;\n+      }\n+    }, () -> complete(StatusCodes.ACCEPTED));\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertStatusCode(StatusCodes.OK);\n+    //#mapRouteResult\n+  }\n+\n+  @Test\n+  public void testMapRouteResultFuture() {\n+    //#mapRouteResultFuture\n+    final Route route = mapRouteResultFuture(cr ->\n+      cr.exceptionally(t -> {\n+        if (t instanceof IllegalArgumentException) {\n+          return new akka.http.scaladsl.server.RouteResult.Complete(\n+            (akka.http.scaladsl.model.HttpResponse)\n+              HttpResponse.create().withStatus(StatusCodes.INTERNAL_SERVER_ERROR));\n+        } else {\n+          return null;\n+        }\n+      }).thenApply(rr -> {\n+        if (rr instanceof akka.http.scaladsl.server.RouteResult.Complete) {\n+          final HttpResponse res = ((akka.http.scaladsl.server.RouteResult.Complete) rr).getResponse();\n+          return new akka.http.scaladsl.server.RouteResult.Complete(\n+            (akka.http.scaladsl.model.HttpResponse)\n+              res.addHeader(Server.create(ProductVersion.create(\"MyServer\", \"1.0\"))));\n+        } else {\n+          return rr;\n+        }\n+      }), () -> complete(\"Hello world!\"));\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertStatusCode(StatusCodes.OK)\n+      .assertHeaderExists(Server.create(ProductVersion.create(\"MyServer\", \"1.0\")));\n+    //#mapRouteResultFuture\n+  }\n+\n+//  @Test\n+//  public void testMapRouteResult() {\n+//    //#0mapRouteResult\n+//    mapRouteResult(result ->)\n+//    //#0mapRouteResult\n+//  }\n+\n+  @Test\n+  public void testMapResponseEntity() {\n+    //#mapResponseEntity\n+    final Route route = mapResponseEntity(entity -> {\n+      if (entity instanceof HttpEntity.Strict) {\n+        final HttpEntity.Strict strict = (HttpEntity.Strict) entity;\n+        return HttpEntities.create(strict.getContentType(), ByteString.fromString(\"test\").$plus$plus(strict.getData()));\n+      } else {\n+        throw new IllegalStateException(\"Unexpected entity type\");\n+      }\n+    }, () -> complete(\"abc\"));\n+\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertEntity(\"testabc\");\n+    //#mapResponseEntity\n+  }\n+\n+  @Test  public void testMapResponseHeaders() {\n+    //#mapResponseHeaders\n+    // adds all request headers to the response\n+    final Route echoRequestHeaders = extract(\n+      ctx -> ctx.getRequest().getHeaders(),\n+      headers -> respondWithHeaders(headers, () -> complete(\"test\"))\n+    );\n+\n+    final Route route = mapResponseHeaders(headers -> {\n+      headers.removeIf(header -> header.lowercaseName().equals(\"id\"));\n+      return headers;\n+    }, () -> echoRequestHeaders);\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\").addHeaders(\n+      Arrays.asList(RawHeader.create(\"id\", \"12345\"),RawHeader.create(\"id2\", \"67890\"))))\n+      .assertHeaderKindNotExists(\"id\")\n+      .assertHeaderExists(\"id2\", \"67890\");\n+    //#mapResponseHeaders\n+  }\n+\n+  @Ignore(\"Not implemented yet\")\n+  @Test\n+  public void testMapInnerRoute() {\n+    //#mapInnerRoute\n+    // TODO: implement mapInnerRoute\n+    //#mapInnerRoute\n+  }\n+\n+  @Test\n+  public void testMapRejections() {\n+    //#mapRejections\n+    // ignore any rejections and replace them by AuthorizationFailedRejection\n+    final Route route = mapRejections(\n+      rejections -> Collections.singletonList((Rejection) Rejections.authorizationFailed()),\n+      () -> path(\"abc\", () -> complete(\"abc\"))\n+    );\n+\n+    // tests:\n+    runRouteUnSealed(route, HttpRequest.GET(\"/\"))\n+      .assertRejections(Rejections.authorizationFailed());\n+    testRoute(route).run(HttpRequest.GET(\"/abc\"))\n+      .assertStatusCode(StatusCodes.OK);\n+    //#mapRejections\n+  }\n+\n+  private boolean existsAuthenticationFailedRejection(Iterable<Rejection> rejections) {\n+    for (Rejection r : rejections) {\n+      if (r instanceof akka.http.scaladsl.server.AuthenticationFailedRejection) {\n+        return true;\n+      }\n+    }\n+    return false;\n+  }\n+\n+  private Optional<Object> neverAuth(Optional<ProvidedCredentials> creds) {\n+    return Optional.empty();\n+  }\n+\n+  private Optional<Object> alwaysAuth(Optional<ProvidedCredentials> creds) {\n+    return Optional.of(\"id\");\n+  }\n+\n+  @Test\n+  public void testRecoverRejections() {\n+    //#recoverRejections\n+    final Route originalRoute = pathPrefix(\"auth\", () ->\n+      route(\n+        path(\"never\", () ->\n+          authenticateBasic(\"my-realm\", this::neverAuth, obj ->  complete(\"Welcome to the bat-cave!\"))\n+        ),\n+        path(\"always\", () ->\n+          authenticateBasic(\"my-realm\", this::alwaysAuth, obj -> complete(\"Welcome to the secret place!\"))\n+        )\n+      )\n+    );\n+\n+    final Route route = recoverRejections(rejections -> {\n+      if (existsAuthenticationFailedRejection(rejections)) {\n+        return new akka.http.scaladsl.server.RouteResult.Complete(\n+          (akka.http.scaladsl.model.HttpResponse)\n+            HttpResponse.create().withEntity(\"Nothing to see here, move along.\"));\n+      } else if (!rejections.iterator().hasNext()) { // see \"Empty Rejections\" for more details\n+        return new akka.http.scaladsl.server.RouteResult.Complete(\n+          (akka.http.scaladsl.model.HttpResponse)\n+            HttpResponse.create().withStatus(StatusCodes.NOT_FOUND).withEntity(\"Literally nothing to see here.\"));\n+      } else {\n+        return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+      }\n+    }, () -> originalRoute);\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/auth/never\"))\n+      .assertStatusCode(StatusCodes.OK)\n+      .assertEntity(\"Nothing to see here, move along.\");\n+    testRoute(route).run(HttpRequest.GET(\"/auth/always\"))\n+      .assertStatusCode(StatusCodes.OK)\n+      .assertEntity(\"Welcome to the secret place!\");\n+    testRoute(route).run(HttpRequest.GET(\"/auth/does_not_exist\"))\n+      .assertStatusCode(StatusCodes.NOT_FOUND)\n+      .assertEntity(\"Literally nothing to see here.\");\n+    //#recoverRejections\n+  }\n+\n+  @Test\n+  public void testRecoverRejectionsWith() {\n+    //#recoverRejectionsWith\n+    final Route originalRoute = pathPrefix(\"auth\", () ->\n+      path(\"never\", () ->\n+        authenticateBasic(\"my-realm\", this::neverAuth, obj ->  complete(\"Welcome to the bat-cave!\"))\n+      )\n+    );\n+\n+    final Route route = recoverRejectionsWith(rejections -> CompletableFuture.supplyAsync(() -> {\n+        if (existsAuthenticationFailedRejection(rejections)) {\n+          return new akka.http.scaladsl.server.RouteResult.Complete(\n+            (akka.http.scaladsl.model.HttpResponse)\n+              HttpResponse.create().withEntity(\"Nothing to see here, move along.\"));\n+        } else {\n+          return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+        }\n+    }), () -> originalRoute);\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/auth/never\"))\n+      .assertStatusCode(StatusCodes.OK)\n+      .assertEntity(\"Nothing to see here, move along.\");\n+    //#recoverRejectionsWith\n+  }\n+\n+  @Test\n+  public void testMapRequest() {\n+    //#mapRequest\n+    final Route route = mapRequest(req ->\n+      req.withMethod(HttpMethods.POST), () ->\n+      extractRequest(req -> complete(\"The request method was \" + req.method().name()))\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertEntity(\"The request method was POST\");\n+    //#mapRequest\n+  }\n+\n+  @Test\n+  public void testMapRequestContext() {\n+    //#mapRequestContext\n+    final Route route = mapRequestContext(ctx ->\n+      ctx.withRequest(HttpRequest.create().withMethod(HttpMethods.POST)), () ->\n+      extractRequest(req -> complete(req.method().value()))\n+    );\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/abc/def/ghi\"))\n+      .assertEntity(\"POST\");\n+    //#mapRequestContext\n+  }\n+\n+  @Test\n+  public void testMapRouteResult0() {\n+    //#mapRouteResult\n+    final Route route = mapRouteResult(rr -> {\n+      final java.util.List<Rejection> rejections = Collections.singletonList(Rejections.authorizationFailed());\n+      return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+    }, () -> complete(\"abc\"));\n+\n+    // tests:\n+    runRouteUnSealed(route, HttpRequest.GET(\"/\"))\n+      .assertRejections(Rejections.authorizationFailed());\n+    //#mapRouteResult\n+  }\n+\n+  public static final class MyCustomRejection implements akka.http.scaladsl.server.Rejection {}\n+\n+  @Test\n+  public void testMapRouteResultPF() {\n+    //#mapRouteResultPF\n+    final Route route = mapRouteResultPF(\n+      new PFBuilder<RouteResult, RouteResult>()\n+        .match(Rejected.class, rejected -> {\n+          final java.util.List<Rejection> rejections = Collections.singletonList(Rejections.authorizationFailed());\n+          return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+        }).build(), () -> reject(new MyCustomRejection()));\n+\n+    // tests:\n+    runRouteUnSealed(route, HttpRequest.GET(\"/\"))\n+      .assertRejections(Rejections.authorizationFailed());\n+    //#mapRouteResultPF\n+  }\n+\n+  @Test\n+  public void testMapRouteResultWithPF() {\n+    //#mapRouteResultWithPF\n+    final Route route = mapRouteResultWithPF(\n+      new PFBuilder<RouteResult, CompletionStage<RouteResult>>()\n+      .match(Rejected.class, rejected -> CompletableFuture.supplyAsync(() -> {\n+        final java.util.List<Rejection> rejections = Collections.singletonList(Rejections.authorizationFailed());\n+        return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+      })\n+    ).build(), () -> reject(new MyCustomRejection()));\n+\n+    // tests:\n+    runRouteUnSealed(route, HttpRequest.GET(\"/\"))\n+      .assertRejections(Rejections.authorizationFailed());\n+    //#mapRouteResultWithPF\n+  }\n+\n+  @Test\n+  public void testMapRouteResultWith() {\n+    //#mapRouteResultWith\n+    final Route route = mapRouteResultWith(rr -> CompletableFuture.supplyAsync(() -> {\n+      if (rr instanceof Rejected) {\n+        final java.util.List<Rejection> rejections = Collections.singletonList(Rejections.authorizationFailed());\n+        return new akka.http.scaladsl.server.RouteResult.Rejected(Util.convertIterable(rejections));\n+      } else {\n+        return rr;\n+      }\n+    }), () -> reject(new MyCustomRejection()));\n+\n+    // tests:\n+    runRouteUnSealed(route, HttpRequest.GET(\"/\"))\n+      .assertRejections(Rejections.authorizationFailed());\n+    //#mapRouteResultWith\n+  }\n+\n+  @Test\n+  public void testPass() {\n+    //#pass\n+    final Route route = pass(() -> complete(\"abc\"));\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertEntity(\"abc\");\n+    //#pass\n+  }\n+\n+  private Route providePrefixedStringRoute(String value) {\n+    return provide(\"prefix:\" + value, v -> complete(v));\n+  }\n+\n+  @Test\n+  public void testProvide() {\n+    //#provide\n+    final Route route = providePrefixedStringRoute(\"test\");\n+\n+    // tests:\n+    testRoute(route).run(HttpRequest.GET(\"/\"))\n+      .assertEntity(\"prefix:test\");\n+    //#provide\n+  }\n+\n+  private Predicate<Rejection> isMethodRejection() {\n+    return p -> {\n+      if (p instanceof MethodRejection) {","path":"akka-docs/rst/java/code/docs/http/javadsl/server/directives/BasicDirectivesExamplesTest.java","position":623,"original_position":623,"commit_id":"3c4f0a2885830f3d6abc6f80b574f90938e74edb","original_commit_id":"3c4f0a2885830f3d6abc6f80b574f90938e74edb","user":{"login":"johanandren","id":666915,"avatar_url":"https://avatars.githubusercontent.com/u/666915?v=3","gravatar_id":"","url":"https://api.github.com/users/johanandren","html_url":"https://github.com/johanandren","followers_url":"https://api.github.com/users/johanandren/followers","following_url":"https://api.github.com/users/johanandren/following{/other_user}","gists_url":"https://api.github.com/users/johanandren/gists{/gist_id}","starred_url":"https://api.github.com/users/johanandren/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johanandren/subscriptions","organizations_url":"https://api.github.com/users/johanandren/orgs","repos_url":"https://api.github.com/users/johanandren/repos","events_url":"https://api.github.com/users/johanandren/events{/privacy}","received_events_url":"https://api.github.com/users/johanandren/received_events","type":"User","site_admin":false},"body":"return instance of boolean result rather than explicit true/false ","created_at":"2016-05-29T22:54:51Z","updated_at":"2016-05-29T22:54:51Z","html_url":"https://github.com/akka/akka/pull/20647#discussion_r65013366","pull_request_url":"https://api.github.com/repos/akka/akka/pulls/20647","_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/comments/65013366"},"html":{"href":"https://github.com/akka/akka/pull/20647#discussion_r65013366"},"pull_request":{"href":"https://api.github.com/repos/akka/akka/pulls/20647"}}},"pull_request":{"url":"https://api.github.com/repos/akka/akka/pulls/20647","id":71765307,"html_url":"https://github.com/akka/akka/pull/20647","diff_url":"https://github.com/akka/akka/pull/20647.diff","patch_url":"https://github.com/akka/akka/pull/20647.patch","issue_url":"https://api.github.com/repos/akka/akka/issues/20647","number":20647,"state":"open","locked":false,"title":"example snippet for akka http java dsl: BasicDirectives","user":{"login":"Hawstein","id":2238491,"avatar_url":"https://avatars.githubusercontent.com/u/2238491?v=3","gravatar_id":"","url":"https://api.github.com/users/Hawstein","html_url":"https://github.com/Hawstein","followers_url":"https://api.github.com/users/Hawstein/followers","following_url":"https://api.github.com/users/Hawstein/following{/other_user}","gists_url":"https://api.github.com/users/Hawstein/gists{/gist_id}","starred_url":"https://api.github.com/users/Hawstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hawstein/subscriptions","organizations_url":"https://api.github.com/users/Hawstein/orgs","repos_url":"https://api.github.com/users/Hawstein/repos","events_url":"https://api.github.com/users/Hawstein/events{/privacy}","received_events_url":"https://api.github.com/users/Hawstein/received_events","type":"User","site_admin":false},"body":"Ref #20466\r\n\r\n\r\nFinished except for the `testCancelRejection`, `testCancelRejections` and `testMapInnerRoute`.\r\n\r\nFor `testCancelRejection/testCancelRejections`, I had try several ways to make it pass the unit test but it always threw the following exception:\r\n\r\n```scala\r\n[info] - testCancelRejection *** FAILED ***\r\n[info]   java.lang.AssertionError: Expected rejections [], but rejected with [MethodRejection(HttpMethod(POST)),TransformationRejection(<function1>)] instead.\r\n[info]   at org.junit.Assert.fail(Assert.java:88)\r\n......\r\n```\r\n\r\nIt seems like that `TransformationRejection` causes the problem. Codes are written as follow for testing cancelRejection:\r\n\r\n```scala\r\n@Ignore(\"Test failed\")\r\n@Test\r\npublic void testCancelRejection() {\r\n  //#cancelRejection\r\n  final Route route = cancelRejection(Rejections.method(HttpMethods.POST), () ->\r\n    post(() ->  complete(\"Result\"))\r\n  );\r\n\r\n  // tests:\r\n  runRouteUnSealed(route, HttpRequest.GET(\"/\"))\r\n    .assertRejections();\r\n  //#cancelRejection\r\n}\r\n```\r\n\r\nFor `mapInnerRoute`, since Route in Java DSL is just a trait instead of an alias for `RequestContext ⇒ Future[RouteResult]` in Scala DSL, I can not figure out a Java version translation for the following codes:\r\n\r\n```scala\r\nval completeWithInnerException =\r\n  mapInnerRoute { route =>\r\n    ctx =>\r\n      try {\r\n        route(ctx)\r\n      } catch {\r\n        case NonFatal(e) => ctx.complete(s\"Got ${e.getClass.getSimpleName} '${e.getMessage}'\")\r\n      }\r\n  }\r\n```\r\n\r\nAnyone has some clues and help me out? Thanks!\r\n\r\nP.S. Besides the above cases(I put an Ignore annotation on them), all the other cases have passed the unit test.","created_at":"2016-05-27T19:59:24Z","updated_at":"2016-05-29T22:54:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"81ab985f901e9734fcb775a4544312fc4119e675","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/akka/akka/pulls/20647/commits","review_comments_url":"https://api.github.com/repos/akka/akka/pulls/20647/comments","review_comment_url":"https://api.github.com/repos/akka/akka/pulls/comments{/number}","comments_url":"https://api.github.com/repos/akka/akka/issues/20647/comments","statuses_url":"https://api.github.com/repos/akka/akka/statuses/3c4f0a2885830f3d6abc6f80b574f90938e74edb","head":{"label":"Hawstein:akka-http-java-dsl-example-snippets","ref":"akka-http-java-dsl-example-snippets","sha":"3c4f0a2885830f3d6abc6f80b574f90938e74edb","user":{"login":"Hawstein","id":2238491,"avatar_url":"https://avatars.githubusercontent.com/u/2238491?v=3","gravatar_id":"","url":"https://api.github.com/users/Hawstein","html_url":"https://github.com/Hawstein","followers_url":"https://api.github.com/users/Hawstein/followers","following_url":"https://api.github.com/users/Hawstein/following{/other_user}","gists_url":"https://api.github.com/users/Hawstein/gists{/gist_id}","starred_url":"https://api.github.com/users/Hawstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hawstein/subscriptions","organizations_url":"https://api.github.com/users/Hawstein/orgs","repos_url":"https://api.github.com/users/Hawstein/repos","events_url":"https://api.github.com/users/Hawstein/events{/privacy}","received_events_url":"https://api.github.com/users/Hawstein/received_events","type":"User","site_admin":false},"repo":{"id":47159849,"name":"akka","full_name":"Hawstein/akka","owner":{"login":"Hawstein","id":2238491,"avatar_url":"https://avatars.githubusercontent.com/u/2238491?v=3","gravatar_id":"","url":"https://api.github.com/users/Hawstein","html_url":"https://github.com/Hawstein","followers_url":"https://api.github.com/users/Hawstein/followers","following_url":"https://api.github.com/users/Hawstein/following{/other_user}","gists_url":"https://api.github.com/users/Hawstein/gists{/gist_id}","starred_url":"https://api.github.com/users/Hawstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hawstein/subscriptions","organizations_url":"https://api.github.com/users/Hawstein/orgs","repos_url":"https://api.github.com/users/Hawstein/repos","events_url":"https://api.github.com/users/Hawstein/events{/privacy}","received_events_url":"https://api.github.com/users/Hawstein/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Hawstein/akka","description":"Akka Project","fork":true,"url":"https://api.github.com/repos/Hawstein/akka","forks_url":"https://api.github.com/repos/Hawstein/akka/forks","keys_url":"https://api.github.com/repos/Hawstein/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Hawstein/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Hawstein/akka/teams","hooks_url":"https://api.github.com/repos/Hawstein/akka/hooks","issue_events_url":"https://api.github.com/repos/Hawstein/akka/issues/events{/number}","events_url":"https://api.github.com/repos/Hawstein/akka/events","assignees_url":"https://api.github.com/repos/Hawstein/akka/assignees{/user}","branches_url":"https://api.github.com/repos/Hawstein/akka/branches{/branch}","tags_url":"https://api.github.com/repos/Hawstein/akka/tags","blobs_url":"https://api.github.com/repos/Hawstein/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Hawstein/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Hawstein/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/Hawstein/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Hawstein/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/Hawstein/akka/languages","stargazers_url":"https://api.github.com/repos/Hawstein/akka/stargazers","contributors_url":"https://api.github.com/repos/Hawstein/akka/contributors","subscribers_url":"https://api.github.com/repos/Hawstein/akka/subscribers","subscription_url":"https://api.github.com/repos/Hawstein/akka/subscription","commits_url":"https://api.github.com/repos/Hawstein/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/Hawstein/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/Hawstein/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/Hawstein/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/Hawstein/akka/contents/{+path}","compare_url":"https://api.github.com/repos/Hawstein/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Hawstein/akka/merges","archive_url":"https://api.github.com/repos/Hawstein/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Hawstein/akka/downloads","issues_url":"https://api.github.com/repos/Hawstein/akka/issues{/number}","pulls_url":"https://api.github.com/repos/Hawstein/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/Hawstein/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/Hawstein/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Hawstein/akka/labels{/name}","releases_url":"https://api.github.com/repos/Hawstein/akka/releases{/id}","deployments_url":"https://api.github.com/repos/Hawstein/akka/deployments","created_at":"2015-12-01T02:20:41Z","updated_at":"2016-05-18T19:29:31Z","pushed_at":"2016-05-27T19:54:29Z","git_url":"git://github.com/Hawstein/akka.git","ssh_url":"git@github.com:Hawstein/akka.git","clone_url":"https://github.com/Hawstein/akka.git","svn_url":"https://github.com/Hawstein/akka","homepage":"http://akka.io","size":192681,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"akka:master","ref":"master","sha":"e2c6948c1592e423097a6c59367e76c7d2fdfc4e","user":{"login":"akka","id":1496237,"avatar_url":"https://avatars.githubusercontent.com/u/1496237?v=3","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"repo":{"id":130013,"name":"akka","full_name":"akka/akka","owner":{"login":"akka","id":1496237,"avatar_url":"https://avatars.githubusercontent.com/u/1496237?v=3","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akka/akka","description":"Akka Project","fork":false,"url":"https://api.github.com/repos/akka/akka","forks_url":"https://api.github.com/repos/akka/akka/forks","keys_url":"https://api.github.com/repos/akka/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akka/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akka/akka/teams","hooks_url":"https://api.github.com/repos/akka/akka/hooks","issue_events_url":"https://api.github.com/repos/akka/akka/issues/events{/number}","events_url":"https://api.github.com/repos/akka/akka/events","assignees_url":"https://api.github.com/repos/akka/akka/assignees{/user}","branches_url":"https://api.github.com/repos/akka/akka/branches{/branch}","tags_url":"https://api.github.com/repos/akka/akka/tags","blobs_url":"https://api.github.com/repos/akka/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akka/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akka/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/akka/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akka/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/akka/akka/languages","stargazers_url":"https://api.github.com/repos/akka/akka/stargazers","contributors_url":"https://api.github.com/repos/akka/akka/contributors","subscribers_url":"https://api.github.com/repos/akka/akka/subscribers","subscription_url":"https://api.github.com/repos/akka/akka/subscription","commits_url":"https://api.github.com/repos/akka/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/akka/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/akka/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/akka/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/akka/akka/contents/{+path}","compare_url":"https://api.github.com/repos/akka/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akka/akka/merges","archive_url":"https://api.github.com/repos/akka/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akka/akka/downloads","issues_url":"https://api.github.com/repos/akka/akka/issues{/number}","pulls_url":"https://api.github.com/repos/akka/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/akka/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/akka/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akka/akka/labels{/name}","releases_url":"https://api.github.com/repos/akka/akka/releases{/id}","deployments_url":"https://api.github.com/repos/akka/akka/deployments","created_at":"2009-02-16T12:51:54Z","updated_at":"2016-05-29T18:42:55Z","pushed_at":"2016-05-29T20:55:40Z","git_url":"git://github.com/akka/akka.git","ssh_url":"git@github.com:akka/akka.git","clone_url":"https://github.com/akka/akka.git","svn_url":"https://github.com/akka/akka","homepage":"http://akka.io","size":232433,"stargazers_count":5572,"watchers_count":5572,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1736,"mirror_url":null,"open_issues_count":701,"forks":1736,"open_issues":701,"watchers":5572,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/20647"},"html":{"href":"https://github.com/akka/akka/pull/20647"},"issue":{"href":"https://api.github.com/repos/akka/akka/issues/20647"},"comments":{"href":"https://api.github.com/repos/akka/akka/issues/20647/comments"},"review_comments":{"href":"https://api.github.com/repos/akka/akka/pulls/20647/comments"},"review_comment":{"href":"https://api.github.com/repos/akka/akka/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/akka/akka/pulls/20647/commits"},"statuses":{"href":"https://api.github.com/repos/akka/akka/statuses/3c4f0a2885830f3d6abc6f80b574f90938e74edb"}}}}
{"actor":{"display_login":"johanandren"}}