View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.sra.predicates;
20  
21  import com.fasterxml.jackson.databind.JsonNode;
22  import java.util.List;
23  import org.springframework.cloud.gateway.handler.AsyncPredicate;
24  import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
25  import org.springframework.http.codec.HttpMessageReader;
26  import org.springframework.web.reactive.function.server.HandlerStrategies;
27  import org.springframework.web.reactive.function.server.ServerRequest;
28  import org.springframework.web.server.ServerWebExchange;
29  import reactor.core.publisher.Mono;
30  
31  /**
32   * Inspired by {@link org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory}.
33   */
34  public class BodyPropertyMatchingRoutePredicateFactory extends CustomRoutePredicateFactory {
35  
36      private static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
37  
38      private static final List<HttpMessageReader<?>> MESSAGE_READERS =
39              HandlerStrategies.withDefaults().messageReaders();
40  
41      @Override
42      public AsyncPredicate<ServerWebExchange> applyAsync(final Config config) {
43          return exchange -> {
44              JsonNode cachedBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
45              if (cachedBody == null) {
46                  return ServerWebExchangeUtils.cacheRequestBodyAndRequest(
47                          exchange, serverHttpRequest -> ServerRequest.create(
48                                  exchange.mutate().request(serverHttpRequest).build(), MESSAGE_READERS).
49                                  bodyToMono(JsonNode.class).
50                                  doOnNext(objectValue -> exchange.getAttributes().
51                                  put(CACHE_REQUEST_BODY_OBJECT_KEY, objectValue)).
52                                  map(objectValue -> objectValue.has(config.getData())));
53              } else {
54                  return Mono.just(cachedBody.has(config.getData()));
55              }
56          };
57      }
58  }