Skip to content

Commit 450fee8

Browse files
committed
fix #172--throw error message when connected operations are attempted after client has been released
1 parent 0ca9df7 commit 450fee8

File tree

3 files changed

+70
-42
lines changed

3 files changed

+70
-42
lines changed

src/main/java/com/marklogic/client/impl/JerseyServices.java

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ public void verify(String hostname, String[] cns, String[] subjectAlts)
174174
private String database = null;
175175
private ApacheHttpClient4 client;
176176
private WebResource connection;
177+
private boolean released = false;
177178

178179
private Random randRetry = new Random();
179180

@@ -430,8 +431,16 @@ public void setDatabaseClient(DatabaseClient client) {
430431
this.databaseClient = client;
431432
}
432433

434+
private WebResource getConnection() {
435+
if ( connection != null ) return connection;
436+
else if ( released ) throw new IllegalStateException(
437+
"You cannot use this connected object anymore--connection has already been released");
438+
else throw new MarkLogicInternalException("Cannot proceed--connection is null for unknown reason");
439+
}
440+
433441
@Override
434442
public void release() {
443+
released = true;
435444
if (databaseClient != null) {
436445
databaseClient = null;
437446
}
@@ -459,7 +468,7 @@ private void checkFirstRequest() {
459468
}
460469

461470
private int makeFirstRequest(int retry) {
462-
ClientResponse response = connection.path("ping").head();
471+
ClientResponse response = getConnection().path("ping").head();
463472
int statusCode = response.getClientResponseStatus().getStatusCode();
464473
if (statusCode != ClientResponse.Status.SERVICE_UNAVAILABLE.getStatusCode()) {
465474
response.close();
@@ -1040,7 +1049,7 @@ public DocumentDescriptor head(RequestLogger reqlog, String uri,
10401049
@Override
10411050
public boolean exists(String uri) throws ForbiddenUserException,
10421051
FailedRequestException {
1043-
return headImpl(null, uri, null, connection.path(uri)) == null ? false : true;
1052+
return headImpl(null, uri, null, getConnection().path(uri)) == null ? false : true;
10441053
}
10451054

10461055
public ClientResponse headImpl(RequestLogger reqlog, String uri,
@@ -1538,8 +1547,8 @@ public String openTransaction(String name, int timeLimit)
15381547
transParams.add("timeLimit", String.valueOf(timeLimit));
15391548
}
15401549

1541-
WebResource resource = (transParams != null) ? connection.path(
1542-
"transactions").queryParams(transParams) : connection
1550+
WebResource resource = (transParams != null) ? getConnection().path(
1551+
"transactions").queryParams(transParams) : getConnection()
15431552
.path("transactions");
15441553

15451554
ClientResponse response = null;
@@ -1628,7 +1637,7 @@ private void completeTransaction(String transactionId, String result)
16281637
MultivaluedMap<String, String> transParams = new MultivaluedMapImpl();
16291638
transParams.add("result", result);
16301639

1631-
WebResource webResource = connection.path("transactions/" + transactionId)
1640+
WebResource webResource = getConnection().path("transactions/" + transactionId)
16321641
.queryParams(transParams);
16331642

16341643
WebResource.Builder builder = webResource.getRequestBuilder();
@@ -1759,7 +1768,7 @@ private MultivaluedMap<String, String> makeDocumentParams(String uri,
17591768

17601769
private WebResource makeDocumentResource(
17611770
MultivaluedMap<String, String> queryParams) {
1762-
return connection.path("documents").queryParams(queryParams);
1771+
return getConnection().path("documents").queryParams(queryParams);
17631772
}
17641773

17651774
private boolean isExternalDescriptor(ContentDescriptor desc) {
@@ -2058,7 +2067,7 @@ else if (payloadFormat == Format.JSON && "xml".equals(params.getFirst("format"))
20582067
String path = (queryDef instanceof RawQueryByExampleDefinition) ?
20592068
"qbe" : "search";
20602069

2061-
WebResource resource = connection.path(path).queryParams(params);
2070+
WebResource resource = getConnection().path(path).queryParams(params);
20622071
builder = (payloadMimetype != null) ?
20632072
resource.type(payloadMimetype).accept(mimetype) :
20642073
resource.accept(mimetype);
@@ -2071,7 +2080,7 @@ else if (payloadFormat == Format.JSON && "xml".equals(params.getFirst("format"))
20712080
addEncodedParam(params, "q", text);
20722081
}
20732082

2074-
builder = connection.path("search").queryParams(params)
2083+
builder = getConnection().path("search").queryParams(params)
20752084
.type("application/xml").accept(mimetype);
20762085
} else if (queryDef instanceof KeyValueQueryDefinition) {
20772086
if (logger.isDebugEnabled())
@@ -2092,29 +2101,29 @@ else if (payloadFormat == Format.JSON && "xml".equals(params.getFirst("format"))
20922101
addEncodedParam(params, "value", entry.getValue());
20932102
}
20942103

2095-
builder = connection.path("keyvalue").queryParams(params)
2104+
builder = getConnection().path("keyvalue").queryParams(params)
20962105
.accept(mimetype);
20972106
} else if (queryDef instanceof StructuredQueryDefinition) {
20982107
structure = ((StructuredQueryDefinition) queryDef).serialize();
20992108

21002109
if (logger.isDebugEnabled())
21012110
logger.debug("Searching for structure {}", structure);
21022111

2103-
builder = connection.path("search").queryParams(params)
2112+
builder = getConnection().path("search").queryParams(params)
21042113
.type("application/xml").accept(mimetype);
21052114
} else if (queryDef instanceof CombinedQueryDefinition) {
21062115
structure = ((CombinedQueryDefinition) queryDef).serialize();
21072116

21082117
if (logger.isDebugEnabled())
21092118
logger.debug("Searching for combined query {}", structure);
21102119

2111-
builder = connection.path("search").queryParams(params)
2120+
builder = getConnection().path("search").queryParams(params)
21122121
.type("application/xml").accept(mimetype);
21132122
} else if (queryDef instanceof DeleteQueryDefinition) {
21142123
if (logger.isDebugEnabled())
21152124
logger.debug("Searching for deletes");
21162125

2117-
builder = connection.path("search").queryParams(params)
2126+
builder = getConnection().path("search").queryParams(params)
21182127
.accept(mimetype);
21192128
} else {
21202129
throw new UnsupportedOperationException("Cannot search with "
@@ -2210,7 +2219,7 @@ public void deleteSearch(RequestLogger reqlog, DeleteQueryDefinition queryDef,
22102219
params.add("txid", transactionId);
22112220
}
22122221

2213-
WebResource webResource = connection.path("search").queryParams(params);
2222+
WebResource webResource = getConnection().path("search").queryParams(params);
22142223

22152224
WebResource.Builder builder = webResource.getRequestBuilder();
22162225

@@ -2375,7 +2384,7 @@ public <T> T values(Class<T> as, ValuesDefinition valDef, String mimetype,
23752384
uri += "/" + valDef.getName();
23762385
}
23772386

2378-
WebResource.Builder builder = connection.path(uri).queryParams(docParams).accept(mimetype);
2387+
WebResource.Builder builder = getConnection().path(uri).queryParams(docParams).accept(mimetype);
23792388

23802389

23812390
ClientResponse response = null;
@@ -2453,7 +2462,7 @@ public <T> T valuesList(Class<T> as, ValuesListDefinition valDef,
24532462

24542463
String uri = "values";
24552464

2456-
WebResource.Builder builder = connection.path(uri)
2465+
WebResource.Builder builder = getConnection().path(uri)
24572466
.queryParams(docParams).accept(mimetype);
24582467

24592468
ClientResponse response = null;
@@ -2521,7 +2530,7 @@ public <T> T optionsList(Class<T> as, String mimetype, String transactionId)
25212530

25222531
String uri = "config/query";
25232532

2524-
WebResource.Builder builder = connection.path(uri)
2533+
WebResource.Builder builder = getConnection().path(uri)
25252534
.queryParams(docParams).accept(mimetype);
25262535

25272536
ClientResponse response = null;
@@ -2587,7 +2596,7 @@ public <T> T getValue(RequestLogger reqlog, String type, String key,
25872596
if (logger.isDebugEnabled())
25882597
logger.debug("Getting {}/{}", type, key);
25892598

2590-
WebResource.Builder builder = connection.path(type + "/" + key).accept(
2599+
WebResource.Builder builder = getConnection().path(type + "/" + key).accept(
25912600
mimetype);
25922601

25932602
ClientResponse response = null;
@@ -2669,8 +2678,8 @@ public <T> T getValues(RequestLogger reqlog, String type, RequestParameters extr
26692678
MultivaluedMap<String, String> requestParams = convertParams(extraParams);
26702679

26712680
WebResource.Builder builder = (requestParams == null) ?
2672-
connection.path(type).accept(mimetype) :
2673-
connection.path(type).queryParams(requestParams).accept(mimetype);
2681+
getConnection().path(type).accept(mimetype) :
2682+
getConnection().path(type).queryParams(requestParams).accept(mimetype);
26742683

26752684
ClientResponse response = null;
26762685
ClientResponse.Status status = null;
@@ -2839,8 +2848,8 @@ private void putPostValueImpl(RequestLogger reqlog, String method,
28392848
if (builder == null) {
28402849
connectPath = (key != null) ? type + "/" + key : type;
28412850
WebResource resource = (requestParams == null) ?
2842-
connection.path(connectPath) :
2843-
connection.path(connectPath).queryParams(requestParams);
2851+
getConnection().path(connectPath) :
2852+
getConnection().path(connectPath).queryParams(requestParams);
28442853
builder = (mimetype == null) ?
28452854
resource.getRequestBuilder() : resource.type(mimetype);
28462855
}
@@ -2852,8 +2861,8 @@ private void putPostValueImpl(RequestLogger reqlog, String method,
28522861
if (builder == null) {
28532862
connectPath = type;
28542863
WebResource resource = (requestParams == null) ?
2855-
connection.path(connectPath) :
2856-
connection.path(connectPath).queryParams(requestParams);
2864+
getConnection().path(connectPath) :
2865+
getConnection().path(connectPath).queryParams(requestParams);
28572866
builder = (mimetype == null) ?
28582867
resource.getRequestBuilder() : resource.type(mimetype);
28592868
}
@@ -2924,7 +2933,7 @@ public void deleteValue(RequestLogger reqlog, String type, String key)
29242933
if (logger.isDebugEnabled())
29252934
logger.debug("Deleting {}/{}", type, key);
29262935

2927-
WebResource builder = connection.path(type + "/" + key);
2936+
WebResource builder = getConnection().path(type + "/" + key);
29282937

29292938
ClientResponse response = null;
29302939
ClientResponse.Status status = null;
@@ -2985,7 +2994,7 @@ public void deleteValues(RequestLogger reqlog, String type)
29852994
if (logger.isDebugEnabled())
29862995
logger.debug("Deleting {}", type);
29872996

2988-
WebResource builder = connection.path(type);
2997+
WebResource builder = getConnection().path(type);
29892998

29902999
ClientResponse response = null;
29913000
ClientResponse.Status status = null;
@@ -4356,7 +4365,7 @@ private WebResource.Builder makeBuilder(String path,
43564365
if ( database != null ) {
43574366
addEncodedParam(params, "database", database);
43584367
}
4359-
WebResource resource = connection.path(path).queryParams(params);
4368+
WebResource resource = getConnection().path(path).queryParams(params);
43604369

43614370
WebResource.Builder builder = resource.getRequestBuilder();
43624371

@@ -4802,7 +4811,7 @@ public <T> T suggest(Class<T> as, SuggestDefinition suggestionDef) {
48024811
}
48034812
}
48044813
WebResource.Builder builder = null;
4805-
builder = connection.path("suggest").queryParams(params)
4814+
builder = getConnection().path("suggest").queryParams(params)
48064815
.accept("application/xml");
48074816
ClientResponse response = null;
48084817
ClientResponse.Status status = null;
@@ -4875,7 +4884,7 @@ public InputStream match(StructureWriteHandle document,
48754884
transform.merge(params);
48764885
}
48774886
WebResource.Builder builder = null;
4878-
builder = connection.path("alert/match").queryParams(params)
4887+
builder = getConnection().path("alert/match").queryParams(params)
48794888
.accept("application/xml").type(mimeType);
48804889

48814890
ClientResponse response = null;
@@ -4973,7 +4982,7 @@ public InputStream match(QueryDefinition queryDef,
49734982
if (logger.isDebugEnabled())
49744983
logger.debug("Searching for structure {}", structure);
49754984

4976-
builder = connection.path("alert/match").queryParams(params)
4985+
builder = getConnection().path("alert/match").queryParams(params)
49774986
.type("application/xml").accept("application/xml");
49784987
} else if (queryDef instanceof StringQueryDefinition) {
49794988
String text = ((StringQueryDefinition) queryDef).getCriteria();
@@ -4984,7 +4993,7 @@ public InputStream match(QueryDefinition queryDef,
49844993
addEncodedParam(params, "q", text);
49854994
}
49864995

4987-
builder = connection.path("alert/match").queryParams(params)
4996+
builder = getConnection().path("alert/match").queryParams(params)
49884997
.accept("application/xml");
49894998
} else if (queryDef instanceof StructuredQueryDefinition) {
49904999
structure = ((StructuredQueryDefinition) queryDef).serialize();
@@ -4993,7 +5002,7 @@ public InputStream match(QueryDefinition queryDef,
49935002
logger.debug("Searching for structure {} in transaction {}",
49945003
structure);
49955004

4996-
builder = connection.path("alert/match").queryParams(params)
5005+
builder = getConnection().path("alert/match").queryParams(params)
49975006
.type("application/xml").accept("application/xml");
49985007
} else {
49995008
throw new UnsupportedOperationException("Cannot match with "
@@ -5081,7 +5090,7 @@ public InputStream match(String[] docIds, String[] candidateRules, ServerTransfo
50815090
if (transform != null) {
50825091
transform.merge(params);
50835092
}
5084-
WebResource.Builder builder = connection.path("alert/match").queryParams(params)
5093+
WebResource.Builder builder = getConnection().path("alert/match").queryParams(params)
50855094
.accept("application/xml");
50865095

50875096
ClientResponse response = null;

src/main/java/com/marklogic/client/impl/ResourceExtensionsImpl.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,15 @@ public void writeServices(
193193
}
194194
}
195195
}
196-
String contentType = null;
197-
if ( metadata.getScriptLanguage() == null ) {
198-
throw new IllegalArgumentException("scriptLanguage cannot be null");
199-
} else if ( metadata.getScriptLanguage() == ScriptLanguage.JAVASCRIPT ) {
200-
contentType = "application/vnd.marklogic-javascript";
201-
} else if ( metadata.getScriptLanguage() == ScriptLanguage.XQUERY ) {
202-
contentType = "application/xquery";
203-
}
196+
String contentType = null;
197+
if ( metadata == null ) {
198+
} else if ( metadata.getScriptLanguage() == null ) {
199+
throw new IllegalArgumentException("scriptLanguage cannot be null");
200+
} else if ( metadata.getScriptLanguage() == ScriptLanguage.JAVASCRIPT ) {
201+
contentType = "application/vnd.marklogic-javascript";
202+
} else if ( metadata.getScriptLanguage() == ScriptLanguage.XQUERY ) {
203+
contentType = "application/xquery";
204+
}
204205

205206
services.putValue(requestLogger, "config/resources", resourceName, extraParams,
206207
contentType, sourceBase);

src/test/java/com/marklogic/client/test/ResourceServicesTest.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
package com.marklogic.client.test;
1717

1818
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
19-
import static org.junit.Assert.assertNotNull;
20-
import static org.junit.Assert.assertTrue;
19+
import static org.junit.Assert.*;
2120

2221
import java.io.IOException;
2322
import java.util.ArrayList;
@@ -147,6 +146,25 @@ public void testResourceServices() throws XpathException {
147146
extensionMgr.deleteServices(ResourceExtensionsTest.RESOURCE_NAME);
148147
}
149148

149+
@Test
150+
/** Avoid regression on https://github.com/marklogic/java-client-api/issues/172 */
151+
public void test_172() {
152+
ResourceExtensionsManager extensionMgr =
153+
Common.client.newServerConfigManager().newResourceExtensionsManager();
154+
Common.client.release();
155+
String expectedMessage = "You cannot use this connected object anymore--connection has already been released";
156+
try { extensionMgr.writeServices(ResourceExtensionsTest.RESOURCE_NAME, null, null);
157+
} catch (IllegalStateException e) { assertEquals("Wrong error", expectedMessage, e.getMessage()); }
158+
try { extensionMgr.readServices(ResourceExtensionsTest.RESOURCE_NAME, new StringHandle());
159+
} catch (IllegalStateException e) { assertEquals("Wrong error", expectedMessage, e.getMessage()); }
160+
try { extensionMgr.listServices(new DOMHandle());
161+
} catch (IllegalStateException e) { assertEquals("Wrong error", expectedMessage, e.getMessage()); }
162+
try { extensionMgr.deleteServices(ResourceExtensionsTest.RESOURCE_NAME);
163+
} catch (IllegalStateException e) { assertEquals("Wrong error", expectedMessage, e.getMessage()); }
164+
// since we released the existing connection, connect again in case this isn't always the last test
165+
Common.connectAdmin();
166+
}
167+
150168
static class SimpleResourceManager extends ResourceManager {
151169
public SimpleResourceManager() {
152170
super();

0 commit comments

Comments
 (0)