diff --git a/.env b/.env
index d5edd373d..c67e5ae05 100644
--- a/.env
+++ b/.env
@@ -1,7 +1,7 @@
# Defines environment variables for docker-compose.
# Can be overridden via e.g. `MARKLOGIC_TAG=latest-10.0 docker-compose up -d --build`.
-#MARKLOGIC_IMAGE=progressofficial/marklogic-db:latest
MARKLOGIC_LOGS_VOLUME=./docker/marklogic/logs
-
-# This image should be used instead of the above image when testing functions that only work with MarkLogic 12.
MARKLOGIC_IMAGE=ml-docker-db-dev-tierpoint.bed-artifactory.bedford.progress.com/marklogic/marklogic-server-ubi:latest-12
+
+# Latest public release
+#MARKLOGIC_IMAGE=progressofficial/marklogic-db:latest
diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/BitemporalTest.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/BitemporalTest.java
index 553d4f801..9d447d098 100644
--- a/marklogic-client-api/src/test/java/com/marklogic/client/test/BitemporalTest.java
+++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/BitemporalTest.java
@@ -15,297 +15,319 @@
import com.marklogic.client.io.StringHandle;
import com.marklogic.client.query.*;
import com.marklogic.client.query.StructuredQueryBuilder.TemporalOperator;
-import org.junit.jupiter.api.*;
+import com.marklogic.mgmt.ManageClient;
+import com.marklogic.mgmt.resource.temporal.TemporalCollectionLSQTManager;
+import jakarta.xml.bind.DatatypeConverter;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
-import jakarta.xml.bind.DatatypeConverter;
import java.util.Calendar;
import java.util.Random;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.junit.jupiter.api.Assertions.*;
-@TestMethodOrder(MethodOrderer.MethodName.class)
-public class BitemporalTest {
- // src/test/resources/bootstrap.xqy is run by com.marklogic.client.test.util.TestServerBootstrapper
- // and sets up the "temporal-collection" and required underlying axes
- // system-axis and valid-axis which have required underlying range indexes
- // system-start, system-end, valid-start, and valid-end
- static String temporalCollection = "temporal-collection";
- static XMLDocumentManager docMgr;
- static QueryManager queryMgr;
- static String uniqueBulkTerm = "temporalBulkDoc" + new Random().nextInt(10000);
- static String uniqueTerm = "temporalDoc" + new Random().nextInt(10000);
- static String docId = "test-" + uniqueTerm + ".xml";
-
- @BeforeAll
- public static void beforeClass() {
- Common.connect();
- docMgr = Common.client.newXMLDocumentManager();
- queryMgr = Common.client.newQueryManager();
- }
- @AfterAll
- public static void afterClass() {
- cleanUp();
- }
-
- @Test
- public void a_testCreate() throws Exception {
- String contents = "" +
- "" +
- "" +
- "2014-08-19T00:00:00Z" +
- "2014-08-19T00:00:01Z" +
- "";
- TemporalDescriptor desc = docMgr.create(docMgr.newDocumentUriTemplate("xml"),
- null, new StringHandle(contents), null, null, temporalCollection);
- assertNotNull(desc);
- assertNotNull(desc.getUri());
- assertTrue(desc.getUri().endsWith(".xml"));
- String lastWriteTimestamp = desc.getTemporalSystemTime();
- Calendar lastWriteTime = DatatypeConverter.parseDateTime(lastWriteTimestamp);
- assertNotNull(lastWriteTime);
- }
-
- @Test
- public void b_testBulk() throws Exception {
- String prefix = "test_" + uniqueBulkTerm;
- String doc1 = "" +
- uniqueBulkTerm + " doc1" +
- "" +
- "" +
- "2014-08-19T00:00:00Z" +
- "2014-08-19T00:00:01Z" +
- "";
- String doc2 = "" +
- uniqueBulkTerm + " doc2" +
- "" +
- "" +
- "2014-08-19T00:00:02Z" +
- "2014-08-19T00:00:03Z" +
- "";
- String doc3 = "" +
- uniqueBulkTerm + " doc3" +
- "" +
- "" +
- "2014-08-19T00:00:03Z" +
- "2014-08-19T00:00:04Z" +
- "";
- String doc4 = "" +
- uniqueBulkTerm + " doc4" +
- "" +
- "" +
- "2014-08-19T00:00:05Z" +
- "2014-08-19T00:00:06Z" +
- "";
- DocumentWriteSet writeSet = docMgr.newWriteSet();
- writeSet.add(prefix + "_1.xml", new StringHandle(doc1).withFormat(Format.XML));
- writeSet.add(prefix + "_2.xml", new StringHandle(doc2).withFormat(Format.XML));
- writeSet.add(prefix + "_3.xml", new StringHandle(doc3).withFormat(Format.XML));
- writeSet.add(prefix + "_4.xml", new StringHandle(doc4).withFormat(Format.XML));
- docMgr.write(writeSet, null, null, temporalCollection);
- // do it one more time so we have two versions of each
- writeSet = docMgr.newWriteSet();
- writeSet.add(prefix + "_1.xml", new StringHandle(doc1).withFormat(Format.XML));
- writeSet.add(prefix + "_2.xml", new StringHandle(doc2).withFormat(Format.XML));
- writeSet.add(prefix + "_3.xml", new StringHandle(doc3).withFormat(Format.XML));
- writeSet.add(prefix + "_4.xml", new StringHandle(doc4).withFormat(Format.XML));
- docMgr.write(writeSet, null, null, temporalCollection);
-
- StringQueryDefinition query = queryMgr.newStringDefinition().withCriteria(uniqueBulkTerm);
- try ( DocumentPage page = docMgr.search(query, 0) ) {
- assertEquals(8, page.size());
- for ( DocumentRecord record : page ) {
- Document doc = record.getContentAs(Document.class);
- if ( record.getUri().startsWith(prefix + "_1") ) {
- assertXpathEvaluatesTo("2014-08-19T00:00:00Z", "//valid-start", doc);
- continue;
- } else if ( record.getUri().startsWith(prefix + "_2") ) {
- assertXpathEvaluatesTo("2014-08-19T00:00:02Z", "//valid-start", doc);
- continue;
- } else if ( record.getUri().startsWith(prefix + "_3") ) {
- assertXpathEvaluatesTo("2014-08-19T00:00:03Z", "//valid-start", doc);
- continue;
- } else if ( record.getUri().startsWith(prefix + "_4") ) {
- assertXpathEvaluatesTo("2014-08-19T00:00:05Z", "//valid-start", doc);
- continue;
- }
- throw new IllegalStateException("Unexpected doc:[" + record.getUri() + "]");
- }
- }
- }
-
- @Test
- @Disabled("Needs updating based on recent 12 nightly server changes")
- public void c_testOther() {
-
- String version1 = "" +
- uniqueTerm + " version1" +
- "" +
- "" +
- "2014-08-19T00:00:00Z" +
- "2014-08-19T00:00:01Z" +
- "";
- String version2 = "" +
- uniqueTerm + " version2" +
- "" +
- "" +
- "2014-08-19T00:00:02Z" +
- "2014-08-19T00:00:03Z" +
- "";
- String version3 = "" +
- uniqueTerm + " version3" +
- "" +
- "" +
- "2014-08-19T00:00:03Z" +
- "2014-08-19T00:00:04Z" +
- "";
- String version4 = "" +
- uniqueTerm + " version4" +
- "" +
- "" +
- "2014-08-19T00:00:05Z" +
- "2014-08-19T00:00:06Z" +
- "";
-
- // write four versions of the same document
- StringHandle handle1 = new StringHandle(version1).withFormat(Format.XML);
- docMgr.write(docId, null, handle1, null, null, temporalCollection);
- StringHandle handle2 = new StringHandle(version2).withFormat(Format.XML);
- docMgr.write(docId, null, handle2, null, null, temporalCollection);
- StringHandle handle3 = new StringHandle(version3).withFormat(Format.XML);
- TemporalDescriptor desc = docMgr.write(docId, null, handle3, null, null, temporalCollection);
- assertNotNull(desc);
- assertEquals(docId, desc.getUri());
- String thirdWriteTimestamp = desc.getTemporalSystemTime();
- assertNotNull(thirdWriteTimestamp);
-
- StringHandle handle4 = new StringHandle(version4).withFormat(Format.XML);
- docMgr.write(docId, null, handle4, null, null, temporalCollection);
-
- // make sure non-temporal document read only returns the latest version
- try ( DocumentPage readResults = docMgr.read(docId) ) {
- assertEquals(1, readResults.size());
- DocumentRecord latestDoc = readResults.next();
- assertEquals(docId, latestDoc.getUri());
- }
-
- // make sure a simple term query returns all versions of bulk and other docs
- StructuredQueryBuilder sqb = queryMgr.newStructuredQueryBuilder();
- StructuredQueryDefinition termsQuery =
- sqb.or( sqb.term(uniqueTerm), sqb.term(uniqueBulkTerm) );
- long start = 1;
- try ( DocumentPage termQueryResults = docMgr.search(termsQuery, start) ) {
- assertEquals(12, termQueryResults.size());
- }
-
- StructuredQueryDefinition currentQuery = sqb.temporalLsqtQuery(temporalCollection, thirdWriteTimestamp, 1);
- StructuredQueryDefinition currentDocQuery = sqb.and(termsQuery, currentQuery);
- try {
- // query with lsqt of last inserted document
- // will throw an error because lsqt has not yet advanced
- try ( DocumentPage results = docMgr.search(currentDocQuery, start) ) {
- fail("Negative test should have generated a FailedRequestException of type TEMPORAL-GTLSQT");
- }
- } catch (FailedRequestException e) {
- assertTrue(e.getMessage().contains("TEMPORAL-GTLSQT"));
- }
-
- // now update lsqt
- Common.connectServerAdmin().newXMLDocumentManager().advanceLsqt(temporalCollection);
-
- // query again with lsqt of last inserted document
- // will match the first three versions -- not the last because it's equal to
- // not greater than the timestamp of this lsqt query
- try ( DocumentPage currentDocQueryResults = docMgr.search(currentDocQuery, start) ) {
- assertEquals(11, currentDocQueryResults.size());
- }
-
- // query with blank lsqt indicating current time
- // will match all four versions
- currentQuery = sqb.temporalLsqtQuery(temporalCollection, "", 1);
- currentDocQuery = sqb.and(termsQuery, currentQuery);
- try ( DocumentPage currentDocQueryResults = docMgr.search(currentDocQuery, start) ) {
- assertEquals(12, currentDocQueryResults.size());
- }
-
- StructuredQueryBuilder.Axis validAxis = sqb.axis("valid-axis");
-
- // create a time axis to query the versions against
- Calendar start1 = DatatypeConverter.parseDateTime("2014-08-19T00:00:00Z");
- Calendar end1 = DatatypeConverter.parseDateTime("2014-08-19T00:00:04Z");
- StructuredQueryBuilder.Period period1 = sqb.period(start1, end1);
-
- // find all documents contained in the time range of our query axis
- StructuredQueryDefinition periodQuery1 = sqb.and(termsQuery,
- sqb.temporalPeriodRange(validAxis, TemporalOperator.ALN_CONTAINED_BY, period1));
- try ( DocumentPage periodQuery1Results = docMgr.search(periodQuery1, start) ) {
- assertEquals(3, periodQuery1Results.size());
- }
-
- // create a second time axis to query the versions against
- Calendar start2 = DatatypeConverter.parseDateTime("2014-08-19T00:00:04Z");
- Calendar end2 = DatatypeConverter.parseDateTime("2014-08-19T00:00:07Z");
- StructuredQueryBuilder.Period period2 = sqb.period(start2, end2);
-
- // find all documents contained in the time range of our second query axis
- StructuredQueryDefinition periodQuery2 = sqb.and(termsQuery,
- sqb.temporalPeriodRange(validAxis, TemporalOperator.ALN_CONTAINED_BY, period2));
- try ( DocumentPage periodQuery2Results = docMgr.search(periodQuery2, start) ) {
- assertEquals(3, periodQuery2Results.size());
- for ( DocumentRecord result : periodQuery2Results ) {
- if ( docId.equals(result.getUri()) ) {
- continue;
- } else if ( result.getUri().startsWith("test_" + uniqueBulkTerm + "_4") ) {
- continue;
- }
- fail("Unexpected uri for ALN_CONTAINED_BY test:" + result.getUri());
- }
- }
-
- // find all documents where valid time is after system time in the document
- StructuredQueryBuilder.Axis systemAxis = sqb.axis("system-axis");
- StructuredQueryDefinition periodCompareQuery1 = sqb.and(termsQuery,
- sqb.temporalPeriodCompare(systemAxis, TemporalOperator.ALN_AFTER, validAxis));
- try ( DocumentPage periodCompareQuery1Results = docMgr.search(periodCompareQuery1, start) ) {
- assertEquals(12, periodCompareQuery1Results.size());
- }
-
- // find all documents where valid time is before system time in the document
- StructuredQueryDefinition periodCompareQuery2 = sqb.and(termsQuery,
- sqb.temporalPeriodCompare(systemAxis, TemporalOperator.ALN_BEFORE, validAxis));
- try ( DocumentPage periodCompareQuery2Results = docMgr.search(periodCompareQuery2, start) ) {
- assertEquals(0, periodCompareQuery2Results.size());
- }
-
- // check that we get a system time when we delete
- desc = docMgr.delete(docId, null, temporalCollection);
- assertNotNull(desc);
- assertEquals(docId, desc.getUri());
- assertNotNull(desc.getTemporalSystemTime());
-
- }
-
-
- static public void cleanUp() {
- DatabaseClient client = Common.newServerAdminClient();
- try {
- QueryManager queryMgr = client.newQueryManager();
- queryMgr.setPageLength(1000);
- QueryDefinition query = queryMgr.newStringDefinition();
- query.setCollections(temporalCollection);
- // DeleteQueryDefinition deleteQuery = client.newQueryManager().newDeleteDefinition();
- // deleteQuery.setCollections(temporalCollection);
- // client.newQueryManager().delete(deleteQuery);
- SearchHandle handle = queryMgr.search(query, new SearchHandle());
- MatchDocumentSummary[] docs = handle.getMatchResults();
- for ( MatchDocumentSummary doc : docs ) {
- if ( ! (temporalCollection + ".lsqt").equals(doc.getUri()) ) {
- client.newXMLDocumentManager().delete(doc.getUri());
- }
- }
- } finally {
- client.release();
- }
- }
+class BitemporalTest {
+
+ static String temporalCollection = "temporal-collection";
+ static XMLDocumentManager docMgr;
+ static QueryManager queryMgr;
+ static String uniqueBulkTerm = "temporalBulkDoc" + new Random().nextInt(10000);
+ static String uniqueTerm = "temporalDoc" + new Random().nextInt(10000);
+ static String docId = "test-" + uniqueTerm + ".xml";
+
+ @BeforeEach
+ void setup() {
+ Common.connect();
+ docMgr = Common.client.newXMLDocumentManager();
+ queryMgr = Common.client.newQueryManager();
+ }
+
+ @AfterEach
+ void teardown() {
+ try (DatabaseClient client = Common.newServerAdminClient()) {
+ QueryManager queryMgr = client.newQueryManager();
+ queryMgr.setPageLength(1000);
+ QueryDefinition query = queryMgr.newStringDefinition();
+ query.setCollections(temporalCollection);
+ SearchHandle handle = queryMgr.search(query, new SearchHandle());
+ MatchDocumentSummary[] docs = handle.getMatchResults();
+ for (MatchDocumentSummary doc : docs) {
+ if (!(temporalCollection + ".lsqt").equals(doc.getUri())) {
+ client.newXMLDocumentManager().delete(doc.getUri());
+ }
+ }
+ }
+ }
+
+ @Test
+ void writeTemporalDoc() {
+ String contents = """
+
+
+
+ 2014-08-19T00:00:00Z
+ 2014-08-19T00:00:01Z
+ """;
+
+ TemporalDescriptor desc = docMgr.create(docMgr.newDocumentUriTemplate("xml"),
+ null, new StringHandle(contents), null, null, temporalCollection);
+ assertNotNull(desc);
+ assertNotNull(desc.getUri());
+ assertTrue(desc.getUri().endsWith(".xml"));
+
+ String lastWriteTimestamp = desc.getTemporalSystemTime();
+ Calendar lastWriteTime = DatatypeConverter.parseDateTime(lastWriteTimestamp);
+ assertNotNull(lastWriteTime);
+ }
+
+ @Test
+ void writeTwoVersionsOfFourDocuments() throws XpathException {
+ String prefix = "test_" + uniqueBulkTerm;
+ String doc1 = """
+
+ %s doc1
+
+
+ 2014-08-19T00:00:00Z
+ 2014-08-19T00:00:01Z
+ """.formatted(uniqueBulkTerm);
+
+ String doc2 = """
+
+ %s doc2
+
+
+ 2014-08-19T00:00:02Z
+ 2014-08-19T00:00:03Z
+ """.formatted(uniqueBulkTerm);
+
+ String doc3 = """
+
+ %s doc3
+
+
+ 2014-08-19T00:00:03Z
+ 2014-08-19T00:00:04Z
+ """.formatted(uniqueBulkTerm);
+
+ String doc4 = """
+
+ %s doc4
+
+
+ 2014-08-19T00:00:05Z
+ 2014-08-19T00:00:06Z
+ """.formatted(uniqueBulkTerm);
+
+ DocumentWriteSet writeSet = docMgr.newWriteSet();
+ writeSet.add(prefix + "_1.xml", new StringHandle(doc1));
+ writeSet.add(prefix + "_2.xml", new StringHandle(doc2));
+ writeSet.add(prefix + "_3.xml", new StringHandle(doc3));
+ writeSet.add(prefix + "_4.xml", new StringHandle(doc4));
+ docMgr.write(writeSet, null, null, temporalCollection);
+
+ // do it one more time so we have two versions of each
+ writeSet = docMgr.newWriteSet();
+ writeSet.add(prefix + "_1.xml", new StringHandle(doc1));
+ writeSet.add(prefix + "_2.xml", new StringHandle(doc2));
+ writeSet.add(prefix + "_3.xml", new StringHandle(doc3));
+ writeSet.add(prefix + "_4.xml", new StringHandle(doc4));
+ docMgr.write(writeSet, null, null, temporalCollection);
+
+ StringQueryDefinition query = queryMgr.newStringDefinition().withCriteria(uniqueBulkTerm);
+ try (DocumentPage page = docMgr.search(query, 0)) {
+ assertEquals(8, page.size());
+ for (DocumentRecord record : page) {
+ Document doc = record.getContentAs(Document.class);
+ if (record.getUri().startsWith(prefix + "_1")) {
+ assertXpathEvaluatesTo("2014-08-19T00:00:00Z", "//valid-start", doc);
+ continue;
+ } else if (record.getUri().startsWith(prefix + "_2")) {
+ assertXpathEvaluatesTo("2014-08-19T00:00:02Z", "//valid-start", doc);
+ continue;
+ } else if (record.getUri().startsWith(prefix + "_3")) {
+ assertXpathEvaluatesTo("2014-08-19T00:00:03Z", "//valid-start", doc);
+ continue;
+ } else if (record.getUri().startsWith(prefix + "_4")) {
+ assertXpathEvaluatesTo("2014-08-19T00:00:05Z", "//valid-start", doc);
+ continue;
+ }
+ throw new IllegalStateException("Unexpected doc:[" + record.getUri() + "]");
+ }
+ }
+ }
+
+ @Test
+ void lsqtTest() {
+ // Due to bug MLE-24511 where LSQT properties aren't updated correctly in ml-gradle 6.0.0, we need to manually
+ // deploy them for this test.
+ ManageClient manageClient = Common.newManageClient();
+ TemporalCollectionLSQTManager mgr = new TemporalCollectionLSQTManager(manageClient, "java-unittest", "temporal-collection");
+ String payload = """
+ {
+ "lsqt-enabled": true,
+ "automation": {
+ "enabled": true,
+ "period": 5000
+ }
+ }
+ """;
+ mgr.save(payload);
+
+ String version1 = """
+
+ %s version1
+
+
+ 2014-08-19T00:00:00Z
+ 2014-08-19T00:00:01Z
+ """.formatted(uniqueTerm);
+
+ String version2 = """
+
+ %s version2
+
+
+ 2014-08-19T00:00:02Z
+ 2014-08-19T00:00:03Z
+ """.formatted(uniqueTerm);
+
+ String version3 = """
+
+ %s version3
+
+
+ 2014-08-19T00:00:03Z
+ 2014-08-19T00:00:04Z
+ """.formatted(uniqueTerm);
+
+ String version4 = """
+
+ %s version4
+
+
+ 2014-08-19T00:00:05Z
+ 2014-08-19T00:00:06Z
+ """.formatted(uniqueTerm);
+
+ // write four versions of the same document
+ StringHandle handle1 = new StringHandle(version1).withFormat(Format.XML);
+ docMgr.write(docId, null, handle1, null, null, temporalCollection);
+ StringHandle handle2 = new StringHandle(version2).withFormat(Format.XML);
+ docMgr.write(docId, null, handle2, null, null, temporalCollection);
+ StringHandle handle3 = new StringHandle(version3).withFormat(Format.XML);
+ TemporalDescriptor desc = docMgr.write(docId, null, handle3, null, null, temporalCollection);
+
+ assertNotNull(desc);
+ assertEquals(docId, desc.getUri());
+ String thirdWriteTimestamp = desc.getTemporalSystemTime();
+ assertNotNull(thirdWriteTimestamp);
+
+ StringHandle handle4 = new StringHandle(version4).withFormat(Format.XML);
+ docMgr.write(docId, null, handle4, null, null, temporalCollection);
+
+ // make sure non-temporal document read only returns the latest version
+ try (DocumentPage readResults = docMgr.read(docId)) {
+ assertEquals(1, readResults.size());
+ DocumentRecord latestDoc = readResults.next();
+ assertEquals(docId, latestDoc.getUri());
+ }
+
+ // make sure a simple term query returns all versions of bulk and other docs
+ StructuredQueryBuilder sqb = queryMgr.newStructuredQueryBuilder();
+ StructuredQueryDefinition termsQuery =
+ sqb.or(sqb.term(uniqueTerm), sqb.term(uniqueBulkTerm));
+ long start = 1;
+ try (DocumentPage termQueryResults = docMgr.search(termsQuery, start)) {
+ assertEquals(4, termQueryResults.size());
+ }
+
+ StructuredQueryDefinition currentQuery = sqb.temporalLsqtQuery(temporalCollection, thirdWriteTimestamp, 1);
+ StructuredQueryDefinition currentDocQuery = sqb.and(termsQuery, currentQuery);
+
+ final StructuredQueryDefinition queryThatWillFail = currentDocQuery;
+ FailedRequestException ex = assertThrows(FailedRequestException.class, () -> docMgr.search(queryThatWillFail, start));
+ String message = ex.getMessage();
+ assertTrue(message.contains("TEMPORAL"), "The query should fail, but the actual error code " +
+ "depends on the MarkLogic version. Prior to 12.1, the code was TEMPORAL-GTLSQT. " +
+ "On the develop branch for 12.1, it's TEMPORAL-NOLSQT. Actual message: " + message);
+
+ try (DatabaseClient client = Common.newServerAdminClient()) {
+ client.newXMLDocumentManager().advanceLsqt(temporalCollection);
+ }
+
+ // query again with lsqt of last inserted document
+ // will match the first three versions -- not the last because it's equal to
+ // not greater than the timestamp of this lsqt query
+ try (DocumentPage currentDocQueryResults = docMgr.search(currentDocQuery, start)) {
+ assertEquals(3, currentDocQueryResults.size());
+ }
+
+ // query with blank lsqt indicating current time
+ // will match all four versions
+ currentQuery = sqb.temporalLsqtQuery(temporalCollection, "", 1);
+ currentDocQuery = sqb.and(termsQuery, currentQuery);
+ try (DocumentPage currentDocQueryResults = docMgr.search(currentDocQuery, start)) {
+ assertEquals(4, currentDocQueryResults.size());
+ }
+
+ StructuredQueryBuilder.Axis validAxis = sqb.axis("valid-axis");
+
+ // create a time axis to query the versions against
+ Calendar start1 = DatatypeConverter.parseDateTime("2014-08-19T00:00:00Z");
+ Calendar end1 = DatatypeConverter.parseDateTime("2014-08-19T00:00:04Z");
+ StructuredQueryBuilder.Period period1 = sqb.period(start1, end1);
+
+ // find all documents contained in the time range of our query axis
+ StructuredQueryDefinition periodQuery1 = sqb.and(termsQuery,
+ sqb.temporalPeriodRange(validAxis, TemporalOperator.ALN_CONTAINED_BY, period1));
+ try (DocumentPage periodQuery1Results = docMgr.search(periodQuery1, start)) {
+ assertEquals(1, periodQuery1Results.size());
+ }
+
+ // create a second time axis to query the versions against
+ Calendar start2 = DatatypeConverter.parseDateTime("2014-08-19T00:00:04Z");
+ Calendar end2 = DatatypeConverter.parseDateTime("2014-08-19T00:00:07Z");
+ StructuredQueryBuilder.Period period2 = sqb.period(start2, end2);
+
+ // find all documents contained in the time range of our second query axis
+ StructuredQueryDefinition periodQuery2 = sqb.and(termsQuery,
+ sqb.temporalPeriodRange(validAxis, TemporalOperator.ALN_CONTAINED_BY, period2));
+ try (DocumentPage periodQuery2Results = docMgr.search(periodQuery2, start)) {
+ assertEquals(1, periodQuery2Results.size());
+ for (DocumentRecord result : periodQuery2Results) {
+ if (docId.equals(result.getUri())) {
+ continue;
+ } else if (result.getUri().startsWith("test_" + uniqueBulkTerm + "_4")) {
+ continue;
+ }
+ fail("Unexpected uri for ALN_CONTAINED_BY test:" + result.getUri());
+ }
+ }
+
+ // find all documents where valid time is after system time in the document
+ StructuredQueryBuilder.Axis systemAxis = sqb.axis("system-axis");
+ StructuredQueryDefinition periodCompareQuery1 = sqb.and(termsQuery,
+ sqb.temporalPeriodCompare(systemAxis, TemporalOperator.ALN_AFTER, validAxis));
+ try (DocumentPage periodCompareQuery1Results = docMgr.search(periodCompareQuery1, start)) {
+ assertEquals(4, periodCompareQuery1Results.size());
+ }
+
+ // find all documents where valid time is before system time in the document
+ StructuredQueryDefinition periodCompareQuery2 = sqb.and(termsQuery,
+ sqb.temporalPeriodCompare(systemAxis, TemporalOperator.ALN_BEFORE, validAxis));
+ try (DocumentPage periodCompareQuery2Results = docMgr.search(periodCompareQuery2, start)) {
+ assertEquals(0, periodCompareQuery2Results.size());
+ }
+
+ // check that we get a system time when we delete
+ desc = docMgr.delete(docId, null, temporalCollection);
+ assertNotNull(desc);
+ assertEquals(docId, desc.getUri());
+ assertNotNull(desc.getTemporalSystemTime());
+ }
}
diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java
index 9b11eee9d..03c795a84 100644
--- a/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java
+++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/Common.java
@@ -77,7 +77,6 @@ public X509Certificate[] getAcceptedIssuers() {
public static DatabaseClient client;
public static DatabaseClient restAdminClient;
- public static DatabaseClient serverAdminClient;
public static DatabaseClient evalClient;
public static DatabaseClient readOnlyClient;
@@ -93,12 +92,6 @@ public static DatabaseClient connectRestAdmin() {
return restAdminClient;
}
- public static DatabaseClient connectServerAdmin() {
- if (serverAdminClient == null)
- serverAdminClient = newServerAdminClient();
- return serverAdminClient;
- }
-
public static DatabaseClient connectEval() {
if (evalClient == null)
evalClient = newEvalClient();
@@ -274,9 +267,11 @@ public static ObjectNode newServerPayload() {
}
public static void deleteUrisWithPattern(String pattern) {
- Common.connectServerAdmin().newServerEval()
- .xquery(String.format("cts:uri-match('%s') ! xdmp:document-delete(.)", pattern))
- .evalAs(String.class);
+ try (DatabaseClient client = Common.newServerAdminClient()) {
+ client.newServerEval()
+ .xquery(String.format("cts:uri-match('%s') ! xdmp:document-delete(.)", pattern))
+ .evalAs(String.class);
+ }
}
/**
diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchWithOptionsTest.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchWithOptionsTest.java
index aa07928b9..acf3651e3 100644
--- a/marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchWithOptionsTest.java
+++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchWithOptionsTest.java
@@ -8,7 +8,6 @@
import com.marklogic.client.row.RowRecord;
import com.marklogic.client.test.junit5.RequiresML12;
import com.marklogic.client.type.PlanSearchOptions;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -45,15 +44,14 @@ void badBm25LengthWeight() {
}
@Test
- @Disabled("zero and random aren't in the 12 EA release.")
void zero() {
-// rowManager.withUpdate(false);
-// PlanSearchOptions options = op.searchOptions().withScoreMethod(PlanSearchOptions.ScoreMethod.ZERO);
-// List rows = resultRows(op.fromSearch(op.cts.wordQuery("saxophone"), null, null, options));
-// assertEquals(2, rows.size());
-// rows.forEach(row -> {
-// assertEquals(0, row.getInt("score"), "The score for every row should be 0.");
-// });
+ rowManager.withUpdate(false);
+ PlanSearchOptions options = op.searchOptions().withScoreMethod(PlanSearchOptions.ScoreMethod.ZERO);
+ List rows = resultRows(op.fromSearch(op.cts.wordQuery("saxophone"), null, null, options));
+ assertEquals(2, rows.size());
+ rows.forEach(row -> {
+ assertEquals(0, row.getInt("score"), "The score for every row should be 0.");
+ });
}
@Test
diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/OneWaySSLTest.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/OneWaySSLTest.java
index 44915e845..4118b5d7a 100644
--- a/marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/OneWaySSLTest.java
+++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/ssl/OneWaySSLTest.java
@@ -20,8 +20,6 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledOnJre;
-import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.extension.ExtendWith;
import javax.net.ssl.SSLContext;
@@ -162,9 +160,6 @@ void tLS13ClientWithTLS12Server() {
}
@ExtendWith(RequiresML12.class)
- // The TLSv1.3 tests are failing on Java 8, because TLSv1.3 is disabled with our version of Java 8.
- // There may be a way to configure Java 8 to use TLSv1.3, but it is not currently working.
- @DisabledOnJre(JRE.JAVA_8)
@Test
void tLS13ClientWithTLS13Server() {
setAppServerMinimumTLSVersion("TLSv1.3");
@@ -177,7 +172,6 @@ void tLS13ClientWithTLS13Server() {
}
@ExtendWith(RequiresML12.class)
- @DisabledOnJre(JRE.JAVA_8)
@Test
void tLS12ClientWithTLS13ServerShouldFail() {
setAppServerMinimumTLSVersion("TLSv1.3");