Update license date and text
[aai/champ.git] / champ-lib / champ-core / src / main / java / org / onap / aai / champcore / schema / DefaultChampSchemaEnforcer.java
1 /**
2  * ============LICENSE_START==========================================
3  * org.onap.aai
4  * ===================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 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  */
21 package org.onap.aai.champcore.schema;
22
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Optional;
27 import java.util.Set;
28 import java.util.concurrent.atomic.AtomicInteger;
29
30 import org.onap.aai.champcore.exceptions.ChampSchemaViolationException;
31 import org.onap.aai.champcore.model.ChampConnectionConstraint;
32 import org.onap.aai.champcore.model.ChampField;
33 import org.onap.aai.champcore.model.ChampObject;
34 import org.onap.aai.champcore.model.ChampObjectConstraint;
35 import org.onap.aai.champcore.model.ChampPartition;
36 import org.onap.aai.champcore.model.ChampPropertyConstraint;
37 import org.onap.aai.champcore.model.ChampRelationship;
38 import org.onap.aai.champcore.model.ChampRelationshipConstraint;
39 import org.onap.aai.champcore.model.ChampSchema;
40
41 public final class DefaultChampSchemaEnforcer implements ChampSchemaEnforcer {
42
43         @Override
44         public void validate(ChampObject champObject, ChampObjectConstraint champObjectConstraint) throws ChampSchemaViolationException {
45                 for (ChampPropertyConstraint pc : champObjectConstraint.getPropertyConstraints()) {
46                         final ChampField field = pc.getField();
47                         final Optional<Object> property = champObject.getProperty(field.getName());
48                         
49                         if (pc.isRequired() && !property.isPresent()) {
50                                 throw new ChampSchemaViolationException("Required property " + pc.getField().getName() + " is not present");
51                         }
52
53                         if (property.isPresent()) {
54                                 switch (pc.getCardinality()) {
55                                 case SINGLE:
56                                         if (!pc.getField().getJavaType().isInstance(property.get())) {
57                                                 throw new ChampSchemaViolationException("Expected type " + pc.getField().getType() + " for type " + pc.getField().getName());
58                                         }
59                                         break;
60                                 case LIST:
61                                         if (!(property.get() instanceof List)) throw new ChampSchemaViolationException("Expected List type for ChampCardinality." + pc.getCardinality());
62                                         break;
63                                 case SET:
64                                         if (!(property.get() instanceof Set)) throw new ChampSchemaViolationException("Expected Set type for ChampCardinality." + pc.getCardinality());
65                                         break;
66                                 default:
67                                         throw new RuntimeException("Unknown property constraint cardinality " + pc.getCardinality());
68                                 }
69                         }
70                 }
71         }
72
73         @Override
74         public void validate(ChampRelationship champRelationship,
75                         ChampRelationshipConstraint champRelationshipConstraint) throws ChampSchemaViolationException {
76
77                 for (ChampPropertyConstraint pc : champRelationshipConstraint.getPropertyConstraints()) {
78                         final ChampField field = pc.getField();
79                         final Optional<Object> property = champRelationship.getProperty(field.getName());
80                         
81                         if (pc.isRequired() && !property.isPresent()) {
82                                 throw new ChampSchemaViolationException("Required property " + pc.getField().getName() + " is not present");
83                         }
84
85                         if (property.isPresent() && !pc.getField().getJavaType().isInstance(property.get())) {
86                                 throw new ChampSchemaViolationException("Expected type " + pc.getField().getType() + " for type " + pc.getField().getName());
87                         }
88                 }
89         }
90
91         @Override
92         public void validate(ChampPartition champPartition, ChampSchema schema) throws ChampSchemaViolationException {
93         
94                 for (ChampObject object : champPartition.getChampObjects()) {
95                         final Optional<ChampObjectConstraint> objConstraint = schema.getObjectConstraint(object.getType());
96
97                         if (!objConstraint.isPresent()) continue;
98                         
99                         validate(object, objConstraint.get());
100
101                         final Map<String, Set<ChampRelationship>> incidentRelationshipsByType = champPartition.getIncidentRelationshipsByType(object);
102
103                         for (Map.Entry<String, Set<ChampRelationship>> incidentRelationshipsOfType : incidentRelationshipsByType.entrySet()) {
104                                 final Optional<ChampRelationshipConstraint> relConstraint = schema.getRelationshipConstraint(incidentRelationshipsOfType.getKey());
105
106                                 if (relConstraint.isPresent()) {
107                                         final ChampRelationshipConstraint relationshipConstraint = relConstraint.get();
108                                         final Map<ChampConnectionConstraint, AtomicInteger> connectionCounts = new HashMap<ChampConnectionConstraint, AtomicInteger> ();
109
110                                         for (ChampRelationship incidentRelationship : incidentRelationshipsOfType.getValue()) {
111                                                 final Optional<ChampConnectionConstraint> connectionConstraint = relationshipConstraint.getConnectionConstraint(incidentRelationship);
112
113                                                 validate(incidentRelationship, relationshipConstraint);
114
115                                                 if (connectionConstraint.isPresent()) {
116
117                                                         if (!connectionCounts.containsKey(connectionConstraint.get())) {
118                                                                 connectionCounts.put(connectionConstraint.get(), new AtomicInteger(0));
119                                                         }
120
121                                                         final int connectionCount = connectionCounts.get(connectionConstraint.get()).incrementAndGet();
122
123                                                         switch (connectionConstraint.get().getMultiplicity()) {
124                                                         case MANY:
125                                                                 //Always valid
126                                                         break;
127                                                         case NONE:
128                                                                 if (connectionCount > 0) throw new ChampSchemaViolationException("Violated connection constraint " + connectionConstraint.get());
129                                                         break;
130                                                         case ONE:
131                                                                 if (connectionCount > 1) throw new ChampSchemaViolationException("Violated connection constraint " + connectionConstraint.get());
132                                                         break;
133                                                         default:
134                                                         break;
135                                                         }
136                                                 }
137                                         }
138                                 }
139                                 
140                         }
141                 }
142         }
143 }