2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 Amdocs
7 * ===================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END============================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.openecomp.aai.champ.core;
24 import static org.junit.Assert.assertTrue;
26 import java.io.IOException;
29 import org.junit.Test;
30 import org.openecomp.aai.champ.ChampAPI;
31 import org.openecomp.aai.champ.ChampGraph;
32 import org.openecomp.aai.champ.exceptions.ChampMarshallingException;
33 import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException;
34 import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException;
35 import org.openecomp.aai.champ.model.ChampConnectionConstraint;
36 import org.openecomp.aai.champ.model.ChampConnectionMultiplicity;
37 import org.openecomp.aai.champ.model.ChampField;
38 import org.openecomp.aai.champ.model.ChampObject;
39 import org.openecomp.aai.champ.model.ChampObject.ReservedTypes;
40 import org.openecomp.aai.champ.model.ChampObjectConstraint;
41 import org.openecomp.aai.champ.model.ChampPartition;
42 import org.openecomp.aai.champ.model.ChampPropertyConstraint;
43 import org.openecomp.aai.champ.model.ChampRelationship;
44 import org.openecomp.aai.champ.model.ChampRelationshipConstraint;
45 import org.openecomp.aai.champ.model.ChampSchema;
46 import org.openecomp.aai.champ.schema.AlwaysValidChampSchemaEnforcer;
47 import org.openecomp.aai.champ.schema.ChampSchemaEnforcer;
48 import org.openecomp.aai.champ.schema.DefaultChampSchemaEnforcer;
50 import com.fasterxml.jackson.databind.ObjectMapper;
52 public class ChampSchemaTest extends BaseChampAPITest {
55 public void runTest() {
56 for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
57 final String graphName = ChampSchemaTest.class.getSimpleName();
69 final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
72 ChampSchemaTest.testChampSchemaCrud(api.getGraph(graphName));
73 } catch (Throwable t) {
74 throw new AssertionError(apiType + " unit test failed", t);
81 public static void testChampSchemaCrud(ChampGraph graph) {
83 final ChampSchema schema = ChampSchema.create()
84 .withObjectConstraint()
86 .withPropertyConstraint()
90 .withPropertyConstraint()
95 .withRelationshipConstraint()
97 .withPropertyConstraint()
99 .ofType(ChampField.Type.STRING)
102 .withConnectionConstraint()
110 graph.storeSchema(schema);
111 } catch (ChampSchemaViolationException e) {
112 throw new AssertionError(e);
115 final ChampObject emptyFoo = ChampObject.create()
121 graph.storeObject(emptyFoo);
122 } catch (ChampMarshallingException e1) {
123 throw new AssertionError(e1);
124 } catch (ChampSchemaViolationException e1) {
125 //Expected, since it does not have the required property "property1"
126 } catch (ChampObjectNotExistsException e) {
127 throw new AssertionError(e);
130 final ChampSchema retrievedSchema = graph.retrieveSchema();
132 if (!schema.equals(retrievedSchema)) throw new AssertionError("Retrieved schema is not the same as the schema that was previously stored");
135 graph.updateSchema(new ChampRelationshipConstraint.Builder("bard").build());
136 assertTrue(graph.retrieveSchema().getRelationshipConstraint("bard").isPresent());
138 graph.updateSchema(new ChampObjectConstraint.Builder("baz").build());
139 assertTrue(graph.retrieveSchema().getObjectConstraint("baz").isPresent());
140 } catch (ChampSchemaViolationException e) {
141 throw new AssertionError(e);
144 final ChampSchema updatedSchema = graph.retrieveSchema();
146 if (!updatedSchema.getObjectConstraint("baz").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates");
147 if (!updatedSchema.getRelationshipConstraint("bard").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates");
150 graph.updateSchema(new ChampObjectConstraint.Builder("foo")
152 new ChampPropertyConstraint.Builder(
153 new ChampField.Builder("property2")
161 final ChampObject storedEmptyFoo = graph.storeObject(emptyFoo);
163 graph.deleteObject(storedEmptyFoo.getKey().get());
164 } catch (ChampMarshallingException e) {
165 throw new AssertionError(e);
166 } catch (ChampSchemaViolationException e) {
167 throw new AssertionError(e);
168 } catch (ChampObjectNotExistsException e) {
169 throw new AssertionError(e);
172 graph.deleteSchema();
173 assertTrue(graph.retrieveSchema().equals(ChampSchema.emptySchema()));
177 public void testChampSchemaFluentApi() {
178 final ChampSchema schema = ChampSchema.create()
179 .withObjectConstraint()
181 .withPropertyConstraint()
183 .ofType(ChampField.Type.STRING)
186 .withPropertyConstraint()
188 .ofType(ChampField.Type.BOOLEAN)
192 .withRelationshipConstraint()
194 .withPropertyConstraint()
196 .ofType(ChampField.Type.STRING)
199 .withPropertyConstraint()
203 .withConnectionConstraint()
206 .withMultiplicity(ChampConnectionMultiplicity.ONE)
208 .withConnectionConstraint()
215 assertTrue(schema.getObjectConstraint("foo").get().getType().equals("foo"));
217 for (ChampPropertyConstraint propConst : schema.getObjectConstraint("foo").get().getPropertyConstraints()) {
218 if (propConst.getField().getName().equals("bar")) {
219 assertTrue(propConst.getField().getJavaType().equals(String.class));
220 assertTrue(propConst.isRequired());
221 } else if (propConst.getField().getName().equals("baz")) {
222 assertTrue(propConst.getField().getJavaType().equals(Boolean.class));
223 assertTrue(!propConst.isRequired());
225 throw new AssertionError("Unknown property constraint found: " + propConst);
229 assertTrue(schema.getRelationshipConstraint("eats").get().getType().equals("eats"));
231 for (ChampPropertyConstraint propConst : schema.getRelationshipConstraint("eats").get().getPropertyConstraints()) {
232 if (propConst.getField().getName().equals("at")) {
233 assertTrue(propConst.getField().getJavaType().equals(String.class));
234 assertTrue(propConst.isRequired());
235 } else if (propConst.getField().getName().equals("for")) {
236 assertTrue(propConst.getField().getJavaType().equals(String.class));
237 assertTrue(!propConst.isRequired());
239 throw new AssertionError("Unknown property constraint found: " + propConst);
243 for (ChampConnectionConstraint connConst : schema.getRelationshipConstraint("eats").get().getConnectionConstraints()) {
244 if (connConst.getSourceType().equals("foo")) {
245 assertTrue(connConst.getTargetType().equals("foo"));
246 assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.ONE);
247 } else if (connConst.getSourceType().equals("bar")) {
248 assertTrue(connConst.getTargetType().equals("bar"));
249 assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.MANY);
251 throw new AssertionError("Unknown connection constraint found: " + connConst);
257 public void testDefaultChampSchemaEnforcer() {
259 final ChampSchemaEnforcer schemaEnforcer = new DefaultChampSchemaEnforcer();
260 final ChampSchema champSchema = ChampSchema.create()
261 .withObjectConstraint()
263 .withPropertyConstraint()
265 .ofType(ChampField.Type.STRING)
269 .withRelationshipConstraint()
271 .withPropertyConstraint()
275 .withConnectionConstraint()
278 .withMultiplicity(ChampConnectionMultiplicity.ONE)
284 schemaEnforcer.validate(ChampObject.create()
287 .withProperty("bar", "true")
289 champSchema.getObjectConstraint("foo").get());
290 } catch (ChampSchemaViolationException e) {
291 throw new AssertionError(e);
295 schemaEnforcer.validate(ChampObject.create()
299 champSchema.getObjectConstraint("foo").get());
300 throw new AssertionError("Failed to enforce required property constraint on object");
301 } catch (ChampSchemaViolationException e) {
306 schemaEnforcer.validate(ChampObject.create()
309 .withProperty("bar", true)
311 champSchema.getObjectConstraint("foo").get());
312 throw new AssertionError("Failed to enforce property type constraint on object");
313 } catch (ChampSchemaViolationException e) {
318 schemaEnforcer.validate(ChampRelationship.create()
329 .withProperty("bar", "true")
331 champSchema.getRelationshipConstraint("makes").get()
333 } catch (ChampSchemaViolationException e) {
334 throw new AssertionError(e);
338 schemaEnforcer.validate(ChampRelationship.create()
350 champSchema.getRelationshipConstraint("makes").get()
352 throw new AssertionError("Failed to enforce required property constraint on relationship");
353 } catch (ChampSchemaViolationException e) {
358 schemaEnforcer.validate(ChampPartition.create()
363 .withProperty("bar", "true")
373 ChampRelationship.create()
379 .withProperty("bar", "true")
385 .withProperty("bar", "true")
389 ChampRelationship.create()
399 .withProperty("bar", "true")
401 .withProperty("bar", "true")
407 } catch (ChampSchemaViolationException e) {
408 throw new AssertionError(e);
412 schemaEnforcer.validate(ChampPartition.create()
417 .withProperty("bar", "true")
427 ChampRelationship.create()
433 .withProperty("bar", "true")
439 .withProperty("bar", "true")
443 ChampRelationship.create()
449 .withProperty("bar", "true")
455 .withProperty("bar", "true")
461 throw new AssertionError("Failed to enforce connection constraint on relationship type 'makes'");
462 } catch (ChampSchemaViolationException e) {
468 public void testAlwaysValidChampSchemaEnforcer() {
470 final ChampSchemaEnforcer schemaEnforcer = new AlwaysValidChampSchemaEnforcer();
473 schemaEnforcer.validate(ChampObject.create()
476 .withProperty("bar", true)
478 new ChampObjectConstraint.Builder("foo")
480 new ChampPropertyConstraint.Builder(
481 new ChampField.Builder("bar")
482 .type(ChampField.Type.STRING)
491 schemaEnforcer.validate(ChampRelationship.create()
502 .withProperty("bar", true)
504 new ChampRelationshipConstraint.Builder("bar")
506 new ChampPropertyConstraint.Builder(
507 new ChampField.Builder("bar")
508 .type(ChampField.Type.STRING)
517 schemaEnforcer.validate(ChampPartition.create()
522 .withProperty("bar", true)
529 .withProperty("bar", true)
533 ChampRelationship.create()
547 ChampRelationship.create()
558 .withProperty("bar", true)
563 .withObjectConstraint()
565 .withPropertyConstraint()
570 .withRelationshipConstraint()
572 .withPropertyConstraint()
576 .withConnectionConstraint()
579 .withMultiplicity(ChampConnectionMultiplicity.ONE)
582 .withRelationshipConstraint()
584 .withConnectionConstraint()
586 .targetedTo("computer")
589 .withRelationshipConstraint()
591 .withConnectionConstraint()
592 .sourcedFrom("computer")
599 } catch (ChampSchemaViolationException e) {
600 throw new AssertionError(e);
605 public void testFluentSchemaApi() {
606 final ChampSchema schema = ChampSchema.create()
607 .withObjectConstraint()
609 .withPropertyConstraint()
611 .ofType(ChampField.Type.STRING)
615 .withObjectConstraint()
617 .withPropertyConstraint()
619 .ofType(ChampField.Type.LONG)
623 .withRelationshipConstraint()
625 .withPropertyConstraint()
627 .ofType(ChampField.Type.INTEGER)
630 .withConnectionConstraint()
633 .withMultiplicity(ChampConnectionMultiplicity.NONE)
635 .withConnectionConstraint()
638 .withMultiplicity(ChampConnectionMultiplicity.ONE)
640 .withConnectionConstraint()
643 .withMultiplicity(ChampConnectionMultiplicity.MANY)
645 .withConnectionConstraint()
648 .withMultiplicity(ChampConnectionMultiplicity.MANY)
653 final ChampObjectConstraint aObjConstraint = schema.getObjectConstraint("a").get();
655 assertTrue(aObjConstraint.getType().equals("a"));
657 final ChampPropertyConstraint zPropertyConstraint = aObjConstraint.getPropertyConstraint("z").get();
659 assertTrue(zPropertyConstraint.getField().getName().equals("z"));
660 assertTrue(zPropertyConstraint.getField().getJavaType().equals(String.class));
661 assertTrue(!zPropertyConstraint.isRequired());
663 final ChampObjectConstraint bObjConstraint = schema.getObjectConstraint("b").get();
665 assertTrue(bObjConstraint.getType().equals("b"));
667 final ChampPropertyConstraint yPropertyConstraint = bObjConstraint.getPropertyConstraint("y").get();
669 assertTrue(yPropertyConstraint.getField().getName().equals("y"));
670 assertTrue(yPropertyConstraint.getField().getJavaType().equals(Long.class));
671 assertTrue(yPropertyConstraint.isRequired());
673 final ChampRelationshipConstraint oneRelConstraint = schema.getRelationshipConstraint("one").get();
675 assertTrue(oneRelConstraint.getType().equals("one"));
677 final ChampPropertyConstraint ninePropertyConstraint = oneRelConstraint.getPropertyConstraint("nine").get();
679 assertTrue(ninePropertyConstraint.getField().getName().equals("nine"));
680 assertTrue(ninePropertyConstraint.getField().getJavaType().equals(Integer.class));
681 assertTrue(!ninePropertyConstraint.isRequired());
683 final Set<ChampConnectionConstraint> connectionConstraints = oneRelConstraint.getConnectionConstraints();
685 for (ChampConnectionConstraint cc : connectionConstraints) {
686 if (cc.getSourceType().equals("a") && cc.getTargetType().equals("b")) {
687 assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.NONE);
688 } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals("b")) {
689 assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY);
690 } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals(ReservedTypes.ANY.toString())) {
691 assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY);
692 } else if (cc.getSourceType().equals("a") && cc.getTargetType().equals(ReservedTypes.ANY.toString())) {
693 assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.ONE);
695 throw new AssertionError("Found unspecified connection constraint " + cc);
701 public void testJacksonObjectMapping() {
702 final ChampSchema schema = ChampSchema.create()
703 .withObjectConstraint()
705 .withPropertyConstraint()
707 .ofType(ChampField.Type.STRING)
711 .withObjectConstraint()
713 .withPropertyConstraint()
715 .ofType(ChampField.Type.LONG)
719 .withRelationshipConstraint()
721 .withPropertyConstraint()
723 .ofType(ChampField.Type.INTEGER)
726 .withConnectionConstraint()
729 .withMultiplicity(ChampConnectionMultiplicity.NONE)
731 .withConnectionConstraint()
734 .withMultiplicity(ChampConnectionMultiplicity.ONE)
736 .withConnectionConstraint()
739 .withMultiplicity(ChampConnectionMultiplicity.MANY)
741 .withConnectionConstraint()
744 .withMultiplicity(ChampConnectionMultiplicity.MANY)
749 final ObjectMapper om = new ObjectMapper();
752 final byte[] serialized = om.writeValueAsBytes(schema);
753 System.out.println(new String(serialized, "UTF-8"));
754 final ChampSchema deserialized = om.readValue(serialized, ChampSchema.class);
755 assert schema.equals(deserialized);
756 } catch (IOException e) {
757 throw new AssertionError(e);