From d10665e0255089f18f34149c4d2ed6f045d0f63f Mon Sep 17 00:00:00 2001 From: Madhu Venugopal Date: Fri, 17 Jan 2014 16:22:47 -0800 Subject: [PATCH] Config save support for networkconfiguration.neutron With the ODL ML2 Integration, the REST APIs are uni-directional, hence a simple controller restart results in synchronization issues between Openstack/CloudStack ML2 and ODL. The solution that was agreed with Kyle, Ryan, Hugo & others is to add the config save support on the ODL side which will effectively remove the inconsistency issues between Openstack / Cloudstack and ODL. Change-Id: I9c5cb1a7d4acd0c147a3014da090770b231fd8d9 Signed-off-by: Madhu Venugopal --- .../neutron/implementation/pom.xml | 6 ++ .../neutron/implementation/Activator.java | 22 ++++++-- .../NeutronFloatingIPInterface.java | 52 ++++++++++++++++- .../NeutronNetworkInterface.java | 54 +++++++++++++++++- .../implementation/NeutronPortInterface.java | 47 +++++++++++++++- .../NeutronRouterInterface.java | 55 +++++++++++++++++- .../NeutronSubnetInterface.java | 56 ++++++++++++++++++- .../neutron/NeutronFloatingIP.java | 5 +- .../networkconfig/neutron/NeutronNetwork.java | 5 +- .../networkconfig/neutron/NeutronPort.java | 5 +- .../networkconfig/neutron/NeutronRouter.java | 6 +- .../neutron/NeutronRouter_Interface.java | 6 +- .../NeutronRouter_NetworkReference.java | 6 +- .../networkconfig/neutron/NeutronSubnet.java | 5 +- .../neutron/NeutronSubnet_HostRoute.java | 6 +- .../NeutronSubnet_IPAllocationPool.java | 8 ++- .../networkconfig/neutron/Neutron_IPs.java | 6 +- 17 files changed, 328 insertions(+), 22 deletions(-) diff --git a/opendaylight/networkconfiguration/neutron/implementation/pom.xml b/opendaylight/networkconfiguration/neutron/implementation/pom.xml index 3b335463d9..8e14d9b366 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/pom.xml +++ b/opendaylight/networkconfiguration/neutron/implementation/pom.xml @@ -50,6 +50,7 @@ org.opendaylight.controller.clustering.services, + org.opendaylight.controller.configuration, org.opendaylight.controller.sal.core, org.opendaylight.controller.sal.utils, org.apache.felix.dm, @@ -78,6 +79,11 @@ clustering.services 0.4.1-SNAPSHOT + + org.opendaylight.controller + configuration + 0.4.1-SNAPSHOT + org.opendaylight.controller networkconfig.neutron diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java index 4202856774..351496abb3 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java @@ -10,11 +10,12 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; import java.util.Hashtable; import java.util.Dictionary; + import org.apache.felix.dm.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.opendaylight.controller.clustering.services.IClusterContainerServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; @@ -32,6 +33,7 @@ public class Activator extends ComponentActivatorAbstractBase { * ComponentActivatorAbstractBase. * */ + @Override public void init() { } @@ -41,6 +43,7 @@ public class Activator extends ComponentActivatorAbstractBase { * cleanup done by ComponentActivatorAbstractBase * */ + @Override public void destroy() { } @@ -54,6 +57,7 @@ public class Activator extends ComponentActivatorAbstractBase { * instantiated in order to get an fully working implementation * Object */ + @Override public Object[] getImplementations() { Object[] res = { NeutronFloatingIPInterface.class, NeutronRouterInterface.class, @@ -76,11 +80,13 @@ public class Activator extends ComponentActivatorAbstractBase { * also optional per-container different behavior if needed, usually * should not be the case though. */ + @Override public void configureInstance(Component c, Object imp, String containerName) { if (imp.equals(NeutronFloatingIPInterface.class)) { // export the service c.setInterface( - new String[] { INeutronFloatingIPCRUD.class.getName() }, null); + new String[] { INeutronFloatingIPCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); Dictionary props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -91,7 +97,8 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(NeutronRouterInterface.class)) { // export the service c.setInterface( - new String[] { INeutronRouterCRUD.class.getName() }, null); + new String[] { INeutronRouterCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); Dictionary props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -102,7 +109,8 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(NeutronPortInterface.class)) { // export the service c.setInterface( - new String[] { INeutronPortCRUD.class.getName() }, null); + new String[] { INeutronPortCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); Dictionary props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -113,7 +121,8 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(NeutronSubnetInterface.class)) { // export the service c.setInterface( - new String[] { INeutronSubnetCRUD.class.getName() }, null); + new String[] { INeutronSubnetCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); Dictionary props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) @@ -124,7 +133,8 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(NeutronNetworkInterface.class)) { // export the service c.setInterface( - new String[] { INeutronNetworkCRUD.class.getName() }, null); + new String[] { INeutronNetworkCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); Dictionary props = new Hashtable(); props.put("salListenerName", "neutron"); c.add(createContainerServiceDependency(containerName) diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java index 7d9a2e6576..ceb009bf2c 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java @@ -8,6 +8,9 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Dictionary; @@ -16,6 +19,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.felix.dm.Component; @@ -23,6 +27,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; @@ -31,11 +36,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP; import org.opendaylight.controller.networkconfig.neutron.NeutronPort; import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ObjectReader; +import org.opendaylight.controller.sal.utils.ObjectWriter; +import org.opendaylight.controller.sal.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { +public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD, IConfigurationContainerAware, + IObjectReader { private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class); + private static String ROOT = GlobalConstants.STARTUPHOME.toString(); + private static final String FILENAME ="neutron.floatingip"; + private static String fileName; private String containerName = null; private IClusterContainerServices clusterContainerService = null; @@ -103,6 +117,9 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (floatingIPDB.isEmpty()) { + loadConfiguration(); + } } /** @@ -119,6 +136,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -178,16 +196,19 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { // IfNBFloatingIPCRUD interface methods + @Override public boolean floatingIPExists(String uuid) { return floatingIPDB.containsKey(uuid); } + @Override public NeutronFloatingIP getFloatingIP(String uuid) { if (!floatingIPExists(uuid)) return null; return floatingIPDB.get(uuid); } + @Override public List getAllFloatingIPs() { Set allIPs = new HashSet(); for (Entry entry : floatingIPDB.entrySet()) { @@ -200,6 +221,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return ans; } + @Override public boolean addFloatingIP(NeutronFloatingIP input) { INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this); INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this); @@ -223,6 +245,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return true; } + @Override public boolean removeFloatingIP(String uuid) { INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this); INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this); @@ -242,6 +265,7 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { return true; } + @Override public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) { INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this); @@ -263,4 +287,30 @@ public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD { target.setFixedIPAddress(delta.getFixedIPAddress()); return true; } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + objReader.read(this, fileName); + + if (confList == null) { + return; + } + + for (String key : confList.keySet()) { + floatingIPDB.put(key, confList.get(key)); + } + } + + @Override + public Status saveConfiguration() { + ObjectWriter objWriter = new ObjectWriter(); + return objWriter.write(new ConcurrentHashMap(floatingIPDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java index b1e382107a..de9b9d1bc4 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java @@ -8,6 +8,9 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Dictionary; @@ -16,6 +19,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.felix.dm.Component; @@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ObjectReader; +import org.opendaylight.controller.sal.utils.ObjectWriter; +import org.opendaylight.controller.sal.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NeutronNetworkInterface implements INeutronNetworkCRUD { +public class NeutronNetworkInterface implements INeutronNetworkCRUD, IConfigurationContainerAware, + IObjectReader { private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class); + private static String ROOT = GlobalConstants.STARTUPHOME.toString(); + private static final String FILENAME ="neutron.network"; + private static String fileName; private String containerName = null; private ConcurrentMap networkDB; @@ -85,6 +99,9 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (networkDB.isEmpty()) { + loadConfiguration(); + } } /** @@ -101,6 +118,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -170,16 +188,19 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { // IfNBNetworkCRUD methods + @Override public boolean networkExists(String uuid) { return networkDB.containsKey(uuid); } + @Override public NeutronNetwork getNetwork(String uuid) { if (!networkExists(uuid)) return null; return networkDB.get(uuid); } + @Override public List getAllNetworks() { Set allNetworks = new HashSet(); for (Entry entry : networkDB.entrySet()) { @@ -192,6 +213,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return ans; } + @Override public boolean addNetwork(NeutronNetwork input) { if (networkExists(input.getID())) return false; @@ -200,6 +222,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; } + @Override public boolean removeNetwork(String uuid) { if (!networkExists(uuid)) return false; @@ -208,6 +231,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; } + @Override public boolean updateNetwork(String uuid, NeutronNetwork delta) { if (!networkExists(uuid)) return false; @@ -215,6 +239,7 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return overwrite(target, delta); } + @Override public boolean networkInUse(String netUUID) { if (!networkExists(netUUID)) return true; @@ -223,4 +248,31 @@ public class NeutronNetworkInterface implements INeutronNetworkCRUD { return true; return false; } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + objReader.read(this, fileName); + + if (confList == null) { + return; + } + + for (String key : confList.keySet()) { + networkDB.put(key, confList.get(key)); + } + } + + @Override + public Status saveConfiguration() { + ObjectWriter objWriter = new ObjectWriter(); + return objWriter.write(new ConcurrentHashMap(networkDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java index fd030e178b..ec439bb927 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java @@ -8,6 +8,9 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Dictionary; @@ -17,6 +20,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.felix.dm.Component; @@ -24,6 +28,7 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; @@ -32,11 +37,20 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; import org.opendaylight.controller.networkconfig.neutron.NeutronPort; import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ObjectReader; +import org.opendaylight.controller.sal.utils.ObjectWriter; +import org.opendaylight.controller.sal.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NeutronPortInterface implements INeutronPortCRUD { +public class NeutronPortInterface implements INeutronPortCRUD, IConfigurationContainerAware, + IObjectReader { private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class); + private static String ROOT = GlobalConstants.STARTUPHOME.toString(); + private static final String FILENAME ="neutron.port"; + private static String fileName; private String containerName = null; private IClusterContainerServices clusterContainerService = null; @@ -104,6 +118,10 @@ public class NeutronPortInterface implements INeutronPortCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (portDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -120,6 +138,7 @@ public class NeutronPortInterface implements INeutronPortCRUD { // In the Global instance case the containerName is empty containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -329,4 +348,30 @@ public class NeutronPortInterface implements INeutronPortCRUD { return null; } + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + objReader.read(this, fileName); + + if (confList == null) { + return; + } + + for (String key : confList.keySet()) { + portDB.put(key, confList.get(key)); + } + } + + @Override + public Status saveConfiguration() { + ObjectWriter objWriter = new ObjectWriter(); + return objWriter.write(new ConcurrentHashMap(portDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java index 0e64dc5a09..850cc02163 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java @@ -8,6 +8,9 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Dictionary; @@ -16,6 +19,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.felix.dm.Component; @@ -23,13 +27,23 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronRouter; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ObjectReader; +import org.opendaylight.controller.sal.utils.ObjectWriter; +import org.opendaylight.controller.sal.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NeutronRouterInterface implements INeutronRouterCRUD { +public class NeutronRouterInterface implements INeutronRouterCRUD, IConfigurationContainerAware, + IObjectReader { private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class); + private static String ROOT = GlobalConstants.STARTUPHOME.toString(); + private static final String FILENAME ="neutron.router"; + private static String fileName; private String containerName = null; private IClusterContainerServices clusterContainerService = null; @@ -96,6 +110,10 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (routerDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -112,6 +130,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -172,16 +191,19 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { // IfNBRouterCRUD Interface methods + @Override public boolean routerExists(String uuid) { return routerDB.containsKey(uuid); } + @Override public NeutronRouter getRouter(String uuid) { if (!routerExists(uuid)) return null; return routerDB.get(uuid); } + @Override public List getAllRouters() { Set allRouters = new HashSet(); for (Entry entry : routerDB.entrySet()) { @@ -194,6 +216,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return ans; } + @Override public boolean addRouter(NeutronRouter input) { if (routerExists(input.getID())) return false; @@ -201,6 +224,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return true; } + @Override public boolean removeRouter(String uuid) { if (!routerExists(uuid)) return false; @@ -208,6 +232,7 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return true; } + @Override public boolean updateRouter(String uuid, NeutronRouter delta) { if (!routerExists(uuid)) return false; @@ -215,10 +240,38 @@ public class NeutronRouterInterface implements INeutronRouterCRUD { return overwrite(target, delta); } + @Override public boolean routerInUse(String routerUUID) { if (!routerExists(routerUUID)) return true; NeutronRouter target = routerDB.get(routerUUID); return (target.getInterfaces().size() > 0); } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + objReader.read(this, fileName); + + if (confList == null) { + return; + } + + for (String key : confList.keySet()) { + routerDB.put(key, confList.get(key)); + } + } + + @Override + public Status saveConfiguration() { + ObjectWriter objWriter = new ObjectWriter(); + return objWriter.write(new ConcurrentHashMap(routerDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java index 62ef64c74c..f908a95c31 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java @@ -8,6 +8,9 @@ package org.opendaylight.controller.networkconfig.neutron.implementation; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Dictionary; @@ -16,6 +19,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.felix.dm.Component; @@ -23,16 +27,27 @@ import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.ObjectReader; +import org.opendaylight.controller.sal.utils.ObjectWriter; +import org.opendaylight.controller.sal.utils.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class NeutronSubnetInterface implements INeutronSubnetCRUD { +public class NeutronSubnetInterface implements INeutronSubnetCRUD, IConfigurationContainerAware, + IObjectReader { private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class); + private static String ROOT = GlobalConstants.STARTUPHOME.toString(); + private static final String FILENAME ="neutron.subnet"; + private static String fileName; + private String containerName = null; private IClusterContainerServices clusterContainerService = null; @@ -100,6 +115,10 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { private void startUp() { allocateCache(); retrieveCache(); + if (subnetDB.isEmpty()) { + loadConfiguration(); + } + } /** @@ -116,6 +135,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { // In the Global instance case the containerName is empty this.containerName = ""; } + fileName = ROOT + FILENAME + "_" + containerName + ".conf"; startUp(); } @@ -176,16 +196,19 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { // IfNBSubnetCRUD methods + @Override public boolean subnetExists(String uuid) { return subnetDB.containsKey(uuid); } + @Override public NeutronSubnet getSubnet(String uuid) { if (!subnetExists(uuid)) return null; return subnetDB.get(uuid); } + @Override public List getAllSubnets() { Set allSubnets = new HashSet(); for (Entry entry : subnetDB.entrySet()) { @@ -198,6 +221,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return ans; } + @Override public boolean addSubnet(NeutronSubnet input) { String id = input.getID(); if (subnetExists(id)) @@ -210,6 +234,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return true; } + @Override public boolean removeSubnet(String uuid) { if (!subnetExists(uuid)) return false; @@ -222,6 +247,7 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return true; } + @Override public boolean updateSubnet(String uuid, NeutronSubnet delta) { if (!subnetExists(uuid)) return false; @@ -229,10 +255,38 @@ public class NeutronSubnetInterface implements INeutronSubnetCRUD { return overwrite(target, delta); } + @Override public boolean subnetInUse(String subnetUUID) { if (!subnetExists(subnetUUID)) return true; NeutronSubnet target = subnetDB.get(subnetUUID); return (target.getPortsInSubnet().size() > 0); } + + @SuppressWarnings("unchecked") + private void loadConfiguration() { + ObjectReader objReader = new ObjectReader(); + ConcurrentMap confList = (ConcurrentMap) + objReader.read(this, fileName); + + if (confList == null) { + return; + } + + for (String key : confList.keySet()) { + subnetDB.put(key, confList.get(key)); + } + } + + @Override + public Status saveConfiguration() { + ObjectWriter objWriter = new ObjectWriter(); + return objWriter.write(new ConcurrentHashMap(subnetDB), fileName); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java index 4d029dccf3..9c8c91b284 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.Iterator; import java.util.List; @@ -19,7 +20,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronFloatingIP { +public class NeutronFloatingIP implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java index 9d7ba5d58a..1277436e23 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -20,10 +21,12 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "network") @XmlAccessorType(XmlAccessType.NONE) -public class NeutronNetwork { +public class NeutronNetwork implements Serializable { // See OpenStack Network API v2.0 Reference for description of // annotated attributes + private static final long serialVersionUID = 1L; + @XmlElement (name="id") String networkUUID; // network UUID diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java index 536fc3fd6e..bcadba202a 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -22,7 +23,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronPort { +public class NeutronPort implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java index 1ef48bd95b..ed65c5c91b 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java @@ -8,9 +8,11 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.List; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -19,7 +21,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronRouter { +public class NeutronRouter implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes @XmlElement (name="id") diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java index 5b5e0ce9cc..e2df13b9aa 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronRouter_Interface { +public class NeutronRouter_Interface implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java index 07f165dc7e..8583d44531 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -16,7 +18,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronRouter_NetworkReference { +public class NeutronRouter_NetworkReference implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java index 1dbe253a58..fbaa63a148 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -23,7 +24,9 @@ import org.apache.commons.net.util.SubnetUtils.SubnetInfo; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronSubnet { +public class NeutronSubnet implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java index 75238c1ad9..07744061e6 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronSubnet_HostRoute { +public class NeutronSubnet_HostRoute implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java index 7829ba2199..15ff548a53 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronSubnet_IPAllocationPool { +public class NeutronSubnet_IPAllocationPool implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes @@ -28,7 +31,8 @@ public class NeutronSubnet_IPAllocationPool { @XmlElement(name="end") String poolEnd; - public NeutronSubnet_IPAllocationPool() { } + public NeutronSubnet_IPAllocationPool() { + } public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) { poolStart = lowAddress; diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java index 6fe7c52994..e862a59e8a 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.networkconfig.neutron; +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -15,7 +17,9 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class Neutron_IPs { +public class Neutron_IPs implements Serializable { + private static final long serialVersionUID = 1L; + // See OpenStack Network API v2.0 Reference for description of // annotated attributes -- 2.36.6