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