Skip to content

Commit 09a5b1e

Browse files
committed
MLE-26427 Fixing Polaris issues
Most of these already existed in OkHttpServices, but Polaris decided to report them recently
1 parent 95b274c commit 09a5b1e

File tree

3 files changed

+82
-58
lines changed

3 files changed

+82
-58
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/datamovement/filter/ContentExclusionUtil.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ private static void removeNodeAtPointer(String uri, JsonNode rootNode, String js
8383
JsonNode parentNode = rootNode.at(parentPointer);
8484

8585
if (parentNode.isObject()) {
86-
String fieldName = pointer.last().getMatchingProperty();
87-
((ObjectNode) parentNode).remove(fieldName);
86+
JsonPointer lastSegment = pointer.last();
87+
if (lastSegment != null) {
88+
String fieldName = lastSegment.getMatchingProperty();
89+
((ObjectNode) parentNode).remove(fieldName);
90+
}
8891
} else if (parentNode.isArray()) {
8992
logger.warn("Array element exclusion not supported for JSONPointer '{}'. " +
9093
"Consider excluding the entire array property instead.", jsonPointer);

marklogic-client-api/src/main/java/com/marklogic/client/datamovement/filter/IncrementalWriteFilter.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,15 @@ protected final DocumentWriteSet filterDocuments(Context context, Function<Strin
152152
continue;
153153
}
154154

155-
final String contentHash = computeHash(serializeContent(doc));
155+
final String serializedContent = serializeContent(doc);
156+
if (serializedContent == null) {
157+
// Not sure if the doc can have null content - possibly for a naked properties document? - but if it
158+
// does, just include it in the write set.
159+
newWriteSet.add(doc);
160+
continue;
161+
}
162+
163+
final String contentHash = computeHash(serializedContent);
156164
final String existingHash = hashRetriever.apply(doc.getUri());
157165
if (logger.isTraceEnabled()) {
158166
logger.trace("URI: {}, existing Hash: {}, new Hash: {}", doc.getUri(), existingHash, contentHash);
@@ -171,7 +179,7 @@ protected final DocumentWriteSet filterDocuments(Context context, Function<Strin
171179
}
172180
}
173181

174-
if (!skippedDocuments.isEmpty()) {
182+
if (!skippedDocuments.isEmpty() && skippedDocumentsConsumer != null) {
175183
skippedDocumentsConsumer.accept(skippedDocuments.toArray(new DocumentWriteOperation[0]));
176184
}
177185

marklogic-client-api/src/main/java/com/marklogic/client/impl/OkHttpServices.java

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2+
* Copyright (c) 2010-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
33
*/
44
package com.marklogic.client.impl;
55

@@ -619,7 +619,7 @@ public Response apply(Request.Builder funcBuilder) {
619619
};
620620
Response response = sendRequestWithRetry(requestBldr, (transaction == null), doGetFunction, null);
621621

622-
int status = response.code();
622+
int status = response != null ? response.code() : 0;
623623
if (status == STATUS_NOT_FOUND) {
624624
throw new ResourceNotFoundException(
625625
"Could not read non-existent document",
@@ -648,18 +648,20 @@ public Response apply(Request.Builder funcBuilder) {
648648

649649
HandleImplementation handleBase = HandleAccessor.as(handle);
650650

651-
Headers responseHeaders = response.headers();
652-
if (isExternalDescriptor(desc)) {
653-
updateVersion(desc, responseHeaders);
654-
updateDescriptor(desc, responseHeaders);
655-
copyDescriptor(desc, handleBase);
656-
} else {
657-
updateDescriptor(handleBase, responseHeaders);
651+
if (response != null) {
652+
Headers responseHeaders = response.headers();
653+
if (isExternalDescriptor(desc)) {
654+
updateVersion(desc, responseHeaders);
655+
updateDescriptor(desc, responseHeaders);
656+
copyDescriptor(desc, handleBase);
657+
} else {
658+
updateDescriptor(handleBase, responseHeaders);
659+
}
658660
}
659661

660662
Class as = handleBase.receiveAs();
661-
ResponseBody body = response.body();
662-
Object entity = body.contentLength() != 0 ? getEntity(body, as) : null;
663+
ResponseBody body = response != null ? response.body() : null;
664+
Object entity = (body != null && body.contentLength() != 0) ? getEntity(body, as) : null;
663665

664666
if (entity == null || (!InputStream.class.isAssignableFrom(as) && !Reader.class.isAssignableFrom(as))) {
665667
closeResponse(response);
@@ -841,7 +843,7 @@ private OkHttpResultIterator getBulkDocumentsImpl(RequestLogger reqlog, long ser
841843
if (searchHandle != null) {
842844
updateServerTimestamp(handleBase, response.headers());
843845
ResponseBody body = response.body();
844-
if (body.contentLength() != 0) {
846+
if (body != null && body.contentLength() != 0) {
845847
entity = getEntity(body, MimeMultipart.class);
846848
if (entity != null) {
847849
List<BodyPart> partList = getPartList(entity);
@@ -895,7 +897,7 @@ public Response apply(Request.Builder funcBuilder) {
895897
}
896898
};
897899
Response response = sendRequestWithRetry(requestBldr, (transaction == null), doGetFunction, null);
898-
int status = response.code();
900+
int status = response != null ? response.code() : 0;
899901
if (status == STATUS_NOT_FOUND) {
900902
throw new ResourceNotFoundException(
901903
"Could not read non-existent document",
@@ -921,8 +923,8 @@ public Response apply(Request.Builder funcBuilder) {
921923
uri, (transaction != null) ? transaction.getTransactionId() : "no", stringJoin(categories, ", ", "no"));
922924

923925
try {
924-
ResponseBody body = response.body();
925-
MimeMultipart entity = body.contentLength() != 0 ?
926+
ResponseBody body = response != null ? response.body() : null;
927+
MimeMultipart entity = (body != null && body.contentLength() != 0) ?
926928
getEntity(body, MimeMultipart.class) : null;
927929
if (entity == null) return false;
928930

@@ -940,15 +942,17 @@ public Response apply(Request.Builder funcBuilder) {
940942

941943
BodyPart contentPart = partList.get(1);
942944

943-
Headers responseHeaders = response.headers();
944-
if (isExternalDescriptor(desc)) {
945-
updateVersion(desc, responseHeaders);
946-
updateFormat(desc, responseHeaders);
947-
updateMimetype(desc, getHeaderMimetype(getHeader(contentPart, HEADER_CONTENT_TYPE)));
948-
updateLength(desc, getHeaderLength(getHeader(contentPart, HEADER_CONTENT_LENGTH)));
949-
copyDescriptor(desc, contentBase);
950-
} else {
951-
updateDescriptor(contentBase, responseHeaders);
945+
if (response != null) {
946+
Headers responseHeaders = response.headers();
947+
if (isExternalDescriptor(desc)) {
948+
updateVersion(desc, responseHeaders);
949+
updateFormat(desc, responseHeaders);
950+
updateMimetype(desc, getHeaderMimetype(getHeader(contentPart, HEADER_CONTENT_TYPE)));
951+
updateLength(desc, getHeaderLength(getHeader(contentPart, HEADER_CONTENT_LENGTH)));
952+
copyDescriptor(desc, contentBase);
953+
} else {
954+
updateDescriptor(contentBase, responseHeaders);
955+
}
952956
}
953957

954958
metadataBase.receiveContent(getEntity(partList.get(0),
@@ -1501,7 +1505,7 @@ public Response apply(Request.Builder funcBuilder) {
15011505
}
15021506
};
15031507
Response response = sendRequestWithRetry(requestBldr, doPostFunction, null);
1504-
int status = response.code();
1508+
int status = response != null ? response.code() : 0;
15051509
if (status == STATUS_FORBIDDEN) {
15061510
throw new ForbiddenUserException("User is not allowed to open transactions", extractErrorFields(response));
15071511
}
@@ -1510,12 +1514,16 @@ public Response apply(Request.Builder funcBuilder) {
15101514
getReasonPhrase(response), extractErrorFields(response));
15111515
}
15121516

1513-
String location = response.headers().get("Location");
1514-
List<ClientCookie> cookies = new ArrayList<>();
1515-
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
1516-
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
1517-
cookies.add(cookie);
1517+
final String location = response != null ? response.headers().get("Location") : null;
1518+
1519+
final List<ClientCookie> cookies = new ArrayList<>();
1520+
if (response != null) {
1521+
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
1522+
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
1523+
cookies.add(cookie);
1524+
}
15181525
}
1526+
15191527
closeResponse(response);
15201528
if (location == null) throw new MarkLogicInternalException("transaction open failed to provide location");
15211529
if (!location.contains("/")) {
@@ -2562,7 +2570,7 @@ public Response apply(Request.Builder funcBuilder) {
25622570
}
25632571
};
25642572
Response response = sendRequestWithRetry(requestBldr, doGetFunction, null);
2565-
int status = response.code();
2573+
int status = response != null ? response.code() : 0;
25662574
if (status == STATUS_FORBIDDEN) {
25672575
throw new ForbiddenUserException("User is not allowed to read "
25682576
+ type, extractErrorFields(response));
@@ -2574,8 +2582,8 @@ public Response apply(Request.Builder funcBuilder) {
25742582

25752583
logRequest(reqlog, "read %s values with %s mime type", type, mimetype);
25762584

2577-
ResponseBody body = response.body();
2578-
T entity = body.contentLength() != 0 ? getEntity(body, as) : null;
2585+
ResponseBody body = response != null ? response.body() : null;
2586+
T entity = body != null && body.contentLength() != 0 ? getEntity(body, as) : null;
25792587
if (entity == null || (as != InputStream.class && as != Reader.class)) {
25802588
closeResponse(response);
25812589
}
@@ -2749,7 +2757,7 @@ public Response apply(Request.Builder funcBuilder) {
27492757
}
27502758
};
27512759
Response response = sendRequestWithRetry(requestBldr, doDeleteFunction, null);
2752-
int status = response.code();
2760+
int status = response != null ? response.code() : 0;
27532761
if (status == STATUS_FORBIDDEN) {
27542762
throw new ForbiddenUserException("User is not allowed to delete "
27552763
+ type, extractErrorFields(response));
@@ -3181,17 +3189,19 @@ public Response apply(Request.Builder funcBuilder) {
31813189
};
31823190

31833191
Response response = sendRequestWithRetry(requestBldr, (transaction == null), doPostFunction, resendableConsumer);
3184-
int status = response.code();
3192+
int status = response != null ? response.code() : 0;
31853193
checkStatus(response, status, operation, "resource", path,
31863194
ResponseStatus.OK_OR_CREATED_OR_NO_CONTENT);
31873195

3188-
Headers headers = response.headers();
3189-
if (responseHeaders != null) {
3190-
// add all the headers from the OkHttp Headers object to the caller-provided map
3191-
responseHeaders.putAll(headers.toMultimap());
3192-
} else if (outputBase != null) {
3193-
updateLength(outputBase, headers);
3194-
updateServerTimestamp(outputBase, headers);
3196+
if (response != null) {
3197+
Headers headers = response.headers();
3198+
if (responseHeaders != null) {
3199+
// add all the headers from the OkHttp Headers object to the caller-provided map
3200+
responseHeaders.putAll(headers.toMultimap());
3201+
} else if (outputBase != null) {
3202+
updateLength(outputBase, headers);
3203+
updateServerTimestamp(outputBase, headers);
3204+
}
31953205
}
31963206

31973207
if (as != null) {
@@ -3712,7 +3722,7 @@ public RESTServiceResultIterator postMultipartForm(
37123722
Consumer<Boolean> resendableConsumer = null;
37133723

37143724
Response response = sendRequestWithRetry(requestBldr, (transaction == null), doPostFunction, resendableConsumer);
3715-
int status = response.code();
3725+
int status = response != null ? response.code() : 0;
37163726
checkStatus(response, status, "apply", "resource", path, ResponseStatus.OK_OR_CREATED_OR_NO_CONTENT);
37173727
return makeResults(OkHttpServiceResultIterator::new, reqlog, "apply", "resource", response);
37183728
}
@@ -3782,10 +3792,11 @@ private <U extends OkHttpResultIterator> U postIteratedResourceImpl(
37823792
);
37833793

37843794
Response response = sendRequestWithRetry(requestBldr, (transaction == null), doPostFunction, resendableConsumer);
3785-
checkStatus(response, response.code(), "apply", "resource", path, ResponseStatus.OK_OR_CREATED_OR_NO_CONTENT);
3795+
final int code = response != null ? response.code() : 0;
3796+
checkStatus(response, code, "apply", "resource", path, ResponseStatus.OK_OR_CREATED_OR_NO_CONTENT);
37863797

37873798
boolean shouldStreamResults = "eval".equalsIgnoreCase(path) || "invoke".equalsIgnoreCase(path);
3788-
boolean hasDataToStream = response.body().contentLength() != 0;
3799+
boolean hasDataToStream = response != null && response.body().contentLength() != 0;
37893800
// If body is empty, we can use the "old" way of reading results as there's nothing to stream.
37903801
return shouldStreamResults && hasDataToStream ?
37913802
evalAndStreamResults(reqlog, response) :
@@ -4820,7 +4831,7 @@ public Response apply(Request.Builder funcBuilder) {
48204831
}
48214832
};
48224833
Response response = sendRequestWithRetry(requestBldr, doGetFunction, null);
4823-
int status = response.code();
4834+
int status = response != null ? response.code() : 0;
48244835
if (status == STATUS_FORBIDDEN) {
48254836
throw new ForbiddenUserException(
48264837
"User is not allowed to get suggestions",
@@ -4831,8 +4842,8 @@ public Response apply(Request.Builder funcBuilder) {
48314842
+ getReasonPhrase(response), extractErrorFields(response));
48324843
}
48334844

4834-
ResponseBody body = response.body();
4835-
T entity = body.contentLength() != 0 ? getEntity(body, as) : null;
4845+
ResponseBody body = response != null ? response.body() : null;
4846+
T entity = body != null && body.contentLength() != 0 ? getEntity(body, as) : null;
48364847
if (entity == null || (as != InputStream.class && as != Reader.class)) {
48374848
closeResponse(response);
48384849
}
@@ -5040,7 +5051,7 @@ public Response apply(Request.Builder funcBuilder) {
50405051
}
50415052
};
50425053
Response response = sendRequestWithRetry(requestBldr, doGetFunction, null);
5043-
int status = response.code();
5054+
final int status = response != null ? response.code() : 0;
50445055
if (status == STATUS_FORBIDDEN) {
50455056
throw new ForbiddenUserException("User is not allowed to match",
50465057
extractErrorFields(response));
@@ -5050,8 +5061,8 @@ public Response apply(Request.Builder funcBuilder) {
50505061
+ getReasonPhrase(response), extractErrorFields(response));
50515062
}
50525063

5053-
ResponseBody body = response.body();
5054-
InputStream entity = body.contentLength() != 0 ?
5064+
ResponseBody body = response != null ? response.body() : null;
5065+
InputStream entity = body != null && body.contentLength() != 0 ?
50555066
getEntity(body, InputStream.class) : null;
50565067
if (entity == null) closeResponse(response);
50575068

@@ -5618,9 +5629,11 @@ private void executeRequest(CallResponseImpl responseImpl) {
56185629

56195630
if (session != null) {
56205631
List<ClientCookie> cookies = new ArrayList<>();
5621-
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
5622-
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
5623-
cookies.add(cookie);
5632+
if (response != null) {
5633+
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
5634+
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
5635+
cookies.add(cookie);
5636+
}
56245637
}
56255638
((SessionStateImpl) session).setCookies(cookies);
56265639
}

0 commit comments

Comments
 (0)