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