Feature uses features-parent as parent
[groupbasedpolicy.git] / renderers / opflex / src / main / java / org / opendaylight / groupbasedpolicy / renderer / opflex / MessageUtils.java
1 /*
2  * Copyright (C) 2014 Cisco Systems, Inc.
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  * Authors : tbachman
9  */
10 package org.opendaylight.groupbasedpolicy.renderer.opflex;
11
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ConcurrentMap;
22
23 import org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.EndpointIdentity;
24 import org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.ManagedObject;
25 import org.opendaylight.groupbasedpolicy.renderer.opflex.lib.messages.ManagedObject.Property;
26 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.AgentOvsMit;
27 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.MitLib;
28 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.PolicyClassInfo;
29 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.PolicyObjectInstance;
30 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.PolicyObjectInstance.PolicyReference;
31 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.PolicyPropertyInfo;
32 import org.opendaylight.groupbasedpolicy.renderer.opflex.mit.PolicyUri;
33 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
34 import org.opendaylight.groupbasedpolicy.resolver.RuleGroup;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
65 import org.opendaylight.yangtools.yang.binding.DataObject;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 import com.google.common.collect.Sets;
70
71 public class MessageUtils {
72
73     private static final Logger LOG = LoggerFactory.getLogger(MessageUtils.class);
74     /*
75      * Endpoint Groups in ODL's Group Based Policy are specified in the
76      * following format:
77      * 
78      * /tenants/tenant/<tenant UUID>/endpoint-group/<endpoint-group UUID>
79      */
80     public static final String POLICY_ROOT = "";
81     public static final String TENANTS_RN = "tenants";
82     public static final String TENANT_RN = "tenant";
83     public static final String CONTRACT_RN = "contract";
84     public static final String SUBJECT_RN = "subject";
85     public static final String RULE_RN = "rule";
86     public static final String CLAUSE_RN = "clause";
87     public static final String EPG_RN = "endpoint-group";
88     public static final String ENDPOINTS_RN = "endpoints";
89     public static final String ENDPOINT_RN = "endpoint";
90     public static final String ENDPOINT_L3_RN = "endpoint-l3";
91     public static final String L2_FLOOD_DOMAIN_RN = "l2-flood-domain";
92     public static final String L2_BRIDGE_DOMAIN_RN = "l2-bridge-domain";
93     public static final String SUBNET_RN = "subnet";
94     public static final String L3_CONTEXT_RN = "l3-context";
95     public static final String CLASSIFIER_INSTANCE_RN = "classifier-instance";
96     public static final String CLASSIFIER_REF_RN = "classifier-ref";
97
98     public static final String GENIE_EPR_L2_ROOT = "EprL2Universe";
99     public static final String GENIE_EPR_L3_ROOT = "EprL3Universe";
100     public static final String GENIE_ENDPOINT_RN = "EprL2Ep";
101     public static final String GENIE_ENDPOINT_L3_RN = "EprL3Ep";
102
103     public static final String GENIE_TENANTS_RN = "PolicyUniverse";
104     public static final String GENIE_POLICY_ROOT = PolicyUri.POLICY_URI_SEP + GENIE_TENANTS_RN;
105     public static final String GENIE_TENANT_RN = "PolicySpace";
106     public static final String GENIE_CONTRACT_RN = "GbpContract";
107     public static final String GENIE_SUBJECT_RN = "GbpSubject";
108     public static final String GENIE_RULE_RN = "GbpRule";
109     public static final String GENIE_EPG_RN = "GbpEpGroup";
110     public static final String GENIE_CLASSIFIER_RN = "GbpeL24Classifier";
111     public static final String GENIE_FLOOD_DOMAIN_RN = "GbpFloodDomain";
112     public static final String GENIE_BRIDGE_DOMAIN_RN = "GbpBridgeDomain";
113     public static final String GENIE_SUBNETS_RN = "GbpSubnets";
114     public static final String GENIE_SUBNET_RN = "GbpSubnet";
115     public static final String GENIE_ROUTING_DOMAIN_RN = "GbpRoutingDomain";
116     public static final String GENIE_ENDPOINT_NET_RN = "EprL3Net";
117
118     public static final String GENIE_ENDPOINT_CONTEXT = "context";
119     public static final String GENIE_ENDPOINT_EPG = "group";
120     public static final String GENIE_ENDPOINT_MAC = "mac";
121     public static final String GENIE_ENDPOINT_UUID = "uuid";
122     public static final String GENIE_ENDPOINT_IP = "ip";
123
124     public static final String GENIE_SUBNET_NAME_DEFAULT = "default-subnet";
125     public static final String GENIE_SUBNET_ADDRESS = "address";
126     public static final String GENIE_SUBNET_NAME = "name";
127     public static final String GENIE_SUBNET_PREFIX_LEN = "prefixLen";
128     public static final String GENIE_SUBNET_VIRTUAL_ROUTER_IP = "virtualRouterIp";
129
130     public static final String GENIE_CLASSIFIER_REF_RN = "GbpRuleToClassifierRSrc";
131     public static final String GENIE_CONSUMER_CONTRACT_REF_RN = "GbpEpGroupToConsContractRSrc";
132     public static final String GENIE_PROVIDER_CONTRACT_REF_RN = "GbpEpGroupToProvContractRSrc";
133     public static final String GENIE_SUBNETS_TO_NETWORK_RN = "GbpSubnetsToNetworkRSrc";
134     public static final String GENIE_FLOOD_DOMAIN_TO_NETWORK_RN = "GbpFloodDomainToNetworkRSrc";
135     public static final String GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN = "GbpBridgeDomainToNetworkRSrc";
136     public static final String GENIE_INTRA_EPG_RN = "intraGroupPolicy";
137     public static final String GENIE_EPG_TO_NETWORK_DOMAIN_RN = "GbpEpGroupToNetworkRSrc";
138     public static final String GENIE_SUBNET_TO_NETWORK_SRC_REF = "GbpSubnetsToNetworkRSrc";
139
140     public static final String TENANT_PREFIX = POLICY_ROOT + PolicyUri.POLICY_URI_SEP + TENANTS_RN
141             + PolicyUri.POLICY_URI_SEP + TENANT_RN + PolicyUri.POLICY_URI_SEP;
142     public static final String GENIE_TENANT_PREFIX = GENIE_POLICY_ROOT + PolicyUri.POLICY_URI_SEP + GENIE_TENANT_RN
143             + PolicyUri.POLICY_URI_SEP;
144
145     public static final String GENIE_CONTRACT_NAME = "name";
146     public static final String GENIE_SUBJECT_NAME = "name";
147     public static final String GENIE_RULE_NAME = "name";
148     public static final String GENIE_CLASSIFIER_NAME = "name";
149     public static final String GENIE_ENDPOINT_GROUP_NAME = "name";
150     public static final String GENIE_SUBNETS_NAME = "name";
151     public static final String GENIE_FLOOD_DOMAIN_NAME = "name";
152     public static final String GENIE_BRIDGE_DOMAIN_NAME = "name";
153     public static final String GENIE_ROUTING_DOMAIN_NAME = "name";
154     public static final String GENIE_CONSUMER_CONTRACT_TARGET = "target";
155     public static final String GENIE_PROVIDER_CONTRACT_TARGET = "target";
156     public static final String GENIE_CLASSIFIER_REF_TARGET = "target";
157     public static final String GENIE_EPG_TO_NETWORK_DOMAIN_TARGET = "target";
158     public static final String GENIE_SUBNETS_TO_NETWORK_DOMAIN_TARGET = "target";
159     public static final String GENIE_FLOOD_DOMAIN_TO_NETWORK_DOMAIN_TARGET = "target";
160     public static final String GENIE_BRIDGE_DOMAIN_TO_NETWORK_DOMAIN_TARGET = "target";
161
162     public static final String GENIE_RULE_ORDER = "order";
163
164     public static final String GENIE_CLASSIFIER_CONNECTION_TRACKING = "connectionTracking";
165     public static final String GENIE_CLASSIFIER_DIRECTION = "direction";
166     public static final String GENIE_CLASSIFIER_ARP_OPC = "arpOpc";
167     public static final String GENIE_CLASSIFIER_DFROM_PORT = "dFromPort";
168     public static final String GENIE_CLASSIFIER_DTO_PORT = "dToPort";
169     public static final String GENIE_CLASSIFIER_ETHERT = "etherT";
170     public static final String GENIE_CLASSIFIER_PROT = "prot";
171     public static final String GENIE_CLASSIFIER_SFROM_PORT = "sFromPort";
172     public static final String GENIE_CLASSIFIER_STO_PORT = "sToPort";
173
174     private static AgentOvsMit mit;
175     private static MitLib lib;
176
177     private static ConcurrentMap<String, Integer> odlKeys;
178     private static ConcurrentMap<String, Integer> genieKeys;
179
180     private static ConcurrentMap<String, String> odlToGenieMap;
181     private static ConcurrentMap<String, String> genieToOdlMap;
182
183     public static void setMit(AgentOvsMit currentMit) {
184         mit = currentMit;
185
186     }
187
188     public static ConcurrentMap<String, Integer> getOdlKeys() {
189         return odlKeys;
190     }
191
192     public static ConcurrentMap<String, Integer> getGenieKeys() {
193         return genieKeys;
194     }
195
196     public static void init() {
197
198         odlKeys = new ConcurrentHashMap<String, Integer>();
199         genieKeys = new ConcurrentHashMap<String, Integer>();
200
201         odlKeys.put(ENDPOINT_RN, 2);
202         odlKeys.put(ENDPOINT_L3_RN, 2);
203         odlKeys.put(TENANT_RN, 1);
204         odlKeys.put(L3_CONTEXT_RN, 1);
205         odlKeys.put(L2_BRIDGE_DOMAIN_RN, 1);
206         odlKeys.put(L2_FLOOD_DOMAIN_RN, 1);
207         odlKeys.put(SUBNET_RN, 1);
208         odlKeys.put(EPG_RN, 1);
209         odlKeys.put(CLASSIFIER_INSTANCE_RN, 1);
210         odlKeys.put(CONTRACT_RN, 1);
211         odlKeys.put(SUBJECT_RN, 1);
212         odlKeys.put(RULE_RN, 1);
213
214         genieKeys.put(GENIE_ENDPOINT_RN, 2);
215         genieKeys.put(GENIE_ENDPOINT_L3_RN, 2);
216         genieKeys.put(GENIE_TENANT_RN, 1);
217         genieKeys.put(GENIE_ROUTING_DOMAIN_RN, 1);
218         genieKeys.put(GENIE_BRIDGE_DOMAIN_RN, 1);
219         genieKeys.put(GENIE_FLOOD_DOMAIN_RN, 1);
220         genieKeys.put(GENIE_SUBNET_RN, 1);
221         genieKeys.put(GENIE_SUBNETS_RN, 1);
222         genieKeys.put(GENIE_EPG_RN, 1);
223         genieKeys.put(GENIE_CLASSIFIER_RN, 1);
224         genieKeys.put(GENIE_CONTRACT_RN, 1);
225         genieKeys.put(GENIE_SUBJECT_RN, 1);
226         genieKeys.put(GENIE_RULE_RN, 1);
227
228         odlToGenieMap = new ConcurrentHashMap<String, String>();
229         odlToGenieMap.put(ENDPOINTS_RN, "");
230         odlToGenieMap.put(ENDPOINT_RN, GENIE_EPR_L2_ROOT + PolicyUri.POLICY_URI_SEP + GENIE_ENDPOINT_RN);
231         odlToGenieMap.put(ENDPOINT_L3_RN, GENIE_EPR_L3_ROOT + PolicyUri.POLICY_URI_SEP + GENIE_ENDPOINT_L3_RN);
232         odlToGenieMap.put(TENANTS_RN, GENIE_TENANTS_RN);
233         odlToGenieMap.put(TENANT_RN, GENIE_TENANT_RN);
234         odlToGenieMap.put(EPG_RN, GENIE_EPG_RN);
235         odlToGenieMap.put(CONTRACT_RN, GENIE_CONTRACT_RN);
236         odlToGenieMap.put(SUBJECT_RN, GENIE_SUBJECT_RN);
237         odlToGenieMap.put(RULE_RN, GENIE_RULE_RN);
238         odlToGenieMap.put(CLAUSE_RN, "");
239         odlToGenieMap.put(CLASSIFIER_REF_RN, GENIE_CLASSIFIER_RN);
240         odlToGenieMap.put(L2_FLOOD_DOMAIN_RN, GENIE_FLOOD_DOMAIN_RN);
241         odlToGenieMap.put(L2_BRIDGE_DOMAIN_RN, GENIE_BRIDGE_DOMAIN_RN);
242         odlToGenieMap.put(SUBNET_RN, GENIE_SUBNETS_RN + PolicyUri.POLICY_URI_SEP + GENIE_SUBNET_NAME_DEFAULT
243                 + PolicyUri.POLICY_URI_SEP + GENIE_SUBNET_RN);
244         odlToGenieMap.put(L3_CONTEXT_RN, GENIE_ROUTING_DOMAIN_RN);
245
246         genieToOdlMap = new ConcurrentHashMap<String, String>();
247         genieToOdlMap.put(GENIE_ENDPOINT_RN, ENDPOINT_RN);
248         genieToOdlMap.put(GENIE_ENDPOINT_L3_RN, ENDPOINT_L3_RN);
249         genieToOdlMap.put(GENIE_TENANTS_RN, TENANTS_RN);
250         genieToOdlMap.put(GENIE_TENANT_RN, TENANT_RN);
251         genieToOdlMap.put(GENIE_EPG_RN, EPG_RN);
252         genieToOdlMap.put(GENIE_CONTRACT_RN, CONTRACT_RN);
253         genieToOdlMap.put(GENIE_SUBJECT_RN, SUBJECT_RN);
254         genieToOdlMap.put(GENIE_RULE_RN, RULE_RN);
255         genieToOdlMap.put(GENIE_CLASSIFIER_RN, CLASSIFIER_REF_RN);
256         genieToOdlMap.put(GENIE_FLOOD_DOMAIN_RN, L2_FLOOD_DOMAIN_RN);
257         genieToOdlMap.put(GENIE_BRIDGE_DOMAIN_RN, L2_BRIDGE_DOMAIN_RN);
258         genieToOdlMap.put(GENIE_SUBNETS_RN, "");
259         genieToOdlMap.put(GENIE_SUBNET_RN, SUBNET_RN);
260         genieToOdlMap.put(GENIE_ROUTING_DOMAIN_RN, L3_CONTEXT_RN);
261         genieToOdlMap.put(GENIE_EPR_L2_ROOT, ENDPOINTS_RN);
262         genieToOdlMap.put(GENIE_EPR_L3_ROOT, ENDPOINTS_RN);
263
264     }
265
266     private static BigInteger intToBigInt(int i) {
267         return new BigInteger(Integer.toString(i));
268     }
269
270     public static void setOpflexLib(MitLib opflexLib) {
271         lib = opflexLib;
272     }
273
274     public static PolicyUri parseUri(String uri) {
275         PolicyUri u = new PolicyUri(uri);
276         if (u.valid())
277             return u;
278         return null;
279     }
280
281     /*
282      * Until I clean this up, this is going to accept the Genie URI. The format
283      * for these URIs is:
284      * 
285      * /PolicyUniverse/PolicySpace/[name]
286      */
287     public static String getTenantFromUri(String uri) {
288         PolicyUri genieUri = odlUriToGenieUri(new PolicyUri(uri));
289         if (genieUri.totalElements() >= 3)
290             return genieUri.getElement(2);
291         return null;
292     }
293
294     /*
295      * Until I clean this up, this is going to be the Genie URI. The format for
296      * these URIs is:
297      * 
298      * /PolicyUniverse/PolicySpace/[name]/GbpEpGroup/[name]
299      * 
300      * Where [name] is the tenant and ID for the EPG
301      */
302     public static String getEndpointGroupFromUri(String uri) {
303         PolicyUri genieUri = odlUriToGenieUri(new PolicyUri(uri));
304         PolicyUri pu = new PolicyUri(genieUri.toString());
305         if (!pu.contains(GENIE_EPG_RN)) {
306             return null;
307         }
308         int epgIdx = pu.whichElement(GENIE_EPG_RN);
309         /*
310          * subtract 1 to compare between total elements and an array index; it's
311          * an EPG URI if it's the second to the last element
312          */
313         if (epgIdx == pu.totalElements() - 1 - 1) {
314             return pu.getElement(epgIdx + 1);
315         }
316         return null;
317     }
318
319     public static String getContextFromUri(String uri) {
320         PolicyUri genieUri = odlUriToGenieUri(new PolicyUri(uri));
321         PolicyUri pu = new PolicyUri(genieUri.toString());
322
323         if (!pu.contains(GENIE_EPG_RN)) {
324             return null;
325         }
326         int epgIdx = pu.whichElement(GENIE_EPG_RN);
327         /*
328          * subtract 1 to compare between total elements and an array index; it's
329          * an EPG URI if it's the second to the last element
330          */
331         if (epgIdx == pu.totalElements() - 1 - 1) {
332             return pu.getElement(epgIdx + 2);
333         }
334         return null;
335     }
336
337     public static String createEpgUri(String tenantId, String epgId) {
338         return GENIE_TENANT_PREFIX + tenantId + PolicyUri.POLICY_URI_SEP + GENIE_EPG_RN + PolicyUri.POLICY_URI_SEP
339                 + epgId;
340     }
341
342     public static boolean hasEpg(String uri) {
343         return new PolicyUri(uri).contains(GENIE_EPG_RN);
344     }
345
346     public static boolean isEpgUri(String uri) {
347         PolicyUri pu = new PolicyUri(uri);
348         if (!pu.contains(GENIE_EPG_RN)) {
349             return false;
350         }
351         int epgIdx = pu.whichElement(GENIE_EPG_RN);
352         /*
353          * subtract 1 to compare between total elements and an array index; it's
354          * an EPG URI if it's the second to the last element
355          */
356         return (epgIdx == pu.totalElements() - 1 - 1);
357     }
358
359     /**
360      * Check to see if the given URI is already in genie format
361      *
362      * @param uri
363      * @return
364      */
365     public static boolean isGenieUri(Uri uri) {
366         PolicyUri puri = new PolicyUri(uri.toString());
367         List<String> genieRoot = Arrays.asList("PolicyUniverse", "EprL2Universe", "EprL3Universe");
368
369         if (genieRoot.contains(puri.getElement(0)))
370             return true;
371
372         return false;
373
374     }
375
376     /**
377      * Check to see if the given URI is already in ODL format
378      *
379      * @param uri
380      * @return
381      */
382     public static boolean isOdlUri(Uri uri) {
383         PolicyUri puri = new PolicyUri(uri.toString());
384         List<String> odlRoot = Arrays.asList("tenants", "endpoints");
385
386         if (odlRoot.contains(puri.getElement(0)))
387             return true;
388
389         return false;
390     }
391
392     /**
393      * Iterator for URIs. Provides iteration, along with identification of key
394      * values needed for URI translation.
395      *
396      * @author tbachman
397      */
398     public static class UriIterator implements Iterator<String> {
399
400         private final PolicyUri uri;
401         private int index;
402         private int keyCount;
403         private final Map<String, Integer> keyMap;
404
405         public UriIterator(PolicyUri uri, ConcurrentMap<String, Integer> keyMap) {
406             this.uri = uri;
407             this.index = 0;
408             this.keyCount = 0;
409             this.keyMap = keyMap;
410         }
411
412         public boolean isKey() {
413             if (keyCount > 0)
414                 return true;
415             return false;
416         }
417
418         public String getElement() {
419             if (this.index >= this.uri.totalElements())
420                 return null;
421             return this.uri.getElement(index);
422         }
423
424         @Override
425         public boolean hasNext() {
426             if (this.index < this.uri.totalElements())
427                 return true;
428
429             return false;
430         }
431
432         @Override
433         public String next() {
434             /*
435              * Check to see if the subsequent elements are keys, and if so, set
436              * the number of keys
437              */
438             if (keyCount > 0) {
439                 keyCount -= 1;
440             }
441             if (keyCount == 0 && keyMap.containsKey(this.getElement())) {
442                 keyCount = keyMap.get(this.getElement());
443             }
444
445             this.index += 1;
446
447             if (this.index >= this.uri.totalElements())
448                 return null;
449
450             return this.uri.getElement(index);
451         }
452
453         @Override
454         public void remove() {
455             throw new UnsupportedOperationException();
456         }
457     }
458
459     /**
460      * Convert ODL URI to a Genie URI. The ODL names are unique, so we are able
461      * to provide a conversion based solely on name.
462      * This only maps URIs from the following roots:
463      * /endpoint /policy
464      *
465      * @param odlUri
466      * @return
467      */
468     public static PolicyUri odlUriToGenieUri(PolicyUri odlUri) {
469
470         PolicyUri genieUri = new PolicyUri();
471
472         /*
473          * If it's already a genie URI, do nothing
474          */
475         if (isGenieUri(new Uri(odlUri.toString()))) {
476             return odlUri;
477         }
478
479         UriIterator it = new UriIterator(odlUri, odlKeys);
480         while (it.getElement() != null) {
481
482             /*
483              * Get the converted element, then make the following checks:
484              * 
485              * o element is key - push the element directly onto the stack
486              * without translation
487              * o no corresponding genie element - return --
488              * we're done
489              * o genie element, but result is null - don't push
490              * anything on the stack; continue
491              * o regular element - convert the
492              * element and push it on the stack
493              */
494             String element = it.getElement();
495             String genieElement = odlToGenieMap.get(element);
496
497             if (it.isKey()) {
498                 genieUri.push(it.getElement());
499                 it.next();
500                 continue;
501             } else if (genieElement == null)
502                 break;
503             else if (genieElement.equals("")) {
504                 it.next();
505                 continue;
506             }
507
508             genieUri.push(genieElement);
509             it.next();
510         }
511
512         return genieUri;
513     }
514
515     public static PolicyUri genieUriToOdlUri(PolicyUri genieUri) {
516
517         PolicyUri odlUri = new PolicyUri();
518
519         /*
520          * If it's already a genie URI, do nothing
521          */
522         if (isOdlUri(new Uri(genieUri.toString()))) {
523             return genieUri;
524         }
525
526         UriIterator it = new UriIterator(genieUri, genieKeys);
527         while (it.getElement() != null) {
528
529             /*
530              * Get the converted element, then make the following checks:
531              * 
532              * o element is key - push the element directly onto the stack
533              * without translation
534              * o no corresponding genie element - return --
535              * we're done
536              * o genie element, but result is null - don't push
537              * anything on the stack; continue
538              * o regular element - convert the
539              * element and push it on the stack
540              */
541             String element = it.getElement();
542             String odlElement = genieToOdlMap.get(element);
543
544             if (it.isKey()) {
545                 odlUri.push(it.getElement());
546                 it.next();
547                 continue;
548             } else if (odlElement == null)
549                 break;
550             else if (odlElement.equals("")) {
551                 it.next();
552                 continue;
553             }
554
555             odlUri.push(odlElement);
556             it.next();
557         }
558
559         return odlUri;
560
561     }
562
563     private static void setParentFields(PolicyUri current, PolicyObjectInstance poi, String parentRelation,
564             boolean hasId) {
565         PolicyUri uriCopy = new PolicyUri(current);
566
567         // Pop off the subject name and class to get to parent
568         uriCopy.pop();
569         uriCopy.pop();
570         PolicyUri parent = new PolicyUri(uriCopy);
571
572         // remove parent ID to get to parent subject
573         if (hasId) {
574             uriCopy.pop();
575         }
576         String parentSubject = uriCopy.pop();
577         poi.setParent(parent.getUri());
578         poi.setParentSubject(parentSubject);
579         poi.setParentRelation(parentRelation);
580     }
581
582     public static List<ManagedObject> getSubjectMo(PolicyUri current, Subject s, RuleGroup rg, IndexedTenant it) {
583         if (s == null)
584             return null;
585
586         // Convert to Genie URI
587         PolicyUri convertedUri = odlUriToGenieUri(current);
588
589         String prefix = convertedUri.toString();
590
591         ManagedObject mo = new ManagedObject();
592         List<ManagedObject> mol = new ArrayList<ManagedObject>();
593         List<Uri> childrenUris = new ArrayList<Uri>();
594
595         /*
596          * Build up the equivalent Genie object
597          */
598         PolicyClassInfo pci = mit.getClass(GENIE_SUBJECT_RN);
599         if (pci == null)
600             return null;
601         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
602         setParentFields(convertedUri, poi, GENIE_SUBJECT_RN, true);
603         poi.setUri(convertedUri.getUri());
604
605         List<PolicyPropertyInfo> ppil = pci.getProperties();
606         if (ppil == null)
607             return null;
608
609         for (PolicyPropertyInfo ppi : ppil) {
610             if (ppi.getPropName().equals(GENIE_SUBJECT_NAME) && s.getName() != null) {
611                 poi.setString(ppi.getPropId(), s.getName().getValue());
612             } else if (ppi.getPropName().equals(GENIE_RULE_RN) && s.getRule() != null) {
613                 /*
614                  * Each subject has a set of resolved rules. Add those as
615                  * children.
616                  */
617
618                 for (Rule r : rg.getRules()) {
619                     PolicyUri uri = new PolicyUri(prefix);
620                     uri.push(GENIE_RULE_RN);
621                     uri.push(r.getName().getValue());
622                     childrenUris.add(uri.getUri());
623                     poi.addChild(uri.getUri()); // TODO: remove?
624                     mol.addAll(MessageUtils.getRuleMo(uri, r, rg, it));
625                 }
626             }
627         }
628
629         lib.serializeMoProperties(pci, poi, mo, mit);
630
631         mo.setChildren(childrenUris);
632
633         mo.setParent_uri(poi.getParent());
634         mo.setParent_subject(poi.getParentSubject());
635         mo.setParent_relation(poi.getParentRelation());
636         mo.setSubject(GENIE_SUBJECT_RN);
637         mo.setUri(convertedUri.getUri());
638         mol.add(mo);
639
640         return mol;
641     }
642
643     public static List<ManagedObject> getRuleMo(PolicyUri current, Rule r, RuleGroup rg, IndexedTenant it) {
644         if (r == null)
645             return null;
646
647         // Convert to Genie URI
648         PolicyUri convertedUri = odlUriToGenieUri(current);
649
650         String prefix = convertedUri.toString();
651
652         ManagedObject mo = new ManagedObject();
653         List<ManagedObject> mol = new ArrayList<ManagedObject>();
654         List<Uri> childrenUris = new ArrayList<Uri>();
655
656         /*
657          * Build up the equivalent Genie object
658          */
659         PolicyClassInfo pci = mit.getClass(GENIE_RULE_RN);
660         if (pci == null)
661             return null;
662         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
663         setParentFields(convertedUri, poi, GENIE_RULE_RN, true);
664         poi.setUri(convertedUri.getUri());
665
666         List<PolicyPropertyInfo> ppil = pci.getProperties();
667         if (ppil == null)
668             return null;
669
670         for (PolicyPropertyInfo ppi : ppil) {
671             if (ppi.getPropName().equals(GENIE_RULE_NAME) && r.getName() != null) {
672                 poi.setString(ppi.getPropId(), r.getName().getValue());
673             } else if (ppi.getPropName().equals(GENIE_RULE_ORDER) && r.getOrder() != null) {
674                 poi.setUint64(ppi.getPropId(), intToBigInt(r.getOrder().intValue()));
675             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_REF_RN) && r.getClassifierRef() != null) {
676                 for (ClassifierRef cr : r.getClassifierRef()) {
677                     ClassifierInstance ci = it.getClassifier(cr.getName());
678                     if (ci != null) {
679                         PolicyUri uri = new PolicyUri(prefix);
680                         uri.push(GENIE_CLASSIFIER_REF_RN);
681                         uri.push(cr.getName().getValue());
682                         mol.addAll(MessageUtils.getClassifierRefMo(uri, ci, cr, rg, it));
683                         childrenUris.add(uri.getUri());
684                         poi.addChild(uri.getUri()); // TODO: remove?
685                     }
686                 }
687             }
688         }
689
690         lib.serializeMoProperties(pci, poi, mo, mit);
691
692         mo.setChildren(childrenUris);
693
694         mo.setParent_uri(poi.getParent());
695         mo.setParent_subject(poi.getParentSubject());
696         mo.setParent_relation(poi.getParentRelation());
697         mo.setSubject(GENIE_RULE_RN);
698         mo.setUri(convertedUri.getUri());
699
700         mol.add(mo);
701
702         return mol;
703     }
704
705     /**
706      * Convert a Contract to the equivalent Genie MO
707      *
708      * @param c
709      * @return
710      */
711     public static List<ManagedObject> getContractAndSubMos(List<ManagedObject> cmol, PolicyUri current, Contract c,
712             RuleGroup rg, IndexedTenant it) {
713         if (c == null)
714             return null;
715
716         ManagedObject mo = new ManagedObject();
717         List<ManagedObject> mol = new ArrayList<ManagedObject>();
718         List<Uri> childrenUris = new ArrayList<Uri>();
719
720         PolicyUri convertedUri = odlUriToGenieUri(current);
721
722         String prefix = convertedUri.toString();
723
724         /*
725          * Build up the equivalent Genie object
726          */
727         PolicyClassInfo pci = mit.getClass(GENIE_CONTRACT_RN);
728         if (pci == null)
729             return null;
730         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
731         setParentFields(convertedUri, poi, GENIE_CONTRACT_RN, true);
732         poi.setUri(convertedUri.getUri());
733
734         List<PolicyPropertyInfo> ppil = pci.getProperties();
735         if (ppil == null)
736             return null;
737
738         if (c.getSubject() == null)
739             LOG.warn("subject is NULL");
740         for (PolicyPropertyInfo ppi : ppil) {
741             if (ppi.getPropName().equals(GENIE_CONTRACT_NAME) && c.getId() != null) {
742                 poi.setString(ppi.getPropId(), c.getId().getValue());
743             } else if (ppi.getPropName().equals(GENIE_SUBJECT_RN) && c.getSubject() != null) {
744
745                 LOG.warn("related subject is {}", rg.getRelatedSubject());
746                 /*
747                  * Get the subject in scope for this contract (NB: there could
748                  * be more than one -- we get multiple subjects for a single
749                  * contract in multiple RuleGroup objects).
750                  */
751                 SubjectName sn = rg.getRelatedSubject();
752                 if (sn == null)
753                     continue;
754
755                 /* Find the related subject object */
756                 for (Subject s : c.getSubject()) {
757                     LOG.warn("subject is {}", s.getName());
758
759                     if (s.getName().getValue().equals(sn.getValue())) {
760
761                         PolicyUri uri = new PolicyUri(prefix);
762                         uri.push(GENIE_SUBJECT_RN);
763                         uri.push(s.getName().getValue());
764
765                         mol.addAll(MessageUtils.getSubjectMo(uri, s, rg, it));
766                         childrenUris.add(uri.getUri());
767                         poi.addChild(uri.getUri()); // TODO: needed?
768                         break;
769                     }
770                 }
771             }
772         }
773         lib.serializeMoProperties(pci, poi, mo, mit);
774
775         mo.setChildren(childrenUris);
776
777         mo.setParent_uri(poi.getParent());
778         mo.setParent_subject(poi.getParentSubject());
779         mo.setParent_relation(poi.getParentRelation());
780         mo.setSubject(GENIE_CONTRACT_RN);
781         mo.setUri(convertedUri.getUri());
782         cmol.add(mo);
783
784         return mol;
785     }
786
787     public static ManagedObject getConsumerNamedSelectorMo(PolicyUri current, Contract c) {
788         if (c == null)
789             return null;
790
791         ManagedObject mo = new ManagedObject();
792
793         PolicyUri convertedUri = odlUriToGenieUri(current);
794
795         /*
796          * Build up the equivalent Genie object
797          */
798         PolicyClassInfo pci = mit.getClass(GENIE_CONSUMER_CONTRACT_REF_RN);
799         if (pci == null)
800             return null;
801         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
802         setParentFields(convertedUri, poi, GENIE_CONSUMER_CONTRACT_REF_RN, true);
803         poi.setUri(convertedUri.getUri());
804
805         List<PolicyPropertyInfo> ppil = pci.getProperties();
806         if (ppil == null)
807             return null;
808
809         for (PolicyPropertyInfo ppi : ppil) {
810             if (ppi.getPropName().equals(GENIE_CONSUMER_CONTRACT_TARGET)) {
811                 PolicyUri uri = new PolicyUri(convertedUri);
812                 // Go up to the EPG
813                 uri.pop();
814                 uri.pop();
815                 uri.push(GENIE_CONSUMER_CONTRACT_REF_RN);
816                 uri.push(c.getId().getValue());
817                 String newUri = odlUriToGenieUri(uri).toString();
818                 PolicyReference pr = new PolicyReference(pci.getClassId(), new Uri(newUri));
819                 poi.setReference(ppi.getPropId(), pr);
820             }
821         }
822
823         lib.serializeMoProperties(pci, poi, mo, mit);
824
825         mo.setParent_uri(poi.getParent());
826         mo.setParent_subject(poi.getParentSubject());
827         mo.setParent_relation(poi.getParentRelation());
828         mo.setSubject(GENIE_CONSUMER_CONTRACT_REF_RN);
829         mo.setUri(convertedUri.getUri());
830
831         return mo;
832     }
833
834     public static ManagedObject getProviderNamedSelectorMo(PolicyUri current, Contract c) {
835         if (c == null)
836             return null;
837         ManagedObject mo = new ManagedObject();
838
839         PolicyUri convertedUri = odlUriToGenieUri(current);
840
841         /*
842          * Build up the equivalent Genie object
843          */
844         PolicyClassInfo pci = mit.getClass(GENIE_PROVIDER_CONTRACT_REF_RN);
845         if (pci == null)
846             return null;
847         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
848         setParentFields(convertedUri, poi, GENIE_PROVIDER_CONTRACT_REF_RN, true);
849         poi.setUri(convertedUri.getUri());
850
851         List<PolicyPropertyInfo> ppil = pci.getProperties();
852         if (ppil == null)
853             return null;
854
855         for (PolicyPropertyInfo ppi : ppil) {
856             if (ppi.getPropName().equals(GENIE_PROVIDER_CONTRACT_TARGET)) {
857                 PolicyUri uri = new PolicyUri(convertedUri);
858                 // Go up to the EPG
859                 uri.pop();
860                 uri.pop();
861                 uri.push(GENIE_CONTRACT_RN);
862                 uri.push(c.getId().getValue());
863                 String newUri = odlUriToGenieUri(uri).toString();
864                 PolicyReference pr = new PolicyReference(pci.getClassId(), new Uri(newUri));
865                 // TODO: should we chase the contracts?
866                 poi.setReference(ppi.getPropId(), pr);
867             }
868         }
869
870         lib.serializeMoProperties(pci, poi, mo, mit);
871
872         mo.setParent_uri(poi.getParent());
873         mo.setParent_subject(poi.getParentSubject());
874         mo.setParent_relation(poi.getParentRelation());
875         mo.setSubject(GENIE_PROVIDER_CONTRACT_REF_RN);
876         mo.setUri(convertedUri.getUri());
877
878         return mo;
879
880     }
881
882     private static List<BigInteger> getParamList(HashMap<String, List<BigInteger>> hm, String type) {
883         List<BigInteger> pvl = hm.get(type);
884         if (pvl == null) {
885             pvl = new ArrayList<>();
886             hm.put(type, pvl);
887         }
888         return pvl;
889     }
890
891     private static final Integer TCP_PROTO = 6;
892     private static final Integer UDP_PROTO = 17;
893
894     /**
895      * Build up a set of possible parameter values using the classifier
896      * instance.
897      *
898      * @param ci
899      * @param cr
900      * @return
901      */
902     private static Map<String, List<BigInteger>> buildParameterValues(ClassifierInstance ci, ClassifierRef cr) {
903         HashMap<String, List<BigInteger>> pmap = new HashMap<>();
904         List<BigInteger> pvl = null;
905
906         /*
907          * Create the map of classifier types/values
908          */
909         for (ParameterValue pv : ci.getParameterValue()) {
910             /*
911              * The parameter-value name tells us the type of classifier
912              * involved: "type": EtherType/L2 "proto": IP/L3
913              * "sourceport"/"destport": TCP/UDP/L4
914              */
915             if (pv.getName().getValue().equals("type")) {
916                 if (pv.getIntValue() != null) {
917                     switch (pv.getIntValue().intValue()) {
918                         case 0x0806:
919                         case 0x8906:
920                         case 0x0800:
921                         case 0x86DD:
922                         case 0x88E5:
923                         case 0x8847:
924                         case 0x22F3:
925
926                             pvl = getParamList(pmap, GENIE_CLASSIFIER_ETHERT);
927                             pvl.add(intToBigInt(pv.getIntValue().intValue()));
928                             break;
929
930                         default:
931                             break;
932                     }
933                 } else if (pv.getStringValue() != null) {
934                     if (pv.getStringValue().equals("TCP")) {
935                         pvl = getParamList(pmap, GENIE_CLASSIFIER_PROT);
936                         pvl.add(intToBigInt(TCP_PROTO.intValue()));
937                     } else if (pv.getStringValue().equals("UDP")) {
938                         pvl = getParamList(pmap, GENIE_CLASSIFIER_PROT);
939                         pvl.add(intToBigInt(UDP_PROTO.intValue()));
940                     }
941                 }
942             }
943             if (pv.getName().getValue().equals("proto")) {
944                 pvl = getParamList(pmap, GENIE_CLASSIFIER_ARP_OPC);
945                 pvl.add(intToBigInt(pv.getIntValue().intValue()));
946
947             }
948             if (pv.getName().getValue().equals("sourceport")) {
949                 if (cr.getDirection().equals(Direction.In)) {
950                     pvl = getParamList(pmap, GENIE_CLASSIFIER_STO_PORT);
951                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
952                 } else if (cr.getDirection().equals(Direction.Out)) {
953                     pvl = getParamList(pmap, GENIE_CLASSIFIER_SFROM_PORT);
954                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
955                 } else {
956                     pvl = getParamList(pmap, GENIE_CLASSIFIER_STO_PORT);
957                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
958                     pvl = getParamList(pmap, GENIE_CLASSIFIER_SFROM_PORT);
959                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
960                 }
961             }
962             if (pv.getName().getValue().equals("destport")) {
963                 if (cr.getDirection().equals(Direction.In)) {
964                     pvl = getParamList(pmap, GENIE_CLASSIFIER_DTO_PORT);
965                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
966                 } else if (cr.getDirection().equals(Direction.Out)) {
967                     pvl = getParamList(pmap, GENIE_CLASSIFIER_DFROM_PORT);
968                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
969                 } else {
970                     pvl = getParamList(pmap, GENIE_CLASSIFIER_DTO_PORT);
971                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
972                     pvl = getParamList(pmap, GENIE_CLASSIFIER_DFROM_PORT);
973                     pvl.add(intToBigInt(pv.getIntValue().intValue()));
974
975                 }
976             }
977         }
978
979         return pmap;
980
981     }
982
983     public static List<ManagedObject> getClassifierRefMo(PolicyUri current, ClassifierInstance ci, ClassifierRef cr,
984             RuleGroup rg, IndexedTenant it) {
985
986         List<ManagedObject> mol = new ArrayList<ManagedObject>();
987         ManagedObject mo = new ManagedObject();
988
989         PolicyUri convertedUri = odlUriToGenieUri(current);
990
991         /*
992          * Build up the equivalent Genie object
993          */
994         PolicyClassInfo pci = mit.getClass(GENIE_CLASSIFIER_REF_RN);
995         if (pci == null)
996             return null;
997         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
998         setParentFields(convertedUri, poi, GENIE_CLASSIFIER_REF_RN, false);
999         poi.setUri(convertedUri.getUri());
1000
1001         List<PolicyPropertyInfo> ppil = pci.getProperties();
1002         if (ppil == null)
1003             return null;
1004
1005         for (PolicyPropertyInfo ppi : ppil) {
1006             if (ppi.getPropName().equals(GENIE_CLASSIFIER_REF_TARGET)) {
1007
1008                 PolicyUri uri = new PolicyUri(GENIE_POLICY_ROOT);
1009                 uri.push(GENIE_TENANT_RN);
1010                 uri.push(rg.getContractTenant().getId().getValue());
1011                 uri.push(GENIE_CLASSIFIER_RN);
1012                 uri.push(ci.getName().getValue());
1013                 ManagedObject clMo = getClassifierInstanceMo(uri, ci, cr, rg, it);
1014                 if (clMo != null) {
1015                     mol.add(clMo);
1016                 }
1017
1018                 PolicyReference pr = new PolicyReference(pci.getClassId(), uri.getUri());
1019                 poi.setReference(ppi.getPropId(), pr);
1020             }
1021         }
1022
1023         lib.serializeMoProperties(pci, poi, mo, mit);
1024
1025         mo.setParent_uri(poi.getParent());
1026         mo.setParent_subject(poi.getParentSubject());
1027         mo.setParent_relation(poi.getParentRelation());
1028         mo.setSubject(GENIE_CLASSIFIER_REF_RN);
1029         mo.setUri(convertedUri.getUri());
1030         mol.add(mo);
1031
1032         return mol;
1033     }
1034
1035     /**
1036      * Create the Genie Classifier Instance MO. We need to use fields from both
1037      * the ClassifierRef and the ClassifierInstance in the ODL model.
1038      *
1039      * @param current
1040      * @param ci
1041      * @param cr
1042      * @param rg
1043      * @param it
1044      * @return
1045      */
1046     public static ManagedObject getClassifierInstanceMo(PolicyUri current, ClassifierInstance ci, ClassifierRef cr,
1047             RuleGroup rg, IndexedTenant it) {
1048         if (ci == null)
1049             return null;
1050
1051         // Convert to Genie URI
1052         PolicyUri convertedUri = odlUriToGenieUri(current);
1053
1054         if (ci.getParameterValue() == null)
1055             return null;
1056
1057         Map<String, List<BigInteger>> pmap = buildParameterValues(ci, cr);
1058
1059         ManagedObject mo = new ManagedObject();
1060
1061         /*
1062          * Build up the equivalent Genie object
1063          */
1064         PolicyClassInfo pci = mit.getClass(GENIE_CLASSIFIER_RN);
1065         if (pci == null)
1066             return null;
1067         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1068         setParentFields(convertedUri, poi, GENIE_CLASSIFIER_RN, true);
1069
1070         List<PolicyPropertyInfo> ppil = pci.getProperties();
1071         if (ppil == null)
1072             return null;
1073
1074         String prefix = convertedUri.toString();
1075
1076         for (PolicyPropertyInfo ppi : ppil) {
1077             if (ppi.getPropName().equals(GENIE_CLASSIFIER_NAME) && cr.getName() != null) {
1078                 poi.setString(ppi.getPropId(), cr.getName().getValue());
1079                 Uri child = new Uri(prefix + GENIE_CLASSIFIER_NAME + cr.getName().getValue());
1080                 poi.setUri(child);
1081             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_DIRECTION) && cr.getDirection() != null) {
1082                 // initialize with bogus values for placeholders, then replace
1083                 // with real ones
1084                 List<Integer> odl2genie = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
1085                 odl2genie.set(0, 1);
1086                 odl2genie.set(1, 2);
1087                 odl2genie.set(2, 0);
1088
1089                 /*
1090                  * The direction enums are different between the ODL and Genie
1091                  * models:
1092                  * 
1093                  * Value: | ODL | Genie --------------+-----+--------
1094                  * bidirectional | 2 | 0 in | 0 | 1 out | 1 | 2
1095                  */
1096                 Integer genieDirection = odl2genie.get(cr.getDirection().getIntValue());
1097                 poi.setUint64(ppi.getPropId(), new BigInteger(genieDirection.toString()));
1098             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_CONNECTION_TRACKING)
1099                     && cr.getConnectionTracking() != null) {
1100                 poi.setUint64(ppi.getPropId(), intToBigInt(cr.getConnectionTracking().getIntValue()));
1101             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_ARP_OPC) && pmap.get(GENIE_CLASSIFIER_ARP_OPC) != null) {
1102                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_ARP_OPC).get(0));
1103             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_ETHERT) && pmap.get(GENIE_CLASSIFIER_ETHERT) != null) {
1104                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_ETHERT).get(0));
1105             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_DFROM_PORT)
1106                     && pmap.get(GENIE_CLASSIFIER_DFROM_PORT) != null) {
1107                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_DFROM_PORT).get(0));
1108             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_DTO_PORT)
1109                     && pmap.get(GENIE_CLASSIFIER_DTO_PORT) != null) {
1110                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_DTO_PORT).get(0));
1111             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_SFROM_PORT)
1112                     && pmap.get(GENIE_CLASSIFIER_SFROM_PORT) != null) {
1113                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_SFROM_PORT).get(0));
1114             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_STO_PORT)
1115                     && pmap.get(GENIE_CLASSIFIER_STO_PORT) != null) {
1116                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_STO_PORT).get(0));
1117             } else if (ppi.getPropName().equals(GENIE_CLASSIFIER_PROT) && pmap.get(GENIE_CLASSIFIER_PROT) != null) {
1118                 poi.setUint64(ppi.getPropId(), pmap.get(GENIE_CLASSIFIER_PROT).get(0));
1119             }
1120         }
1121
1122         lib.serializeMoProperties(pci, poi, mo, mit);
1123
1124         mo.setParent_uri(poi.getParent());
1125         mo.setParent_subject(poi.getParentSubject());
1126         mo.setParent_relation(poi.getParentRelation());
1127         mo.setSubject(GENIE_CLASSIFIER_RN);
1128         mo.setUri(convertedUri.getUri());
1129
1130         return mo;
1131     }
1132
1133     public static class Ipv4PlusSubnet {
1134
1135         private String prefix;
1136         private final String mask;
1137
1138         public Ipv4PlusSubnet(String ipAndMask) {
1139             String[] parts = ipAndMask.split("/");
1140             this.mask = parts[1];
1141             this.prefix = "";
1142
1143             int ip = 0;
1144             int index = 0;
1145             for (String s : parts[0].split("\\.")) {
1146                 ip |= (Integer.parseInt(s) & 0xff) << (24 - 8 * index);
1147                 index += 1;
1148             }
1149
1150             int msk = -1 << (32 - Integer.parseInt(parts[1]));
1151             int sub = ip & msk;
1152             for (int i = 0; i < 3; i++) {
1153                 this.prefix = this.prefix + String.valueOf((sub >> (24 - 8 * i)) & 0xff) + ".";
1154             }
1155             this.prefix = this.prefix + String.valueOf(sub & 0xff);
1156         }
1157
1158         public String getPrefixAsString() {
1159             return this.prefix;
1160         }
1161
1162         public String getMaskAsString() {
1163             return this.mask;
1164         }
1165
1166         public int getMaskAsInt() {
1167             return Integer.parseInt(this.mask);
1168         }
1169
1170         public BigInteger getMaskAsBigInt() {
1171             return new BigInteger(this.mask);
1172         }
1173
1174     }
1175
1176     public static ManagedObject getSubnetMo(PolicyUri current, Subnet s, Tenant t) {
1177
1178         /*
1179          * Build up the equivalent Genie object
1180          */
1181         PolicyClassInfo pci = mit.getClass(GENIE_SUBNET_RN);
1182         if (pci == null)
1183             return null;
1184
1185         // Convert to Genie URI
1186         PolicyUri convertedUri = odlUriToGenieUri(current);
1187
1188         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1189         setParentFields(convertedUri, poi, GENIE_SUBNET_RN, true);
1190         poi.setUri(convertedUri.getUri());
1191
1192         List<PolicyPropertyInfo> ppil = pci.getProperties();
1193         if (ppil == null)
1194             return null;
1195
1196         // convert this once - we'll use it below
1197         Ipv4PlusSubnet ipv4 = new Ipv4PlusSubnet(s.getIpPrefix().getIpv4Prefix().getValue());
1198
1199         for (PolicyPropertyInfo ppi : ppil) {
1200
1201             // use the subnet ID for the subnets (plural) ID
1202             if (ppi.getPropName().equals(GENIE_SUBNET_NAME) && s.getId() != null) {
1203                 poi.setString(ppi.getPropId(), GENIE_SUBNET_NAME_DEFAULT);
1204             }
1205             if (ppi.getPropName().equals(GENIE_SUBNET_ADDRESS) && s.getIpPrefix() != null) {
1206                 /*
1207                  * We need to strip off the subnet delimiter
1208                  */
1209                 poi.setString(ppi.getPropId(), ipv4.getPrefixAsString());
1210             }
1211             if (ppi.getPropName().equals(GENIE_SUBNET_PREFIX_LEN) && s.getIpPrefix() != null) {
1212                 poi.setUint64(ppi.getPropId(), ipv4.getMaskAsBigInt());
1213             }
1214             if (ppi.getPropName().equals(GENIE_SUBNET_VIRTUAL_ROUTER_IP) && s.getVirtualRouterIp() != null) {
1215                 poi.setString(ppi.getPropId(), s.getVirtualRouterIp().getIpv4Address().getValue());
1216             }
1217         }
1218
1219         ManagedObject mo = new ManagedObject();
1220         lib.serializeMoProperties(pci, poi, mo, mit);
1221
1222         mo.setParent_uri(poi.getParent());
1223         mo.setParent_subject(poi.getParentSubject());
1224         mo.setParent_relation(poi.getParentRelation());
1225         mo.setSubject(GENIE_SUBNET_RN);
1226         mo.setUri(convertedUri.getUri());
1227
1228         return mo;
1229     }
1230
1231     public static List<ManagedObject> getSubnetNetworkRefMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1232         if (ndid == null)
1233             return null;
1234
1235         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1236         ManagedObject mo = new ManagedObject();
1237
1238         PolicyUri convertedUri = odlUriToGenieUri(current);
1239
1240         /*
1241          * Build up the equivalent Genie object
1242          */
1243         PolicyClassInfo pci = mit.getClass(GENIE_SUBNETS_TO_NETWORK_RN);
1244         if (pci == null)
1245             return null;
1246         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1247         setParentFields(convertedUri, poi, GENIE_SUBNETS_TO_NETWORK_RN, false);
1248         poi.setUri(convertedUri.getUri());
1249
1250         List<PolicyPropertyInfo> ppil = pci.getProperties();
1251         if (ppil == null)
1252             return null;
1253
1254         for (PolicyPropertyInfo ppi : ppil) {
1255             if (ppi.getPropName().equals(GENIE_SUBNETS_TO_NETWORK_DOMAIN_TARGET)) {
1256
1257                 PolicyUri uri = new PolicyUri(convertedUri);
1258                 uri.pop();
1259                 uri.pop();
1260                 uri.push(GENIE_FLOOD_DOMAIN_RN);
1261                 uri.push(ndid.getValue());
1262                 mol = getL2FloodDomainMo(uri, ndid, t);
1263                 if (mol == null) {
1264                     uri.pop();
1265                     uri.pop();
1266                     uri.push(GENIE_BRIDGE_DOMAIN_RN);
1267                     uri.push(ndid.getValue());
1268                     mol = getL2BridgeDomainMo(uri, ndid, t);
1269                 }
1270                 if (mol == null) {
1271                     uri.pop();
1272                     uri.pop();
1273                     uri.push(GENIE_ROUTING_DOMAIN_RN);
1274                     uri.push(ndid.getValue());
1275                     mol = new ArrayList<ManagedObject>();
1276                     ManagedObject l3cmo = getL3ContextMo(uri, ndid, t);
1277                     if (l3cmo != null) {
1278                         mol.add(l3cmo);
1279                     }
1280                 }
1281                 /*
1282                  * We default to this being a routing domain reference if the
1283                  * actual reference can't be resolved.
1284                  */
1285                 PolicyReference pr = new PolicyReference(pci.getClassId(), uri.getUri());
1286                 poi.setReference(ppi.getPropId(), pr);
1287             }
1288         }
1289
1290         lib.serializeMoProperties(pci, poi, mo, mit);
1291
1292         mo.setParent_uri(poi.getParent());
1293         mo.setParent_subject(poi.getParentSubject());
1294         mo.setParent_relation(poi.getParentRelation());
1295         mo.setSubject(GENIE_SUBNETS_TO_NETWORK_RN);
1296         mo.setUri(convertedUri.getUri());
1297         mol.add(mo);
1298
1299         return mol;
1300     }
1301
1302     public static List<ManagedObject> getSubnetsMo(PolicyUri current, NetworkDomainId nid, Tenant t) {
1303         if (nid == null)
1304             return null;
1305         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1306
1307         Subnet subnetMatch = null;
1308         List<Subnet> sl = t.getSubnet();
1309         if (sl != null) {
1310             for (Subnet s : sl) {
1311                 if (s.getId().getValue().equals(nid.getValue())) {
1312                     subnetMatch = s;
1313                     break;
1314                 }
1315             }
1316         }
1317         if (subnetMatch == null)
1318             return null;
1319
1320         ManagedObject mo = new ManagedObject();
1321
1322         /*
1323          * Build up the equivalent Genie object
1324          */
1325         PolicyClassInfo pci = mit.getClass(GENIE_SUBNETS_RN);
1326         if (pci == null)
1327             return null;
1328         List<Uri> childrenUris = new ArrayList<Uri>();
1329
1330         // Convert to Genie URI
1331         PolicyUri convertedUri = odlUriToGenieUri(current);
1332         String prefix = convertedUri.toString();
1333
1334         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1335         setParentFields(convertedUri, poi, GENIE_SUBNETS_RN, true);
1336         poi.setUri(convertedUri.getUri());
1337
1338         List<PolicyPropertyInfo> ppil = pci.getProperties();
1339         if (ppil == null)
1340             return null;
1341
1342         for (PolicyPropertyInfo ppi : ppil) {
1343             // use the subnet ID for the subnets (plural) ID
1344             if (ppi.getPropName().equals(GENIE_SUBNETS_NAME) && subnetMatch.getId() != null) {
1345                 poi.setString(ppi.getPropId(), subnetMatch.getId().getValue());
1346             }
1347             if (ppi.getPropName().equals(GENIE_SUBNET_RN) && subnetMatch.getId() != null) {
1348                 PolicyUri child = new PolicyUri(prefix);
1349                 child.push(GENIE_SUBNET_RN);
1350                 child.push(GENIE_SUBNET_NAME_DEFAULT);
1351                 ManagedObject snetMo = getSubnetMo(child, subnetMatch, t);
1352                 if (snetMo != null) {
1353                     mol.add(snetMo);
1354                 }
1355                 childrenUris.add(child.getUri());
1356             }
1357             if (ppi.getPropName().equals(GENIE_SUBNETS_TO_NETWORK_RN) && subnetMatch.getParent() != null) {
1358                 PolicyUri child = new PolicyUri(prefix);
1359                 child.push(GENIE_SUBNETS_TO_NETWORK_RN);
1360                 mol = getSubnetNetworkRefMo(child, subnetMatch.getParent(), t);
1361                 childrenUris.add(child.getUri());
1362             }
1363         }
1364
1365         lib.serializeMoProperties(pci, poi, mo, mit);
1366
1367         mo.setChildren(childrenUris);
1368
1369         mo.setParent_uri(poi.getParent());
1370         mo.setParent_subject(poi.getParentSubject());
1371         mo.setParent_relation(poi.getParentRelation());
1372         mo.setSubject(GENIE_SUBNETS_RN);
1373         mo.setUri(convertedUri.getUri());
1374
1375         mol.add(mo);
1376
1377         return mol;
1378     }
1379
1380     public static List<ManagedObject> getL2FloodDomainRefMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1381         if (ndid == null)
1382             return null;
1383         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1384         ManagedObject mo = new ManagedObject();
1385
1386         PolicyUri convertedUri = odlUriToGenieUri(current);
1387
1388         /*
1389          * Build up the equivalent Genie object
1390          */
1391         PolicyClassInfo pci = mit.getClass(GENIE_FLOOD_DOMAIN_TO_NETWORK_RN);
1392         if (pci == null)
1393             return null;
1394
1395         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1396         setParentFields(convertedUri, poi, GENIE_FLOOD_DOMAIN_TO_NETWORK_RN, false);
1397         poi.setUri(convertedUri.getUri());
1398
1399         List<PolicyPropertyInfo> ppil = pci.getProperties();
1400         if (ppil == null)
1401             return null;
1402
1403         for (PolicyPropertyInfo ppi : ppil) {
1404             if (ppi.getPropName().equals(GENIE_EPG_TO_NETWORK_DOMAIN_TARGET)) {
1405
1406                 /*
1407                  * We have to move back to the tenant, since all of the
1408                  * references are relative to the tenant
1409                  */
1410                 PolicyUri uri = new PolicyUri(GENIE_POLICY_ROOT);
1411                 uri.push(GENIE_TENANT_RN);
1412                 uri.push(t.getId().getValue());
1413                 uri.push(GENIE_BRIDGE_DOMAIN_RN);
1414                 uri.push(ndid.getValue());
1415
1416                 /*
1417                  * Go chase the network domain references. Look for the
1418                  * reference in the bridge domain list.
1419                  */
1420                 mol = getL2BridgeDomainMo(uri, ndid, t);
1421                 if (mol == null) {
1422                     uri.pop();
1423                     uri.pop();
1424                     uri.push(GENIE_ROUTING_DOMAIN_RN);
1425                     uri.push(ndid.getValue());
1426                     mol = new ArrayList<ManagedObject>();
1427                     ManagedObject l3cmo = getL3ContextMo(uri, ndid, t);
1428                     if (l3cmo != null) {
1429                         mol.add(l3cmo);
1430                     }
1431                 }
1432                 /*
1433                  * We default to this being a routing domain reference if the
1434                  * actual reference can't be resolved.
1435                  */
1436                 PolicyReference pr = new PolicyReference(pci.getClassId(), uri.getUri());
1437                 poi.setReference(ppi.getPropId(), pr);
1438             }
1439         }
1440
1441         lib.serializeMoProperties(pci, poi, mo, mit);
1442
1443         mo.setParent_uri(poi.getParent());
1444         mo.setParent_subject(poi.getParentSubject());
1445         mo.setParent_relation(poi.getParentRelation());
1446         mo.setSubject(GENIE_FLOOD_DOMAIN_TO_NETWORK_RN);
1447         mo.setUri(convertedUri.getUri());
1448         mol.add(mo);
1449
1450         return mol;
1451     }
1452
1453     public static List<ManagedObject> getL2FloodDomainMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1454         if (ndid == null)
1455             return null;
1456
1457         // Convert to Genie URI
1458         PolicyUri convertedUri = odlUriToGenieUri(current);
1459         String prefix = convertedUri.toString();
1460         L2FloodDomain l2fdMatch = null;
1461
1462         List<L2FloodDomain> l2fdl = t.getL2FloodDomain();
1463         if (l2fdl != null) {
1464             for (L2FloodDomain l2fd : l2fdl) {
1465                 if (l2fd.getId().getValue().equals(ndid.getValue())) {
1466                     l2fdMatch = l2fd;
1467                     break;
1468                 }
1469             }
1470         }
1471
1472         if (l2fdMatch == null)
1473             return null;
1474
1475         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1476         List<Uri> childrenUris = new ArrayList<Uri>();
1477         ManagedObject mo = new ManagedObject();
1478
1479         /*
1480          * Build up the equivalent Genie object
1481          */
1482         PolicyClassInfo pci = mit.getClass(GENIE_FLOOD_DOMAIN_RN);
1483         if (pci == null)
1484             return null;
1485
1486         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1487         setParentFields(convertedUri, poi, GENIE_FLOOD_DOMAIN_RN, true);
1488         poi.setUri(convertedUri.getUri());
1489
1490         List<PolicyPropertyInfo> ppil = pci.getProperties();
1491         if (ppil == null)
1492             return null;
1493
1494         for (PolicyPropertyInfo ppi : ppil) {
1495             if (ppi.getPropName().equals(GENIE_FLOOD_DOMAIN_NAME)) {
1496                 poi.setString(ppi.getPropId(), l2fdMatch.getId().getValue());
1497             }
1498             if (ppi.getPropName().equals(GENIE_FLOOD_DOMAIN_TO_NETWORK_RN) && l2fdMatch.getParent() != null) {
1499                 /*
1500                  * Add as a child, not a property, and get the child
1501                  */
1502                 PolicyUri child = new PolicyUri(prefix);
1503                 child.push(GENIE_FLOOD_DOMAIN_TO_NETWORK_RN);
1504                 mol.addAll(getL2FloodDomainRefMo(child, l2fdMatch.getParent(), t));
1505                 childrenUris.add(child.getUri());
1506             }
1507         }
1508
1509         lib.serializeMoProperties(pci, poi, mo, mit);
1510
1511         mo.setChildren(childrenUris);
1512
1513         mo.setParent_uri(poi.getParent());
1514         mo.setParent_subject(poi.getParentSubject());
1515         mo.setParent_relation(poi.getParentRelation());
1516         mo.setSubject(GENIE_FLOOD_DOMAIN_RN);
1517         mo.setUri(convertedUri.getUri());
1518         mol.add(mo);
1519
1520         return mol;
1521     }
1522
1523     public static List<ManagedObject> getL2BridgeDomainRefMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1524         if (ndid == null)
1525             return null;
1526
1527         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1528         ManagedObject mo = new ManagedObject();
1529
1530         PolicyUri convertedUri = odlUriToGenieUri(current);
1531
1532         /*
1533          * Build up the equivalent Genie object
1534          */
1535         PolicyClassInfo pci = mit.getClass(GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN);
1536         if (pci == null)
1537             return null;
1538
1539         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1540         setParentFields(convertedUri, poi, GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN, false);
1541         poi.setUri(convertedUri.getUri());
1542
1543         List<PolicyPropertyInfo> ppil = pci.getProperties();
1544         if (ppil == null)
1545             return null;
1546
1547         for (PolicyPropertyInfo ppi : ppil) {
1548             if (ppi.getPropName().equals(GENIE_BRIDGE_DOMAIN_TO_NETWORK_DOMAIN_TARGET)) {
1549
1550                 /*
1551                  * We have to move back to the tenant, since all of the
1552                  * references are relative to the tenant
1553                  */
1554                 PolicyUri uri = new PolicyUri(GENIE_POLICY_ROOT);
1555                 uri.push(GENIE_TENANT_RN);
1556                 uri.push(t.getId().getValue());
1557                 uri.push(GENIE_ROUTING_DOMAIN_RN);
1558                 uri.push(ndid.getValue());
1559                 mol = new ArrayList<ManagedObject>();
1560                 ManagedObject l3cmo = getL3ContextMo(uri, ndid, t);
1561                 if (l3cmo != null) {
1562                     mol.add(l3cmo);
1563                 }
1564
1565                 /*
1566                  * We default to this being a routing domain reference if the
1567                  * actual reference can't be resolved.
1568                  */
1569                 PolicyReference pr = new PolicyReference(pci.getClassId(), uri.getUri());
1570                 poi.setReference(ppi.getPropId(), pr);
1571             }
1572         }
1573
1574         lib.serializeMoProperties(pci, poi, mo, mit);
1575
1576         mo.setParent_uri(poi.getParent());
1577         mo.setParent_subject(poi.getParentSubject());
1578         mo.setParent_relation(poi.getParentRelation());
1579         mo.setSubject(GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN);
1580         mo.setUri(convertedUri.getUri());
1581
1582         mol.add(mo);
1583
1584         return mol;
1585     }
1586
1587     public static List<ManagedObject> getL2BridgeDomainMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1588         List<L2BridgeDomain> l2bdl = t.getL2BridgeDomain();
1589         if (ndid == null || l2bdl == null)
1590             return null;
1591
1592         // Convert to Genie URI
1593         PolicyUri convertedUri = odlUriToGenieUri(current);
1594         String prefix = convertedUri.toString();
1595
1596         L2BridgeDomain l2bdMatch = null;
1597         for (L2BridgeDomain l2bd : l2bdl) {
1598             if (l2bd.getId().getValue().equals(ndid.getValue())) {
1599                 l2bdMatch = l2bd;
1600                 break;
1601             }
1602         }
1603
1604         if (l2bdMatch == null)
1605             return null;
1606
1607         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1608         List<Uri> childrenUris = new ArrayList<Uri>();
1609         ManagedObject mo = new ManagedObject();
1610
1611         /*
1612          * Build up the equivalent Genie object
1613          */
1614         PolicyClassInfo pci = mit.getClass(GENIE_BRIDGE_DOMAIN_RN);
1615         if (pci == null)
1616             return null;
1617
1618         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1619         setParentFields(convertedUri, poi, GENIE_BRIDGE_DOMAIN_RN, true);
1620         poi.setUri(convertedUri.getUri());
1621
1622         List<PolicyPropertyInfo> ppil = pci.getProperties();
1623         if (ppil == null)
1624             return null;
1625
1626         for (PolicyPropertyInfo ppi : ppil) {
1627             if (ppi.getPropName().equals(GENIE_BRIDGE_DOMAIN_NAME)) {
1628                 poi.setString(ppi.getPropId(), l2bdMatch.getId().getValue());
1629             }
1630             if (ppi.getPropName().equals(GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN) && l2bdMatch.getParent() != null) {
1631                 /*
1632                  * Add as a child, not a property, and get the child
1633                  */
1634                 PolicyUri child = new PolicyUri(prefix);
1635                 child.push(GENIE_BRIDGE_DOMAIN_TO_NETWORK_RN);
1636                 mol.addAll(getL2BridgeDomainRefMo(child, l2bdMatch.getParent(), t));
1637                 childrenUris.add(child.getUri());
1638             }
1639         }
1640
1641         lib.serializeMoProperties(pci, poi, mo, mit);
1642
1643         mo.setChildren(childrenUris);
1644
1645         mo.setParent_uri(poi.getParent());
1646         mo.setParent_subject(poi.getParentSubject());
1647         mo.setParent_relation(poi.getParentRelation());
1648         mo.setSubject(GENIE_BRIDGE_DOMAIN_RN);
1649         mo.setUri(convertedUri.getUri());
1650         mol.add(mo);
1651
1652         return mol;
1653     }
1654
1655     public static ManagedObject getL3ContextMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1656         List<L3Context> l3cl = t.getL3Context();
1657         if (ndid == null || l3cl == null)
1658             return null;
1659
1660         // Convert to Genie URI
1661         PolicyUri convertedUri = odlUriToGenieUri(current);
1662
1663         L3Context l3cMatch = null;
1664         for (L3Context l3c : l3cl) {
1665             if (l3c.getId().getValue().equals(ndid.getValue())) {
1666                 l3cMatch = l3c;
1667                 break;
1668             }
1669         }
1670
1671         if (l3cMatch == null)
1672             return null;
1673
1674         ManagedObject mo = new ManagedObject();
1675
1676         /*
1677          * Build up the equivalent Genie object
1678          */
1679         PolicyClassInfo pci = mit.getClass(GENIE_ROUTING_DOMAIN_RN);
1680         if (pci == null)
1681             return null;
1682
1683         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1684         setParentFields(convertedUri, poi, GENIE_ROUTING_DOMAIN_RN, true);
1685         poi.setUri(convertedUri.getUri());
1686
1687         List<PolicyPropertyInfo> ppil = pci.getProperties();
1688         if (ppil == null)
1689             return null;
1690
1691         for (PolicyPropertyInfo ppi : ppil) {
1692             if (ppi.getPropName().equals(GENIE_ROUTING_DOMAIN_NAME)) {
1693                 poi.setString(ppi.getPropId(), l3cMatch.getId().getValue());
1694             }
1695         }
1696
1697         lib.serializeMoProperties(pci, poi, mo, mit);
1698
1699         mo.setParent_uri(poi.getParent());
1700         mo.setParent_subject(poi.getParentSubject());
1701         mo.setParent_relation(poi.getParentRelation());
1702         mo.setSubject(GENIE_ROUTING_DOMAIN_RN);
1703         mo.setUri(convertedUri.getUri());
1704         return mo;
1705     }
1706
1707     /**
1708      * This is the equivalent of a network reference object in the Genie MIT. We
1709      * chase the reference to get any other objects in a network hierarchy.
1710      *
1711      * @param current
1712      * @param ndid
1713      * @param t
1714      * @return
1715      */
1716     public static List<ManagedObject> getNetwokDomainRefMo(PolicyUri current, NetworkDomainId ndid, Tenant t) {
1717         if (ndid == null)
1718             return null;
1719         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1720         ManagedObject mo = new ManagedObject();
1721
1722         PolicyUri convertedUri = odlUriToGenieUri(current);
1723
1724         /*
1725          * Build up the equivalent Genie object
1726          */
1727         PolicyClassInfo pci = mit.getClass(GENIE_EPG_TO_NETWORK_DOMAIN_RN);
1728         if (pci == null)
1729             return null;
1730
1731         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1732         setParentFields(convertedUri, poi, GENIE_EPG_TO_NETWORK_DOMAIN_RN, false);
1733         poi.setUri(convertedUri.getUri());
1734
1735         List<PolicyPropertyInfo> ppil = pci.getProperties();
1736         if (ppil == null)
1737             return null;
1738
1739         for (PolicyPropertyInfo ppi : ppil) {
1740             if (ppi.getPropName().equals(GENIE_EPG_TO_NETWORK_DOMAIN_TARGET)) {
1741
1742                 /*
1743                  * We have to move back to the tenant, since all of the
1744                  * references are relative to the tenant
1745                  */
1746                 PolicyUri uri = new PolicyUri(GENIE_POLICY_ROOT);
1747                 uri.push(GENIE_TENANT_RN);
1748                 uri.push(t.getId().getValue());
1749                 uri.push(GENIE_SUBNETS_RN);
1750                 uri.push(ndid.getValue());
1751
1752                 /*
1753                  * Go chase the network domain references. Look first for the
1754                  * reference in the subnets list.
1755                  */
1756                 mol = getSubnetsMo(uri, ndid, t);
1757                 if (mol == null) {
1758                     uri.pop();
1759                     uri.pop();
1760                     uri.push(GENIE_FLOOD_DOMAIN_RN);
1761                     uri.push(ndid.getValue());
1762                     mol = getL2FloodDomainMo(uri, ndid, t);
1763                 }
1764                 if (mol == null) {
1765                     uri.pop();
1766                     uri.pop();
1767                     uri.push(GENIE_BRIDGE_DOMAIN_RN);
1768                     uri.push(ndid.getValue());
1769                     mol = getL2BridgeDomainMo(uri, ndid, t);
1770                 }
1771                 if (mol == null) {
1772                     uri.pop();
1773                     uri.pop();
1774                     uri.push(GENIE_ROUTING_DOMAIN_RN);
1775                     uri.push(ndid.getValue());
1776                     mol = new ArrayList<ManagedObject>();
1777                     ManagedObject l3cmo = getL3ContextMo(uri, ndid, t);
1778                     if (l3cmo != null) {
1779                         mol.add(l3cmo);
1780                     }
1781                 }
1782                 /*
1783                  * We default to this being a routing domain reference if the
1784                  * actual reference can't be resolved.
1785                  */
1786                 PolicyReference pr = new PolicyReference(pci.getClassId(), uri.getUri());
1787                 poi.setReference(ppi.getPropId(), pr);
1788             }
1789         }
1790
1791         lib.serializeMoProperties(pci, poi, mo, mit);
1792
1793         mo.setParent_uri(poi.getParent());
1794         mo.setParent_subject(poi.getParentSubject());
1795         mo.setParent_relation(poi.getParentRelation());
1796         mo.setSubject(GENIE_EPG_TO_NETWORK_DOMAIN_RN);
1797         mo.setUri(convertedUri.getUri());
1798         mol.add(mo);
1799
1800         return mol;
1801
1802     }
1803
1804     public static Set<ManagedObject> getEndpointGroupMo(ManagedObject epgMo, PolicyUri current, EndpointGroup epg,
1805             RuleGroup rg) {
1806         if (epg == null)
1807             return null;
1808
1809         // Convert to Genie URI
1810         PolicyUri convertedUri = odlUriToGenieUri(current);
1811
1812         String prefix = convertedUri.toString();
1813
1814         // Arrays for MOs that follow
1815         List<ManagedObject> mol = new ArrayList<ManagedObject>();
1816         List<Uri> childrenUris = new ArrayList<Uri>();
1817
1818         /*
1819          * Build up the equivalent Genie object
1820          */
1821         PolicyClassInfo pci = mit.getClass(GENIE_EPG_RN);
1822         if (pci == null)
1823             return null;
1824         PolicyObjectInstance poi = new PolicyObjectInstance(pci.getClassId());
1825         setParentFields(convertedUri, poi, GENIE_EPG_RN, true);
1826
1827         List<PolicyPropertyInfo> ppil = pci.getProperties();
1828         if (ppil == null)
1829             return null;
1830
1831         // Use the name to set the URI of this object
1832         poi.setUri(convertedUri.getUri());
1833
1834         Contract c = rg.getRelatedContract();
1835         for (PolicyPropertyInfo ppi : ppil) {
1836             if (ppi.getPropName().equals(GENIE_ENDPOINT_GROUP_NAME) && epg.getId() != null) {
1837                 poi.setString(ppi.getPropId(), epg.getId().getValue());
1838             }
1839             if (ppi.getPropName().equals(GENIE_INTRA_EPG_RN) && epg.getIntraGroupPolicy() != null) {
1840                 poi.setUint64(ppi.getPropId(), intToBigInt(epg.getIntraGroupPolicy().getIntValue()));
1841             }
1842
1843             // TODO: the following only maps named selectors. What about target
1844             // selectors?
1845             if (ppi.getPropName().equals(GENIE_CONSUMER_CONTRACT_REF_RN) && epg.getConsumerNamedSelector() != null) {
1846                 // TODO: this does all the selectors -- should we just do those
1847                 // that are in scope?
1848                 for (ConsumerNamedSelector cns : epg.getConsumerNamedSelector()) {
1849                     for (ContractId cid : cns.getContract()) {
1850                         if (!cid.getValue().equals(c.getId().getValue())) {
1851                             PolicyUri child = new PolicyUri(prefix);
1852                             child.push(GENIE_CONSUMER_CONTRACT_REF_RN);
1853                             child.push(cns.getName().getValue());
1854                             ManagedObject conMo = getConsumerNamedSelectorMo(child, c);
1855                             if (conMo != null) {
1856                                 mol.add(conMo);
1857                             }
1858                             childrenUris.add(child.getUri());
1859                         }
1860                     }
1861                 }
1862             }
1863
1864             // TODO: the following only maps named selectors. What about target
1865             // selectors?
1866             if (ppi.getPropName().equals(GENIE_PROVIDER_CONTRACT_REF_RN) && epg.getProviderNamedSelector() != null) {
1867                 // TODO: this does all the selectors -- should we just do those
1868                 // that are in scope?
1869                 for (ProviderNamedSelector pns : epg.getProviderNamedSelector()) {
1870                     for (ContractId cid : pns.getContract()) {
1871                         if (cid.getValue().equals(c.getId().getValue())) {
1872                             PolicyUri child = new PolicyUri(prefix);
1873                             child.push(GENIE_PROVIDER_CONTRACT_REF_RN);
1874                             child.push(pns.getName().getValue());
1875                             ManagedObject provMo = getProviderNamedSelectorMo(child, c);
1876                             if (provMo != null) {
1877                                 mol.add(provMo);
1878                             }
1879                             childrenUris.add(child.getUri());
1880                         }
1881                     }
1882                 }
1883             }
1884             /*
1885              * Don't bother getting network references if we have them already
1886              */
1887             if (ppi.getPropName().equals(GENIE_EPG_TO_NETWORK_DOMAIN_RN) && epg.getNetworkDomain() != null) {
1888                 PolicyUri child = new PolicyUri(prefix);
1889                 child.push(GENIE_EPG_TO_NETWORK_DOMAIN_RN);
1890                 mol.addAll(MessageUtils.getNetwokDomainRefMo(child, epg.getNetworkDomain(), rg.getContractTenant()));
1891                 childrenUris.add(child.getUri());
1892             }
1893
1894         }
1895
1896         lib.serializeMoProperties(pci, poi, epgMo, mit);
1897
1898         epgMo.setChildren(childrenUris);
1899
1900         epgMo.setParent_uri(poi.getParent());
1901         epgMo.setParent_subject(poi.getParentSubject());
1902         epgMo.setParent_relation(poi.getParentRelation());
1903         epgMo.setSubject(GENIE_EPG_RN);
1904         epgMo.setUri(convertedUri.getUri());
1905
1906         return Sets.newHashSet(mol);
1907     }
1908
1909     /**
1910      * Deserialize the MO properties, convert them to objects that are used in
1911      * the ODL tree, and return them as a list of objects.
1912      *
1913      * @param mo
1914      * @return
1915      */
1916     public static EprOperation getEprOpFromEpMo(ManagedObject mo, int prr, String agentId) {
1917         MacAddress mac = null;
1918         EndpointGroupId epgid = null;
1919         L2BridgeDomainId l2bdid = null;
1920         L3ContextId l3cid = null;
1921         IpAddress ip = null;
1922         EprOperation op = null;
1923         TenantId tid = null;
1924         List<L3Address> l3al = new ArrayList<L3Address>();
1925
1926         if (mo.getProperties() == null)
1927             return null;
1928
1929         // Deserialize the MO properties
1930         PolicyObjectInstance poi = lib.deserializeMoProperties(mo, mit);
1931         if (poi == null)
1932             return null;
1933
1934         PolicyClassInfo pci = mit.getClass(poi.getClassId());
1935         List<PolicyPropertyInfo> ppil = pci.getProperties();
1936         if (ppil == null)
1937             return null;
1938
1939         /*
1940          * We want to extract the properties we need to map to the corresponding
1941          * ODL MIT. We have to roll through the list of properties that were
1942          * present and map each of them independently. We know what type of
1943          * Endpoint we're mapping by the "subject" field of the MO.
1944          */
1945         // TODO: add support for vector values
1946         for (PolicyPropertyInfo ppi : ppil) {
1947             if (poi.isSet(ppi.getPropId(), ppi.getType(), ppi.getPropCardinality())) {
1948                 switch (ppi.getPropName()) {
1949                     case GENIE_ENDPOINT_MAC:
1950                         mac = poi.getMacAddress(ppi.getPropId());
1951                         break;
1952                     case GENIE_ENDPOINT_EPG:
1953                         /*
1954                          * This must be a full URI of the EPG -- otherwise, it can't
1955                          * be uniquely resolved.
1956                          */
1957                         String epg = poi.getString(ppi.getPropId());
1958                         epgid = new EndpointGroupId(epg);
1959                         break;
1960                     case GENIE_ENDPOINT_CONTEXT:
1961                         /*
1962                          * It seems like this should be scoped by tenant as well,
1963                          * which means it would have to be a full URI. If that's the
1964                          * case, then the code below needs fixing.
1965                          */
1966                         if (mo.getSubject().equals(GENIE_ENDPOINT_RN)) {
1967                             l2bdid = new L2BridgeDomainId(poi.getString(ppi.getPropId()));
1968                         } else if (mo.getSubject().equals(GENIE_ENDPOINT_L3_RN)) {
1969                             l3cid = new L3ContextId(poi.getString(ppi.getPropId()));
1970                         }
1971                         break;
1972                     case GENIE_ENDPOINT_UUID:
1973                         String uuid = poi.getString(ppi.getPropId());
1974                         tid = new TenantId(uuid);
1975                         break;
1976                     case GENIE_ENDPOINT_IP:
1977                         // TODO: support v6
1978                         Ipv4Address ipv4 = new Ipv4Address(poi.getString(ppi.getPropId()));
1979                         ip = new IpAddress(ipv4);
1980                         break;
1981                     default:
1982                         break;
1983                 }
1984             }
1985
1986         }
1987
1988         if (ip != null && l3cid != null) {
1989             L3AddressBuilder l3ab = new L3AddressBuilder();
1990             l3ab.setIpAddress(ip);
1991             l3ab.setL3Context(l3cid);
1992             l3al.add(l3ab.build());
1993         }
1994
1995         String epType = mo.getSubject();
1996         if (epType.equals(GENIE_ENDPOINT_RN)) {
1997             L2EprOperation l2eo = new L2EprOperation(prr);
1998             l2eo.setAgentId(agentId);
1999             l2eo.setContextId(l2bdid);
2000             l2eo.setEndpointGroupId(epgid);
2001             l2eo.setL3AddressList(l3al);
2002             l2eo.setMacAddress(mac);
2003             l2eo.setTenantId(tid);
2004             op = l2eo;
2005         } else if (epType.equals(GENIE_ENDPOINT_L3_RN)) {
2006             L3EprOperation l3eo = new L3EprOperation(prr);
2007             l3eo.setAgentId(agentId);
2008             l3eo.setContextId(l3cid);
2009             l3eo.setEndpointGroupId(epgid);
2010             l3eo.setIpAddress(ip);
2011             l3eo.setL3AddressList(l3al);
2012             l3eo.setMacAddress(mac);
2013             l3eo.setTenantId(tid);
2014             op = l3eo;
2015         }
2016
2017         return op;
2018     }
2019
2020     /**
2021      * Get the Endpoint Registry Operation from the Genie URI. The Genie URI
2022      * must be a URI for an Endpoint in the EPR.
2023      *
2024      * @param uri
2025      * @param subject
2026      * @return
2027      */
2028     public static EprOperation getEprOpFromUri(Uri uri, String subject) {
2029         PolicyUri convertedUri = genieUriToOdlUri(new PolicyUri(uri.getValue()));
2030         String convertedSubject = genieToOdlMap.get(subject);
2031
2032         /*
2033          * Get the objects that are common to all EPs
2034          */
2035         EprOperation op = null;
2036         String identifier = convertedUri.pop();
2037         String context = convertedUri.pop();
2038         Identity id = new Identity(identifier);
2039         id.setContext(context);
2040
2041         /*
2042          * Determine if it's an L2 or L3 EPR Op, and get the EP-specific objects
2043          */
2044
2045         if (convertedSubject.equals(ENDPOINT_RN)) {
2046             L2EprOperation l2eo = new L2EprOperation();
2047             l2eo.setContextId(new L2BridgeDomainId(context));
2048             l2eo.setMacAddress(new MacAddress(identifier));
2049
2050             op = l2eo;
2051         } else if (convertedSubject.equals(ENDPOINT_L3_RN)) {
2052             L3EprOperation l3eo = new L3EprOperation();
2053             l3eo.setContextId(new L3ContextId(context));
2054             Ipv4Address ipv4 = new Ipv4Address(identifier);
2055             l3eo.setIpAddress(new IpAddress(ipv4));
2056
2057             op = l3eo;
2058         }
2059
2060         return op;
2061     }
2062
2063     public static EprOperation getEprOpFromEpId(EndpointIdentity eid, String subject) {
2064         EprOperation op = null;
2065         Uri uri = eid.getContext();
2066         String rn = eid.getIdentifier();
2067
2068         PolicyUri convertedUri = genieUriToOdlUri(new PolicyUri(uri.getValue()));
2069         String convertedSubject = genieToOdlMap.get(subject);
2070
2071         /*
2072          * It's not clear if the identifier contains both of the keys for an EP
2073          * (e.g. context + MAC/IP), or if it's just the last identifier
2074          * (MAC/IP). From the description in the RFC, it seems to be just the
2075          * last identifer, so we'll start with that.
2076          */
2077         String context = convertedUri.pop();
2078         Identity id = new Identity(rn);
2079         id.setContext(context);
2080
2081         /*
2082          * Determine if it's an L2 or L3 EPR Op, and get the EP-specific objects
2083          */
2084
2085         if (convertedSubject.equals(ENDPOINT_RN)) {
2086             L2EprOperation l2eo = new L2EprOperation();
2087             l2eo.setContextId(new L2BridgeDomainId(context));
2088             l2eo.setMacAddress(new MacAddress(rn));
2089
2090             op = l2eo;
2091         } else if (convertedSubject.equals(ENDPOINT_L3_RN)) {
2092             L3EprOperation l3eo = new L3EprOperation();
2093             l3eo.setContextId(new L3ContextId(context));
2094             Ipv4Address ipv4 = new Ipv4Address(rn);
2095             l3eo.setIpAddress(new IpAddress(ipv4));
2096
2097             op = l3eo;
2098         }
2099
2100         return op;
2101     }
2102
2103     public static ManagedObject getMoFromEp(DataObject obj) {
2104         MacAddress mac = null;
2105         EndpointGroupId epgid = null;
2106         String context = null;
2107         String uuid = null;
2108         IpAddress ip = null;
2109         PolicyUri uri = new PolicyUri();
2110
2111         ManagedObject mo = new ManagedObject();
2112         String className = null;
2113         PolicyClassInfo pci = null;
2114         PolicyObjectInstance poi = null;
2115
2116         if (obj instanceof Endpoint) {
2117             Endpoint ep = (Endpoint) obj;
2118             epgid = ep.getEndpointGroup();
2119             mac = ep.getMacAddress();
2120             uuid = ep.getTenant().getValue();
2121             context = ep.getL2Context().getValue();
2122             className = GENIE_ENDPOINT_RN;
2123             pci = mit.getClass(className);
2124             poi = new PolicyObjectInstance(pci.getClassId());
2125             uri.push(GENIE_EPR_L2_ROOT);
2126             uri.push(GENIE_ENDPOINT_RN);
2127             uri.push(ep.getL2Context().getValue());
2128             uri.push(ep.getMacAddress().getValue());
2129             setParentFields(uri, poi, GENIE_ENDPOINT_RN, true);
2130         } else if (obj instanceof EndpointL3) {
2131             EndpointL3 ep = (EndpointL3) obj;
2132             epgid = ep.getEndpointGroup();
2133             mac = ep.getMacAddress();
2134             uuid = ep.getTenant().getValue();
2135             ip = ep.getIpAddress();
2136             context = ep.getL3Context().getValue();
2137             className = GENIE_ENDPOINT_L3_RN;
2138             pci = mit.getClass(className);
2139             poi = new PolicyObjectInstance(pci.getClassId());
2140             uri.push(GENIE_EPR_L3_ROOT);
2141             uri.push(GENIE_ENDPOINT_L3_RN);
2142             uri.push(ep.getL3Context().getValue());
2143             uri.push(ep.getIpAddress().getIpv4Address().getValue());
2144             setParentFields(uri, poi, GENIE_ENDPOINT_L3_RN, true);
2145         } else {
2146             return null;
2147         }
2148
2149         mo.setSubject(className);
2150
2151         List<PolicyPropertyInfo> ppil = pci.getProperties();
2152         if (ppil == null)
2153             return null;
2154
2155         /*
2156          * Set all the properties based on the EP
2157          */
2158         // TODO: add support for vector values
2159         for (PolicyPropertyInfo ppi : ppil) {
2160             switch (ppi.getPropName()) {
2161                 case GENIE_ENDPOINT_MAC:
2162                     poi.setMacAddress(ppi.getPropId(), mac);
2163                     break;
2164                 case GENIE_ENDPOINT_EPG:
2165                     poi.setString(ppi.getPropId(), epgid.getValue());
2166                     break;
2167                 case GENIE_ENDPOINT_CONTEXT:
2168                     poi.setString(ppi.getPropId(), context);
2169                     break;
2170                 case GENIE_ENDPOINT_IP:
2171                     // TODO: support v6
2172                     poi.setString(ppi.getPropId(), ip.toString());
2173                     break;
2174                 case GENIE_ENDPOINT_UUID:
2175                     poi.setString(ppi.getPropId(), uuid);
2176                     break;
2177                 default:
2178                     break;
2179
2180             }
2181         }
2182         lib.serializeMoProperties(pci, poi, mo, mit);
2183
2184         mo.setParent_uri(poi.getParent());
2185         mo.setParent_subject(poi.getParentSubject());
2186         mo.setParent_relation(poi.getParentRelation());
2187         mo.setSubject(GENIE_EPG_TO_NETWORK_DOMAIN_RN);
2188         mo.setUri(uri.getUri());
2189
2190         return mo;
2191     }
2192
2193     public static ManagedObject getMoFromOp(EprOperation op) {
2194         MacAddress mac = null;
2195         EndpointGroupId epgid = null;
2196         String context = null;
2197         // String uuid = null;
2198         IpAddress ip = null;
2199
2200         ManagedObject mo = new ManagedObject();
2201         String className = null;
2202         PolicyClassInfo pci = null;
2203         PolicyObjectInstance poi = null;
2204
2205         /*
2206          * The problem is that the op can return different types of things -
2207          * Endpoint, EndpointL3. I guess I need to return the individual pieces
2208          * from the op, and use those to construct the MO
2209          */
2210         if (op instanceof L2EprOperation) {
2211             L2EprOperation l2eo = (L2EprOperation) op;
2212             Endpoint ep = l2eo.getEp();
2213             if (ep == null)
2214                 return null;
2215             epgid = ep.getEndpointGroup();
2216             mac = ep.getMacAddress();
2217             context = ep.getL2Context().getValue();
2218             className = GENIE_ENDPOINT_RN;
2219
2220         } else if (op instanceof L3EprOperation) {
2221             L3EprOperation l3eo = (L3EprOperation) op;
2222             EndpointL3 ep = l3eo.getEp();
2223             if (ep == null)
2224                 return null;
2225
2226             epgid = ep.getEndpointGroup();
2227             mac = ep.getMacAddress();
2228             ip = ep.getIpAddress();
2229             context = ep.getL3Context().getValue();
2230             className = GENIE_ENDPOINT_L3_RN;
2231         }
2232         pci = mit.getClass(className);
2233         poi = new PolicyObjectInstance(pci.getClassId());
2234
2235         mo.setSubject(className);
2236
2237         List<PolicyPropertyInfo> ppil = pci.getProperties();
2238         if (ppil == null)
2239             return null;
2240
2241         /*
2242          * Set all the properties based on the EP
2243          */
2244         // TODO: add support for vector values
2245         for (PolicyPropertyInfo ppi : ppil) {
2246             switch (ppi.getPropName()) {
2247                 case GENIE_ENDPOINT_MAC:
2248                     poi.setMacAddress(ppi.getPropId(), mac);
2249                     break;
2250                 case GENIE_ENDPOINT_EPG:
2251                     poi.setString(ppi.getPropId(), epgid.getValue());
2252                     break;
2253                 case GENIE_ENDPOINT_CONTEXT:
2254                     poi.setString(ppi.getPropId(), context);
2255                     break;
2256                 case GENIE_ENDPOINT_IP:
2257                     // TODO: support v6
2258                     poi.setString(ppi.getPropId(), ip.toString());
2259                     break;
2260                 case GENIE_ENDPOINT_UUID:
2261                 default:
2262                     break;
2263
2264             }
2265         }
2266         lib.serializeMoProperties(pci, poi, mo, mit);
2267
2268         return mo;
2269     }
2270
2271     /**
2272      * Merge the contents of two {@link ManagedObject} objects that represent
2273      * the same MO. The contents of mo2 are merged into the contents of mo1
2274      *
2275      * @param mo1
2276      * @param mo2
2277      */
2278     public static void mergeMos(ManagedObject mo1, ManagedObject mo2) {
2279
2280         /*
2281          * Some sanity checks, to make sure we're dealing with the same MO
2282          */
2283         if (!mo1.getSubject().equals(mo2.getSubject()) || !mo1.getUri().getValue().equals(mo2.getUri().getValue())) {
2284             return;
2285         }
2286
2287         /*
2288          * The only things that need merging are the children URIs and the
2289          * properties.
2290          */
2291         List<Property> mo1Props = mo1.getProperties();
2292         List<Property> mo2Props = mo2.getProperties();
2293         if (mo2Props != null) {
2294             if (mo1Props == null) {
2295                 mo1.setProperties(mo2Props);
2296             } else {
2297                 for (Property prop : mo2Props) {
2298                     if (!mo1Props.contains(prop)) {
2299                         mo1Props.add(prop);
2300                     }
2301                 }
2302             }
2303         }
2304
2305         List<Uri> mo1Children = mo1.getChildren();
2306         List<Uri> mo2Children = mo2.getChildren();
2307         if (mo2Children != null) {
2308             if (mo1Children == null) {
2309                 mo1.setChildren(mo2Children);
2310             } else {
2311                 for (Uri child : mo2Children) {
2312                     if (!mo1Children.contains(child)) {
2313                         mo1Children.add(child);
2314                     }
2315                 }
2316             }
2317         }
2318     }
2319
2320 }