/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openengsb.core.edb.jpa.internal; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.Test; import org.openengsb.core.api.context.ContextHolder; import org.openengsb.core.api.model.CommitMetaInfo; import org.openengsb.core.api.model.CommitQueryRequest; import org.openengsb.core.api.model.QueryRequest; import org.openengsb.core.edb.api.EDBCommit; import org.openengsb.core.edb.api.EDBException; import org.openengsb.core.edb.api.EDBObject; import org.openengsb.core.edb.api.EDBObjectEntry; import com.google.common.collect.Lists; public class EDBQueryTest extends AbstractEDBTest { @Test public void testQueryWithSomeAspects_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("A", "B", data1); putValue("Cow", "Milk", data1); putValue("Dog", "Food", data1); EDBObject v1 = new EDBObject("/test/query1", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); long time1 = db.commit(ci); Map<String, EDBObjectEntry> data2 = new HashMap<String, EDBObjectEntry>(); putValue("Cow", "Milk", data2); putValue("House", "Garden", data2); v1 = new EDBObject("/test/query2", data2); ci = getEDBCommit(); ci.insert(v1); long time2 = db.commit(ci); QueryRequest req = QueryRequest.query("A", "B"); List<EDBObject> list1 = db.query(req); req = QueryRequest.query("A", "B").addParameter("Dog", "Food"); List<EDBObject> list2 = db.query(req); req = QueryRequest.query("Cow", "Milk"); List<EDBObject> list3 = db.query(req); req = QueryRequest.query("A", "B").addParameter("Cow", "Milk") .addParameter("House", "Garden"); List<EDBObject> list4 = db.query(req); assertThat(list1.size(), is(1)); assertThat(list2.size(), is(1)); assertThat(list3.size(), is(2)); assertThat(list4.size(), is(0)); checkTimeStamps(Arrays.asList(time1, time2)); } @Test public void testQueryOfOldVersion_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1v1 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 1", data1v1); putValue("pre:KeyB", "pre:Value A 1", data1v1); EDBObject v11 = new EDBObject("pre:/test/object1", data1v1); EDBCommit ci = getEDBCommit(); ci.insert(v11); Map<String, EDBObjectEntry> data2v1 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 2", data2v1); putValue("pre:KeyB", "pre:Value A 1", data2v1); EDBObject v12 = new EDBObject("pre:/test/object2", data2v1); ci.insert(v12); Map<String, EDBObjectEntry> data3v1 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 3", data3v1); putValue("pre:KeyB", "pre:Value A 1", data3v1); EDBObject v13 = new EDBObject("pre:/test/object3", data3v1); ci.insert(v13); long time1 = db.commit(ci); Map<String, EDBObjectEntry> data1v2 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 1", data1v2); putValue("pre:KeyB", "pre:Value A 1", data1v2); EDBObject v21 = new EDBObject("pre:/test/object1", data1v2); ci = getEDBCommit(); ci.update(v21); Map<String, EDBObjectEntry> data2v2 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 2", data2v2); putValue("pre:KeyB", "pre:Value A 1", data2v2); EDBObject v22 = new EDBObject("pre:/test/object2", data2v2); ci.update(v22); Map<String, EDBObjectEntry> data4v1 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 4", data4v1); putValue("pre:KeyB", "pre:Value A 1", data4v1); EDBObject v23 = new EDBObject("pre:/test/object4", data4v1); ci.update(v23); long time2 = db.commit(ci); Map<String, EDBObjectEntry> data1v3 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 1", data1v3); putValue("pre:KeyB", "pre:Value A 1", data1v3); EDBObject v31 = new EDBObject("pre:/test/object1", data1v3); ci = getEDBCommit(); ci.update(v31); Map<String, EDBObjectEntry> data2v3 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 2a", data2v3); putValue("pre:KeyB", "pre:Value A 1", data2v3); EDBObject v32 = new EDBObject("pre:/test/object2", data2v3); ci.update(v32); Map<String, EDBObjectEntry> data4v2 = new HashMap<String, EDBObjectEntry>(); putValue("pre:KeyA", "pre:Value A 4", data4v2); putValue("pre:KeyB", "pre:Value A 1", data4v2); EDBObject v33 = new EDBObject("pre:/test/object4", data4v2); ci.update(v33); long time3 = db.commit(ci); List<EDBObject> result = db.query(QueryRequest.query("pre:KeyB", "pre:Value A 1") .setTimestamp(time2)); boolean b1 = false; boolean b2 = false; boolean b3 = false; for (EDBObject e : result) { if (e.getString("pre:KeyA").equals("pre:Value A 1")) { b1 = true; } if (e.getString("pre:KeyA").equals("pre:Value A 2")) { b2 = true; } if (e.getString("pre:KeyA").equals("pre:Value A 3")) { b3 = true; } } assertThat(b1, is(true)); assertThat(b2, is(true)); assertThat(b3, is(true)); assertThat(time1 > 0, is(true)); assertThat(time2 > 0, is(true)); assertThat(time3 > 0, is(true)); } @Test public void testQueryWithTimestamp_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("K", "B", data1); putValue("Cow", "Milk", data1); putValue("Dog", "Food", data1); EDBObject v1 = new EDBObject("/test/querynew1", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); data1 = new HashMap<String, EDBObjectEntry>(); putValue("Dog", "Food", data1); v1 = new EDBObject("/test/querynew1", data1); ci = getEDBCommit(); ci.update(v1); db.commit(ci); data1 = new HashMap<String, EDBObjectEntry>(); putValue("K", "B", data1); putValue("Dog", "Food", data1); v1 = new EDBObject("/test/querynew2", data1); ci = getEDBCommit(); ci.insert(v1); db.commit(ci); List<EDBObject> result = db.query(QueryRequest.query("K", "B")); assertThat(result.size(), is(1)); } @Test public void testQueryWithTimestampAndEmptyMap_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("K", "B", data1); putValue("Cow", "Milk", data1); putValue("Dog", "Food", data1); EDBObject v1 = new EDBObject("/test/querynew3", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); data1 = new HashMap<String, EDBObjectEntry>(); putValue("Dog", "Food", data1); v1 = new EDBObject("/test/querynew3", data1); ci = getEDBCommit(); ci.update(v1); db.commit(ci); data1 = new HashMap<String, EDBObjectEntry>(); putValue("K", "B", data1); putValue("Dog", "Food", data1); v1 = new EDBObject("/test/querynew4", data1); ci = getEDBCommit(); ci.insert(v1); db.commit(ci); List<EDBObject> result = db.query(QueryRequest.create()); EDBObject result1 = getEDBObjectOutOfList(result, "/test/querynew3"); EDBObject result2 = getEDBObjectOutOfList(result, "/test/querynew4"); assertThat(result.size(), is(2)); assertThat(result1.containsKey("K"), is(false)); assertThat(result2.containsKey("Dog"), is(true)); } @Test public void testQueryOfLastKnownVersion_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1v1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 1", data1v1); putValue("KeyB", "Value A 1", data1v1); EDBObject v11 = new EDBObject("/test/object1", data1v1); EDBCommit ci = getEDBCommit(); ci.insert(v11); Map<String, EDBObjectEntry> data2v1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 2", data2v1); putValue("KeyB", "Value A 1", data2v1); EDBObject v12 = new EDBObject("/test/object2", data2v1); ci.insert(v12); Map<String, EDBObjectEntry> data3v1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 3", data3v1); putValue("KeyB", "Value A 1", data3v1); EDBObject v13 = new EDBObject("/test/object3", data3v1); ci.insert(v13); long time1 = db.commit(ci); ci = getEDBCommit(); Map<String, EDBObjectEntry> data1v2 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 1", data1v2); putValue("KeyB", "Value A 1", data1v2); EDBObject v21 = new EDBObject("/test/object1", data1v2); ci.update(v21); Map<String, EDBObjectEntry> data2v2 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 2", data2v2); putValue("KeyB", "Value A 1", data2v2); EDBObject v22 = new EDBObject("/test/object2", data2v2); ci.update(v22); long time2 = db.commit(ci); ci = getEDBCommit(); Map<String, EDBObjectEntry> data2v3 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 2a", data2v3); putValue("KeyB", "Value A 1", data2v3); EDBObject v32 = new EDBObject("/test/object2", data2v3); ci.update(v32); Map<String, EDBObjectEntry> data4v1 = new HashMap<String, EDBObjectEntry>(); putValue("KeyA", "Value A 4", data4v1); putValue("KeyB", "Value A 1", data4v1); EDBObject v33 = new EDBObject("/test/object4", data4v1); ci.insert(v33); long time3 = db.commit(ci); Map<String, Object> map = new HashMap<String, Object>(); map.put("KeyB", "Value A 1"); List<EDBObject> result = db.query(QueryRequest.query("KeyB", "Value A 1").setTimestamp(time3)); boolean b1 = false; boolean b2 = false; boolean b3 = false; boolean b4 = false; for (EDBObject e : result) { if (e.getString("KeyA").equals("Value A 1")) { b1 = true; } if (e.getString("KeyA").equals("Value A 2a")) { b2 = true; } if (e.getString("KeyA").equals("Value A 3")) { b3 = true; } if (e.getString("KeyA").equals("Value A 4")) { b4 = true; } } assertThat(b1, is(true)); assertThat(b2, is(true)); assertThat(b3, is(true)); assertThat(b4, is(true)); assertThat(time1 > 0, is(true)); assertThat(time2 > 0, is(true)); assertThat(time3 > 0, is(true)); } @Test public void testIfQueryingWithLikeWorks_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("bla", "teststring", data1); EDBObject v1 = new EDBObject("/test/query/8", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); List<EDBObject> result = db.query(QueryRequest.query("bla", "test%").wildcardAware()); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/8")); result = db.query(QueryRequest.query("bla", "test_tring").wildcardAware()); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/8")); result = db.query(QueryRequest.query("bla", "test%").wildcardUnaware()); assertThat(result.size(), is(0)); } @Test public void testIfRetrievingCommitByRevisionWorks_shouldWork() throws Exception { Map<String, EDBObjectEntry> entries = new HashMap<String, EDBObjectEntry>(); entries.put("test", new EDBObjectEntry("test", "test", String.class)); EDBObject obj = new EDBObject("/test/query/9", entries); EDBCommit ci = getEDBCommit(); ci.insert(obj); db.commit(ci); EDBCommit test = db.getCommitByRevision(ci.getRevisionNumber().toString()); assertThat(test, notNullValue()); assertThat(test, is(ci)); assertThat(test.getInserts().get(0).getString("test"), is("test")); } @Test public void testIfRetrievingCommitByRevisionWithIntermediateCommitsWorks_shouldWork() throws Exception { Map<String, EDBObjectEntry> entries = new HashMap<String, EDBObjectEntry>(); entries.put("test", new EDBObjectEntry("test", "test", String.class)); EDBObject obj = new EDBObject("/test/query/10", entries); EDBCommit ci = getEDBCommit(); ci.insert(obj); db.commit(ci); String revision = ci.getRevisionNumber().toString(); obj.putEDBObjectEntry("test", "test2", String.class); EDBCommit ci2 = getEDBCommit(); ci2.update(obj); db.commit(ci2); EDBCommit test = db.getCommitByRevision(revision); assertThat(test, notNullValue()); assertThat(test, is(ci)); assertThat(test.getInserts().get(0).getString("test"), is("test")); } @Test(expected = EDBException.class) public void testIfRetrievingCommitByInvalidRevisionFails_shouldFail() throws Exception { db.getCommitByRevision(UUID.randomUUID().toString()); } @Test public void testIfRetrievingCommitRevisionsByRequestGivesCorrectRevisions_shouldWork() throws Exception { Map<String, EDBObjectEntry> entries = new HashMap<String, EDBObjectEntry>(); entries.put("test", new EDBObjectEntry("test", "test", String.class)); EDBObject obj = new EDBObject("/test/query/11", entries); EDBCommit ci = getEDBCommit(); ci.insert(obj); Long timestamp1 = db.commit(ci); String revision1 = ci.getRevisionNumber().toString(); obj.putEDBObjectEntry("test2", "test2", String.class); ci = getEDBCommit(); ci.setComment("this is a comment"); ci.update(obj); Long timestamp2 = db.commit(ci); String revision2 = ci.getRevisionNumber().toString(); CommitQueryRequest request = new CommitQueryRequest(); request.setCommitter("wrongName"); assertThat(db.getRevisionsOfMatchingCommits(request).size(), is(0)); request = new CommitQueryRequest(); request.setCommitter("wrongContext"); assertThat(db.getRevisionsOfMatchingCommits(request).size(), is(0)); request = new CommitQueryRequest(); request.setStartTimestamp(timestamp1); List<CommitMetaInfo> revisions = db.getRevisionsOfMatchingCommits(request); assertThat(revisions.size(), is(2)); assertThat(revisions.get(0).getRevision(), is(revision1)); assertThat(revisions.get(1).getRevision(), is(revision2)); request = new CommitQueryRequest(); request.setStartTimestamp(timestamp1); request.setCommitter("testuser"); revisions = db.getRevisionsOfMatchingCommits(request); assertThat(revisions.size(), is(2)); assertThat(revisions.get(0).getRevision(), is(revision1)); assertThat(revisions.get(1).getRevision(), is(revision2)); request = new CommitQueryRequest(); request.setStartTimestamp(timestamp2); revisions = db.getRevisionsOfMatchingCommits(request); assertThat(revisions.size(), is(1)); assertThat(revisions.get(0).getRevision(), is(revision2)); assertThat(revisions.get(0).getCommitter(), is(COMMITTER)); assertThat(revisions.get(0).getContext(), is(CONTEXT)); assertThat(revisions.get(0).getTimestamp(), is(timestamp2)); assertThat(revisions.get(0).getComment(), is("this is a comment")); } @Test public void testIfQueryingWithCaseInsensitivity_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("test", "This is A test", data1); EDBObject v1 = new EDBObject("/test/query/12", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); List<EDBObject> result = db.query(QueryRequest.query("test", "this is a test").caseInsensitive()); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/12")); result = db.query(QueryRequest.query("test", "this is a test").caseSensitive()); assertThat(result.size(), is(0)); } @Test public void testIfQueryingWithCaseSensitivityAndWildcards_shouldWork() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<String, EDBObjectEntry>(); putValue("test", "This is A new test", data1); EDBObject v1 = new EDBObject("/test/query/13", data1); EDBCommit ci = getEDBCommit(); ci.insert(v1); db.commit(ci); List<EDBObject> result = db.query(QueryRequest.query("test", "this is a % test") .caseInsensitive().wildcardAware()); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/13")); result = db.query(QueryRequest.query("test", "this is a % test").caseInsensitive().wildcardUnaware()); assertThat(result.size(), is(0)); result = db.query(QueryRequest.query("test", "This is % new test").caseSensitive().wildcardUnaware()); assertThat(result.size(), is(0)); result = db.query(QueryRequest.query("test", "This is % new test").caseSensitive().wildcardAware()); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/13")); } @Test public void testIfLastRevisionNumberOfContextWorks_shouldReturnCorrectRevisions() throws Exception { String context1 = "context1"; String context2 = "context2"; String context3 = "context3"; ContextHolder.get().setCurrentContextId(context1); EDBObject obj = new EDBObject("/test/context/1"); EDBCommit commit = getEDBCommit(); commit.insert(obj); db.commit(commit); UUID revision1 = commit.getRevisionNumber(); ContextHolder.get().setCurrentContextId(context2); obj = new EDBObject("/test/context/2"); commit = getEDBCommit(); commit.insert(obj); db.commit(commit); UUID revision2 = commit.getRevisionNumber(); ContextHolder.get().setCurrentContextId(context3); obj = new EDBObject("/test/context/3"); commit = getEDBCommit(); commit.insert(obj); db.commit(commit); UUID revision3 = commit.getRevisionNumber(); ContextHolder.get().setCurrentContextId(CONTEXT); obj = new EDBObject("/test/context/4"); commit = getEDBCommit(); commit.insert(obj); db.commit(commit); assertThat(db.getLastRevisionNumberOfContext(context1), is(revision1)); assertThat(db.getLastRevisionNumberOfContext(context2), is(revision2)); assertThat(db.getLastRevisionNumberOfContext(context3), is(revision3)); assertThat(db.getLastRevisionNumberOfContext("notExistingContext"), nullValue()); } @Test public void testIfOrRequestsAreWorking_shouldReturnCorrectObjects() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<>(); putValue("Cow", "Milk", data1); putValue("Cheese", "Cheddar", data1); EDBObject v1 = new EDBObject("/test/query/14/1", data1); Map<String, EDBObjectEntry> data2 = new HashMap<>(); putValue("Animal", "Dog", data2); putValue("Cow", "Milk", data2); EDBObject v2 = new EDBObject("/test/query/14/2", data2); Map<String, EDBObjectEntry> data3 = new HashMap<>(); putValue("House", "Garden", data3); EDBObject v3 = new EDBObject("/test/query/14/3", data3); Map<String, EDBObjectEntry> data4 = new HashMap<>(); putValue("Cheese", "Cheddar", data4); putValue("Animal", "Dog", data4); EDBObject v4 = new EDBObject("/test/query/14/4", data4); Map<String, EDBObjectEntry> data5 = new HashMap<>(); putValue("Cheese", "Cheddar", data5); putValue("Animal", "Dog", data5); putValue("Cow", "Steak", data5); EDBObject v5 = new EDBObject("/test/query/14/5", data5); EDBCommit commit = getEDBCommit(); commit.insert(v1); commit.insert(v2); commit.insert(v3); commit.insert(v4); commit.insert(v5); db.commit(commit); QueryRequest request = QueryRequest.create().orJoined(); request.addParameter("Cow", "Milk"); assertThat(db.query(request).size(), is(2)); request.addParameter("Cow", "Steak"); assertThat(db.query(request).size(), is(3)); request.addParameter("Animal", "Dog"); assertThat(db.query(request).size(), is(4)); request.removeParameter("Cow"); assertThat(db.query(request).size(), is(3)); request.addParameter("Cow", "Milk").addParameter("House", "Garden"); assertThat(db.query(request).size(), is(5)); } @Test public void testIfContextSpecificQueriesWork_shouldReturnCorrectObjects() throws Exception { Map<String, EDBObjectEntry> data1 = new HashMap<>(); putValue("Cow", "Milk", data1); putValue("Cheese", "Cheddar", data1); EDBObject v1 = new EDBObject("/test/query/15/1", data1); Map<String, EDBObjectEntry> data2 = new HashMap<>(); putValue("Animal", "Dog", data2); putValue("Cow", "Milk", data2); EDBObject v2 = new EDBObject("/test/query/15/2", data2); EDBCommit commit = getEDBCommit(); commit.insert(v1); commit.insert(v2); db.commit(commit); Map<String, EDBObjectEntry> data3 = new HashMap<>(); putValue("House", "Garden", data3); EDBObject v3 = new EDBObject("/test2/query/15/3", data3); Map<String, EDBObjectEntry> data4 = new HashMap<>(); putValue("Cheese", "Cheddar", data4); putValue("Animal", "Dog", data4); EDBObject v4 = new EDBObject("/test2/query/15/4", data4); commit = getEDBCommit(); commit.insert(v3); commit.insert(v4); db.commit(commit); QueryRequest request = QueryRequest.create().orJoined(); request.addParameter("Animal", "Dog"); assertThat(db.query(request).size(), is(2)); request.setContextId("/test"); List<EDBObject> result = db.query(request); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test/query/15/2")); request.setContextId("/test2"); result = db.query(request); assertThat(result.size(), is(1)); assertThat(result.get(0).getOID(), is("/test2/query/15/4")); } @Test public void testIfQueryForDeletedObjects_onlyReturnsDeletedObjects() { EDBObject v1 = createRandomTestObject("/test/query/16/1"); commitObjects(Lists.newArrayList(v1), null, null); commitObjects(null, null, Lists.newArrayList(v1)); QueryRequest request = QueryRequest.create(); List<EDBObject> result = db.query(request); assertThat(result.size(), is(0)); result = db.query(request.deleted()); assertThat(result.size(), is(1)); } }