Added range type to subject-feature-definition/parameter
[groupbasedpolicy.git] / renderers / opflex / src / main / java / org / opendaylight / groupbasedpolicy / renderer / opflex / mit / MitLib.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.opflex.mit;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.ManagedObject;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import com.fasterxml.jackson.databind.DeserializationFeature;
22 import com.fasterxml.jackson.databind.JsonNode;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
25 import com.fasterxml.jackson.databind.node.ArrayNode;
26 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
27 import com.fasterxml.jackson.databind.node.ObjectNode;
28
29 public class MitLib {
30
31     protected static final Logger LOG = LoggerFactory.getLogger(MitLib.class);
32     private ObjectMapper objectMapper;
33         private JsonNodeFactory jnf;
34
35         @JsonSerialize
36         public static class Reference {
37                 String subject;
38                 String reference_uri;
39                 public String getSubject() {
40                         return subject;
41                 }
42                 public void setSubject(String subject) {
43                         this.subject = subject;
44                 }
45                 public String getReference_uri() {
46                         return reference_uri;
47                 }
48                 public void setReference_uri(String reference_uri) {
49                         this.reference_uri = reference_uri;
50                 }
51
52         }
53
54         public MitLib() {
55                  objectMapper = new ObjectMapper();
56                  objectMapper.configure(
57                             DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
58                  jnf = objectMapper.getNodeFactory();
59         }
60
61         public static final String REFERENCE_SUBJECT = "subject";
62         public static final String REFERENCE_URI = "reference_uri";
63
64         public BigInteger deserializeMoPropertyEnum(JsonNode node, PolicyPropertyInfo ppi) {
65
66                 EnumInfo ei = ppi.getEnumInfo();
67                 return  ei.getEnumValue(node.asText());
68         }
69
70         public String serializeMoPropertyEnum(PolicyPropertyInfo ppi, PolicyObjectInstance poi) {
71
72                 EnumInfo ei = ppi.getEnumInfo();
73                 return ei.getEnumValue(poi.getUint64(ppi.getPropId()));
74         }
75
76         /**
77          * Deserialize a REFERENCE property
78          *
79          * @param node
80          * @return
81          */
82         public PolicyObjectInstance.PolicyReference deserializeMoPropertyRef(JsonNode node, OpflexMit mit) {
83
84                 JsonNode sn = node.findValue(REFERENCE_SUBJECT);
85                 if (sn == null) return null;
86                 JsonNode un = node.findValue(REFERENCE_URI);
87                 if (un == null) return null;
88
89                 PolicyClassInfo pci = mit.getClass(sn.asText());
90                 if (pci == null) return null;
91
92                 return new PolicyObjectInstance.PolicyReference(pci.getClassId(), new Uri(un.asText()));
93
94         }
95
96         /**
97          * Serialize a REFERENCE property
98          *
99          * @param reference
100          * @param mit
101          * @return
102          */
103         public ObjectNode serializeMoPropertyRef(PolicyObjectInstance.PolicyReference reference, OpflexMit mit) {
104
105                 ObjectNode on = jnf.objectNode();
106             PolicyClassInfo pci = mit.getClass(reference.getClassId());
107             if (pci == null) return null;
108             PolicyUri puri = new PolicyUri(reference.getUri().getValue());
109             // walk our way up until we find a valid class
110             String identifier = puri.pop();
111             while (mit.getClass(identifier) == null) {
112                     identifier = puri.pop();
113             }
114                 on.put(REFERENCE_SUBJECT, identifier);
115                 on.put(REFERENCE_URI, reference.getUri().getValue());
116             return on;
117         }
118
119         /**
120          * Take the {@link ManagedObject} and deserialize the properties
121          * into a concrete type to be used by the renderer. It also
122          * adds URIs for any children that are referenced in the
123          * properties to the MO's "children" array.
124          *
125          * @param mo
126          */
127         public PolicyObjectInstance deserializeMoProperties(ManagedObject mo, OpflexMit mit) {
128
129                 /*
130                  * The subject gives us the class to use for the schema
131                  */
132                 PolicyClassInfo pci = mit.getClass(mo.getSubject());
133
134                 // sanity checks
135                 if (pci == null) return null;
136
137                 PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
138
139                 if (mo.getProperties() == null) return poi;
140
141                 for (ManagedObject.Property prop : mo.getProperties()) {
142                         PolicyPropertyInfo ppi = pci.getProperty(prop.getName());
143                         if ((ppi == null) || (prop.getData() == null)) continue;
144
145                         JsonNode node = prop.getData();
146
147                         boolean vectored = false;
148                         if (ppi.getPropCardinality().equals(PolicyPropertyInfo.PropertyCardinality.VECTOR)) {
149                                 vectored = true;
150                         }
151                         switch(ppi.getType()) {
152                         case STRING:
153                                 if (vectored == true) {
154                                         if (!node.isArray()) continue;
155
156                                         List<String> sl = new ArrayList<String>();
157                                         for (int i=0; i <node.size(); i++ ) {
158                                                 JsonNode jn = node.get(i);
159                                                 if (!jn.isTextual()) continue;
160
161                                                 sl.add(jn.asText());
162                                         }
163                                         poi.setString(ppi.getPropId(), sl);
164                                 }
165                                 else {
166                                         if (!node.isTextual()) continue;
167
168                                         poi.setString(ppi.getPropId(), node.asText());
169                                 }
170                                 break;
171
172                         case U64:
173                                 if (vectored == true) {
174                                         if (!node.isArray()) continue;
175
176                                         List<BigInteger> bil = new ArrayList<BigInteger>();
177
178                                         for (int i=0; i <node.size(); i++ ) {
179                                                 JsonNode jn = node.get(i);
180                                                 if (!jn.isBigInteger()) continue;
181
182                                                 bil.add(new BigInteger(jn.asText()));
183                                         }
184                                         poi.setUint64(ppi.getPropId(), bil);
185                                 }
186                                 else {
187                                         if (!node.isBigInteger()) continue;
188
189                                         poi.setUint64(ppi.getPropId(), new BigInteger(node.asText()));
190                                 }
191                                 break;
192
193                         case S64:
194                                 if (vectored == true) {
195                                         if (!node.isArray()) continue;
196
197                                         List<Long> ll = new ArrayList<Long>();
198
199                                         for (int i=0; i <node.size(); i++ ) {
200                                                 JsonNode jn = node.get(i);
201
202                                                 if (!jn.isBigInteger()) continue;
203
204                                                 ll.add(jn.asLong());
205                                         }
206                                         poi.setInt64(ppi.getPropId(), ll);
207                                 }
208                                 else {
209                                         if (!node.isBigInteger()) continue;
210
211                                         poi.setInt64(ppi.getPropId(), node.asLong());
212                                 }
213                                 break;
214
215                         case REFERENCE:
216                                 if (vectored == true) {
217                                         if (!node.isArray()) continue;
218
219                                         List<PolicyObjectInstance.PolicyReference> prl =
220                                                         new ArrayList<PolicyObjectInstance.PolicyReference>();
221
222                                         for (int i=0; i <node.size(); i++ ) {
223                                                 JsonNode jn = node.get(i);
224                                                 PolicyObjectInstance.PolicyReference pr = deserializeMoPropertyRef(jn, mit);
225                                                 if (pr == null) continue;
226
227                                                 prl.add(pr);
228                                         }
229                                         poi.setReference(ppi.getPropId(), prl);
230                                 }
231                                 else {
232                                         PolicyObjectInstance.PolicyReference pr = deserializeMoPropertyRef(node, mit);
233                                         if (pr == null) continue;
234
235                                         poi.setReference(ppi.getPropId(), pr);
236                                 }
237                                 break;
238
239                         case ENUM8:
240                         case ENUM16:
241                         case ENUM32:
242                         case ENUM64:
243                                 if (vectored == true) {
244                                         if (!node.isArray()) continue;
245
246                                         List<BigInteger> bil = new ArrayList<BigInteger>();
247
248                                         for (int i=0; i <node.size(); i++ ) {
249                                                 JsonNode jn = node.get(i);
250                                                 if (!jn.isTextual()) continue;
251                                                 BigInteger bi = deserializeMoPropertyEnum(node,ppi);
252
253                                                 bil.add(bi);
254                                         }
255                                         poi.setUint64(ppi.getPropId(), bil);
256                                 }
257                                 else {
258                                         if (!node.isTextual()) continue;
259
260                                         BigInteger bi = deserializeMoPropertyEnum(node,ppi);
261                                         poi.setUint64(ppi.getPropId(), bi);
262                                 }
263                                 break;
264
265                         case MAC:
266                                 if (vectored == true) {
267                                         if (!node.isArray()) continue;
268
269                                         List<MacAddress> ml = new ArrayList<MacAddress>();
270
271                                         for (int i=0; i <node.size(); i++ ) {
272                                                 JsonNode jn = node.get(i);
273
274                                                 if (!jn.isTextual()) continue;
275
276                                                 ml.add(new MacAddress(jn.asText()));
277                                         }
278                                         poi.setMacAddress(ppi.getPropId(), ml);
279                                 }
280                                 else {
281                                         if (!node.isTextual()) continue;
282
283                                         poi.setMacAddress(ppi.getPropId(), new MacAddress(node.asText()));
284                                 }
285                                 break;
286
287                         case COMPOSITE:
288
289                         }
290
291                 }
292
293                 return poi;
294         }
295
296         /**
297          * Serialize the properties contained in the {@link PolicyObjectInstance}
298          * into the properties field of the {@link ManagedObject}
299          *
300          * @param pci
301          * @param poi
302          * @param mo
303          * @param mit
304          */
305         public void serializeMoProperties(PolicyClassInfo pci, PolicyObjectInstance poi, ManagedObject mo, OpflexMit mit) {
306
307                 List<PolicyPropertyInfo> ppil = pci.getProperties();
308                 if (ppil == null) return;
309
310                 List<ManagedObject.Property> pl = new ArrayList<ManagedObject.Property>();
311
312                 /*
313                  * For serialization of values, we can cheat a bit,
314                  * as the native "toString" method gives us exactly
315                  * the formatting we need (including vectors).
316                  */
317                 for (PolicyPropertyInfo ppi: ppil) {
318                         /*
319                          * Skip any properties that aren't populated for this
320                          * object instance
321                          */
322                         if (ppi.getType() != PolicyPropertyInfo.PropertyType.COMPOSITE &&
323                                 !poi.isSet(ppi.getPropId(), ppi.getType(), ppi.getPropCardinality())) {
324                                 continue;
325                         }
326                         ManagedObject.Property p = null;
327                         boolean scalar = true;
328
329                         if (ppi.getPropCardinality() == PolicyPropertyInfo.PropertyCardinality.VECTOR) {
330                                 scalar = false;
331                         }
332
333                         switch (ppi.getType()) {
334                         case STRING:
335                                 p = new ManagedObject.Property();
336                                 p.setName(ppi.getPropName());
337                                 if (scalar == true) {
338                                         JsonNode jn = jnf.textNode(poi.getString(ppi.getPropId()));
339                                         p.setData(jn);
340                                 }
341                                 else {
342                                         int len = poi.getStringSize(ppi.getPropId());
343                                         ArrayNode an = jnf.arrayNode();
344                                         for (int i = 0; i < len; i++ ) {
345                                                 an.add(poi.getString(ppi.getPropId(), i));
346                                         }
347                                         p.setData(an);
348                                 }
349                                 break;
350
351                         case S64:
352                                 p = new ManagedObject.Property();
353                                 p.setName(ppi.getPropName());
354                                 if (scalar == true) {
355                                         JsonNode jn = jnf.numberNode(poi.getInt64(ppi.getPropId()));
356                                         p.setData(jn);
357                                 }
358                                 else {
359                                         int len = poi.getInt64Size(ppi.getPropId());
360                                         ArrayNode an = jnf.arrayNode();
361                                         for (int i = 0; i < len; i++ ) {
362                                                 an.add(Long.valueOf(poi.getInt64(ppi.getPropId(), i)));
363                                         }
364                                         p.setData(an);
365                                 }
366                                 break;
367
368                         case ENUM8:
369                         case ENUM16:
370                         case ENUM32:
371                         case ENUM64:
372                                 p = new ManagedObject.Property();
373                                 p.setName(ppi.getPropName());
374                                 if (scalar == true) {
375                                         JsonNode jn = jnf.textNode(serializeMoPropertyEnum(ppi, poi));
376                                         p.setData(jn);
377                                 }
378                                 else {
379                                         int len = poi.getUint64Size(ppi.getPropId());
380                                         ArrayNode an = jnf.arrayNode();
381                                         for (int i = 0; i < len; i++ ) {
382                                                 an.add(serializeMoPropertyEnum(ppi, poi));
383                                         }
384                                         p.setData(an);
385                                 }
386                                 break;
387
388                         case U64:
389                                 p = new ManagedObject.Property();
390                                 p.setName(ppi.getPropName());
391                                 if (scalar == true) {
392                                         JsonNode jn = jnf.numberNode(poi.getUint64(ppi.getPropId()));
393                                         p.setData(jn);
394                                 }
395                                 else {
396                                         int len = poi.getUint64Size(ppi.getPropId());
397                                         ArrayNode an = jnf.arrayNode();
398                                         for (int i = 0; i < len; i++ ) {
399                                                 an.numberNode(poi.getUint64(ppi.getPropId()));
400                                         }
401                                         p.setData(an);
402                                 }
403                                 break;
404
405                         case MAC:
406                                 p = new ManagedObject.Property();
407                                 p.setName(ppi.getPropName());
408                                 if (scalar == true) {
409                                         MacAddress mac = poi.getMacAddress(ppi.getPropId());
410                                         JsonNode jn = jnf.textNode(mac.getValue().toString());
411                                         p.setData(jn);
412                                 }
413                                 else {
414                                         int len = poi.getMacAddressSize(ppi.getPropId());
415                                         ArrayNode an = jnf.arrayNode();
416                                         for (int i = 0; i < len; i++ ) {
417                                                 MacAddress mac = poi.getMacAddress(ppi.getPropId());
418                                                 an.add(mac.getValue().toString());
419                                         }
420                                         p.setData(an);
421                                 }
422                                 break;
423
424                         case REFERENCE:
425                                 p = new ManagedObject.Property();
426                                 p.setName(ppi.getPropName());
427                                 if (scalar == true) {
428                                         ObjectNode on = serializeMoPropertyRef(poi.getReference(ppi.getPropId()), mit);
429                                         p.setData(on);
430                                 }
431                                 else {
432                                         int len = poi.getReferenceSize(ppi.getPropId());
433                                         ArrayNode an = jnf.arrayNode();
434                                         for (int i = 0; i < len; i++ ) {
435                                                 ObjectNode on = serializeMoPropertyRef(poi.getReference(ppi.getPropId(), i), mit);
436                                                 an.add(on);
437                                         }
438                                         p.setData(an);
439                                 }
440                                 break;
441
442                         case COMPOSITE:
443                                 /*
444                                  * Get the URI to add to the list of children
445                                  */
446                                 break;
447
448                                 default:
449
450                         }
451                         if (p != null) {
452                                 pl.add(p);
453                         }
454                 }
455
456                 mo.setProperties(pl);
457         }
458 }