aboutsummaryrefslogtreecommitdiffstats
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java72
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java50
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java239
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java62
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java53
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java142
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java331
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java195
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java57
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java175
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java261
-rw-r--r--src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java761
-rw-r--r--src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java1029
-rw-r--r--src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java150
-rw-r--r--src/test/java/org/openecomp/aai/champ/ie/ExportTest.java42
-rw-r--r--src/test/java/org/openecomp/aai/champ/ie/ImportTest.java93
-rwxr-xr-xsrc/test/resources/import-test.graphml49
-rw-r--r--src/test/resources/logback.xml43
18 files changed, 3804 insertions, 0 deletions
diff --git a/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java b/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java
new file mode 100644
index 0000000..a9a6b75
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java
@@ -0,0 +1,72 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.concurrency;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.core.ChampObjectTest;
+import org.openecomp.aai.champ.core.ChampRelationshipTest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConcurrencyTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConcurrencyTest.class);
+
+ @Test
+ public void runConcurrentTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ runConcurrencyTest(api);
+ api.shutdown();
+ }
+ }
+
+ private void runConcurrencyTest(ChampAPI api) {
+ final int numThreads = 10;
+ final ExecutorService es = Executors.newFixedThreadPool(numThreads);
+
+ for (int i = 0; i < numThreads * 2; i++) {
+ es.submit(new Runnable() {
+ @Override
+ public void run() {
+ final ChampGraph graph = api.getGraph(ConcurrencyTest.class.getSimpleName());
+ ChampObjectTest.testChampObjectCrud(graph);
+ ChampRelationshipTest.testChampRelationshipCrud(graph);
+ }
+ });
+ }
+
+ try {
+ es.shutdown();
+ es.awaitTermination(60, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ LOGGER.warn("Interrupted while waiting for concurrency test to finish", e);
+ return;
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java b/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java
new file mode 100644
index 0000000..7d374c3
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java
@@ -0,0 +1,50 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BaseChampAPITest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BaseChampAPITest.class);
+
+ protected static void cleanUp(String graphName) {
+ LOGGER.warn("cleanUp is disabled for unit tests - you can enable it by commenting out the code below this log message, please don't commit it though");
+
+ /*
+ LOGGER.debug("Cleaning up graph {}", graphName);
+
+ try {
+ final TitanGraph graph = TitanFactory.build()
+ .set("storage.backend", "cassandra")
+ .set("storage.hostname", "localhost")
+ .set("storage.cassandra.keyspace", graphName)
+ .open();
+ graph.close();
+ TitanCleanup.clear(graph);
+ } catch (IllegalArgumentException e) {
+ LOGGER.warn("Could not clean up graph - unable to instantiate");
+ }
+ */
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java b/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java
new file mode 100644
index 0000000..7cd259e
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java
@@ -0,0 +1,239 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.model.ChampObjectConstraint;
+import org.openecomp.aai.champ.model.ChampRelationshipConstraint;
+
+public class ChampAPITest {
+
+ @Test
+ public void testChampAPIInstantiation() {
+
+ for (ChampGraph.Type type : ChampGraph.Type.values()) {
+
+ final ChampAPI api = ChampAPI.Factory.newInstance(type);
+
+ assertTrue(type == ChampGraph.Type.valueOf(type.name()));
+ assertTrue(api.getType() == type);
+
+ api.getGraph("foo");
+ api.shutdown();
+
+ try {
+ api.getGraph("foo");
+ throw new AssertionError("Able to call getGraph(String name) after shutdown()");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+ }
+ }
+
+ @Test
+ public void testChampGraphInstantiation() throws Exception {
+ for (ChampGraph.Type type : ChampGraph.Type.values()) {
+ final ChampGraph graph = ChampGraph.Factory.newInstance(type, "foo");
+
+ graph.shutdown();
+
+ try {
+ graph.deleteObject(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.deleteObjectIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.deletePartition(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.deleteRelationship(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.deleteRelationshipIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.deleteSchema();
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.queryObjects(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.queryRelationships(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveObject(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveObjectIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveObjectIndices();
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveRelationship(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveRelationshipIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveRelationshipIndices();
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveRelationships(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.retrieveSchema();
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeObject(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeObjectIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storePartition(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeRelationship(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeRelationshipIndex(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeSchema(null);
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.updateSchema(new ChampObjectConstraint.Builder("").build());
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.updateSchema(new ChampRelationshipConstraint.Builder("").build());
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+
+ try {
+ graph.shutdown();
+ throw new AssertionError("Able to call API method after shutdown was initiated");
+ } catch (IllegalStateException e) {
+ //Expected
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java
new file mode 100644
index 0000000..4d34f8a
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.model.ChampElement;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampRelationship;
+
+public class ChampElementTest {
+
+ @Test
+ public void testChampElement() {
+ final ChampElement fooElement = new ChampObject.Builder("foo").build();
+
+ assertTrue(fooElement.isObject());
+ assertTrue(!fooElement.isRelationship());
+ assertTrue(fooElement.asObject() instanceof ChampObject);
+
+ try {
+ fooElement.asRelationship();
+ throw new AssertionError("Failed to throw exception when calling asRelationship() on a ChampObject");
+ } catch (UnsupportedOperationException e) {
+ //Expected
+ }
+
+ final ChampElement barElement = new ChampObject.Builder("bar").build();
+ final ChampElement usesElement = new ChampRelationship.Builder(fooElement.asObject(), barElement.asObject(), "uses").build();
+
+ assertTrue(usesElement.isRelationship());
+ assertTrue(!usesElement.isObject());
+ assertTrue(usesElement.asRelationship() instanceof ChampRelationship);
+
+ try {
+ usesElement.asObject();
+ throw new AssertionError("Failed to throw exception when calling asObject() on a ChampRelationship");
+ } catch (UnsupportedOperationException e) {
+ //Expected
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java
new file mode 100644
index 0000000..f852d9d
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.model.ChampField;
+
+public class ChampFieldTest {
+
+ @Test
+ public void testChampField() {
+ final ChampField a = new ChampField.Builder("a")
+ .type(ChampField.Type.STRING)
+ .build();
+
+ final ChampField aEquivalent = new ChampField.Builder("a")
+ .build();
+
+ final ChampField b = new ChampField.Builder("b")
+ .build();
+
+ assertTrue(a.equals(aEquivalent));
+ assertTrue(!a.equals(new Object()));
+ assertTrue(!a.equals(b));
+
+ assertTrue(a.compareTo(aEquivalent) == 0);
+ assertTrue(a.compareTo(b) != 0);
+
+ assertTrue(a.toString().equals(aEquivalent.toString()));
+ assertTrue(!a.toString().equals(b.toString()));
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java
new file mode 100644
index 0000000..6f71664
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java
@@ -0,0 +1,142 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException;
+import org.openecomp.aai.champ.model.ChampObjectIndex;
+
+public class ChampObjectIndexTest extends BaseChampAPITest {
+ @Test
+ public void runTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ final String graphName = api.getClass().getSimpleName();
+
+ switch (apiType) {
+ case IN_MEMORY:
+ break;
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ ChampObjectIndexTest.testChampObjectIndexCrud(api.getGraph(graphName));
+
+ api.shutdown();
+ }
+ }
+
+ private static void testChampObjectIndexCrud(ChampGraph graph) {
+
+ final ChampObjectIndex objectIndex = ChampObjectIndex.create()
+ .ofName("fooObjectIndex")
+ .onType("foo")
+ .forField("propertyName")
+ .build();
+
+ testChampObjectIndexStorage(graph, objectIndex);
+ testChampObjectIndexDelete(graph, objectIndex);
+ }
+
+ private static void testChampObjectIndexDelete(ChampGraph graph, ChampObjectIndex objectIndex) {
+
+ if (!graph.capabilities().canDeleteObjectIndices()) {
+ try {
+ graph.deleteObjectIndex("someindex");
+ throw new AssertionError("Graph claims it does not support object index delete, but failed to throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ } catch (ChampIndexNotExistsException e) {
+ throw new AssertionError("Graph claims it does not support object index delete, but failed to throw UnsupportedOperationException");
+ }
+ } else {
+ try {
+ graph.deleteObjectIndex(objectIndex.getName());
+
+ final Optional<ChampObjectIndex> retrievedObjectIndex = graph.retrieveObjectIndex(objectIndex.getName());
+
+ if (retrievedObjectIndex.isPresent()) throw new AssertionError("Retrieved object index after deleting it");
+
+ final Stream<ChampObjectIndex> retrievedObjectIndices = graph.retrieveObjectIndices();
+ final Collection<ChampObjectIndex> allObjectIndices = retrievedObjectIndices.collect(Collectors.toList());
+
+ if (allObjectIndices.contains(objectIndex)) throw new AssertionError("Retrieve all indices contained index previously deleted");
+ if (allObjectIndices.size() != 0) throw new AssertionError("Wrong number of indices returned by retrieve all indices");
+
+ } catch (ChampIndexNotExistsException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ graph.deleteObjectIndex(objectIndex.getName());
+ throw new AssertionError("Failed to throw exception on non-existent object index");
+ } catch (ChampIndexNotExistsException e) {
+ //Expected
+ }
+ }
+ }
+
+ private static void testChampObjectIndexStorage(ChampGraph graph, ChampObjectIndex objectIndex) {
+
+ graph.storeObjectIndex(objectIndex);
+ graph.storeObjectIndex(objectIndex); //Test storing an already existing object index
+
+ assertTrue(!graph.retrieveRelationshipIndex(objectIndex.getName()).isPresent()); //Make sure this wasn't stored as an object index
+
+ final Optional<ChampObjectIndex> retrieveObjectIndex = graph.retrieveObjectIndex(objectIndex.getName());
+
+ if (!retrieveObjectIndex.isPresent()) throw new AssertionError("Failed to retrieve object index after storing it");
+ if (!objectIndex.equals(retrieveObjectIndex.get())) throw new AssertionError("Non-equal object index returned from API after storing it");
+
+ final Stream<ChampObjectIndex> retrievedObjectIndices = graph.retrieveObjectIndices();
+ final Collection<ChampObjectIndex> allObjectIndices = retrievedObjectIndices.collect(Collectors.toList());
+
+ if (!allObjectIndices.contains(objectIndex)) throw new AssertionError("Retrieve all indices did not contained index previously stored");
+ if (allObjectIndices.size() != 1) throw new AssertionError("Wrong number of indices returned by retrieve all indices");
+
+ assertTrue(!graph.retrieveObjectIndex("nonExistentIndexName").isPresent());
+ }
+
+ @Test
+ public void testFluentRelationshipCreation() {
+ final ChampObjectIndex objectIndex = ChampObjectIndex.create()
+ .ofName("fooNameIndex")
+ .onType("foo")
+ .forField("name")
+ .build();
+
+ assertTrue(objectIndex.getName().equals("fooNameIndex"));
+ assertTrue(objectIndex.getType().equals("foo"));
+ assertTrue(objectIndex.getField().getName().equals("name"));
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java
new file mode 100644
index 0000000..f149243
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java
@@ -0,0 +1,331 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
+import org.openecomp.aai.champ.model.ChampCardinality;
+import org.openecomp.aai.champ.model.ChampField;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampSchema;
+
+public class ChampObjectTest extends BaseChampAPITest {
+
+ @Test
+ public void testHashCode() {
+ final ChampObject foo1 = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("property", "value")
+ .withProperty("prop", 1)
+ .build();
+
+ final ChampObject foo2 = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("property", "value")
+ .withProperty("prop", 1)
+ .build();
+
+ final ChampObject foo1Copy = ChampObject.create()
+ .from(foo1)
+ .withoutKey()
+ .build();
+
+ final ChampObject foo2Copy = ChampObject.create()
+ .from(foo2)
+ .withoutKey()
+ .build();
+
+ assertTrue(foo1.hashCode() == foo2.hashCode());
+ assertTrue(foo1.hashCode() == foo1.hashCode());
+ assertTrue(foo2.hashCode() == foo2.hashCode());
+ assertTrue(foo1.hashCode() == foo1Copy.hashCode());
+ assertTrue(foo2.hashCode() == foo2Copy.hashCode());
+
+ assertTrue(Collections.singleton(foo1).contains(foo1));
+ assertTrue(Collections.singleton(foo1).contains(foo1Copy));
+ }
+
+ @Test
+ public void runTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final String graphName = ChampObjectTest.class.getSimpleName();
+ switch (apiType) {
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ ChampObjectTest.testChampObjectCrud(api.getGraph(graphName));
+ testChampObjectReservedProperties(api.getGraph(graphName));
+ api.shutdown();
+ }
+ }
+
+ public static void testChampObjectCrud(ChampGraph graph) {
+ final ChampObject bookooObject = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("property1", "value1")
+ .withProperty("integer", 1)
+ .withProperty("long", 1L)
+ .withProperty("double", 1.2)
+ .withProperty("float", 2.3F)
+ .withProperty("string", "foo")
+ .withProperty("boolean", true)
+ .withProperty("list", Collections.singletonList("list"))
+ .withProperty("set", Collections.singleton("set"))
+ .build();
+
+ final ChampObject storedBookooObject;
+
+ try {
+
+ graph.storeSchema(ChampSchema.create()
+ .withObjectConstraint()
+ .onType("foo")
+ .withPropertyConstraint()
+ .onField("list")
+ .ofType(ChampField.Type.STRING)
+ .cardinality(ChampCardinality.LIST)
+ .optional()
+ .build()
+ .withPropertyConstraint()
+ .onField("set")
+ .ofType(ChampField.Type.STRING)
+ .cardinality(ChampCardinality.SET)
+ .optional()
+ .build()
+ .build()
+ .build());
+
+ storedBookooObject = graph.storeObject(bookooObject);
+
+ assertTrue(storedBookooObject.getProperty("property1").get().equals("value1"));
+ assertTrue(storedBookooObject.getProperty("integer").get().equals(1));
+ assertTrue(storedBookooObject.getProperty("long").get().equals(1L));
+ assertTrue(storedBookooObject.getProperty("double").get().equals(1.2));
+ assertTrue(storedBookooObject.getProperty("float").get().equals(2.3F));
+ assertTrue(storedBookooObject.getProperty("string").get().equals("foo"));
+ assertTrue(storedBookooObject.getProperty("boolean").get().equals(true));
+ assertTrue(storedBookooObject.getProperty("list").get().equals(Collections.singletonList("list")));
+ assertTrue(storedBookooObject.getProperty("set").get().equals(Collections.singleton("set")));
+
+ final Optional<ChampObject> retrievedBookooObject = graph.retrieveObject(storedBookooObject.getKey().get());
+ final Stream<ChampObject> emptyStream = graph.queryObjects(new HashMap<String, Object> () {{
+ put(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_TYPE.toString(), "foo");
+ put("long", 2L);
+ }});
+
+ assertTrue(emptyStream.limit(1).count() == 0);
+
+ final Stream<ChampObject> oneStream = graph.queryObjects(new HashMap<String, Object> () {{
+ put(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_TYPE.toString(), "foo");
+ put("long", 1L);
+ }});
+ final List<ChampObject> oneObject = oneStream.limit(2).collect(Collectors.toList());
+ assertTrue(oneObject.size() == 1);
+ assertTrue(oneObject.get(0).equals(storedBookooObject));
+
+ final List<ChampObject> queryByKey = graph.queryObjects(Collections.singletonMap(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_KEY.toString(), storedBookooObject.getKey().get()))
+ .limit(2)
+ .collect(Collectors.toList());
+
+ assertTrue(queryByKey.size() == 1);
+ assertTrue(queryByKey.get(0).equals(storedBookooObject));
+
+ if (!retrievedBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + bookooObject);
+ if (!storedBookooObject.equals(retrievedBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object");
+
+ final ChampObject updatedBookoo = graph.storeObject(ChampObject.create()
+ .from(storedBookooObject)
+ .withKey(storedBookooObject.getKey().get())
+ .withProperty("long", 2L)
+ .build());
+
+ final Optional<ChampObject> retrievedUpdBookooObject = graph.retrieveObject(updatedBookoo.getKey().get());
+
+ assertTrue(updatedBookoo.getProperty("property1").get().equals("value1"));
+ assertTrue(updatedBookoo.getProperty("integer").get().equals(1));
+ assertTrue(updatedBookoo.getProperty("long").get().equals(2L));
+ assertTrue(updatedBookoo.getProperty("double").get().equals(1.2));
+ assertTrue(updatedBookoo.getProperty("float").get().equals(2.3F));
+ assertTrue(updatedBookoo.getProperty("string").get().equals("foo"));
+ assertTrue(updatedBookoo.getProperty("boolean").get().equals(true));
+ assertTrue(updatedBookoo.getProperty("list").get().equals(Collections.singletonList("list")));
+ assertTrue(updatedBookoo.getProperty("set").get().equals(Collections.singleton("set")));
+
+ if (!retrievedUpdBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + bookooObject);
+ if (!updatedBookoo.equals(retrievedUpdBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object");
+
+ //validate the replaceObject method
+ final ChampObject replacedBookoo = graph.replaceObject(ChampObject.create()
+ .ofType("foo")
+ .withKey(storedBookooObject.getKey().get())
+ .withProperty("property1", "value2")
+ .withProperty("list", Collections.singletonList("list"))
+ .withProperty("set", Collections.singleton("set"))
+ .build());
+
+ final Optional<ChampObject> retrievedReplacedBookooObject = graph.retrieveObject(replacedBookoo.getKey().get());
+
+ assertTrue(replacedBookoo.getProperties().size()==3);
+ assertTrue(replacedBookoo.getProperty("property1").get().equals("value2"));
+ assertTrue(replacedBookoo.getProperty("list").get().equals(Collections.singletonList("list")));
+ assertTrue(replacedBookoo.getProperty("set").get().equals(Collections.singleton("set")));
+
+
+ if (!retrievedReplacedBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + replacedBookoo);
+ if (!replacedBookoo.equals(retrievedReplacedBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object");
+
+
+
+
+
+ graph.deleteObject(storedBookooObject.getKey().get());
+ if (graph.retrieveObject(storedBookooObject.getKey().get()).isPresent()) throw new AssertionError("Object not successfully deleted");
+
+ assertTrue(graph.queryObjects(Collections.emptyMap()).count() == 0);
+ assertTrue(graph.queryRelationships(Collections.emptyMap()).count() == 0);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError("Schema mismatch while storing object", e);
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError("Marshalling exception while storing object", e);
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError("Unmarshalling exception while retrieving object", e);
+ }catch (ChampObjectNotExistsException e) {
+ throw new AssertionError("Missing object on delete/update", e);
+ }
+
+ try {
+ graph.deleteObject(storedBookooObject.getKey().get());
+ throw new AssertionError("Delete succeeded when it should have failed");
+ } catch (ChampObjectNotExistsException e) {
+ //Expected
+ }
+
+ try {
+ graph.storeObject(ChampObject.create()
+ .ofType("foo")
+ .withKey("non-existent object key")
+ .build());
+ throw new AssertionError("Expected ChampObjectNotExistsException but object was successfully stored");
+ } catch (ChampObjectNotExistsException e) {
+ //Expected
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ // validate the replaceObject method when Object key is not passed
+ graph.replaceObject(
+ ChampObject.create().ofType("foo").withoutKey().withProperty("property1", "value2").build());
+ } catch (ChampObjectNotExistsException e) {
+ // Expected
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ }
+
+ public void testChampObjectReservedProperties(ChampGraph graph) {
+
+ for (ChampObject.ReservedPropertyKeys key : ChampObject.ReservedPropertyKeys.values()) {
+ try {
+ ChampObject.create()
+ .ofType(ChampObject.ReservedTypes.ANY.toString())
+ .withoutKey()
+ .withProperty(key.toString(), "")
+ .build();
+ throw new AssertionError("Allowed reserved property key to be used during object creation");
+ } catch (IllegalArgumentException e) {
+ //Expected
+ }
+ }
+ }
+
+ @Test
+ public void testFluentObjectCreation() {
+ final Object value1 = new Object();
+ final String value2 = "value2";
+ final float value3 = 0.0f;
+
+ final ChampObject champObject1 = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("key1", value1)
+ .withProperty("key2", value2)
+ .withProperty("key3", value3)
+ .build();
+
+ assertTrue(champObject1.getKey().equals(Optional.empty()));
+ assertTrue(champObject1.getKey().isPresent() == false);
+ assertTrue(champObject1.getType().equals("foo"));
+ assertTrue(champObject1.getProperty("key1").get() instanceof Object);
+ assertTrue(champObject1.getProperty("key1").get().equals(value1));
+ assertTrue(champObject1.getProperty("key2").get() instanceof String);
+ assertTrue(champObject1.getProperty("key2").get().equals(value2));
+ assertTrue(champObject1.getProperty("key3").get() instanceof Float);
+ assertTrue(champObject1.getProperty("key3").get().equals(value3));
+
+ final ChampObject champObject2 = ChampObject.create()
+ .ofType("foo")
+ .withKey(1)
+ .withProperty("key1", value1)
+ .withProperty("key2", value2)
+ .withProperty("key3", value3)
+ .build();
+
+ assertTrue(champObject2.getType().equals("foo"));
+ assertTrue(champObject2.getKey().isPresent() == true);
+ assertTrue(champObject2.getKey().get() instanceof Integer);
+ assertTrue(champObject2.getKey().get().equals(1));
+ assertTrue(champObject2.getProperty("key1").get() instanceof Object);
+ assertTrue(champObject2.getProperty("key1").get().equals(value1));
+ assertTrue(champObject2.getProperty("key2").get() instanceof String);
+ assertTrue(champObject2.getProperty("key2").get().equals(value2));
+ assertTrue(champObject2.getProperty("key3").get() instanceof Float);
+ assertTrue(champObject2.getProperty("key3").get().equals(value3));
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java
new file mode 100644
index 0000000..c8671bb
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java
@@ -0,0 +1,195 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Optional;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampPartition;
+import org.openecomp.aai.champ.model.ChampRelationship;
+
+public class ChampPartitionTest extends BaseChampAPITest {
+
+ @Test
+ public void runTests() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ final String graphName = ChampPartitionTest.class.getSimpleName();
+
+ switch (apiType) {
+ case IN_MEMORY:
+ break;
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ ChampPartitionTest.testChampPartitionCrud(api.getGraph(graphName));
+ api.shutdown();
+ }
+ }
+
+ @Test
+ public void testHashCode() {
+
+ final ChampObject foo = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build();
+ final ChampObject bar = ChampObject.create()
+ .ofType("bar")
+ .withoutKey()
+ .build();
+ final ChampRelationship baz = ChampRelationship.create()
+ .ofType("baz")
+ .withoutKey()
+ .withSource()
+ .from(foo)
+ .build()
+ .withTarget()
+ .from(bar)
+ .build()
+ .build();
+
+ final ChampPartition partition = ChampPartition.create()
+ .withObject(foo)
+ .withObject(bar)
+ .withRelationship(baz)
+ .build();
+
+ assertTrue(partition.getChampObjects().contains(foo));
+ assertTrue(partition.getChampObjects().contains(bar));
+ assertTrue(partition.getChampRelationships().contains(baz));
+ }
+
+ @Test
+ public void testBuilder() {
+ final ChampObject foo = new ChampObject.Builder("foo").build();
+ final ChampObject bar = new ChampObject.Builder("bar").build();
+ final ChampRelationship uses = new ChampRelationship.Builder(foo, bar, "uses")
+ .build();
+ final ChampPartition a = new ChampPartition.Builder()
+ .object(foo)
+ .objects(Collections.singleton(bar))
+ .relationship(uses)
+ .relationships(Collections.singleton(uses))
+ .build();
+ assertTrue(a.getChampObjects().size() == 2);
+ assertTrue(a.getChampObjects().contains(foo));
+ assertTrue(a.getChampObjects().contains(bar));
+
+ assertTrue(a.getChampRelationships().size() == 1);
+ assertTrue(a.getChampRelationships().contains(uses));
+ }
+
+ public static void testChampPartitionCrud(ChampGraph graph) {
+
+ final ChampObject foo = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("prop1", "value1")
+ .build();
+ final ChampObject bar = ChampObject.create()
+ .ofType("bar")
+ .withoutKey()
+ .withProperty("prop2", "value2")
+ .build();
+
+ final ChampRelationship baz = ChampRelationship.create()
+ .ofType("baz")
+ .withoutKey()
+ .withSource()
+ .from(foo)
+ .build()
+ .withTarget()
+ .from(bar)
+ .build()
+ .withProperty("prop3", "value3")
+ .build();
+
+ final ChampPartition partition = ChampPartition.create()
+ .withObject(foo)
+ .withObject(bar)
+ .withRelationship(baz)
+ .build();
+
+ assertTrue(partition.getIncidentRelationships(foo).contains(baz));
+ assertTrue(partition.getIncidentRelationships(bar).contains(baz));
+ assertTrue(partition.getIncidentRelationshipsByType(foo).get("baz").contains(baz));
+
+ try {
+ final ChampPartition storedPartition = graph.storePartition(partition);
+
+ ChampPartitionTest.retrievePartitionElements(graph, storedPartition, true);
+
+ graph.deletePartition(storedPartition);
+
+ ChampPartitionTest.retrievePartitionElements(graph, storedPartition, false);
+
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampObjectNotExistsException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ } catch (ChampRelationshipNotExistsException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private static void retrievePartitionElements(ChampGraph graph, ChampPartition partition, boolean expectFound) {
+ for (ChampObject object : partition.getChampObjects()) {
+ try {
+ final Optional<ChampObject> retrievedObject = graph.retrieveObject(object.getKey().get());
+
+ if (!expectFound && retrievedObject.isPresent()) throw new AssertionError("Expected object to not be found, but it was found");
+ if (expectFound && !retrievedObject.isPresent()) throw new AssertionError("Expected object to be found, but it was not found");
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ for (ChampRelationship relationship : partition.getChampRelationships()) {
+ try {
+ final Optional<ChampRelationship> retrievedRelationship = graph.retrieveRelationship(relationship.getKey().get());
+
+ if (!expectFound && retrievedRelationship.isPresent()) throw new AssertionError("Expected relationship to not be found, but it was found");
+ if (expectFound && !retrievedRelationship.isPresent()) throw new AssertionError("Expected relationship to be found, but it was not found");
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java
new file mode 100644
index 0000000..8ee45f4
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.model.ChampCardinality;
+import org.openecomp.aai.champ.model.ChampField;
+import org.openecomp.aai.champ.model.ChampPropertyConstraint;
+
+public class ChampPropertyConstraintTest {
+
+ @Test
+ public void testChampPropertyConstraint() {
+ final ChampField z = new ChampField.Builder("z").build();
+ final ChampField y = new ChampField.Builder("y").build();
+
+ final ChampPropertyConstraint a = new ChampPropertyConstraint.Builder(z)
+ .cardinality(ChampCardinality.SINGLE)
+ .required(false)
+ .build();
+ final ChampPropertyConstraint aEquivalent = new ChampPropertyConstraint.Builder(z)
+ .build();
+
+ final ChampPropertyConstraint b = new ChampPropertyConstraint.Builder(y)
+ .build();
+ assertTrue(a.equals(aEquivalent));
+ assertTrue(!a.equals(b));
+ assertTrue(!a.equals(new Object()));
+
+ assertTrue(a.toString().equals(aEquivalent.toString()));
+ assertTrue(!a.toString().equals(b.toString()));
+
+ assertTrue(a.compareTo(aEquivalent) == 0);
+ assertTrue(a.compareTo(b) != 0);
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java
new file mode 100644
index 0000000..a611df7
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java
@@ -0,0 +1,175 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
+import org.openecomp.aai.champ.model.ChampField;
+import org.openecomp.aai.champ.model.ChampRelationship;
+import org.openecomp.aai.champ.model.ChampRelationshipIndex;
+
+public class ChampRelationshipIndexTest extends BaseChampAPITest {
+
+ @Test
+ public void runTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final String graphName = ChampRelationshipIndexTest.class.getSimpleName();
+
+ switch (apiType) {
+ case IN_MEMORY:
+ break;
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ testChampRelationshipIndexCrud(api.getGraph(graphName));
+ api.shutdown();
+ }
+ }
+
+ private void testChampRelationshipIndexCrud(ChampGraph graph) {
+
+ final ChampField relationshipField = new ChampField.Builder("propertyName").build();
+ final ChampRelationshipIndex relationshipIndex = new ChampRelationshipIndex.Builder("fooEdgeIndex", "foo", relationshipField).build();
+
+ //Test on an empty graph
+ testChampRelationshipIndexStorage(graph, relationshipIndex);
+ testChampRelationshipIndexDelete(graph, relationshipIndex);
+
+ //Test with existing data in graph
+ try {
+ graph.storeRelationship(ChampRelationship.create()
+ .ofType("uses")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("bar")
+ .withoutKey()
+ .build()
+ .build());
+ testChampRelationshipIndexStorage(graph, relationshipIndex);
+ testChampRelationshipIndexDelete(graph, relationshipIndex);
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ } catch (ChampObjectNotExistsException e) {
+ throw new AssertionError(e);
+ } catch (ChampRelationshipNotExistsException e) {
+ throw new AssertionError(e);
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private void testChampRelationshipIndexDelete(ChampGraph graph, ChampRelationshipIndex relationshipIndex) {
+
+ if (!graph.capabilities().canDeleteRelationshipIndices()) {
+ try {
+ graph.deleteRelationshipIndex("someindex");
+ throw new AssertionError("Graph claims it doesn't support relationship index delete, but it failed to throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ //Expected
+ } catch (ChampIndexNotExistsException e) {
+ throw new AssertionError("Graph claims it doesn't support relationship index delete, but it failed to throw UnsupportedOperationException");
+ }
+ } else {
+ try {
+ graph.deleteRelationshipIndex(relationshipIndex.getName());
+
+ final Optional<ChampRelationshipIndex> retrieveRelationshipIndex = graph.retrieveRelationshipIndex(relationshipIndex.getName());
+
+ if (retrieveRelationshipIndex.isPresent()) throw new AssertionError("Retrieve relationship index after deleting it");
+
+ final Stream<ChampRelationshipIndex> relationshipIndices = graph.retrieveRelationshipIndices();
+ final Collection<ChampRelationshipIndex> allRelationshipIndices = relationshipIndices.collect(Collectors.toList());
+
+ if (allRelationshipIndices.contains(relationshipIndex)) throw new AssertionError("Retrieve all relationship indices contains previously deleted index");
+ if (allRelationshipIndices.size() != 0) throw new AssertionError("Wrong number of relationship indices returned by retrieve all indices");
+ } catch (ChampIndexNotExistsException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ graph.deleteRelationshipIndex(relationshipIndex.getName());
+ throw new AssertionError("Failed to throw exception on non-existent object index");
+ } catch (ChampIndexNotExistsException e) {
+ //Expected
+ }
+ }
+ }
+
+ private void testChampRelationshipIndexStorage(ChampGraph graph, ChampRelationshipIndex relationshipIndex) {
+
+ graph.storeRelationshipIndex(relationshipIndex);
+ graph.storeRelationshipIndex(relationshipIndex); //Test storing duplicate relationship index
+
+ assertTrue(!graph.retrieveObjectIndex(relationshipIndex.getName()).isPresent()); //Make sure this wasn't stored as an object index
+
+ final Optional<ChampRelationshipIndex> retrieveRelationshipIndex = graph.retrieveRelationshipIndex(relationshipIndex.getName());
+
+ if (!retrieveRelationshipIndex.isPresent()) throw new AssertionError("Failed to retrieve relationship index after storing it");
+ if (!relationshipIndex.equals(retrieveRelationshipIndex.get())) throw new AssertionError("Non-equal relationship index returned from API after storing it");
+
+ final Stream<ChampRelationshipIndex> relationshipIndices = graph.retrieveRelationshipIndices();
+ final Collection<ChampRelationshipIndex> allRelationshipIndices = relationshipIndices.collect(Collectors.toList());
+
+ if (!allRelationshipIndices.contains(relationshipIndex)) throw new AssertionError("Retrieve all relationship indices did not return previously stored relationship index");
+ if (allRelationshipIndices.size() != 1) throw new AssertionError("Wrong number of relationship indices returned by retrieve all indices");
+
+ assertTrue(!graph.retrieveRelationshipIndex("nonExistentIndexName").isPresent());
+ }
+
+ @Test
+ public void testFluentRelationshipIndexCreation() {
+ final ChampRelationshipIndex relationshipIndex = ChampRelationshipIndex.create()
+ .ofName("fooNameIndex")
+ .onType("foo")
+ .forField("name")
+ .build();
+
+ assertTrue(relationshipIndex.getName().equals("fooNameIndex"));
+ assertTrue(relationshipIndex.getType().equals("foo"));
+ assertTrue(relationshipIndex.getField().getName().equals("name"));
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java
new file mode 100644
index 0000000..cf025d6
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java
@@ -0,0 +1,261 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampRelationship;
+import org.openecomp.aai.champ.model.ChampRelationship.ReservedPropertyKeys;
+import org.openecomp.aai.champ.model.ChampRelationship.ReservedTypes;
+
+public class ChampRelationshipTest extends BaseChampAPITest {
+
+ @Test
+ public void runTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final String graphName = ChampRelationshipTest.class.getSimpleName();
+
+ switch (apiType) {
+ case IN_MEMORY:
+ break;
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+ ChampRelationshipTest.testChampRelationshipCrud(api.getGraph(graphName));
+ api.shutdown();
+ }
+ }
+
+ public static void testChampRelationshipCrud(ChampGraph graph) {
+ final ChampObject source = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("property1", "value1")
+ .build();
+
+ final ChampObject target = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build();
+
+ try {
+ final ChampObject storedSource = graph.storeObject(source);
+ final ChampObject storedTarget = graph.storeObject(target);
+
+ final ChampRelationship relationship = new ChampRelationship.Builder(storedSource, storedTarget, "relationship")
+ .property("property-1", "value-1")
+ .property("property-2", 3)
+ .build();
+
+ final ChampRelationship storedRelationship = graph.storeRelationship(relationship);
+ final Optional<ChampRelationship> retrievedRelationship = graph.retrieveRelationship(storedRelationship.getKey().get());
+
+ if (!retrievedRelationship.isPresent()) throw new AssertionError("Failed to retrieve stored relationship " + storedRelationship);
+ if (!storedRelationship.equals(retrievedRelationship.get())) throw new AssertionError("Retrieved relationship does not equal stored object");
+
+ assertTrue(retrievedRelationship.get().getProperty("property-1").get().equals("value-1"));
+ assertTrue(retrievedRelationship.get().getProperty("property-2").get().equals(3));
+
+ if (!graph.retrieveRelationships(storedRelationship.getSource()).collect(Collectors.toList()).contains(storedRelationship))
+ throw new AssertionError("Failed to retrieve relationships for source object");
+
+ final ChampRelationship updatedRelationship = ChampRelationship.create()
+ .from(retrievedRelationship.get())
+ .withKey(retrievedRelationship.get().getKey().get())
+ .withProperty("property-2", 4)
+ .build();
+
+ final ChampRelationship storedUpdRel = graph.storeRelationship(updatedRelationship);
+ final Optional<ChampRelationship> retrievedUpdRel = graph.retrieveRelationship(storedUpdRel.getKey().get());
+
+ assertTrue(retrievedUpdRel.isPresent());
+ assertTrue(retrievedUpdRel.get().equals(storedUpdRel));
+ assertTrue(retrievedUpdRel.get().getProperty("property-1").get().equals("value-1"));
+ assertTrue(retrievedUpdRel.get().getProperty("property-2").get().equals(4));
+
+
+ // validate the replaceRelationship method
+ final ChampRelationship replacedRelationship = new ChampRelationship.Builder(storedSource, storedTarget, "relationship")
+ .key(retrievedRelationship.get().getKey().get())
+ .property("property-2", 4)
+ .build();
+
+ final ChampRelationship replacedRel = graph.replaceRelationship(replacedRelationship);
+ final Optional<ChampRelationship> retrievedReplacedRel = graph
+ .retrieveRelationship(replacedRel.getKey().get());
+
+ assertTrue(replacedRel.getProperties().size()==1);
+ assertTrue(replacedRel.getProperty("property-2").get().equals(4));
+
+ assertTrue(retrievedReplacedRel.get().getProperties().size()==1);
+ assertTrue(retrievedReplacedRel.get().getProperty("property-2").get().equals(4));
+
+ if (!retrievedReplacedRel.isPresent()) throw new AssertionError("Failed to retrieve stored relationship " + replacedRel);
+ if (!replacedRel.equals(retrievedReplacedRel.get())) throw new AssertionError("Retrieved relationship does not equal stored object");
+
+
+ graph.deleteRelationship(retrievedRelationship.get());
+
+ if (graph.retrieveRelationship(relationship.getKey()).isPresent()) throw new AssertionError("Relationship not successfully deleted");
+
+ try {
+ graph.deleteRelationship(retrievedRelationship.get());
+ throw new AssertionError("Failed to throw exception for missing relationship");
+ } catch (ChampRelationshipNotExistsException e) {
+ //Expected
+ }
+
+ assertTrue(graph.queryRelationships(Collections.emptyMap()).count() == 0);
+ assertTrue(graph.queryObjects(Collections.emptyMap()).count() == 2);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError("Schema mismatch while storing object", e);
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError("Marshalling exception while storing object", e);
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError("Unmarshalling exception while retrieving relationship", e);
+ } catch (ChampRelationshipNotExistsException e) {
+ throw new AssertionError("Attempted to delete non-existent relationship", e);
+ } catch (ChampObjectNotExistsException e) {
+ throw new AssertionError("Object does not exist after storing it", e);
+ }
+
+ try {
+ graph.retrieveRelationships(ChampObject.create().ofType("").withoutKey().build());
+ throw new AssertionError("Failed to handle missing object while retrieving relationships");
+ } catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampObjectNotExistsException e) {
+ //Expected
+ }
+ //Negative test cases for replace relationship
+
+ try{
+ graph.replaceRelationship(new ChampRelationship.Builder(ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build(), ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build(), "relationship")
+ .key("1234")
+ .property("property-2", 4)
+ .build());
+ }
+ catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ } catch (ChampRelationshipNotExistsException e) {
+ throw new AssertionError(e);
+ } catch(IllegalArgumentException e){
+ //expected
+ }
+
+ try{
+ graph.replaceRelationship(new ChampRelationship.Builder(ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .build(), ChampObject.create()
+ .ofType("foo")
+ .withKey("456")
+ .build(), "relationship")
+ .property("property-2", 4)
+ .build());
+ }
+ catch (ChampUnmarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ } catch (ChampRelationshipNotExistsException e) {
+ //expected
+ } catch(IllegalArgumentException e){
+ throw new AssertionError(e);
+ }
+
+
+ }
+
+ @Test
+ public void testFluentRelationshipCreation() {
+ final Object value1 = new Object();
+ final String value2 = "value2";
+ final float value3 = 0.0f;
+
+ final ChampRelationship champRelationship = ChampRelationship.create()
+ .ofType("foo")
+ .withoutKey()
+ .withSource()
+ .ofType("bar")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("baz")
+ .withKey(1)
+ .build()
+ .withProperty("key1", value1)
+ .withProperty("key2", value2)
+ .withProperty("key3", value3)
+ .build();
+
+ assertTrue(champRelationship.getKey().equals(Optional.empty()));
+ assertTrue(champRelationship.getType().equals("foo"));
+ assertTrue(champRelationship.getProperty("key1").get() instanceof Object);
+ assertTrue(champRelationship.getProperty("key1").get().equals(value1));
+ assertTrue(champRelationship.getProperty("key2").get() instanceof String);
+ assertTrue(champRelationship.getProperty("key2").get().equals(value2));
+ assertTrue(champRelationship.getProperty("key3").get() instanceof Float);
+ assertTrue(champRelationship.getProperty("key3").get().equals(value3));
+ }
+
+ @Test
+ public void testChampRelationshipEnums() {
+ for (ReservedPropertyKeys key : ChampRelationship.ReservedPropertyKeys.values()) {
+ assertTrue(ChampRelationship.ReservedPropertyKeys.valueOf(key.name()) == key);
+ }
+
+ for (ReservedTypes type : ChampRelationship.ReservedTypes.values()) {
+ assertTrue(ChampRelationship.ReservedTypes.valueOf(type.name()) == type);
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java
new file mode 100644
index 0000000..e3f099e
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java
@@ -0,0 +1,761 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.core;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.model.ChampConnectionConstraint;
+import org.openecomp.aai.champ.model.ChampConnectionMultiplicity;
+import org.openecomp.aai.champ.model.ChampField;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampObject.ReservedTypes;
+import org.openecomp.aai.champ.model.ChampObjectConstraint;
+import org.openecomp.aai.champ.model.ChampPartition;
+import org.openecomp.aai.champ.model.ChampPropertyConstraint;
+import org.openecomp.aai.champ.model.ChampRelationship;
+import org.openecomp.aai.champ.model.ChampRelationshipConstraint;
+import org.openecomp.aai.champ.model.ChampSchema;
+import org.openecomp.aai.champ.schema.AlwaysValidChampSchemaEnforcer;
+import org.openecomp.aai.champ.schema.ChampSchemaEnforcer;
+import org.openecomp.aai.champ.schema.DefaultChampSchemaEnforcer;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class ChampSchemaTest extends BaseChampAPITest {
+
+ @Test
+ public void runTest() {
+ for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
+ final String graphName = ChampSchemaTest.class.getSimpleName();
+
+ switch (apiType) {
+ case IN_MEMORY:
+ break;
+ case TITAN:
+ cleanUp(graphName);
+ break;
+ default:
+ break;
+ }
+
+ final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
+
+ try {
+ ChampSchemaTest.testChampSchemaCrud(api.getGraph(graphName));
+ } catch (Throwable t) {
+ throw new AssertionError(apiType + " unit test failed", t);
+ }
+
+ api.shutdown();
+ }
+ }
+
+ public static void testChampSchemaCrud(ChampGraph graph) {
+
+ final ChampSchema schema = ChampSchema.create()
+ .withObjectConstraint()
+ .onType("foo")
+ .withPropertyConstraint()
+ .onField("property1")
+ .required()
+ .build()
+ .withPropertyConstraint()
+ .onField("property2")
+ .optional()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("bar")
+ .withPropertyConstraint()
+ .onField("at")
+ .ofType(ChampField.Type.STRING)
+ .optional()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("foo")
+ .targetedToAny()
+ .build()
+ .build()
+ .build();
+
+ try {
+ graph.storeSchema(schema);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ final ChampObject emptyFoo = ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build();
+
+ try {
+ graph.storeObject(emptyFoo);
+ } catch (ChampMarshallingException e1) {
+ throw new AssertionError(e1);
+ } catch (ChampSchemaViolationException e1) {
+ //Expected, since it does not have the required property "property1"
+ } catch (ChampObjectNotExistsException e) {
+ throw new AssertionError(e);
+ }
+
+ final ChampSchema retrievedSchema = graph.retrieveSchema();
+
+ if (!schema.equals(retrievedSchema)) throw new AssertionError("Retrieved schema is not the same as the schema that was previously stored");
+
+ try {
+ graph.updateSchema(new ChampRelationshipConstraint.Builder("bard").build());
+ assertTrue(graph.retrieveSchema().getRelationshipConstraint("bard").isPresent());
+
+ graph.updateSchema(new ChampObjectConstraint.Builder("baz").build());
+ assertTrue(graph.retrieveSchema().getObjectConstraint("baz").isPresent());
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ final ChampSchema updatedSchema = graph.retrieveSchema();
+
+ if (!updatedSchema.getObjectConstraint("baz").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates");
+ if (!updatedSchema.getRelationshipConstraint("bard").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates");
+
+ try {
+ graph.updateSchema(new ChampObjectConstraint.Builder("foo")
+ .constraint(
+ new ChampPropertyConstraint.Builder(
+ new ChampField.Builder("property2")
+ .build()
+ )
+ .required(false)
+ .build()
+ )
+ .build());
+
+ final ChampObject storedEmptyFoo = graph.storeObject(emptyFoo);
+
+ graph.deleteObject(storedEmptyFoo.getKey().get());
+ } catch (ChampMarshallingException e) {
+ throw new AssertionError(e);
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ } catch (ChampObjectNotExistsException e) {
+ throw new AssertionError(e);
+ }
+
+ graph.deleteSchema();
+ assertTrue(graph.retrieveSchema().equals(ChampSchema.emptySchema()));
+ }
+
+ @Test
+ public void testChampSchemaFluentApi() {
+ final ChampSchema schema = ChampSchema.create()
+ .withObjectConstraint()
+ .onType("foo")
+ .withPropertyConstraint()
+ .onField("bar")
+ .ofType(ChampField.Type.STRING)
+ .required()
+ .build()
+ .withPropertyConstraint()
+ .onField("baz")
+ .ofType(ChampField.Type.BOOLEAN)
+ .optional()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("eats")
+ .withPropertyConstraint()
+ .onField("at")
+ .ofType(ChampField.Type.STRING)
+ .required()
+ .build()
+ .withPropertyConstraint()
+ .onField("for")
+ .optional()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("foo")
+ .targetedTo("foo")
+ .withMultiplicity(ChampConnectionMultiplicity.ONE)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("bar")
+ .targetedTo("bar")
+ .build()
+ .build()
+ .build();
+
+ assertTrue(schema.getObjectConstraint("foo").get().getType().equals("foo"));
+
+ for (ChampPropertyConstraint propConst : schema.getObjectConstraint("foo").get().getPropertyConstraints()) {
+ if (propConst.getField().getName().equals("bar")) {
+ assertTrue(propConst.getField().getJavaType().equals(String.class));
+ assertTrue(propConst.isRequired());
+ } else if (propConst.getField().getName().equals("baz")) {
+ assertTrue(propConst.getField().getJavaType().equals(Boolean.class));
+ assertTrue(!propConst.isRequired());
+ } else {
+ throw new AssertionError("Unknown property constraint found: " + propConst);
+ }
+ }
+
+ assertTrue(schema.getRelationshipConstraint("eats").get().getType().equals("eats"));
+
+ for (ChampPropertyConstraint propConst : schema.getRelationshipConstraint("eats").get().getPropertyConstraints()) {
+ if (propConst.getField().getName().equals("at")) {
+ assertTrue(propConst.getField().getJavaType().equals(String.class));
+ assertTrue(propConst.isRequired());
+ } else if (propConst.getField().getName().equals("for")) {
+ assertTrue(propConst.getField().getJavaType().equals(String.class));
+ assertTrue(!propConst.isRequired());
+ } else {
+ throw new AssertionError("Unknown property constraint found: " + propConst);
+ }
+ }
+
+ for (ChampConnectionConstraint connConst : schema.getRelationshipConstraint("eats").get().getConnectionConstraints()) {
+ if (connConst.getSourceType().equals("foo")) {
+ assertTrue(connConst.getTargetType().equals("foo"));
+ assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.ONE);
+ } else if (connConst.getSourceType().equals("bar")) {
+ assertTrue(connConst.getTargetType().equals("bar"));
+ assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.MANY);
+ } else {
+ throw new AssertionError("Unknown connection constraint found: " + connConst);
+ }
+ }
+ }
+
+ @Test
+ public void testDefaultChampSchemaEnforcer() {
+
+ final ChampSchemaEnforcer schemaEnforcer = new DefaultChampSchemaEnforcer();
+ final ChampSchema champSchema = ChampSchema.create()
+ .withObjectConstraint()
+ .onType("foo")
+ .withPropertyConstraint()
+ .onField("bar")
+ .ofType(ChampField.Type.STRING)
+ .required()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("makes")
+ .withPropertyConstraint()
+ .onField("bar")
+ .required()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("foo")
+ .targetedTo("fiz")
+ .withMultiplicity(ChampConnectionMultiplicity.ONE)
+ .build()
+ .build()
+ .build();
+
+ try {
+ schemaEnforcer.validate(ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build(),
+ champSchema.getObjectConstraint("foo").get());
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ schemaEnforcer.validate(ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .build(),
+ champSchema.getObjectConstraint("foo").get());
+ throw new AssertionError("Failed to enforce required property constraint on object");
+ } catch (ChampSchemaViolationException e) {
+ //Expected
+ }
+
+ try {
+ schemaEnforcer.validate(ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", true)
+ .build(),
+ champSchema.getObjectConstraint("foo").get());
+ throw new AssertionError("Failed to enforce property type constraint on object");
+ } catch (ChampSchemaViolationException e) {
+ //Expected
+ }
+
+ try {
+ schemaEnforcer.validate(ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", "true")
+ .build(),
+ champSchema.getRelationshipConstraint("makes").get()
+ );
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ schemaEnforcer.validate(ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .build(),
+ champSchema.getRelationshipConstraint("makes").get()
+ );
+ throw new AssertionError("Failed to enforce required property constraint on relationship");
+ } catch (ChampSchemaViolationException e) {
+ //Expected
+ }
+
+ try {
+ schemaEnforcer.validate(ChampPartition.create()
+ .withObject(
+ ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .withObject(
+ ChampObject.create()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .build(),
+ champSchema
+ );
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ schemaEnforcer.validate(ChampPartition.create()
+ .withObject(
+ ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .withObject(
+ ChampObject.create()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", "true")
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", "true")
+ .build()
+ )
+ .build(),
+ champSchema
+ );
+ throw new AssertionError("Failed to enforce connection constraint on relationship type 'makes'");
+ } catch (ChampSchemaViolationException e) {
+ //Expected
+ }
+ }
+
+ @Test
+ public void testAlwaysValidChampSchemaEnforcer() {
+
+ final ChampSchemaEnforcer schemaEnforcer = new AlwaysValidChampSchemaEnforcer();
+
+ try {
+ schemaEnforcer.validate(ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", true)
+ .build(),
+ new ChampObjectConstraint.Builder("foo")
+ .constraint(
+ new ChampPropertyConstraint.Builder(
+ new ChampField.Builder("bar")
+ .type(ChampField.Type.STRING)
+ .build()
+ )
+ .required(true)
+ .build()
+ )
+ .build()
+ );
+
+ schemaEnforcer.validate(ChampRelationship.create()
+ .ofType("foo")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", true)
+ .build(),
+ new ChampRelationshipConstraint.Builder("bar")
+ .constraint(
+ new ChampPropertyConstraint.Builder(
+ new ChampField.Builder("bar")
+ .type(ChampField.Type.STRING)
+ .build()
+ )
+ .required(true)
+ .build()
+ )
+ .build()
+ );
+
+ schemaEnforcer.validate(ChampPartition.create()
+ .withObject(
+ ChampObject.create()
+ .ofType("foo")
+ .withoutKey()
+ .withProperty("bar", true)
+ .build()
+ )
+ .withObject(
+ ChampObject.create()
+ .ofType("fiz")
+ .withoutKey()
+ .withProperty("bar", true)
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .build()
+ )
+ .withRelationship(
+ ChampRelationship.create()
+ .ofType("makes")
+ .withoutKey()
+ .withSource()
+ .ofType("foo")
+ .withoutKey()
+ .build()
+ .withTarget()
+ .ofType("fiz")
+ .withoutKey()
+ .build()
+ .withProperty("bar", true)
+ .build()
+ )
+ .build(),
+ ChampSchema.create()
+ .withObjectConstraint()
+ .onType("foo")
+ .withPropertyConstraint()
+ .onField("bar")
+ .required()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("makes")
+ .withPropertyConstraint()
+ .onField("bar")
+ .required()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("foo")
+ .targetedTo("fiz")
+ .withMultiplicity(ChampConnectionMultiplicity.ONE)
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("uses")
+ .withConnectionConstraint()
+ .sourcedFromAny()
+ .targetedTo("computer")
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("destroys")
+ .withConnectionConstraint()
+ .sourcedFrom("computer")
+ .targetedToAny()
+ .build()
+ .build()
+ .build()
+
+ );
+ } catch (ChampSchemaViolationException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ @Test
+ public void testFluentSchemaApi() {
+ final ChampSchema schema = ChampSchema.create()
+ .withObjectConstraint()
+ .onType("a")
+ .withPropertyConstraint()
+ .onField("z")
+ .ofType(ChampField.Type.STRING)
+ .optional()
+ .build()
+ .build()
+ .withObjectConstraint()
+ .onType("b")
+ .withPropertyConstraint()
+ .onField("y")
+ .ofType(ChampField.Type.LONG)
+ .required()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("one")
+ .withPropertyConstraint()
+ .onField("nine")
+ .ofType(ChampField.Type.INTEGER)
+ .optional()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("a")
+ .targetedTo("b")
+ .withMultiplicity(ChampConnectionMultiplicity.NONE)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("a")
+ .targetedToAny()
+ .withMultiplicity(ChampConnectionMultiplicity.ONE)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFromAny()
+ .targetedTo("b")
+ .withMultiplicity(ChampConnectionMultiplicity.MANY)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFromAny()
+ .targetedToAny()
+ .withMultiplicity(ChampConnectionMultiplicity.MANY)
+ .build()
+ .build()
+ .build();
+
+ final ChampObjectConstraint aObjConstraint = schema.getObjectConstraint("a").get();
+
+ assertTrue(aObjConstraint.getType().equals("a"));
+
+ final ChampPropertyConstraint zPropertyConstraint = aObjConstraint.getPropertyConstraint("z").get();
+
+ assertTrue(zPropertyConstraint.getField().getName().equals("z"));
+ assertTrue(zPropertyConstraint.getField().getJavaType().equals(String.class));
+ assertTrue(!zPropertyConstraint.isRequired());
+
+ final ChampObjectConstraint bObjConstraint = schema.getObjectConstraint("b").get();
+
+ assertTrue(bObjConstraint.getType().equals("b"));
+
+ final ChampPropertyConstraint yPropertyConstraint = bObjConstraint.getPropertyConstraint("y").get();
+
+ assertTrue(yPropertyConstraint.getField().getName().equals("y"));
+ assertTrue(yPropertyConstraint.getField().getJavaType().equals(Long.class));
+ assertTrue(yPropertyConstraint.isRequired());
+
+ final ChampRelationshipConstraint oneRelConstraint = schema.getRelationshipConstraint("one").get();
+
+ assertTrue(oneRelConstraint.getType().equals("one"));
+
+ final ChampPropertyConstraint ninePropertyConstraint = oneRelConstraint.getPropertyConstraint("nine").get();
+
+ assertTrue(ninePropertyConstraint.getField().getName().equals("nine"));
+ assertTrue(ninePropertyConstraint.getField().getJavaType().equals(Integer.class));
+ assertTrue(!ninePropertyConstraint.isRequired());
+
+ final Set<ChampConnectionConstraint> connectionConstraints = oneRelConstraint.getConnectionConstraints();
+
+ for (ChampConnectionConstraint cc : connectionConstraints) {
+ if (cc.getSourceType().equals("a") && cc.getTargetType().equals("b")) {
+ assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.NONE);
+ } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals("b")) {
+ assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY);
+ } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals(ReservedTypes.ANY.toString())) {
+ assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY);
+ } else if (cc.getSourceType().equals("a") && cc.getTargetType().equals(ReservedTypes.ANY.toString())) {
+ assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.ONE);
+ } else {
+ throw new AssertionError("Found unspecified connection constraint " + cc);
+ }
+ }
+ }
+
+ @Test
+ public void testJacksonObjectMapping() {
+ final ChampSchema schema = ChampSchema.create()
+ .withObjectConstraint()
+ .onType("a")
+ .withPropertyConstraint()
+ .onField("z")
+ .ofType(ChampField.Type.STRING)
+ .optional()
+ .build()
+ .build()
+ .withObjectConstraint()
+ .onType("b")
+ .withPropertyConstraint()
+ .onField("y")
+ .ofType(ChampField.Type.LONG)
+ .required()
+ .build()
+ .build()
+ .withRelationshipConstraint()
+ .onType("one")
+ .withPropertyConstraint()
+ .onField("nine")
+ .ofType(ChampField.Type.INTEGER)
+ .optional()
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("a")
+ .targetedTo("b")
+ .withMultiplicity(ChampConnectionMultiplicity.NONE)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFrom("a")
+ .targetedToAny()
+ .withMultiplicity(ChampConnectionMultiplicity.ONE)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFromAny()
+ .targetedTo("b")
+ .withMultiplicity(ChampConnectionMultiplicity.MANY)
+ .build()
+ .withConnectionConstraint()
+ .sourcedFromAny()
+ .targetedToAny()
+ .withMultiplicity(ChampConnectionMultiplicity.MANY)
+ .build()
+ .build()
+ .build();
+
+ final ObjectMapper om = new ObjectMapper();
+
+ try {
+ final byte[] serialized = om.writeValueAsBytes(schema);
+ System.out.println(new String(serialized, "UTF-8"));
+ final ChampSchema deserialized = om.readValue(serialized, ChampSchema.class);
+ assert schema.equals(deserialized);
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java b/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java
new file mode 100644
index 0000000..5383d28
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java
@@ -0,0 +1,1029 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.event;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampCapabilities;
+import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
+import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException;
+import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
+import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException;
+import org.openecomp.aai.champ.model.ChampObject;
+import org.openecomp.aai.champ.model.ChampObjectConstraint;
+import org.openecomp.aai.champ.model.ChampObjectIndex;
+import org.openecomp.aai.champ.model.ChampPartition;
+import org.openecomp.aai.champ.model.ChampRelationship;
+import org.openecomp.aai.champ.model.ChampRelationshipConstraint;
+import org.openecomp.aai.champ.model.ChampRelationshipIndex;
+import org.openecomp.aai.champ.model.ChampSchema;
+import org.slf4j.Logger;
+
+import com.att.nsa.cambria.client.CambriaPublisher;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+
+public class AbstractLoggingChampGraphTest {
+
+ /** Event stream producer stub. */
+ private InMemoryPublisher producer;
+
+ /** In memory graph for testing purposes. */
+ private TestGraph testGraph;
+
+
+ /**
+ * Perform any setup tasks that need to be done prior to each test.
+ */
+ @Before
+ public void setup() {
+
+ // Instantiate an event stream producer stub to use in our tests.
+ producer = new InMemoryPublisher();
+
+ // Instantiate an 'in-memory' graph for test purposes.
+ Map<String, Object> graphProperties = new HashMap<String, Object>();
+ graphProperties.put("champ.event.stream.hosts", "myeventstreamhost");
+ graphProperties.put("champ.event.stream.batch-size", 1);
+ testGraph = new TestGraph(graphProperties, producer);
+ }
+
+
+ /**
+ * Perform any cleanup that needs to be done after each test.
+ */
+ @After
+ public void tearDown() {
+
+ // Close our stubbed producer and graph.
+ producer.close();
+ testGraph.shutdown();
+ }
+
+
+ /**
+ * Validates that store/replace/delete operation against vertices result in the expected events
+ * being published to the event stream.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ */
+ @Test
+ public void vertexOperationsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException {
+
+ // Create a vertex and store it in the graph data store.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+ testGraph.storeObject(obj1);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected STORE event.", loggedEventStr.contains("STORE"));
+ assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex"));
+
+ // Create a new vertex based on the one that we already created.
+ ChampObject obj2 = ChampObject.create()
+ .from(obj1)
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ // Now, try doing a replace operation.
+ testGraph.replaceObject(obj2);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected REPLACE event.", loggedEventStr.contains("REPLACE"));
+ assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex"));
+
+ // Finally, delete the vertex.
+ testGraph.deleteObject("123");
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE"));
+ assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex"));
+ }
+
+
+ /**
+ * This test validates that performing vertex operations in the case where the data to be
+ * forwarded to the event stream is unavailable results in no event being generated, but
+ * does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ */
+ @Test
+ public void vertexOperationsWithNullsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException {
+
+ // Setup our test graph to simulate failures to retrieve data from the graph data store.
+ testGraph.returnNulls();
+
+ // Create a vertex and store it in the graph data store.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+ testGraph.storeObject(obj1);
+
+ // Check our simulated event stream to verify that an event log was produced.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr);
+
+ // Create a new vertex based on the one that we already created.
+ ChampObject obj2 = ChampObject.create()
+ .from(obj1)
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ // Now, try doing a replace operation.
+ testGraph.replaceObject(obj2);
+
+ // Check our simulated event stream to see if an event log was not produced.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr);
+
+ // Finally, delete the vertex.
+ testGraph.deleteObject("123");
+
+ // Check our simulated event stream to see if an event log was not produced.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr);
+ }
+
+
+ /**
+ * Validates that store/replace/delete operation against edges result in the expected events
+ * being published to the event stream.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ */
+ @Test
+ public void edgeOperationsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException {
+
+ // Create two vertices to act as the end points of our edge.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+
+ ChampObject obj2 = ChampObject.create()
+ .ofType("bar")
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ // Now, create an edge object and write it to the graph data store.
+ ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship")
+ .property("property-1", "value-1")
+ .property("property-2", "value-2")
+ .build();
+ testGraph.storeRelationship(rel);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected STORE event.", loggedEventStr.contains("STORE"));
+ assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship"));
+
+ // Now, create another edge object based on the one we just wrote, and use it to perform
+ // a replace operation.
+ ChampRelationship rel2 = ChampRelationship.create()
+ .from(rel)
+ .withKey("123")
+ .withProperty("property-3", "value-3")
+ .build();
+ testGraph.replaceRelationship(rel2);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected REPLACE event.", loggedEventStr.contains("REPLACE"));
+ assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship"));
+
+ // Finally, delete our edge.
+ testGraph.deleteRelationship(rel2);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE"));
+ assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship"));
+ }
+
+
+ /**
+ * This test validates that performing edge operations in the case where the data to be
+ * forwarded to the event stream is unavailable results in no event being generated, but
+ * does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ */
+ @Test
+ public void edgeOperationsWithNullsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException {
+
+ // Set up our graph to simulate a failure to retrieve some of the data we need to generate
+ // events.
+ testGraph.returnNulls();
+
+ // Create two vertices to act as the endpoints of our edge.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+
+ ChampObject obj2 = ChampObject.create()
+ .ofType("bar")
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ // Now, create an edge object and write it to the graph data store.
+ ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship")
+ .property("property-1", "value-1")
+ .property("property-2", "value-2")
+ .build();
+ testGraph.storeRelationship(rel);
+
+ // Check our simulated event stream to see if an event log was produced.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store edge event should not have been logged to the event stream", loggedEventStr);
+
+ // Now, create another edge object based on the one we just wrote, and use it to perform
+ // a replace operation.
+ ChampRelationship rel2 = ChampRelationship.create()
+ .from(rel)
+ .withKey("123")
+ .withProperty("property-3", "value-3")
+ .build();
+ testGraph.replaceRelationship(rel2);
+
+ // Check our simulated event stream to see if an event log was produced.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store edge event should not have been logged to the event stream", loggedEventStr);
+ }
+
+
+ /**
+ * Validates that store/replace/delete operation against partitions result in the expected events
+ * being published to the event stream.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ */
+ @Test
+ public void partitionOperationsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException {
+
+ // Create the vertices and edge objects that we need to create a partition.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+
+ ChampObject obj2 = ChampObject.create()
+ .ofType("bar")
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ // Now, create an edge object and write it to the graph data store.
+ ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship")
+ .property("property-1", "value-1")
+ .property("property-2", "value-2")
+ .build();
+
+ // Now, create our partition object and store it in the graph.
+ ChampPartition partition = ChampPartition.create()
+ .withObject(obj1)
+ .withObject(obj2)
+ .withRelationship(rel)
+ .build();
+ testGraph.storePartition(partition);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected STORE event.", loggedEventStr.contains("STORE"));
+ assertTrue("Entity type for store event was not a partition.", loggedEventStr.contains("partition"));
+
+ // Now, delete our partition.
+ testGraph.deletePartition(partition);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE"));
+ assertTrue("Entity type for store event was not a partition.", loggedEventStr.contains("partition"));
+ }
+
+
+ /**
+ * This test validates that performing partition operations in the case where the data to be
+ * forwarded to the event stream is unavailable results in no event being generated, but
+ * does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ */
+ @Test
+ public void partitionOperationsWithNullsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException {
+
+ // Set up our graph to simulate a failure to retrieve some of the data we need to generate
+ // events.
+ testGraph.returnNulls();
+
+ // Create all of the objects we need to create a partition, and store the partition
+ // in the graph.
+ ChampObject obj1 = ChampObject.create()
+ .ofType("foo")
+ .withKey("123")
+ .withProperty("p1", "v1")
+ .withProperty("p2", "v2")
+ .build();
+
+ ChampObject obj2 = ChampObject.create()
+ .ofType("bar")
+ .withKey("123")
+ .withProperty("p3", "v3")
+ .build();
+
+ ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship")
+ .property("property-1", "value-1")
+ .property("property-2", "value-2")
+ .build();
+
+ ChampPartition partition = ChampPartition.create()
+ .withObject(obj1)
+ .withObject(obj2)
+ .withRelationship(rel)
+ .build();
+ testGraph.storePartition(partition);
+
+ // Check our simulated event stream to see if an an event log was produced.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Store partition event should not have been logged to the event stream", loggedEventStr);
+ }
+
+
+ /**
+ * Validates that store/replace/delete operation against vertex indexes result in the expected
+ * events being published to the event stream.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ * @throws ChampIndexNotExistsException
+ */
+ @Test
+ public void indexOperationsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException,
+ ChampIndexNotExistsException {
+
+ // Create an index object and store it in the graph.
+ ChampObjectIndex objIndex = ChampObjectIndex.create()
+ .ofName("myIndex")
+ .onType("type")
+ .forField("myField")
+ .build();
+ testGraph.storeObjectIndex(objIndex);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected STORE event.", loggedEventStr.contains("STORE"));
+ assertTrue("Entity type for store event was not a vertex index.", loggedEventStr.contains("objectIndex"));
+
+ // Now, delete our partition.
+ testGraph.deleteObjectIndex("myIndex");
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE"));
+ assertTrue("Entity type for store event was not a vertex index.", loggedEventStr.contains("objectIndex"));
+ }
+
+ /**
+ * This test validates that performing index operations in the case where the data to be
+ * forwarded to the event stream is unavailable results in no event being generated, but
+ * does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ * @throws ChampIndexNotExistsException
+ */
+ @Test
+ public void indexOperationsWithNullsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException,
+ ChampIndexNotExistsException {
+
+ // Set up our graph to simulate a failure to retrieve some of the data we need to generate
+ // events.
+ testGraph.returnNulls();
+
+ // Create an index object and store it in the graph.
+ ChampObjectIndex objIndex = ChampObjectIndex.create()
+ .ofName("myIndex")
+ .onType("type")
+ .forField("myField")
+ .build();
+ testGraph.storeObjectIndex(objIndex);
+
+ // Check our simulated event stream to see if an an event log was produced.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Now, delete our index.
+ testGraph.deleteObjectIndex("myIndex");
+
+ // Check our simulated event stream to see if an an event log was produced.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Delete partition event should not have been logged to the event stream", loggedEventStr);
+ }
+
+
+ /**
+ * This test validates that performing relationship index operations in the case where
+ * the data to be forwarded to the event stream is unavailable results in no event being
+ * generated, but does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ * @throws ChampIndexNotExistsException
+ */
+ @Test
+ public void relationshipIndexOperationsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException,
+ ChampIndexNotExistsException {
+
+ // Create a relationship index object and store it in the graph.
+ ChampRelationshipIndex relIndex = ChampRelationshipIndex.create()
+ .ofName("myIndex")
+ .onType("type")
+ .forField("myField")
+ .build();
+ testGraph.storeRelationshipIndex(relIndex);
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected STORE event.", loggedEventStr.contains("STORE"));
+ assertTrue("Entity type for store event was not a relationship index.", loggedEventStr.contains("relationshipIndex"));
+
+ // Now, delete our partition.
+ testGraph.deleteRelationshipIndex("myIndex");
+
+ // Retrieve the next event from the event stream and validate that it is what we expect.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+ assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE"));
+ assertTrue("Entity type for store event was not a relationship index.", loggedEventStr.contains("relationshipIndex"));
+ }
+
+
+ /**
+ * This test validates that performing index operations in the case where the data to be
+ * forwarded to the event stream is unavailable results in no event being generated, but
+ * does not otherwise create issues.
+ *
+ * @throws ChampMarshallingException
+ * @throws ChampSchemaViolationException
+ * @throws ChampObjectNotExistsException
+ * @throws InterruptedException
+ * @throws JsonParseException
+ * @throws JsonMappingException
+ * @throws IOException
+ * @throws ChampUnmarshallingException
+ * @throws ChampRelationshipNotExistsException
+ * @throws ChampIndexNotExistsException
+ */
+ @Test
+ public void relationshipIndexOperationsWithNullsTest() throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException,
+ InterruptedException,
+ JsonParseException,
+ JsonMappingException,
+ IOException,
+ ChampUnmarshallingException,
+ ChampRelationshipNotExistsException,
+ ChampIndexNotExistsException {
+
+ // Set up our graph to simulate a failure to retrieve some of the data we need to generate
+ // events.
+ testGraph.returnNulls();
+
+ // Create a relationship index object and store it in the graph.
+ ChampRelationshipIndex relIndex = ChampRelationshipIndex.create()
+ .ofName("myIndex")
+ .onType("type")
+ .forField("myField")
+ .build();
+
+ testGraph.storeRelationshipIndex(relIndex);
+
+ // Check our simulated event stream to see if an an event log was produced.
+ String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Now, delete our index.
+ testGraph.deleteRelationshipIndex("myIndex");
+
+ // Check our simulated event stream to see if an event log was produced.
+ loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS);
+
+ // Validate that we did not get an event from the stream.
+ assertNull("Delete partition event should not have been logged to the event stream", loggedEventStr);
+ }
+
+
+ /**
+ * This is a simple graph stub that extends our {@link AbstractLoggingChampGraph} class which
+ * we can use to validate that log events get generated without worrying about having a real
+ * underlying graph.
+ */
+ private class TestGraph extends AbstractLoggingChampGraph {
+
+ /** If set, this causes simulated retrieve operations to fail. */
+ private boolean returnNulls = false;
+
+
+ protected TestGraph(Map<String, Object> properties, CambriaPublisher producer) {
+ super(properties);
+
+ setProducer(producer);
+ }
+
+ public void returnNulls() {
+ returnNulls = true;
+ }
+
+ @Override
+ public void shutdown() {
+ if(returnNulls) {
+ publisherPool = null;
+ }
+ super.shutdown();
+ }
+
+ @Override
+ public ChampObject executeStoreObject(ChampObject object) throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException {
+ if(!returnNulls) {
+ return object;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public ChampObject executeReplaceObject(ChampObject object) throws ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampObjectNotExistsException {
+ if(!returnNulls) {
+ return object;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Optional<ChampObject> retrieveObject(Object key) throws ChampUnmarshallingException {
+
+ if(!returnNulls) {
+ return(Optional.of(ChampObject.create()
+ .ofType("foo")
+ .withKey(key)
+ .build()));
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public void executeDeleteObject(Object key) throws ChampObjectNotExistsException {
+
+ }
+
+ @Override
+ public Stream<ChampObject> queryObjects(Map<String, Object> queryParams) {
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public ChampRelationship executeStoreRelationship(ChampRelationship relationship)
+ throws ChampUnmarshallingException,
+ ChampMarshallingException,
+ ChampObjectNotExistsException,
+ ChampSchemaViolationException,
+ ChampRelationshipNotExistsException {
+
+ if(!returnNulls) {
+ return relationship;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public ChampRelationship executeReplaceRelationship(ChampRelationship relationship)
+ throws ChampUnmarshallingException,
+ ChampMarshallingException,
+ ChampSchemaViolationException,
+ ChampRelationshipNotExistsException {
+
+ if(!returnNulls) {
+ return relationship;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Optional<ChampRelationship> retrieveRelationship(Object key) throws ChampUnmarshallingException {
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public void executeDeleteRelationship(ChampRelationship relationship) throws ChampRelationshipNotExistsException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public Stream<ChampRelationship> retrieveRelationships(ChampObject object)
+ throws ChampUnmarshallingException, ChampObjectNotExistsException {
+
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public Stream<ChampRelationship> queryRelationships(Map<String, Object> queryParams) {
+
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public ChampPartition executeStorePartition(ChampPartition partition)
+ throws ChampSchemaViolationException,
+ ChampRelationshipNotExistsException,
+ ChampMarshallingException,
+ ChampObjectNotExistsException {
+
+ if(!returnNulls) {
+ return partition;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void executeDeletePartition(ChampPartition graph) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void executeStoreObjectIndex(ChampObjectIndex index) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
+
+ if(!returnNulls) {
+ return Optional.of(ChampObjectIndex.create()
+ .ofName(indexName)
+ .onType("doesnt matter")
+ .forField("doesnt matter")
+ .build());
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public Stream<ChampObjectIndex> retrieveObjectIndices() {
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
+ if(!returnNulls) {
+ return Optional.of(ChampRelationshipIndex.create()
+ .ofName(indexName)
+ .onType("doesnt matter")
+ .forField("doesnt matter")
+ .build());
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ @Override
+ public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public void executeDeleteRelationshipIndex(String indexName)
+ throws ChampIndexNotExistsException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void storeSchema(ChampSchema schema) throws ChampSchemaViolationException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public ChampSchema retrieveSchema() {
+ // Not used by any tests.
+ return null;
+ }
+
+ @Override
+ public void updateSchema(ChampObjectConstraint objectConstraint)
+ throws ChampSchemaViolationException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void updateSchema(ChampRelationshipConstraint schema)
+ throws ChampSchemaViolationException {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void deleteSchema() {
+ // Not used by any tests.
+ }
+
+ @Override
+ public ChampCapabilities capabilities() {
+ // Not used by any tests.
+ return null;
+ }
+ }
+
+ private class InMemoryPublisher implements CambriaPublisher {
+
+ public BlockingQueue<String> eventStream = new ArrayBlockingQueue<String>(50);
+ public BlockingQueue<String> failedMsgs = new ArrayBlockingQueue<String>(10);
+
+ private boolean failMode=false;
+
+ public void enterFailMode() {
+ failMode=true;
+ }
+
+ @Override
+ public void logTo(Logger log) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void setApiCredentials(String apiKey, String apiSecret) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void clearApiCredentials() {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void setHttpBasicCredentials(String username, String password) {
+ // Not used by any tests.
+ }
+
+ @Override
+ public void clearHttpBasicCredentials() {
+ // Not used by any tests.
+ }
+
+ @Override
+ public int send(String partition, String msg) throws IOException {
+
+ if(!failMode) {
+ eventStream.add(msg);
+ return 0;
+ } else {
+ failedMsgs.add(msg);
+ throw new IOException("nope");
+ }
+ }
+
+ @Override
+ public int send(message msg) throws IOException {
+ eventStream.add(msg.toString());
+ return 0;
+ }
+
+ @Override
+ public int send(Collection<message> msgs) throws IOException {
+ for(message msg : msgs) {
+ eventStream.add(msg.toString());
+ }
+ return 0;
+ }
+
+ @Override
+ public void close() {
+ // Not used by any tests.
+ }
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java b/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java
new file mode 100644
index 0000000..3f813f5
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java
@@ -0,0 +1,150 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.exceptions;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class ChampExceptionTest {
+
+ @Test
+ public void testChampIndexNotExistsException() {
+ final ChampIndexNotExistsException e1 = new ChampIndexNotExistsException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampIndexNotExistsException e2 = new ChampIndexNotExistsException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampIndexNotExistsException e4 = new ChampIndexNotExistsException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+ @Test
+ public void testChampMarshallingException() {
+ final ChampMarshallingException e1 = new ChampMarshallingException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampMarshallingException e2 = new ChampMarshallingException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampMarshallingException e4 = new ChampMarshallingException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+ @Test
+ public void testChampObjectNotExistsException() {
+ final ChampObjectNotExistsException e1 = new ChampObjectNotExistsException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampObjectNotExistsException e2 = new ChampObjectNotExistsException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampObjectNotExistsException e4 = new ChampObjectNotExistsException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+ @Test
+ public void testChampRelationshipNotExistsException() {
+ final ChampRelationshipNotExistsException e1 = new ChampRelationshipNotExistsException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampRelationshipNotExistsException e2 = new ChampRelationshipNotExistsException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampRelationshipNotExistsException e4 = new ChampRelationshipNotExistsException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+ @Test
+ public void testChampSchemaViolationException() {
+ final ChampSchemaViolationException e1 = new ChampSchemaViolationException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampSchemaViolationException e2 = new ChampSchemaViolationException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampSchemaViolationException e4 = new ChampSchemaViolationException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+ @Test
+ public void testChampUnmarshallingException() {
+ final ChampUnmarshallingException e1 = new ChampUnmarshallingException();
+
+ assertTrue(e1.getMessage() == null);
+
+ final ChampUnmarshallingException e2 = new ChampUnmarshallingException("foo");
+
+ assertTrue(e2.getMessage().equals("foo"));
+
+ final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2);
+
+ assertTrue(e3.getCause().equals(e2));
+
+ final ChampUnmarshallingException e4 = new ChampUnmarshallingException("foo", e3);
+
+ assertTrue(e4.getMessage().equals("foo"));
+ assertTrue(e4.getCause().equals(e3));
+ }
+
+}
diff --git a/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java b/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java
new file mode 100644
index 0000000..7ecb3de
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.ie;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+
+public class ExportTest {
+
+ @Test
+ public void testGraphMLExport() {
+
+ final GraphMLImporterExporter ie = new GraphMLImporterExporter();
+ final ChampAPI api = ChampAPI.Factory.newInstance(ChampGraph.Type.IN_MEMORY);
+
+ ie.importData(api, getClass().getClassLoader().getResourceAsStream("import-test.graphml"));
+
+ ie.exportData(api.getGraph("unit-test"), System.out);
+
+ api.shutdown();
+ }
+}
diff --git a/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java b/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java
new file mode 100644
index 0000000..ba2cbb1
--- /dev/null
+++ b/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java
@@ -0,0 +1,93 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 Amdocs
+ * ===================================================================
+ * Licensed 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.
+ * ============LICENSE_END============================================
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.aai.champ.ie;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Optional;
+
+import org.junit.Test;
+import org.openecomp.aai.champ.ChampAPI;
+import org.openecomp.aai.champ.ChampGraph;
+
+public class ImportTest {
+
+ private final String GRAPH_NAME = "unit-test";
+
+ @Test
+ public void testGraphMLImport() {
+
+ final GraphMLImporterExporter importer = new GraphMLImporterExporter();
+ final ChampAPI api = ChampAPI.Factory.newInstance(ChampGraph.Type.IN_MEMORY);
+
+ importer.importData(api, getClass().getClassLoader().getResourceAsStream("import-test.graphml"));
+
+ final ChampGraph graph = api.getGraph(GRAPH_NAME);
+
+ graph.queryObjects(Collections.emptyMap()).forEach(object -> {
+ final Optional<String> nameOpt = object.getProperty("name");
+ final Optional<Boolean> studentOpt = object.getProperty("student");
+ final Optional<Long> worthOpt = object.getProperty("worth");
+ final Optional<Integer> ageOpt = object.getProperty("age");
+ final Optional<Float> heightOpt = object.getProperty("height");
+ final Optional<Double> weightOpt = object.getProperty("weight");
+ final Optional<String> favoriteColorOpt = object.getProperty("favoriteColor");
+
+ final String name = nameOpt.get();
+
+ if (name.equals("Champ")) {
+ assertTrue(!studentOpt.isPresent());
+ assertTrue(!ageOpt.isPresent());
+ assertTrue(!worthOpt.isPresent());
+ assertTrue(!heightOpt.isPresent());
+ assertTrue(!weightOpt.isPresent());
+ assertTrue(favoriteColorOpt.get().equals("green"));
+ } else if (name.equals("Max")) {
+ assertTrue(!studentOpt.isPresent());
+ assertTrue(!ageOpt.isPresent());
+ assertTrue(!worthOpt.isPresent());
+ assertTrue(!heightOpt.isPresent());
+ assertTrue(!weightOpt.isPresent());
+ assertTrue(favoriteColorOpt.get().equals("red"));
+ } else if (name.equals("Ace")) {
+ assertTrue(studentOpt.get());
+ assertTrue(worthOpt.get().equals(50000L));
+ assertTrue(ageOpt.get().equals(21));
+ assertTrue(heightOpt.get().equals(72.5f));
+ assertTrue(weightOpt.get().equals(180.5d));
+ assertTrue(favoriteColorOpt.get().equals("yellow"));
+ } else if (name.equals("Fido")) {
+ assertTrue(!studentOpt.isPresent());
+ assertTrue(!ageOpt.isPresent());
+ assertTrue(!worthOpt.isPresent());
+ assertTrue(!heightOpt.isPresent());
+ assertTrue(!weightOpt.isPresent());
+ assertTrue(favoriteColorOpt.get().equals("blue"));
+ } else {
+ throw new AssertionError("Unknown object " + name + " - update unit test");
+ }
+ });
+
+ api.shutdown();
+ }
+}
diff --git a/src/test/resources/import-test.graphml b/src/test/resources/import-test.graphml
new file mode 100755
index 0000000..fd13b6b
--- /dev/null
+++ b/src/test/resources/import-test.graphml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+ <key id="d0" for="node" attr.name="student" attr.type="boolean"/>
+ <key id="d1" for="node" attr.name="worth" attr.type="long"/>
+ <key id="d2" for="node" attr.name="age" attr.type="int"/>
+ <key id="d3" for="node" attr.name="height" attr.type="float"/>
+ <key id="d4" for="node" attr.name="weight" attr.type="double"/>
+ <key id="d5" for="node" attr.name="favoriteColor" attr.type="string">
+ <default>green</default>
+ </key>
+ <key id="d6" for="node" attr.name="name" attr.type="string"/>
+ <key id="d7" for="edge" attr.name="at" attr.type="long"/>
+ <key id="d8" for="node" attr.name="type" attr.type="string"/>
+ <key id="d9" for="edge" attr.name="type" attr.type="string"/>
+ <graph id="unit-test" edgedefault="directed">
+ <node id="n0">
+ <data key="d0">true</data>
+ <data key="d1">50000</data>
+ <data key="d2">21</data>
+ <data key="d3">72.5</data>
+ <data key="d4">180.5</data>
+ <data key="d5">yellow</data>
+ <data key="d6">Ace</data>
+ <data key="d8">Dog</data>
+ </node>
+ <node id="n1">
+ <data key="d6">Champ</data>
+ <data key="d8">Dog</data>
+ </node>
+ <node id="n2">
+ <data key="d5">blue</data>
+ <data key="d6">Fido</data>
+ <data key="d8">Dog</data>
+ </node>
+ <node id="n3">
+ <data key="d5">red</data>
+ <data key="d6">Max</data>
+ <data key="d8">Dog</data>
+ </node>
+ <edge id="e0" source="n0" target="n2">
+ <data key="d7">12348234</data>
+ <data key="d9">Dog</data>
+ </edge>
+ <edge id="e3" source="n3" target="n2">
+ <data key="d9">Dog</data>
+ </edge>
+ </graph>
+</graphml> \ No newline at end of file
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
new file mode 100644
index 0000000..72cd644
--- /dev/null
+++ b/src/test/resources/logback.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ ============LICENSE_START==========================================
+ org.onap.aai
+ ===================================================================
+ Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ Copyright © 2017 Amdocs
+ ===================================================================
+ Licensed 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.
+ ============LICENSE_END============================================
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+-->
+<configuration>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d %-5level [%thread] %logger{255}: %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="com.thinkaurelius.titan" level="OFF"/>
+ <logger name="com.netflix.astyanax" level="OFF"/>
+ <logger name="com.datastax" level="ERROR"/>
+ <logger name="org.apache.hadoop" level="ERROR"/>
+ <logger name="org.apache.zookeeper" level="ERROR"/>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>