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