Skip to content

Commit cca263d

Browse files
committed
✨ Updated AdaptiveFormsService to use RestClient
1 parent 1f24d91 commit cca263d

5 files changed

Lines changed: 260 additions & 486 deletions

File tree

rest-services/client/src/main/java/com/_4point/aem/docservices/rest_services/client/RestClient.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public record ContentType(String contentType) {
2727
public static final ContentType APPLICATION_PDF = ContentType.of("application/pdf");
2828
public static final ContentType APPLICATION_XDP = ContentType.of("application/vnd.adobe.xdp+xml");
2929
public static final ContentType APPLICATION_XML = ContentType.of("application/xml");
30+
public static final ContentType APPLICATION_JSON = ContentType.of("application/json");
3031
public static final ContentType TEXT_PLAIN = ContentType.of("text/plain");
3132
public static final ContentType TEXT_HTML = ContentType.of("text/html");
3233
public static final ContentType APPLICATION_OCTET_STREAM = ContentType.of("application/octet-stream");
@@ -193,6 +194,13 @@ public interface Builder {
193194
*/
194195
public GetRequest.Builder getRequestBuilder();
195196

197+
/**
198+
* Returns a builder that is used to construct a GET request.
199+
*
200+
* @param additionalPath - additional path segments
201+
* @return
202+
*/
203+
public GetRequest.Builder getRequestBuilder(String additionalPath);
196204

197205
/**
198206
* A response from the AEM Rest Service

rest-services/client/src/main/java/com/_4point/aem/docservices/rest_services/client/af/AdaptiveFormsService.java

Lines changed: 56 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
11
package com._4point.aem.docservices.rest_services.client.af;
22

3-
import java.io.BufferedReader;
43
import java.io.IOException;
54
import java.io.InputStream;
6-
import java.io.InputStreamReader;
5+
import java.io.UncheckedIOException;
76
import java.nio.file.Path;
87
import java.util.List;
98
import java.util.Objects;
109
import java.util.function.Function;
1110
import java.util.function.Supplier;
1211

13-
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
14-
12+
import com._4point.aem.docservices.rest_services.client.RestClient;
13+
import com._4point.aem.docservices.rest_services.client.RestClient.ContentType;
14+
import com._4point.aem.docservices.rest_services.client.RestClient.GetRequest;
15+
import com._4point.aem.docservices.rest_services.client.RestClient.MultipartPayload;
16+
import com._4point.aem.docservices.rest_services.client.RestClient.Response;
17+
import com._4point.aem.docservices.rest_services.client.RestClient.RestClientException;
18+
import com._4point.aem.docservices.rest_services.client.helpers.AemConfig;
1519
import com._4point.aem.docservices.rest_services.client.helpers.AemServerType;
1620
import com._4point.aem.docservices.rest_services.client.helpers.Builder;
1721
import com._4point.aem.docservices.rest_services.client.helpers.BuilderImpl;
1822
import com._4point.aem.docservices.rest_services.client.helpers.RestServicesServiceAdapter;
23+
import com._4point.aem.docservices.rest_services.client.helpers.BuilderImpl.TriFunction;
1924
import com._4point.aem.fluentforms.api.Document;
2025
import com._4point.aem.fluentforms.api.PathOrUrl;
2126
import com._4point.aem.fluentforms.impl.SimpleDocumentFactoryImpl;
2227

23-
import jakarta.ws.rs.client.Client;
24-
import jakarta.ws.rs.client.Invocation;
25-
import jakarta.ws.rs.client.WebTarget;
26-
import jakarta.ws.rs.core.HttpHeaders;
27-
import jakarta.ws.rs.core.MediaType;
28-
import jakarta.ws.rs.core.Response;
29-
import jakarta.ws.rs.core.Response.Status.Family;
30-
import jakarta.ws.rs.core.Response.StatusType;
31-
3228
/**
3329
* Adaptive Forms Service for rendering Adaptive Forms. The forms can be pre-populated with data by passing in an XML data file.
3430
*
3531
*/
3632
public class AdaptiveFormsService extends RestServicesServiceAdapter {
33+
private static final String AF_FORMS_PATH = "/content/forms/af";
3734
// private static final String RENDER_ADAPTIVE_FORM_PATH = "/services/AdaptiveForms/RenderAdaptiveForm"; // Not currently being used.
3835
// private static final String TEMPLATE_PARAM = "template";
3936
private static final String DATA_CACHE_SERVICE_NAME = "DataServices";
@@ -42,9 +39,13 @@ public class AdaptiveFormsService extends RestServicesServiceAdapter {
4239
private static final String DATA_SERVICE_DATA_PARAM = "Data";
4340

4441
private final Function<InputStream, InputStream> responseFilter;
42+
private final RestClient dataCacheRestClient;
43+
private final RestClient afRestClient;
4544

46-
public AdaptiveFormsService(WebTarget baseTarget, Supplier<String> correlationIdFn, AemServerType aemServerType, Function<InputStream, InputStream> responseFilter) {
47-
super(baseTarget, correlationIdFn, aemServerType);
45+
AdaptiveFormsService(BuilderImpl builder, Supplier<String> correlationIdFn, Function<InputStream, InputStream> responseFilter) {
46+
super(correlationIdFn);
47+
this.dataCacheRestClient = builder.createClient(DATA_CACHE_SERVICE_NAME, DATA_CACHE_METHOD_NAME);
48+
this.afRestClient = builder.createClient(AF_FORMS_PATH);
4849
this.responseFilter = responseFilter;
4950
}
5051

@@ -101,78 +102,60 @@ public Document renderAdaptiveForm(PathOrUrl template, Document data) throws Ada
101102
throw new AdaptiveFormsServiceException("Only relative paths are supported");
102103
}
103104

104-
WebTarget target = baseTarget.path(constructAfPath(template.convertRelativePathToRelativeUrl()))
105-
.queryParam("wcmmode", "disabled");
105+
String afPath = constructAfPath(template.convertRelativePathToRelativeUrl());
106+
GetRequest.Builder builder = afRestClient.getRequestBuilder(afPath);
107+
builder = builder.queryParam("wcmmode", "disabled");
106108

107109
if (!data.isEmpty()) {
108-
target = target.queryParam(DATA_REF_PARAM, generateDataRefParam(postDataToDataCacheService(data)));
110+
builder = builder.queryParam(DATA_REF_PARAM, generateDataRefParam(postDataToDataCacheService(data)));
109111
}
110112

111-
Invocation.Builder invokeBuilder = target.request()
112-
.accept(MediaType.TEXT_HTML_TYPE);
113+
GetRequest getRequest = builder.build();
113114

114-
if (this.correlationIdFn != null) {
115-
invokeBuilder.header(CORRELATION_ID_HTTP_HDR, this.correlationIdFn.get());
116-
}
117-
118-
Response result = invokeBuilder.get();
119-
120115
try {
121-
return responseFilter == null ? responseToDoc(result, MediaType.TEXT_HTML_TYPE, msg->new AdaptiveFormsServiceException(msg))
122-
: responseToDoc(result, MediaType.TEXT_HTML_TYPE, msg->new AdaptiveFormsServiceException(msg), responseFilter);
123-
} catch (IOException e) {
124-
String msg = e.getMessage();
125-
throw new AdaptiveFormsServiceException("Error while reading Adaptive Form (" + (msg == null ? e.getClass().getName() : msg) + ").", e );
116+
return getRequest.getFromServer(ContentType.TEXT_HTML)
117+
.map(responseFilter == null ? d->responseToDoc(d) : d->responseToDoc(d, responseFilter))
118+
.orElseThrow();
119+
} catch (RestClientException e) {
120+
throw new AdaptiveFormsServiceException("Error while performing GET to server (" + afRestClient.target() + ").", e);
126121
}
127122
}
128123

129124
private String constructAfPath(String formName) {
130-
return this.aemServerType.pathPrefix() + "/content/forms/af/" + formName + ".html";
125+
return "/" + formName + ".html";
131126
}
132127

133128
private String generateDataRefParam(String uuid) {
134129
return "service://FFPrefillService/" + uuid;
135130
}
136131

137132
private String postDataToDataCacheService(Document data) throws AdaptiveFormsServiceException {
138-
139-
WebTarget dataCacheServiceTarget = baseTarget.path(constructStandardPath(DATA_CACHE_SERVICE_NAME, DATA_CACHE_METHOD_NAME));
140-
141-
try (final FormDataMultiPart multipart = new FormDataMultiPart()) {
142-
String contentType = data.getContentType();
143-
multipart.field(DATA_SERVICE_DATA_PARAM, data.getInputStream(), contentType != null ? MediaType.valueOf(contentType) : MediaType.APPLICATION_XML_TYPE);
133+
try (MultipartPayload payload = dataCacheRestClient.multipartPayloadBuilder()
134+
.add(DATA_SERVICE_DATA_PARAM, data, getContentType(data))
135+
.build()) {
136+
return payload.postToServer(ContentType.TEXT_PLAIN)
137+
.map(uncheck(AdaptiveFormsService::responseToString))
138+
.orElseThrow();
139+
140+
} catch (IOException e) {
141+
throw new AdaptiveFormsServiceException("I/O Error while generating Adaptive Form. (" + dataCacheRestClient.target() + ").", e);
142+
} catch (RestClientException e) {
143+
throw new AdaptiveFormsServiceException("Error while POSTing to server (" + dataCacheRestClient.target() + ").", e);
144+
}
145+
}
144146

145-
Response result = postToServer(dataCacheServiceTarget, multipart, MediaType.TEXT_PLAIN_TYPE);
146-
147-
StatusType resultStatus = result.getStatusInfo();
148-
if (!Family.SUCCESSFUL.equals(resultStatus.getFamily())) {
149-
String message = "Call to server failed while posting data to dataCache, statusCode='" + resultStatus.getStatusCode() + "', reason='" + resultStatus.getReasonPhrase() + "'.";
150-
if (result.hasEntity()) {
151-
InputStream entityStream = (InputStream) result.getEntity();
152-
message += "\n" + inputStreamtoString(entityStream);
153-
}
154-
throw new AdaptiveFormsServiceException(message);
155-
}
156-
157-
if (!result.hasEntity()) {
158-
throw new AdaptiveFormsServiceException("Call to dataCache on the server succeeded but server failed to return document with dataKey in it. This should never happen.");
159-
}
160-
161-
String responseContentType = result.getHeaderString(HttpHeaders.CONTENT_TYPE);
162-
if ( responseContentType == null || !MediaType.TEXT_PLAIN_TYPE.isCompatible(MediaType.valueOf(responseContentType))) {
163-
String msg = "DataCache response from AEM server was not plain text. " + (responseContentType != null ? "content-type='" + responseContentType + "'" : "content-type was null") + ".";
164-
InputStream entityStream = (InputStream) result.getEntity();
165-
msg += "\n" + inputStreamtoString(entityStream);
166-
throw new AdaptiveFormsServiceException(msg);
167-
}
168-
169-
return (new BufferedReader(new InputStreamReader(((InputStream)result.getEntity())))).readLine();
170-
171-
} catch (IOException | RestServicesServiceException e) {
172-
String msg = e.getMessage();
173-
throw new AdaptiveFormsServiceException("Error while posting data to dataCache (" + (msg == null ? e.getClass().getName() : msg) + ").", e );
147+
private static ContentType getContentType(Document data) {
148+
try {
149+
String contentType = data.getContentType();
150+
return contentType != null ? ContentType.of(contentType) : ContentType.APPLICATION_XML;
151+
} catch (IOException e) {
152+
throw new UncheckedIOException(e);
174153
}
175154
}
155+
156+
private static String responseToString(Response result) throws IOException {
157+
return new String(result.data().readAllBytes());
158+
}
176159

177160
/**
178161
* See renderAdaptiveForm(PathOrUrl template, Document data).
@@ -203,17 +186,17 @@ public Document renderAdaptiveForm(Path template, Document data) throws Adaptive
203186
*
204187
* @return
205188
*/
206-
public static AdaptiveFormsServiceBuilder builder() {
207-
return new AdaptiveFormsServiceBuilder();
189+
public static AdaptiveFormsServiceBuilder builder(TriFunction<AemConfig, String, Supplier<String>, RestClient> clientFactory) {
190+
return new AdaptiveFormsServiceBuilder(clientFactory);
208191
}
209192

210193
public static class AdaptiveFormsServiceBuilder implements Builder {
211-
private final BuilderImpl builder = new BuilderImpl();
194+
private final BuilderImpl builder;
212195
private Function<InputStream, InputStream> renderResultFilter;
213196

214197
// Prevent it from being instantiated outside of this class
215-
private AdaptiveFormsServiceBuilder() {
216-
super();
198+
private AdaptiveFormsServiceBuilder(TriFunction<AemConfig, String, Supplier<String>, RestClient> clientFactory) {
199+
this.builder = new BuilderImpl(clientFactory);
217200
}
218201

219202
@Override
@@ -234,12 +217,6 @@ public AdaptiveFormsServiceBuilder useSsl(boolean useSsl) {
234217
return this;
235218
}
236219

237-
@Override
238-
public AdaptiveFormsServiceBuilder clientFactory(Supplier<Client> clientFactory) {
239-
builder.clientFactory(clientFactory);
240-
return this;
241-
}
242-
243220
@Override
244221
public AdaptiveFormsServiceBuilder basicAuthentication(String username, String password) {
245222
builder.basicAuthentication(username, password);
@@ -257,11 +234,6 @@ public Supplier<String> getCorrelationIdFn() {
257234
return builder.getCorrelationIdFn();
258235
}
259236

260-
@Override
261-
public WebTarget createLocalTarget() {
262-
return builder.createLocalTarget();
263-
}
264-
265237
public AdaptiveFormsServiceBuilder addRenderResultFilter(Function<InputStream, InputStream> filter) {
266238
this.renderResultFilter = this.renderResultFilter != null
267239
? this.renderResultFilter.andThen(filter)
@@ -290,7 +262,7 @@ public AemServerType getAemServerType() {
290262
}
291263

292264
public AdaptiveFormsService build() {
293-
return new AdaptiveFormsService(this.createLocalTarget(), this.getCorrelationIdFn(), this.getAemServerType(), this.getRenderResultFilter());
265+
return new AdaptiveFormsService(this.builder, this.getCorrelationIdFn(), this.getRenderResultFilter());
294266
}
295267
}
296268

rest-services/client/src/main/java/com/_4point/aem/docservices/rest_services/client/helpers/BuilderImpl.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public AemServerType getAemServerType() {
7878
return this.aemServerType;
7979
}
8080

81-
private RestClient createClient(String endpoint) {
81+
private RestClient createClientImplementation(String endpoint) {
8282
return Objects.requireNonNull(clientFactory, "Client Factory was not provided.").apply(aemConfigBuilder.build(), endpoint, correlationIdFn);
8383
}
8484

@@ -87,7 +87,11 @@ private String constructStandardPath(String serviceName, String methodName) {
8787
}
8888

8989
public RestClient createClient(String serviceName, String methodName) {
90-
return createClient(constructStandardPath(serviceName, methodName));
90+
return createClientImplementation(constructStandardPath(serviceName, methodName));
91+
}
92+
93+
public RestClient createClient(String endpoint) {
94+
return createClientImplementation(this.aemServerType.pathPrefix() + endpoint);
9195
}
9296

9397
@FunctionalInterface

0 commit comments

Comments
 (0)