You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ch...@apache.org on 2013/10/08 15:38:35 UTC

[3/6] Contrail network virtualization plugin.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ModelObjectBase.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ModelObjectBase.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ModelObjectBase.java
new file mode 100644
index 0000000..9440937
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ModelObjectBase.java
@@ -0,0 +1,94 @@
+package net.juniper.contrail.model;
+
+import java.util.Comparator;
+import java.util.TreeSet;
+
+public abstract class ModelObjectBase implements ModelObject {
+    public static class UuidComparator implements Comparator<ModelObject> {
+        @Override
+        public int compare(ModelObject lhs, ModelObject rhs) {
+            if (lhs == null) {
+                if (rhs == null) {
+                    return 0;
+                }
+                return -1;
+            }
+            if (rhs == null) {
+                return 1;
+            }
+            return lhs.compareTo(rhs);
+        }
+    }
+    private TreeSet<ModelReference> _ancestors;
+    
+    private TreeSet<ModelObject> _successors;
+
+    ModelObjectBase() {
+        _ancestors = new TreeSet<ModelReference>();
+        _successors = new TreeSet<ModelObject>(new UuidComparator());
+    }
+    
+    @Override
+    public void addSuccessor(ModelObject child) {
+        _successors.add(child);
+        ModelObjectBase base = (ModelObjectBase) child;
+        base._ancestors.add(new ModelReference(this));
+    }
+    
+    @Override
+    public TreeSet<ModelReference> ancestors() {
+        return _ancestors;
+    }
+    
+    private void clearAncestorReference(ModelObjectBase child) {
+        ModelReference ref = null;
+        for (ModelReference objref : child._ancestors) {
+            if (objref.get() == this) {
+                ref = objref;
+                break;
+            }
+        }
+        if (ref != null) {
+            child._ancestors.remove(ref);
+        }
+    }
+    
+    @Override
+    public void clearSuccessors() {
+        for (ModelObject successor : _successors) {
+            clearAncestorReference((ModelObjectBase) successor);
+        }
+        _successors.clear();
+    }
+
+    @Override
+    public boolean equals(Object rhs) {
+        ModelObject other;
+        try {
+            other = (ModelObject) rhs;
+        } catch (ClassCastException ex) {
+            return false;
+        }
+        return compareTo(other) == 0;
+    }
+    
+    @Override
+    protected void finalize() {
+        clearSuccessors();
+    }
+
+    public boolean hasDescendents() {
+        return !successors().isEmpty();
+    }
+    
+    @Override
+    public void removeSuccessor(ModelObject child) {
+        clearAncestorReference((ModelObjectBase) child);
+        _successors.remove(child);
+    }
+
+    @Override
+    public TreeSet<ModelObject> successors() {
+        return _successors;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ServiceInstanceModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ServiceInstanceModel.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ServiceInstanceModel.java
new file mode 100644
index 0000000..b70663e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/ServiceInstanceModel.java
@@ -0,0 +1,303 @@
+package net.juniper.contrail.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.NetworkPolicy;
+import net.juniper.contrail.api.types.PolicyEntriesType;
+import net.juniper.contrail.api.types.PolicyEntriesType.PolicyRuleType;
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.ServiceInstanceType;
+import net.juniper.contrail.api.types.ServiceTemplate;
+import net.juniper.contrail.api.types.ServiceTemplateType;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VirtualNetworkPolicyType;
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.management.ContrailManager;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class ServiceInstanceModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(ServiceInstanceModel.class);
+
+    private String _uuid;
+    private String _fq_name;
+    private String _projectId;
+    private String _mgmtName;
+    private String _leftName;
+    private String _rightName;
+   
+    private String _templateName;
+    private String _templateId;
+    private String _templateUrl;
+    private VirtualNetwork _left;
+    private VirtualNetwork _right;
+    private ServiceTemplate _tmpl;
+    private ServiceInstance _serviceInstance;
+    private NetworkPolicy _policy;
+
+    /**
+     * Create a ServiceInstance as result of an API call.
+     * 
+     * @param owner
+     * @param name
+     * @param template
+     * @param serviceOffering
+     * @param left
+     * @param right
+     */
+    public ServiceInstanceModel(Project project, String name, VirtualMachineTemplate template,
+            ServiceOffering serviceOffering, VirtualNetwork left, VirtualNetwork right) {
+        String parent_name;
+        if (project != null) {
+            parent_name = StringUtils.join(project.getQualifiedName(), ':');
+        } else {
+            parent_name = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT;
+        }
+        _fq_name = parent_name + ":" + name;
+        
+        _mgmtName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT + ":"
+                + ContrailManager.managementNetworkName;
+        _left = left;
+        _right = right;
+        _leftName = StringUtils.join(left.getQualifiedName(), ":");
+        _rightName = StringUtils.join(right.getQualifiedName(), ":");
+        
+        _templateName = template.getName();
+        _templateId = template.getUuid();
+        _templateUrl = template.getUrl();
+        
+        _projectId = project.getUuid();
+    }
+
+    /**
+     * Create an empty ServiceInstance.
+     * @param uuid
+     */
+    public ServiceInstanceModel(String uuid) {
+        _uuid  = uuid;
+    }
+    
+    public String getQualifiedName() {
+        return _fq_name;
+    }
+    
+    public String getName() {
+        return _fq_name.substring(_fq_name.lastIndexOf(':') + 1);
+    }
+    
+    private void applyNetworkPolicy(ModelController controller, NetworkPolicy policy,
+            VirtualNetwork left, VirtualNetwork right) {
+        left.setNetworkPolicy(policy, new VirtualNetworkPolicyType(
+                new VirtualNetworkPolicyType.SequenceType(1, 0), null));
+        // TODO: network_ipam_refs attr is missing
+        left.clearNetworkIpam();
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.update(left);
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to update virtual-network", ex);
+        }
+        
+        right.setNetworkPolicy(policy, new VirtualNetworkPolicyType(
+                new VirtualNetworkPolicyType.SequenceType(1, 0), null));
+        // TODO: network_ipam_refs attr is missing
+        right.clearNetworkIpam();
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.update(right);
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to update virtual-network", ex);
+        }
+    }
+
+    /**
+     * Recreate the model object from the Contrail API which is the master for this type of object.
+     * @param siObj
+     */
+    public void build(ModelController controller, ServiceInstance siObj) {
+        ApiConnector api = controller.getApiAccessor();
+        _serviceInstance = siObj;
+        _fq_name = StringUtils.join(siObj.getQualifiedName(), ':');
+        ServiceInstanceType props = siObj.getProperties();
+        // TODO: read management network names and cache network objects.
+        ObjectReference ref = siObj.getServiceTemplate().get(0);
+        if (ref != null) {
+            try {
+                ServiceTemplate tmpl = (ServiceTemplate) api.findById(ServiceTemplate.class, ref.getUuid());
+                _templateId = tmpl.getUuid();
+            } catch (IOException ex) {
+                s_logger.warn("service-template read", ex);
+            }
+        }
+        try {
+            Project project = (Project) api.findById(Project.class, siObj.getParentUuid());
+            if (project != null) {
+                _projectId = project.getUuid();
+            }
+            String policyId = api.findByName(NetworkPolicy.class, project, siObj.getName());
+            if (policyId != null) {
+                _policy = (NetworkPolicy) api.findById(NetworkPolicy.class, policyId);
+            }
+        } catch (IOException ex) {
+            s_logger.warn("network-policy read", ex);
+        }
+    }
+    
+    @Override
+    public int compareTo(ModelObject o) {
+        ServiceInstanceModel other;
+        try {
+            other = (ServiceInstanceModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return ServiceInstanceModel.class.getName().compareTo(clsname);
+        }
+        return _fq_name.compareTo(other._fq_name);
+    }
+    
+    private ServiceInstance createServiceInstance(ModelController controller) {
+        Project project  = null;
+        if (_projectId != null) {
+            try {
+                ApiConnector api = controller.getApiAccessor();
+                project = (Project) api.findById(Project.class, _projectId);
+           } catch (IOException ex) {
+                s_logger.warn("project read", ex);
+                throw new CloudRuntimeException("Unable to create service-instance object", ex);            
+           }
+        }
+
+        ServiceInstance si_obj = new ServiceInstance();
+        if (project != null) {
+            si_obj.setParent(project);
+        }
+        si_obj.setName(getName());
+        si_obj.setServiceTemplate(_tmpl);
+        si_obj.setProperties(new ServiceInstanceType(false, _mgmtName, _leftName, null, _rightName, null,
+                new ServiceInstanceType.ServiceScaleOutType(1, false)));
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.create(si_obj);
+        } catch (IOException ex) {
+            s_logger.warn("service-instance create", ex);
+            throw new CloudRuntimeException("Unable to create service-instance object", ex);
+        }
+        
+        return si_obj;
+    }
+    
+    private NetworkPolicy createServicePolicy(ModelController controller) {
+        NetworkPolicy policy = new NetworkPolicy();
+        policy.setParent(_serviceInstance.getParent());
+        policy.setName(_serviceInstance.getName());
+        PolicyEntriesType policy_map = new PolicyEntriesType();
+        List<PolicyRuleType.AddressType> srcList = new ArrayList<PolicyRuleType.AddressType>();
+        srcList.add(new PolicyRuleType.AddressType(null, _leftName, null));
+        List<PolicyRuleType.AddressType> dstList = new ArrayList<PolicyRuleType.AddressType>();
+        dstList.add(new PolicyRuleType.AddressType(null, _rightName, null));
+        List<String> siList = new ArrayList<String>();
+        siList.add(StringUtils.join(_serviceInstance.getQualifiedName(), ':'));
+        List<PolicyRuleType.PortType> portAny = new ArrayList<PolicyRuleType.PortType>();
+        portAny.add(new PolicyRuleType.PortType(0, 65535));
+        
+        PolicyRuleType rule = new PolicyRuleType(
+                new PolicyRuleType.SequenceType(1, 0), /* uuid */ null, "<>", null, "any",
+                srcList, portAny, /* application */ null, dstList, portAny,
+                new PolicyRuleType.ActionListType("pass", "in-network", siList, null));
+        policy_map.addPolicyRule(rule);
+        policy.setEntries(policy_map);
+        
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            if (!api.create(policy)) {
+                throw new CloudRuntimeException("Unable to create network-policy");
+            }
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to create network-policy", ex);
+        }
+        return policy;
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        if (_serviceInstance != null) {
+            api.delete(_serviceInstance);
+        }
+    }
+    
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+    }
+    
+    public ServiceInstance getServiceInstance() {
+        return _serviceInstance;
+    }
+
+    public String getUuid() {
+        return _uuid;
+    }
+    
+    private ServiceTemplate locateServiceTemplate(ModelController controller) {
+        ServiceTemplate tmpl;
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            tmpl = (ServiceTemplate) api.findById(ServiceTemplate.class, _templateId);
+        } catch (IOException ex) {
+            s_logger.warn("service-template read", ex);
+            throw new CloudRuntimeException("Unable to create service-template object", ex);
+        }
+        if (tmpl == null) {
+            tmpl = new ServiceTemplate();
+            tmpl.setName(_templateName);
+            tmpl.setUuid(_templateId);
+            ServiceTemplateType props = new ServiceTemplateType("in-network", null, _templateUrl, false, null);
+            tmpl.setProperties(props);
+            try {
+                ApiConnector api = controller.getApiAccessor();
+                api.create(tmpl);
+            } catch (IOException ex) {
+                throw new CloudRuntimeException("Unable to create service-template object", ex);
+            }
+        }
+        return tmpl;
+    }
+
+    @Override
+    public void update(ModelController controller) {
+        _tmpl = locateServiceTemplate(controller);
+        if (_serviceInstance == null) {
+            _serviceInstance = createServiceInstance(controller);
+        }
+        _uuid = _serviceInstance.getUuid();
+        if (_policy == null) {
+            _policy = createServicePolicy(controller);
+            // TODO: update the network model objects and call update
+            applyNetworkPolicy(controller, _policy, _left, _right);
+        }
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VMInterfaceModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VMInterfaceModel.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VMInterfaceModel.java
new file mode 100644
index 0000000..1ac0840
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VMInterfaceModel.java
@@ -0,0 +1,248 @@
+package net.juniper.contrail.model;
+
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+
+import net.juniper.contrail.api.types.MacAddressesType;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.VirtualMachineInterfacePropertiesType;
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.management.ContrailManager;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Network;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+
+public class VMInterfaceModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VMInterfaceModel.class);
+
+    private String _uuid;
+    
+    /**
+     * properties
+     */
+    private String _vmName;
+    private int _deviceId;
+    private boolean _netActive;
+    private boolean _nicActive;
+    private String _serviceTag;
+    private String _networkId;
+    private String _macAddress;
+
+    /**
+     * cached objects
+     */
+    private VirtualMachineModel _vmModel;
+    private VirtualNetworkModel _vnModel;
+    private VirtualMachineInterface _vmi;
+    
+    public VMInterfaceModel(String uuid) {
+        _uuid = uuid;
+    }
+    
+    public void addToVirtualMachine(VirtualMachineModel vmModel) {
+        _vmModel = vmModel;
+        if (vmModel != null) {
+            vmModel.addSuccessor(this);
+        }
+    }
+    
+    public void addToVirtualNetwork(VirtualNetworkModel vnModel) {
+        _vnModel = vnModel;
+        if (vnModel != null) {
+            vnModel.addSuccessor(this);
+        }
+    }
+    
+    public void build(ModelController controller, VMInstanceVO instance, NicVO nic) throws IOException {
+        setProperties(controller, instance, nic);
+
+        InstanceIpModel ipModel = getInstanceIp();
+        String ipAddress = nic.getIp4Address();
+        if (ipAddress != null) {
+            if (ipModel == null) {
+                ipModel = new InstanceIpModel(_vmName, _deviceId);
+                ipModel.addToVMInterface(this);
+            }
+            ipModel.setAddress(ipAddress);
+        } else if (ipModel != null) {
+            removeSuccessor(ipModel);
+        }
+        
+        _macAddress = nic.getMacAddress();
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        VMInterfaceModel other;
+        try {
+            other = (VMInterfaceModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VMInterfaceModel.class.getName().compareTo(clsname);
+        }
+        return _uuid.compareTo(other._uuid);
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+
+        ApiConnector api = controller.getApiAccessor();
+        api.delete(VirtualMachineInterface.class, _uuid);        
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+        
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+    
+    public InstanceIpModel getInstanceIp() {
+        for (ModelObject successor : successors()) {
+            if (successor.getClass() == InstanceIpModel.class) {
+                return (InstanceIpModel) successor;
+            }
+        }
+        return null;
+    }
+    
+    public String getNetworkUuid() {
+        return _networkId;
+    }
+    
+    public VirtualNetworkModel getVirtualNetworkModel() {
+        return _vnModel;
+    }
+    
+    public String getUuid() {
+        return _uuid;
+    }
+    
+    public VirtualMachineInterface getVMInterface() {
+        return _vmi;
+    }
+    
+    public void setProperties(ModelController controller, VMInstanceVO instance, NicVO nic) throws IOException {
+        _vmName = instance.getInstanceName();
+        _deviceId = nic.getDeviceId();
+        Network network = controller.getNetworkDao().findById(nic.getNetworkId());
+
+        switch (nic.getState()) {
+        case Allocated:
+        case Reserved:
+            _nicActive = true;
+            break;
+        default:
+            _nicActive = false;
+            break;
+        }
+        
+        switch (network.getState()) {
+        case Implemented:
+        case Setup:
+            _netActive = true;
+            break;
+        default:
+            _netActive = false;
+            break;
+        }
+        assert _vnModel != null;
+        _networkId = _vnModel.getUuid();        
+    }
+    
+    public void setActive() {
+        _nicActive = true;
+    }
+    
+    void setServiceTag(String tag) {
+        _serviceTag = tag;
+    }
+    
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+        if (!_netActive || !_nicActive) {
+            s_logger.debug("vm interface update, _netActive: " + _netActive + ", _nicActive: " + _nicActive);
+            delete(controller);
+            return;
+        }
+        if (_vmModel == null) {
+            throw new InternalErrorException("virtual-machine not set on VMI: " + _uuid);
+        }
+        if (_vnModel == null) {
+            throw new InternalErrorException("virtual-network not set on VMI: " + _uuid);
+        }
+        ContrailManager manager = controller.getManager();
+        ApiConnector api = controller.getApiAccessor();
+
+        VirtualMachineInterface vmi = (VirtualMachineInterface) api.findById(VirtualMachineInterface.class, _uuid);
+        boolean create = false;
+        if (vmi == null) {
+            create = true;
+            vmi = new VirtualMachineInterface();
+            vmi.setParent(_vmModel.getVirtualMachine());
+            vmi.setName(manager.getVifNameByVmName(_vmModel.getInstanceName(), _deviceId));
+            vmi.setUuid(_uuid);
+            vmi.setVirtualNetwork(_vnModel.getVirtualNetwork());
+        } else {
+            // Do not try to update VMI to routing-instance references. These are managed by schema-transformer.
+            vmi.clearRoutingInstance();
+        }
+        _vmi = vmi;
+        if (_macAddress != null) {
+            MacAddressesType mac = new MacAddressesType();
+            mac.addMacAddress(_macAddress);
+            vmi.setMacAddresses(mac);
+        }
+        
+        if (_serviceTag != null) {
+            vmi.setProperties(new VirtualMachineInterfacePropertiesType(_serviceTag, null));
+        }
+
+        if (create) {
+            if (!api.create(vmi)) {
+                throw new InternalErrorException("Unable to create virtual-machine-interface " +  _uuid);
+            }
+        } else {
+            if (!api.update(vmi)) {
+                throw new InternalErrorException("Unable to update virtual-machine-interface " +  _uuid);
+            }
+        }
+
+        api.read(vmi);
+        
+        int ipCount = 0;
+        for (ModelObject successor: successors()) {
+            if (successor.getClass() == InstanceIpModel.class) {
+                ipCount++;
+            }
+            successor.update(controller);
+        }
+        // TODO: if there are no instance-ip successors present and we have an instance-ip object reference
+        // delete the object.
+        if (ipCount == 0) {
+            s_logger.warn("virtual-machine-interface " + _uuid + " has no instance-ip");
+        }
+    }
+    
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualMachineModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualMachineModel.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualMachineModel.java
new file mode 100644
index 0000000..591eac3
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualMachineModel.java
@@ -0,0 +1,332 @@
+package net.juniper.contrail.model;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.NicDao;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.VirtualMachine;
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.management.ContrailManager;
+
+public class VirtualMachineModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VirtualMachineModel.class);
+
+    private String _uuid;
+    private long _instanceId;
+    
+    /*
+     * current state for object properties 
+     */
+    private boolean _initialized;
+    private boolean _active;
+    private String _serviceUuid;
+    private String _instanceName;
+    private String _projectId;
+    
+    /*
+     * cached API server objects
+     */
+    private VirtualMachine _vm;
+    private ServiceInstanceModel _serviceModel;
+    
+    public VirtualMachineModel(VMInstanceVO vm, String uuid) {
+        _uuid = uuid;
+        if (vm != null) {
+            _instanceId = vm.getId();
+            _instanceName = vm.getInstanceName();
+        }
+    }
+    
+    /**
+     * Resynchronize internal state from the cloudstack DB object.
+     * @param instance
+     */
+    public void build(ModelController controller, VMInstanceVO instance) {
+        setProperties(controller, instance);
+        UserVm userVm = controller.getVmDao().findById(instance.getId());
+        if (userVm != null && userVm.getUserData() != null) {
+            s_logger.debug("vm " + instance.getInstanceName() + " user data: " + userVm.getUserData());
+            final Gson json = new Gson();
+            Map<String, String> kvmap = json.fromJson(userVm.getUserData(),
+                    new TypeToken<Map<String, String>>(){}.getType());
+            String data = kvmap.get("service-instance");
+            if (data != null) {
+                /* link the object with the service instance */
+                buildServiceInstance(controller, data);
+            }
+        }
+    }
+
+    /**
+     * Link the virtual machine with the service instance when recovering state from database.
+     * 
+     * @param controller
+     * @param serviceUuid
+     */
+    private void buildServiceInstance(ModelController controller, String serviceUuid) {
+        ContrailManager manager = controller.getManager();
+        ApiConnector api = controller.getApiAccessor();
+        _serviceUuid = serviceUuid;
+        
+        ServiceInstanceModel siModel = manager.getDatabase().lookupServiceInstance(serviceUuid);
+        if (siModel == null) {
+            ServiceInstance siObj;
+            try {
+                siObj = (ServiceInstance) api.findById(ServiceInstance.class, serviceUuid);
+            } catch (IOException ex) {
+                s_logger.warn("service-instance read", ex);
+                throw new CloudRuntimeException("Unable to read service-instance object", ex);
+            }
+            if (siObj == null) {
+                siModel = new ServiceInstanceModel(serviceUuid);
+                siModel.build(controller, siObj);
+            }
+        }
+        _serviceModel = siModel;
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        VirtualMachineModel other;
+        try {
+            other = (VirtualMachineModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VirtualMachineModel.class.getName().compareTo(clsname);
+        }
+        return _uuid.compareTo(other._uuid);
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+        
+        try {
+            api.delete(VirtualMachine.class, _uuid);
+        } catch (IOException ex) {
+            s_logger.warn("virtual-machine delete", ex);
+        }
+
+
+        if (_serviceModel != null) {
+            _serviceModel.delete(controller);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+
+        clearSuccessors();
+        
+        if (_serviceModel != null) {
+            _serviceModel.removeSuccessor(this);
+            _serviceModel.destroy(controller);
+            ContrailManager manager = controller.getManager();
+            manager.getDatabase().getServiceInstances().remove(_serviceModel);
+            _serviceModel = null;
+        }
+    }
+
+    public String getInstanceName() {
+        return _instanceName;
+    }
+    
+    public String getUuid() {
+        return _uuid;
+    }
+
+    
+    public VirtualMachine getVirtualMachine() {
+        return _vm;
+    }
+    
+    public VMInterfaceModel getVMInterface(String uuid) {
+        TreeSet<ModelObject> tree = successors();
+        VMInterfaceModel vmiKey = new VMInterfaceModel(uuid);
+        VMInterfaceModel current = (VMInterfaceModel) tree.ceiling(vmiKey);
+        if (current != null && current.getUuid().equals(uuid)) {
+            return current;
+        }
+        return null;
+    }
+    
+    public boolean isActive() {
+        return _active;
+    }
+    
+    boolean isActiveInstance(VMInstanceVO instance) {
+        switch (instance.getState()) {
+        case Migrating:
+        case Starting:
+        case Running:
+        case Shutdowned:
+        case Stopped:
+        case Stopping:
+            return true;
+            
+        case Destroyed:
+        case Error:
+        case Expunging:
+            return false;
+            
+        default:
+            s_logger.warn("Unknown VMInstance state " + instance.getState().getDescription());
+        }
+        return true;
+    }
+    
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller, VMInstanceVO instance) {
+        ContrailManager manager = controller.getManager();
+        _instanceName = instance.getInstanceName();
+        _active = isActiveInstance(instance);
+        
+        try {
+            _projectId = manager.getProjectId(instance.getDomainId(), instance.getAccountId());
+        } catch (IOException ex) {
+            s_logger.warn("project read", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        _initialized = true;
+    }
+
+    /**
+     * Link the virtual machine with a service instance via programmatic API call.
+     * @throws IOException 
+     */
+    public void setServiceInstance(ModelController controller, VMInstanceVO instance,
+            ServiceInstanceModel serviceModel) throws IOException {
+        _serviceUuid = serviceModel.getUuid();
+        _serviceModel = serviceModel;
+        serviceModel.addSuccessor(this);
+        setServiceInstanceNics(controller, instance);
+    }
+    
+    private void setServiceInstanceNics(ModelController controller, VMInstanceVO instance) throws IOException {
+        NicDao nicDao = controller.getNicDao();
+        ContrailManager manager = controller.getManager();
+        NetworkDao networkDao = controller.getNetworkDao();
+        
+        List<NicVO> nics = nicDao.listByVmId(_instanceId);
+        for (NicVO nic : nics) {
+            String tag;
+            
+            switch (nic.getDeviceId()) {
+            case 0:
+                tag = "management";
+                break;
+            case 1:
+                tag = "left";
+                break;
+            case 2:
+                tag = "right";
+                break;
+            default:
+                tag = null;
+            }
+
+            VMInterfaceModel vmiModel = getVMInterface(nic.getUuid());
+            if (vmiModel == null) {
+                vmiModel = new VMInterfaceModel(nic.getUuid());
+                vmiModel.addToVirtualMachine(this);
+                NetworkVO network = networkDao.findById(nic.getNetworkId());
+                VirtualNetworkModel vnModel = manager.getDatabase().lookupVirtualNetwork(
+                        network.getUuid(), manager.getCanonicalName(network), network.getTrafficType());
+                assert vnModel != null;
+                vmiModel.addToVirtualNetwork(vnModel);
+            }
+            vmiModel.setProperties(controller, instance, nic);
+            vmiModel.setServiceTag(tag);
+        }
+    }
+    
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+        assert _initialized;
+        ApiConnector api = controller.getApiAccessor();
+
+        VirtualMachine vm = _vm;
+        if (vm == null) {
+            _vm = vm = (VirtualMachine) api.findById(VirtualMachine.class, _uuid);
+            if (vm == null) {
+                vm = new VirtualMachine();
+                if (_projectId != null) {
+                    Project project;
+                    try {
+                        project = (Project) api.findById(Project.class, _projectId);
+                    } catch (IOException ex) {
+                        s_logger.debug("project read", ex);
+                        throw new CloudRuntimeException("Failed to read project", ex);                    
+                    }
+                    vm.setParent(project);
+                }
+                vm.setName(_instanceName);
+                vm.setUuid(_uuid);
+            }
+        }
+
+        if (_serviceModel != null) { 
+            vm.setServiceInstance(_serviceModel.getServiceInstance());
+        }
+
+        if (_vm == null) {
+            try {
+                api.create(vm);
+            } catch (Exception ex) {
+                s_logger.debug("virtual-machine create", ex);
+                throw new CloudRuntimeException("Failed to create virtual-machine", ex);
+            }
+            _vm = vm;
+        } else {
+            try {
+                api.update(vm);
+            } catch (IOException ex) {
+                s_logger.warn("virtual-machine update", ex);
+                throw new CloudRuntimeException("Unable to update virtual-machine object", ex);
+            }            
+        }
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+    
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualNetworkModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualNetworkModel.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualNetworkModel.java
new file mode 100644
index 0000000..5e5b299
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/model/VirtualNetworkModel.java
@@ -0,0 +1,477 @@
+package net.juniper.contrail.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.NetworkIpam;
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.SubnetType;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VnSubnetsType;
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.management.ContrailManager;
+
+public class VirtualNetworkModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VirtualNetworkModel.class);
+
+    private String _uuid;
+    private long _id;
+    private TrafficType _trafficType; 
+
+    /*
+     * current state for object properties 
+     */
+    private boolean _initialized;
+    private String _name;
+    private String _prefix;
+    private String _gateway;
+    private String _projectId;
+
+    /*
+     * cached API server objects
+     */
+    private VirtualNetwork _vn;
+    private NetworkIpam _ipam;
+
+    private FloatingIpPoolModel _fipPoolModel;
+
+    public VirtualNetworkModel(Network network, String uuid, String name, TrafficType trafficType) {
+        _uuid = uuid;
+        _name = name;
+        _trafficType = trafficType;
+        if (network != null) {
+            _id = network.getId();
+        }
+
+        if (isDynamicNetwork()) {
+            assert _uuid != null : "uuid is must for dynamic networks";
+        } else {
+            assert _name != null : "name is must for static networks";
+        }
+    }
+
+    /*
+     * Resynchronize internal state from the cloudstack DB object.
+     */
+    public void build(ModelController controller, Network network) {
+        setProperties(controller, network);
+    }
+
+    /**
+     * Determine whether this network is dynamically created by cloudstack or is created by default by the contrail
+     * API server.
+     * 
+     * @return
+     */
+    boolean isDynamicNetwork() {
+        return (_trafficType == TrafficType.Guest) || (_trafficType == TrafficType.Public);
+    }
+    
+    @Override
+    public int compareTo(ModelObject o) {
+        VirtualNetworkModel other;
+        try {
+            other = (VirtualNetworkModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VirtualNetworkModel.class.getName().compareTo(clsname);
+        }
+        
+        if (!isDynamicNetwork()) {
+            if (!other.isDynamicNetwork()) {
+                // name is not unique since both management and storage networks may map to ip-fabric
+                int cmp = _name.compareTo(other.getName());
+                if (cmp != 0) {
+                    return cmp;
+                }
+                return _trafficType.compareTo(other._trafficType);
+            }
+            return -1;
+        } else if (!other.isDynamicNetwork()) {
+            return 1;
+        }
+                
+        return _uuid.compareTo(other._uuid);
+    }
+
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+
+        try {
+            api.delete(VirtualNetwork.class, _uuid);
+        } catch (IOException ex) {
+            s_logger.warn("virtual-network delete", ex);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public String getUuid() {
+        return _uuid;
+    }
+
+
+    public VirtualNetwork getVirtualNetwork() {
+        return _vn;
+    }
+
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller, Network network) {
+        ContrailManager manager = controller.getManager();
+        _name = manager.getCanonicalName(network);
+        _prefix = network.getCidr();
+        _gateway = network.getGateway();
+        
+        // For non-cloudstack managed network, find the uuid at this stage.
+        if (!isDynamicNetwork()) {
+            try {
+                _uuid = manager.findVirtualNetworkId(network);
+            } catch (IOException ex) {
+                s_logger.warn("Unable to read virtual-network", ex);
+            }
+        }
+        
+        try {
+            _projectId = manager.getProjectId(network.getDomainId(), network.getAccountId());
+        } catch (IOException ex) {
+            s_logger.warn("project read", ex);
+            throw new CloudRuntimeException(ex);
+        }
+      
+        _initialized = true;
+    }
+
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+
+        assert _initialized;
+
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+        VirtualNetwork vn = _vn;
+        
+        if (!isDynamicNetwork()) {
+            _vn = (VirtualNetwork) controller.getApiAccessor().findById(VirtualNetwork.class, _uuid);
+            return;
+        }
+        
+        assert _uuid != null : "uuid is not set";
+
+        if (_vn == null) {
+            vn = _vn = (VirtualNetwork) controller.getApiAccessor().findById(VirtualNetwork.class, _uuid);
+            if (vn == null) {
+                vn = new VirtualNetwork();
+                if (_projectId != null) {
+                    Project project;
+                    try {
+                        project = (Project) api.findById(Project.class, _projectId);
+                    } catch (IOException ex) {
+                        s_logger.debug("project read", ex);
+                        throw new CloudRuntimeException("Failed to read project", ex);                    
+                    }
+                    vn.setParent(project);
+                }
+                vn.setName(_name);
+                vn.setUuid(_uuid);
+            } 
+        }
+     
+        if (_ipam == null) {
+            NetworkIpam ipam = null;
+            try {
+                String ipam_id = api.findByName(NetworkIpam.class, null, "default-network-ipam");
+                if (ipam_id == null) {
+                    s_logger.debug("could not find default-network-ipam");
+                    return;
+                }
+                ipam = (NetworkIpam) api.findById(NetworkIpam.class, ipam_id);
+                if (ipam == null) {
+                    s_logger.debug("could not find NetworkIpam with ipam_id: " + ipam_id);
+                    return;
+                }
+            } catch (IOException ex) {
+                s_logger.error(ex);
+                return;
+            }
+            _ipam = ipam;
+        }
+
+        if (_prefix != null) {
+            VnSubnetsType subnet = new VnSubnetsType();
+            String[] addr_pair = _prefix.split("\\/");
+            subnet.addIpamSubnets(new SubnetType(addr_pair[0], Integer.parseInt(addr_pair[1])), _gateway);
+            vn.setNetworkIpam(_ipam, subnet);
+        } else if (_trafficType == TrafficType.Public) {
+            vn.clearNetworkIpam();
+            /* Subnet information for Public is stored in the vlan table */
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan : vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                int slash = cidr.indexOf('/');
+                String ip_addr = cidr.substring(0, slash);
+                int plen = Integer.parseInt(cidr.substring(slash + 1));
+                VnSubnetsType subnet = new VnSubnetsType();
+                subnet.addIpamSubnets(new SubnetType(ip_addr, plen), vlan.getVlanGateway());
+                vn.addNetworkIpam(_ipam, subnet);
+            }
+        } 
+
+        if (_vn == null) {
+            try {
+                api.create(vn);
+            } catch (Exception ex) {
+                s_logger.debug("virtual-network create", ex);
+                throw new CloudRuntimeException("Failed to create virtual-network", ex);
+            }
+            _vn = vn;
+        } else {
+            try {
+                api.update(vn);
+            } catch (IOException ex) {
+                s_logger.warn("virtual-network update", ex);
+                throw new CloudRuntimeException("Unable to update virtual-network object", ex);
+            }            
+        }
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+
+    public void read(ModelController controller) {
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+        try {
+            _vn = (VirtualNetwork) api.findById(VirtualNetwork.class, _uuid);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (_vn == null) {
+            return;
+        }
+        if (_ipam == null) {
+            NetworkIpam ipam = null;
+            try {
+                String ipam_id = api.findByName(NetworkIpam.class, null, "default-network-ipam");
+                if (ipam_id == null) {
+                    s_logger.debug("could not find default-network-ipam");
+                    return;
+                }
+                ipam = (NetworkIpam) api.findById(NetworkIpam.class, ipam_id);
+                if (ipam == null) {
+                    s_logger.debug("could not find NetworkIpam with ipam_id: " + ipam_id);
+                    return;
+                }
+            } catch (IOException ex) {
+                s_logger.error(ex);
+                return;
+            }
+            _ipam = ipam;
+        }
+
+        if (_prefix != null) {
+            VnSubnetsType subnet = new VnSubnetsType();
+            String[] addr_pair = _prefix.split("\\/");
+            subnet.addIpamSubnets(new SubnetType(addr_pair[0], Integer.parseInt(addr_pair[1])), _gateway);
+            _vn.setNetworkIpam(_ipam, subnet);
+        } else if (_trafficType == TrafficType.Public) {
+            _vn.clearNetworkIpam();
+            /* Subnet information for Public is stored in the vlan table */
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan : vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                int slash = cidr.indexOf('/');
+                String ip_addr = cidr.substring(0, slash);
+                int plen = Integer.parseInt(cidr.substring(slash + 1));
+                VnSubnetsType subnet = new VnSubnetsType();
+                subnet.addIpamSubnets(new SubnetType(ip_addr, plen), vlan.getVlanGateway());
+                _vn.addNetworkIpam(_ipam, subnet);
+            }
+        } 
+        return;
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        assert _initialized : "initialized is false";
+        assert _uuid != null : "uuid is not set";
+
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+
+        try {
+            _vn = (VirtualNetwork) api.findById(VirtualNetwork.class, _uuid);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (_vn == null) {
+            return false;
+        }
+
+        if (!isDynamicNetwork()) {
+            return true;
+        }
+        
+        List<String> dbSubnets = new ArrayList<String>();
+        if (_trafficType == TrafficType.Public) {
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan:vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                dbSubnets.add(vlan.getVlanGateway() + cidr);
+            }
+        } else {
+            dbSubnets.add(this._gateway + this._prefix);  
+        }
+            
+        List<ObjectReference<VnSubnetsType>> ipamRefs = _vn.getNetworkIpam();
+        List<String> vncSubnets = new ArrayList<String>();
+        
+        if (ipamRefs == null && !dbSubnets.isEmpty()) {
+            return false;
+        }
+        
+        if (ipamRefs != null) {
+            for (ObjectReference<VnSubnetsType> ref: ipamRefs) {
+                VnSubnetsType vnSubnetType = ref.getAttr();
+                if (vnSubnetType != null) {
+                    List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                    if (subnets != null && !subnets.isEmpty()) {
+                        VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                        vncSubnets.add(ipamSubnet.getDefaultGateway() +
+                                ipamSubnet.getSubnet().getIpPrefix() +"/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                    }  
+                } 
+            }
+        }
+        // unordered, no duplicates hence perform negation operation as set 
+        Set<String> diff = new HashSet<String>(dbSubnets);
+        diff.removeAll(vncSubnets);
+        
+        if (!diff.isEmpty()) {
+            s_logger.debug("Subnets changed, network: " + this._name + 
+                    "; db: " + dbSubnets + ", vnc: " + vncSubnets + ", diff: " + diff);
+            return false;
+        }
+        
+        for (ModelObject successor: successors()) {
+            if (!successor.verify(controller)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject o) {
+        VirtualNetworkModel latest;
+        ApiConnector api = controller.getApiAccessor();
+
+        assert this._vn != null : "vnc virtual network current is not initialized";
+
+        try {
+            latest = (VirtualNetworkModel) o;            
+        } catch (ClassCastException ex) {
+            s_logger.warn("Invalid model object is passed to cast to VirtualNetworkModel");
+            return false;
+        }
+        
+        try {
+            latest.read(controller);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+        assert latest._vn != null : "vnc virtual network new is not initialized";
+        
+        List<ObjectReference<VnSubnetsType>> currentIpamRefs = this._vn.getNetworkIpam();
+        List<ObjectReference<VnSubnetsType>> newIpamRefs = latest._vn.getNetworkIpam();
+        List<String> currentSubnets = new ArrayList<String>();
+        List<String> newSubnets = new ArrayList<String>();
+
+        
+        if ((currentIpamRefs == null && newIpamRefs != null) || 
+            (currentIpamRefs != null && newIpamRefs == null)) {  //Check for existence only
+            s_logger.debug("ipams differ: current=" + currentIpamRefs + ", new=" + newIpamRefs);
+            return false;
+        }        
+        if (currentIpamRefs == null) {
+            return true;
+        }
+        
+        for (ObjectReference<VnSubnetsType> ref: currentIpamRefs) {
+            VnSubnetsType vnSubnetType = ref.getAttr();
+            if (vnSubnetType != null) {
+                List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                if (subnets != null && !subnets.isEmpty()) {
+                    VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                    currentSubnets.add(ipamSubnet.getDefaultGateway() + ipamSubnet.getSubnet().getIpPrefix() +
+                            "/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                } 
+            } 
+        }
+        
+        for (ObjectReference<VnSubnetsType> ref: newIpamRefs) {
+            VnSubnetsType vnSubnetType = ref.getAttr();
+            if (vnSubnetType != null) {
+                List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                if (subnets != null && !subnets.isEmpty()) {
+                    VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                    newSubnets.add(ipamSubnet.getDefaultGateway() + ipamSubnet.getSubnet().getIpPrefix() +
+                            "/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                } 
+            } 
+        }
+        
+        Set<String> diff = new HashSet<String>(currentSubnets);
+        diff.removeAll(newSubnets);
+        
+        if (!diff.isEmpty()) {
+            s_logger.debug("Subnets differ, network: " + this._name + 
+                    "; db: " + currentSubnets + ", vnc: " + newSubnets + ", diff: " + diff);
+            return false;
+        }
+                
+        return true;
+    }
+
+    public FloatingIpPoolModel getFipPoolModel() {
+        return _fipPoolModel;
+    }
+    public void setFipPoolModel(FloatingIpPoolModel fipPoolModel) {
+        _fipPoolModel = fipPoolModel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/test/net/juniper/contrail/management/MockAccountManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/net/juniper/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/net/juniper/contrail/management/MockAccountManager.java
new file mode 100644
index 0000000..e3e73bf
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/net/juniper/contrail/management/MockAccountManager.java
@@ -0,0 +1,354 @@
+package net.juniper.contrail.management;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.db.Transaction;
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import org.apache.cloudstack.context.CallContext;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.api.query.dao.AccountJoinDao;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.api.query.vo.AccountJoinVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+import org.mockito.Mockito;
+
+public class MockAccountManager extends ManagerBase implements AccountManager {
+    private static final Logger s_logger =
+            Logger.getLogger(MockAccountManager.class);
+
+	@Inject AccountDao _accountDao;
+        @Inject ResourceCountDao _resourceCountDao;
+
+        @Inject AccountJoinDao _accountJoinDao;
+	@Inject UserDao _userDao;
+	
+	UserVO _systemUser;
+	AccountVO _systemAccount;
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _systemAccount = _accountDao.findById(AccountVO.ACCOUNT_ID_SYSTEM);
+        if (_systemAccount == null) {
+            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        _systemUser = _userDao.findById(UserVO.UID_SYSTEM);
+        if (_systemUser == null) {
+            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
+        }
+        CallContext.register(_systemUser, _systemAccount);
+        s_logger.info("MockAccountManager initialization successful");
+        return true;
+    }
+
+    @Override
+    public void checkAccess(Account arg0, Domain arg1)
+            throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void checkAccess(Account arg0, AccessType arg1, boolean arg2,
+            ControlledEntity... arg3) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(RegisterCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User createUser(String arg0, String arg1, String arg2, String arg3,
+            String arg4, String arg5, String arg6, Long arg7, String arg8) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String arg0, String arg1, String arg2,
+            String arg3, String arg4, String arg5, String arg6, short arg7,
+            Long arg8, String arg9, Map<String, String> arg10, String arg11,
+            String arg12) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account finalizeOwner(Account arg0, String arg1, Long arg2, Long arg3) {
+        return _systemAccount; 
+    }
+
+    @Override
+    public Account getActiveAccountByName(String arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getActiveUser(long arg0) {
+        return _systemUser;
+    }
+
+    @Override
+    public User getActiveUserByRegistrationToken(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RoleType getRoleType(Account arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getSystemAccount() {
+        return _systemAccount;
+    }
+
+    @Override
+    public User getSystemUser() {
+        return _systemUser;
+    }
+
+    @Override
+    public UserAccount getUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getUserIncludingRemoved(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isAdmin(short arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isRootAdmin(short arg0) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public UserAccount lockUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void markUserRegistered(long arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public UserAccount authenticateUser(String arg0, String arg1, Long arg2,
+            String arg3, Map<String, Object[]> arg4) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void buildACLSearchBuilder(
+            SearchBuilder<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLSearchCriteria(
+            SearchCriteria<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLSearchParameters(Account arg0, Long arg1, String arg2,
+            Long arg3, List<Long> arg4,
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> arg5,
+            boolean arg6, boolean arg7) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLViewSearchBuilder(
+            SearchBuilder<? extends ControlledViewEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLViewSearchCriteria(
+            SearchCriteria<? extends ControlledViewEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean deleteAccount(AccountVO arg0, long arg1, Account arg2) {
+        return true;
+    }
+
+    @Override
+    public boolean deleteUser(DeleteUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean deleteUserAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean disableAccount(long arg0)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account disableAccount(String arg0, Long arg1, Long arg2)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount disableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean enableAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account enableAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount enableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<User, Account> findUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account lockAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account updateAccount(UpdateAccountCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount updateUser(UpdateUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+	@Override
+	public Account getActiveAccountById(long accountId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Account getAccount(long accountId) {
+               return _systemAccount;
+	}
+
+	@Override
+	public Account createAccount(String accountName, short accountType,
+			Long domainId, String networkDomain, Map<String, String> details,
+			String uuid) {
+            try {
+                AccountVO account = new AccountVO(accountName, domainId, networkDomain, accountType, uuid);
+                Transaction txn = Transaction.currentTxn();
+                txn.start();
+                _accountDao.persist(account);
+                _resourceCountDao.createResourceCounts(account.getId(), ResourceLimit.ResourceOwnerType.Account);
+                txn.commit();
+                return account;
+            } catch (Exception e) {
+               e.printStackTrace();
+            }
+            return null;
+	}
+
+	@Override
+	public void logoutUser(long userId) {
+		// TODO Auto-generated method stub
+		
+	}
+    
+
+}