Renaming openecomp to onap
[aai/champ.git] / src / test / java / org / onap / aai / champ / core / ChampSchemaTest.java
1 /**
2  * ============LICENSE_START==========================================
3  * org.onap.aai
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
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
21  */
22 package org.onap.aai.champ.core;
23
24 import static org.junit.Assert.assertTrue;
25
26 import java.io.IOException;
27 import java.util.Set;
28
29 import org.junit.Test;
30 import org.onap.aai.champ.ChampAPI;
31 import org.onap.aai.champ.ChampGraph;
32 import org.onap.aai.champ.exceptions.ChampMarshallingException;
33 import org.onap.aai.champ.exceptions.ChampObjectNotExistsException;
34 import org.onap.aai.champ.exceptions.ChampSchemaViolationException;
35 import org.onap.aai.champ.model.ChampConnectionConstraint;
36 import org.onap.aai.champ.model.ChampConnectionMultiplicity;
37 import org.onap.aai.champ.model.ChampField;
38 import org.onap.aai.champ.model.ChampObject;
39 import org.onap.aai.champ.model.ChampObjectConstraint;
40 import org.onap.aai.champ.model.ChampPartition;
41 import org.onap.aai.champ.model.ChampPropertyConstraint;
42 import org.onap.aai.champ.model.ChampRelationship;
43 import org.onap.aai.champ.model.ChampRelationshipConstraint;
44 import org.onap.aai.champ.model.ChampSchema;
45 import org.onap.aai.champ.model.ChampObject.ReservedTypes;
46 import org.onap.aai.champ.schema.AlwaysValidChampSchemaEnforcer;
47 import org.onap.aai.champ.schema.ChampSchemaEnforcer;
48 import org.onap.aai.champ.schema.DefaultChampSchemaEnforcer;
49
50 import com.fasterxml.jackson.databind.ObjectMapper;
51
52 public class ChampSchemaTest extends BaseChampAPITest {
53
54         @Test
55         public void runTest() {
56                 for (ChampGraph.Type apiType : ChampGraph.Type.values()) {
57                         final String graphName = ChampSchemaTest.class.getSimpleName();
58
59                         switch (apiType) {
60                         case IN_MEMORY:
61                         break;
62                         case TITAN:
63                                 cleanUp(graphName);
64                         break;
65                         default:
66                         break;
67                         }
68
69                         final ChampAPI api = ChampAPI.Factory.newInstance(apiType);
70
71                         try {
72                                 ChampSchemaTest.testChampSchemaCrud(api.getGraph(graphName));
73                         } catch (Throwable t) {
74                                 throw new AssertionError(apiType + " unit test failed", t);
75                         }
76
77                         api.shutdown();
78                 }
79         }
80
81         public static void testChampSchemaCrud(ChampGraph graph) {
82
83                 final ChampSchema schema = ChampSchema.create()
84                                         .withObjectConstraint()
85                                                 .onType("foo")
86                                                 .withPropertyConstraint()
87                                                         .onField("property1")
88                                                         .required()
89                                                         .build()
90                                                 .withPropertyConstraint()
91                                                         .onField("property2")
92                                                         .optional()
93                                                         .build()
94                                                 .build()
95                                         .withRelationshipConstraint()
96                                                 .onType("bar")
97                                                 .withPropertyConstraint()
98                                                         .onField("at")
99                                                         .ofType(ChampField.Type.STRING)
100                                                         .optional()
101                                                         .build()
102                                                 .withConnectionConstraint()
103                                                         .sourcedFrom("foo")
104                                                         .targetedToAny()
105                                                         .build()
106                                                 .build()
107                                         .build();
108
109                 try {
110                         graph.storeSchema(schema);
111                 } catch (ChampSchemaViolationException e) {
112                         throw new AssertionError(e);
113                 }
114
115                 final ChampObject emptyFoo = ChampObject.create()
116                                                                                                 .ofType("foo")
117                                                                                                 .withoutKey()
118                                                                                                 .build();
119
120                 try {
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);
128                 }
129
130                 final ChampSchema retrievedSchema = graph.retrieveSchema();
131
132                 if (!schema.equals(retrievedSchema)) throw new AssertionError("Retrieved schema is not the same as the schema that was previously stored");
133
134                 try {
135                         graph.updateSchema(new ChampRelationshipConstraint.Builder("bard").build());
136                         assertTrue(graph.retrieveSchema().getRelationshipConstraint("bard").isPresent());
137
138                         graph.updateSchema(new ChampObjectConstraint.Builder("baz").build());
139                         assertTrue(graph.retrieveSchema().getObjectConstraint("baz").isPresent());
140                 } catch (ChampSchemaViolationException e) {
141                         throw new AssertionError(e);
142                 }
143
144                 final ChampSchema updatedSchema = graph.retrieveSchema();
145
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");
148
149                 try {
150                         graph.updateSchema(new ChampObjectConstraint.Builder("foo")
151                                                                                                                 .constraint(
152                                                                                                                         new ChampPropertyConstraint.Builder(
153                                                                                                                                 new ChampField.Builder("property2")
154                                                                                                                                                                 .build()
155                                                                                                                         )
156                                                                                                                         .required(false)
157                                                                                                                         .build()
158                                                                                                                 )
159                                                                                                                 .build());
160
161                         final ChampObject storedEmptyFoo = graph.storeObject(emptyFoo);
162                         
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);
170                 }
171                 
172                 graph.deleteSchema();
173                 assertTrue(graph.retrieveSchema().equals(ChampSchema.emptySchema()));
174         }
175
176         @Test
177         public void testChampSchemaFluentApi() {
178                 final ChampSchema schema = ChampSchema.create()
179                                         .withObjectConstraint()
180                                                 .onType("foo")
181                                                 .withPropertyConstraint()
182                                                         .onField("bar")
183                                                         .ofType(ChampField.Type.STRING)
184                                                         .required()
185                                                         .build()
186                                                 .withPropertyConstraint()
187                                                         .onField("baz")
188                                                         .ofType(ChampField.Type.BOOLEAN)
189                                                         .optional()
190                                                         .build()
191                                                 .build()
192                                         .withRelationshipConstraint()
193                                                 .onType("eats")
194                                                 .withPropertyConstraint()
195                                                         .onField("at")
196                                                         .ofType(ChampField.Type.STRING)
197                                                         .required()
198                                                         .build()
199                                                 .withPropertyConstraint()
200                                                         .onField("for")
201                                                         .optional()
202                                                         .build()
203                                                 .withConnectionConstraint()
204                                                         .sourcedFrom("foo")
205                                                         .targetedTo("foo")
206                                                         .withMultiplicity(ChampConnectionMultiplicity.ONE)
207                                                         .build()
208                                                 .withConnectionConstraint()
209                                                         .sourcedFrom("bar")
210                                                         .targetedTo("bar")
211                                                         .build()
212                                         .build()
213                                 .build();
214
215                 assertTrue(schema.getObjectConstraint("foo").get().getType().equals("foo"));
216                 
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());
224                         } else {
225                                 throw new AssertionError("Unknown property constraint found: " + propConst);
226                         }
227                 }
228
229                 assertTrue(schema.getRelationshipConstraint("eats").get().getType().equals("eats"));
230
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());
238                         } else {
239                                 throw new AssertionError("Unknown property constraint found: " + propConst);
240                         }
241                 }
242
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);
250                         } else {
251                                 throw new AssertionError("Unknown connection constraint found: " + connConst);
252                         }
253                 }
254         }
255
256         @Test
257         public void testDefaultChampSchemaEnforcer() {
258
259                 final ChampSchemaEnforcer schemaEnforcer = new DefaultChampSchemaEnforcer();
260                 final ChampSchema champSchema = ChampSchema.create()
261                                                                                         .withObjectConstraint()
262                                                                                                 .onType("foo")
263                                                                                                 .withPropertyConstraint()
264                                                                                                         .onField("bar")
265                                                                                                         .ofType(ChampField.Type.STRING)
266                                                                                                         .required()
267                                                                                                         .build()
268                                                                                                 .build()
269                                                                                         .withRelationshipConstraint()
270                                                                                                 .onType("makes")
271                                                                                                 .withPropertyConstraint()
272                                                                                                         .onField("bar")
273                                                                                                         .required()
274                                                                                                         .build()
275                                                                                                 .withConnectionConstraint()
276                                                                                                         .sourcedFrom("foo")
277                                                                                                         .targetedTo("fiz")
278                                                                                                         .withMultiplicity(ChampConnectionMultiplicity.ONE)
279                                                                                                         .build()
280                                                                                                 .build()
281                                                                                         .build();
282
283                 try {
284                         schemaEnforcer.validate(ChampObject.create()
285                                                                                                 .ofType("foo")
286                                                                                                 .withoutKey()
287                                                                                                 .withProperty("bar", "true")
288                                                                                                 .build(),
289                                                                         champSchema.getObjectConstraint("foo").get());
290                 } catch (ChampSchemaViolationException e) {
291                         throw new AssertionError(e);
292                 }
293
294                 try {
295                         schemaEnforcer.validate(ChampObject.create()
296                                                                                                 .ofType("foo")
297                                                                                                 .withoutKey()
298                                                                                                 .build(),
299                                                                         champSchema.getObjectConstraint("foo").get());
300                         throw new AssertionError("Failed to enforce required property constraint on object");
301                 } catch (ChampSchemaViolationException e) {
302                         //Expected
303                 }
304
305                 try {
306                         schemaEnforcer.validate(ChampObject.create()
307                                                                                                 .ofType("foo")
308                                                                                                 .withoutKey()
309                                                                                                 .withProperty("bar", true)
310                                                                                                 .build(),
311                                                                         champSchema.getObjectConstraint("foo").get());
312                         throw new AssertionError("Failed to enforce property type constraint on object");
313                 } catch (ChampSchemaViolationException e) {
314                         //Expected
315                 }
316
317                 try {
318                         schemaEnforcer.validate(ChampRelationship.create()
319                                                                                                 .ofType("makes")
320                                                                                                 .withoutKey()
321                                                                                                 .withSource()
322                                                                                                         .ofType("foo")
323                                                                                                         .withoutKey()
324                                                                                                         .build()
325                                                                                                 .withTarget()
326                                                                                                         .ofType("fiz")
327                                                                                                         .withoutKey()
328                                                                                                         .build()
329                                                                                                 .withProperty("bar", "true")
330                                                                                                 .build(),
331                                                                         champSchema.getRelationshipConstraint("makes").get()
332                                                                 );
333                 } catch (ChampSchemaViolationException e) {
334                         throw new AssertionError(e);
335                 }
336
337                 try {
338                         schemaEnforcer.validate(ChampRelationship.create()
339                                                                                                                 .ofType("makes")
340                                                                                                                 .withoutKey()
341                                                                                                                 .withSource()
342                                                                                                                         .ofType("foo")
343                                                                                                                         .withoutKey()
344                                                                                                                         .build()
345                                                                                                                 .withTarget()
346                                                                                                                         .ofType("fiz")
347                                                                                                                         .withoutKey()
348                                                                                                                         .build()
349                                                                                                                 .build(),
350                                                                         champSchema.getRelationshipConstraint("makes").get()
351                                                                 );
352                         throw new AssertionError("Failed to enforce required property constraint on relationship");
353                 } catch (ChampSchemaViolationException e) {
354                         //Expected
355                 }
356
357                 try {
358                         schemaEnforcer.validate(ChampPartition.create()
359                                                                                                 .withObject(
360                                                                                                         ChampObject.create()
361                                                                                                                                 .ofType("foo")
362                                                                                                                                 .withoutKey()
363                                                                                                                                 .withProperty("bar", "true")
364                                                                                                                                 .build()
365                                                                                                 )
366                                                                                                 .withObject(
367                                                                                                         ChampObject.create()
368                                                                                                                                 .ofType("fiz")
369                                                                                                                                 .withoutKey()
370                                                                                                                                 .build()
371                                                                                                 )
372                                                                                                 .withRelationship(
373                                                                                                         ChampRelationship.create()
374                                                                                                                                                 .ofType("makes")
375                                                                                                                                                 .withoutKey()
376                                                                                                                                                 .withSource()
377                                                                                                                                                         .ofType("foo")
378                                                                                                                                                         .withoutKey()
379                                                                                                                                                         .withProperty("bar", "true")
380                                                                                                                                                         .build()
381                                                                                                                                                 .withTarget()
382                                                                                                                                                         .ofType("fiz")
383                                                                                                                                                         .withoutKey()
384                                                                                                                                                         .build()
385                                                                                                                                                 .withProperty("bar",  "true")
386                                                                                                                                                 .build()
387                                                                                                 )
388                                                                                                 .withRelationship(
389                                                                                                         ChampRelationship.create()
390                                                                                                                                                 .ofType("makes")
391                                                                                                                                                 .withoutKey()
392                                                                                                                                                 .withSource()
393                                                                                                                                                         .ofType("fiz")
394                                                                                                                                                         .withoutKey()
395                                                                                                                                                         .build()
396                                                                                                                                                 .withTarget()
397                                                                                                                                                         .ofType("foo")
398                                                                                                                                                         .withoutKey()
399                                                                                                                                                         .withProperty("bar", "true")
400                                                                                                                                                         .build()
401                                                                                                                                                 .withProperty("bar", "true")
402                                                                                                                                                 .build()
403                                                                                                 )
404                                                                                                 .build(),
405                                                                                                 champSchema                                     
406                                                                 );
407                 } catch (ChampSchemaViolationException e) {
408                         throw new AssertionError(e);
409                 }
410
411                 try {
412                         schemaEnforcer.validate(ChampPartition.create()
413                                                                                                 .withObject(
414                                                                                                         ChampObject.create()
415                                                                                                                                 .ofType("foo")
416                                                                                                                                 .withoutKey()
417                                                                                                                                 .withProperty("bar", "true")
418                                                                                                                                 .build()
419                                                                                                 )
420                                                                                                 .withObject(
421                                                                                                         ChampObject.create()
422                                                                                                                                 .ofType("fiz")
423                                                                                                                                 .withoutKey()
424                                                                                                                                 .build()
425                                                                                                 )
426                                                                                                 .withRelationship(
427                                                                                                         ChampRelationship.create()
428                                                                                                                                                 .ofType("makes")
429                                                                                                                                                 .withoutKey()
430                                                                                                                                                 .withSource()
431                                                                                                                                                         .ofType("foo")
432                                                                                                                                                         .withoutKey()
433                                                                                                                                                         .withProperty("bar", "true")
434                                                                                                                                                         .build()
435                                                                                                                                                 .withTarget()
436                                                                                                                                                         .ofType("fiz")
437                                                                                                                                                         .withoutKey()
438                                                                                                                                                         .build()
439                                                                                                                                                 .withProperty("bar",  "true")
440                                                                                                                                                 .build()
441                                                                                                 )
442                                                                                                 .withRelationship(
443                                                                                                         ChampRelationship.create()
444                                                                                                                                                 .ofType("makes")
445                                                                                                                                                 .withoutKey()
446                                                                                                                                                 .withSource()
447                                                                                                                                                         .ofType("foo")
448                                                                                                                                                         .withoutKey()
449                                                                                                                                                         .withProperty("bar", "true")
450                                                                                                                                                         .build()
451                                                                                                                                                 .withTarget()
452                                                                                                                                                         .ofType("fiz")
453                                                                                                                                                         .withoutKey()
454                                                                                                                                                         .build()
455                                                                                                                                                 .withProperty("bar", "true")
456                                                                                                                                                 .build()
457                                                                                                 )
458                                                                                                 .build(),
459                                                                                                 champSchema                                     
460                                                                 );
461                         throw new AssertionError("Failed to enforce connection constraint on relationship type 'makes'");
462                 } catch (ChampSchemaViolationException e) {
463                         //Expected
464                 }
465         }
466
467         @Test
468         public void testAlwaysValidChampSchemaEnforcer() {
469
470                 final ChampSchemaEnforcer schemaEnforcer = new AlwaysValidChampSchemaEnforcer();
471
472                 try {
473                         schemaEnforcer.validate(ChampObject.create()
474                                                                                                 .ofType("foo")
475                                                                                                 .withoutKey()
476                                                                                                 .withProperty("bar", true)
477                                                                                                 .build(),
478                                                                         new ChampObjectConstraint.Builder("foo")
479                                                                                                                                 .constraint(
480                                                                                                                                         new ChampPropertyConstraint.Builder(
481                                                                                                                                                 new ChampField.Builder("bar")
482                                                                                                                                                                                 .type(ChampField.Type.STRING)
483                                                                                                                                                                                 .build()
484                                                                                                                                         )
485                                                                                                                                         .required(true)
486                                                                                                                                         .build()
487                                                                                                                                 )
488                                                                                                                                 .build()
489                                                                 );
490
491                         schemaEnforcer.validate(ChampRelationship.create()
492                                                                                                 .ofType("foo")
493                                                                                                 .withoutKey()
494                                                                                                 .withSource()
495                                                                                                         .ofType("foo")
496                                                                                                         .withoutKey()
497                                                                                                         .build()
498                                                                                                 .withTarget()
499                                                                                                         .ofType("fiz")
500                                                                                                         .withoutKey()
501                                                                                                         .build()
502                                                                                                 .withProperty("bar", true)
503                                                                                                 .build(),
504                                                                         new ChampRelationshipConstraint.Builder("bar")
505                                                                                                                                 .constraint(
506                                                                                                                                         new ChampPropertyConstraint.Builder(
507                                                                                                                                                 new ChampField.Builder("bar")
508                                                                                                                                                                                 .type(ChampField.Type.STRING)
509                                                                                                                                                                                 .build()
510                                                                                                                                         )
511                                                                                                                                         .required(true)
512                                                                                                                                         .build()
513                                                                                                                                 )
514                                                                                                                                 .build()
515                                                                 );
516
517                         schemaEnforcer.validate(ChampPartition.create()
518                                                                                                 .withObject(
519                                                                                                         ChampObject.create()
520                                                                                                                                 .ofType("foo")
521                                                                                                                                 .withoutKey()
522                                                                                                                                 .withProperty("bar", true)
523                                                                                                                                 .build()
524                                                                                                 )
525                                                                                                 .withObject(
526                                                                                                         ChampObject.create()
527                                                                                                                                 .ofType("fiz")
528                                                                                                                                 .withoutKey()
529                                                                                                                                 .withProperty("bar", true)
530                                                                                                                                 .build()
531                                                                                                 )
532                                                                                                 .withRelationship(
533                                                                                                         ChampRelationship.create()
534                                                                                                                                                 .ofType("makes")
535                                                                                                                                                 .withoutKey()
536                                                                                                                                                 .withSource()
537                                                                                                                                                         .ofType("foo")
538                                                                                                                                                         .withoutKey()
539                                                                                                                                                         .build()
540                                                                                                                                                 .withTarget()
541                                                                                                                                                         .ofType("fiz")
542                                                                                                                                                         .withoutKey()
543                                                                                                                                                         .build()
544                                                                                                                                                 .build()
545                                                                                                 )
546                                                                                                 .withRelationship(
547                                                                                                         ChampRelationship.create()
548                                                                                                                                                 .ofType("makes")
549                                                                                                                                                 .withoutKey()
550                                                                                                                                                 .withSource()
551                                                                                                                                                         .ofType("foo")
552                                                                                                                                                         .withoutKey()
553                                                                                                                                                         .build()
554                                                                                                                                                 .withTarget()
555                                                                                                                                                         .ofType("fiz")
556                                                                                                                                                         .withoutKey()
557                                                                                                                                                         .build()
558                                                                                                                                                 .withProperty("bar", true)
559                                                                                                                                                 .build()
560                                                                                                 )
561                                                                                                 .build(),
562                                                                 ChampSchema.create()
563                                                                                         .withObjectConstraint()
564                                                                                                 .onType("foo")
565                                                                                                 .withPropertyConstraint()
566                                                                                                         .onField("bar")
567                                                                                                         .required()
568                                                                                                         .build()
569                                                                                                 .build()
570                                                                                         .withRelationshipConstraint()
571                                                                                                 .onType("makes")
572                                                                                                 .withPropertyConstraint()
573                                                                                                         .onField("bar")
574                                                                                                         .required()
575                                                                                                         .build()
576                                                                                                 .withConnectionConstraint()
577                                                                                                         .sourcedFrom("foo")
578                                                                                                         .targetedTo("fiz")
579                                                                                                         .withMultiplicity(ChampConnectionMultiplicity.ONE)
580                                                                                                         .build()
581                                                                                                 .build()
582                                                                                         .withRelationshipConstraint()
583                                                                                                 .onType("uses")
584                                                                                                 .withConnectionConstraint()
585                                                                                                         .sourcedFromAny()
586                                                                                                         .targetedTo("computer")
587                                                                                                         .build()
588                                                                                                 .build()
589                                                                                         .withRelationshipConstraint()
590                                                                                                 .onType("destroys")
591                                                                                                 .withConnectionConstraint()
592                                                                                                         .sourcedFrom("computer")
593                                                                                                         .targetedToAny()
594                                                                                                         .build()
595                                                                                                 .build()
596                                                                                         .build()
597                                                                                                         
598                                                                 );
599                 } catch (ChampSchemaViolationException e) {
600                         throw new AssertionError(e);
601                 }
602         }
603
604         @Test
605         public void testFluentSchemaApi() {
606                 final ChampSchema schema = ChampSchema.create()
607                                                                                                 .withObjectConstraint()
608                                                                                                         .onType("a")
609                                                                                                         .withPropertyConstraint()
610                                                                                                                 .onField("z")
611                                                                                                                 .ofType(ChampField.Type.STRING)
612                                                                                                                 .optional()
613                                                                                                                 .build()
614                                                                                                         .build()
615                                                                                                 .withObjectConstraint()
616                                                                                                         .onType("b")
617                                                                                                         .withPropertyConstraint()
618                                                                                                                 .onField("y")
619                                                                                                                 .ofType(ChampField.Type.LONG)
620                                                                                                                 .required()
621                                                                                                                 .build()
622                                                                                                         .build()
623                                                                                                 .withRelationshipConstraint()
624                                                                                                         .onType("one")
625                                                                                                         .withPropertyConstraint()
626                                                                                                                 .onField("nine")
627                                                                                                                 .ofType(ChampField.Type.INTEGER)
628                                                                                                                 .optional()
629                                                                                                                 .build()
630                                                                                                         .withConnectionConstraint()
631                                                                                                                 .sourcedFrom("a")
632                                                                                                                 .targetedTo("b")
633                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.NONE)
634                                                                                                                 .build()
635                                                                                                         .withConnectionConstraint()
636                                                                                                                 .sourcedFrom("a")
637                                                                                                                 .targetedToAny()
638                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.ONE)
639                                                                                                                 .build()
640                                                                                                         .withConnectionConstraint()
641                                                                                                                 .sourcedFromAny()
642                                                                                                                 .targetedTo("b")
643                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.MANY)
644                                                                                                                 .build()
645                                                                                                         .withConnectionConstraint()
646                                                                                                                 .sourcedFromAny()
647                                                                                                                 .targetedToAny()
648                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.MANY)
649                                                                                                                 .build()
650                                                                                                         .build()
651                                                                                                 .build();
652
653                 final ChampObjectConstraint aObjConstraint = schema.getObjectConstraint("a").get();
654
655                 assertTrue(aObjConstraint.getType().equals("a"));
656
657                 final ChampPropertyConstraint zPropertyConstraint = aObjConstraint.getPropertyConstraint("z").get();
658
659                 assertTrue(zPropertyConstraint.getField().getName().equals("z"));
660                 assertTrue(zPropertyConstraint.getField().getJavaType().equals(String.class));
661                 assertTrue(!zPropertyConstraint.isRequired());
662
663                 final ChampObjectConstraint bObjConstraint = schema.getObjectConstraint("b").get();
664
665                 assertTrue(bObjConstraint.getType().equals("b"));
666
667                 final ChampPropertyConstraint yPropertyConstraint = bObjConstraint.getPropertyConstraint("y").get();
668
669                 assertTrue(yPropertyConstraint.getField().getName().equals("y"));
670                 assertTrue(yPropertyConstraint.getField().getJavaType().equals(Long.class));
671                 assertTrue(yPropertyConstraint.isRequired());
672
673                 final ChampRelationshipConstraint oneRelConstraint = schema.getRelationshipConstraint("one").get();
674
675                 assertTrue(oneRelConstraint.getType().equals("one"));
676
677                 final ChampPropertyConstraint ninePropertyConstraint = oneRelConstraint.getPropertyConstraint("nine").get();
678
679                 assertTrue(ninePropertyConstraint.getField().getName().equals("nine"));
680                 assertTrue(ninePropertyConstraint.getField().getJavaType().equals(Integer.class));
681                 assertTrue(!ninePropertyConstraint.isRequired());
682
683                 final Set<ChampConnectionConstraint> connectionConstraints = oneRelConstraint.getConnectionConstraints();
684
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);
694                         } else {
695                                 throw new AssertionError("Found unspecified connection constraint " + cc);
696                         }
697                 }       
698         }
699
700         @Test
701         public void testJacksonObjectMapping() {
702                 final ChampSchema schema = ChampSchema.create()
703                                                                                                 .withObjectConstraint()
704                                                                                                         .onType("a")
705                                                                                                         .withPropertyConstraint()
706                                                                                                                 .onField("z")
707                                                                                                                 .ofType(ChampField.Type.STRING)
708                                                                                                                 .optional()
709                                                                                                                 .build()
710                                                                                                         .build()
711                                                                                                 .withObjectConstraint()
712                                                                                                         .onType("b")
713                                                                                                         .withPropertyConstraint()
714                                                                                                                 .onField("y")
715                                                                                                                 .ofType(ChampField.Type.LONG)
716                                                                                                                 .required()
717                                                                                                                 .build()
718                                                                                                         .build()
719                                                                                                 .withRelationshipConstraint()
720                                                                                                         .onType("one")
721                                                                                                         .withPropertyConstraint()
722                                                                                                                 .onField("nine")
723                                                                                                                 .ofType(ChampField.Type.INTEGER)
724                                                                                                                 .optional()
725                                                                                                                 .build()
726                                                                                                         .withConnectionConstraint()
727                                                                                                                 .sourcedFrom("a")
728                                                                                                                 .targetedTo("b")
729                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.NONE)
730                                                                                                                 .build()
731                                                                                                         .withConnectionConstraint()
732                                                                                                                 .sourcedFrom("a")
733                                                                                                                 .targetedToAny()
734                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.ONE)
735                                                                                                                 .build()
736                                                                                                         .withConnectionConstraint()
737                                                                                                                 .sourcedFromAny()
738                                                                                                                 .targetedTo("b")
739                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.MANY)
740                                                                                                                 .build()
741                                                                                                         .withConnectionConstraint()
742                                                                                                                 .sourcedFromAny()
743                                                                                                                 .targetedToAny()
744                                                                                                                 .withMultiplicity(ChampConnectionMultiplicity.MANY)
745                                                                                                                 .build()
746                                                                                                         .build()
747                                                                                                 .build();
748
749                 final ObjectMapper om = new ObjectMapper();
750
751                 try {
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);
758                 }
759
760         }
761 }