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.client.lib.batch;
20  
21  import java.util.List;
22  import java.util.UUID;
23  import javax.ws.rs.core.HttpHeaders;
24  import javax.ws.rs.core.MediaType;
25  import org.apache.cxf.configuration.jsse.TLSClientParameters;
26  import org.apache.cxf.jaxrs.client.Client;
27  import org.apache.cxf.jaxrs.client.ClientConfiguration;
28  import org.apache.cxf.jaxrs.client.WebClient;
29  import org.apache.cxf.transport.http.HTTPConduit;
30  import org.apache.syncope.common.rest.api.Preference;
31  import org.apache.syncope.common.rest.api.RESTHeaders;
32  import org.apache.syncope.common.rest.api.batch.BatchPayloadGenerator;
33  import org.apache.syncope.common.rest.api.batch.BatchRequestItem;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  /**
38   * Encapsulates the Batch request management via CXF Proxy Client.
39   */
40  public class BatchRequest {
41  
42      private static final Logger LOG = LoggerFactory.getLogger(BatchRequest.class);
43  
44      private final MediaType mediaType;
45  
46      private final String jwt;
47  
48      private final String address;
49  
50      private final List<?> providers;
51  
52      private final TLSClientParameters tlsClientParameters;
53  
54      private BatchClientFactoryBean bcfb;
55  
56      public BatchRequest(
57              final MediaType mediaType,
58              final String address,
59              final List<?> providers,
60              final String jwt,
61              final TLSClientParameters tlsClientParameters) {
62  
63          this.mediaType = mediaType;
64          this.jwt = jwt;
65          this.address = address;
66          this.providers = providers;
67          this.tlsClientParameters = tlsClientParameters;
68          initBatchClientFactoryBean();
69      }
70  
71      private void initBatchClientFactoryBean() {
72          this.bcfb = new BatchClientFactoryBean();
73          this.bcfb.setAddress(address);
74          this.bcfb.setProviders(providers);
75      }
76  
77      public <T> T getService(final Class<T> serviceClass) {
78          bcfb.setServiceClass(serviceClass);
79          T serviceInstance = bcfb.create(serviceClass);
80  
81          Client client = WebClient.client(serviceInstance);
82          client.type(mediaType).accept(mediaType);
83  
84          return serviceInstance;
85      }
86  
87      public List<BatchRequestItem> getItems() {
88          return bcfb.getBatchRequestItems();
89      }
90  
91      /**
92       * Sends the current request, with items accumulated by invoking methods on proxies obtained via
93       * {@link #getService(java.lang.Class)}, to the Batch service, and awaits for synchronous response.
94       * It also clears out the accumulated items, in case of reuse of this instance for subsequent requests.
95       *
96       * @return batch response
97       */
98      public BatchResponse commit() {
99          return commit(false);
100     }
101 
102     /**
103      * Sends the current request, with items accumulated by invoking methods on proxies obtained via
104      * {@link #getService(java.lang.Class)}, to the Batch service, and awaits for a synchronous or asynchronous
105      * response, depending on the {@code async} parameter.
106      * It also clears out the accumulated items, in case of reuse of this instance for subsequent requests.
107      *
108      * @param async whether asynchronous Batch process is requested, or not
109      * @return batch response
110      */
111     public BatchResponse commit(final boolean async) {
112         String boundary = "--batch_" + UUID.randomUUID().toString();
113 
114         WebClient webClient = WebClient.create(bcfb.getAddress()).path("batch").
115                 header(HttpHeaders.AUTHORIZATION, "Bearer " + jwt).
116                 type(RESTHeaders.multipartMixedWith(boundary.substring(2)));
117         if (async) {
118             webClient.header(RESTHeaders.PREFER, Preference.RESPOND_ASYNC);
119         }
120         if (tlsClientParameters != null) {
121             ClientConfiguration config = WebClient.getConfig(webClient);
122             HTTPConduit httpConduit = (HTTPConduit) config.getConduit();
123             httpConduit.setTlsClientParameters(tlsClientParameters);
124         }
125 
126         String body = BatchPayloadGenerator.generate(bcfb.getBatchRequestItems(), boundary);
127         LOG.debug("Batch request body:\n{}", body);
128 
129         initBatchClientFactoryBean();
130 
131         return new BatchResponse(boundary, jwt, tlsClientParameters, webClient.post(body));
132     }
133 }