850cc02163bd7965a2aefd936e39149e607bf26f
[controller.git] / opendaylight / networkconfiguration / neutron / implementation / src / main / java / org / opendaylight / controller / networkconfig / neutron / implementation / NeutronRouterInterface.java
1 /*
2  * Copyright IBM Corporation, 2013.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.networkconfig.neutron.implementation;
10
11 import java.io.FileNotFoundException;
12 import java.io.IOException;
13 import java.io.ObjectInputStream;
14 import java.lang.reflect.Method;
15 import java.util.ArrayList;
16 import java.util.Dictionary;
17 import java.util.EnumSet;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.Map.Entry;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24
25 import org.apache.felix.dm.Component;
26 import org.opendaylight.controller.clustering.services.CacheConfigException;
27 import org.opendaylight.controller.clustering.services.CacheExistException;
28 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
29 import org.opendaylight.controller.clustering.services.IClusterServices;
30 import org.opendaylight.controller.configuration.IConfigurationContainerAware;
31 import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
32 import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
33 import org.opendaylight.controller.sal.utils.GlobalConstants;
34 import org.opendaylight.controller.sal.utils.IObjectReader;
35 import org.opendaylight.controller.sal.utils.ObjectReader;
36 import org.opendaylight.controller.sal.utils.ObjectWriter;
37 import org.opendaylight.controller.sal.utils.Status;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public class NeutronRouterInterface implements INeutronRouterCRUD, IConfigurationContainerAware,
42                                                IObjectReader {
43     private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
44     private static String ROOT = GlobalConstants.STARTUPHOME.toString();
45     private static final String FILENAME ="neutron.router";
46     private static String fileName;
47     private String containerName = null;
48
49     private IClusterContainerServices clusterContainerService = null;
50     private ConcurrentMap<String, NeutronRouter> routerDB;
51     // methods needed for creating caches
52
53     void setClusterContainerService(IClusterContainerServices s) {
54         logger.debug("Cluster Service set");
55         this.clusterContainerService = s;
56     }
57
58     void unsetClusterContainerService(IClusterContainerServices s) {
59         if (this.clusterContainerService == s) {
60             logger.debug("Cluster Service removed!");
61             this.clusterContainerService = null;
62         }
63     }
64
65     @SuppressWarnings("deprecation")
66     private void allocateCache() {
67         if (this.clusterContainerService == null) {
68             logger.error("un-initialized clusterContainerService, can't create cache");
69             return;
70         }
71         logger.debug("Creating Cache for Neutron Routers");
72         try {
73             // neutron caches
74             this.clusterContainerService.createCache("neutronRouters",
75                     EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
76         } catch (CacheConfigException cce) {
77             logger.error("Cache couldn't be created for Neutron Routers -  check cache mode");
78         } catch (CacheExistException cce) {
79             logger.error("Cache for Neutron Routers already exists, destroy and recreate");
80         }
81         logger.debug("Cache successfully created for Neutron Routers");
82     }
83
84     @SuppressWarnings({ "unchecked", "deprecation" })
85     private void retrieveCache() {
86         if (this.clusterContainerService == null) {
87             logger.error("un-initialized clusterContainerService, can't retrieve cache");
88             return;
89         }
90
91         logger.debug("Retrieving cache for Neutron Routers");
92         routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService
93         .getCache("neutronRouters");
94         if (routerDB == null) {
95             logger.error("Cache couldn't be retrieved for Neutron Routers");
96         }
97         logger.debug("Cache was successfully retrieved for Neutron Routers");
98     }
99
100     @SuppressWarnings("deprecation")
101     private void destroyCache() {
102         if (this.clusterContainerService == null) {
103             logger.error("un-initialized clusterMger, can't destroy cache");
104             return;
105         }
106         logger.debug("Destroying Cache for HostTracker");
107         this.clusterContainerService.destroyCache("neutronRouters");
108     }
109
110     private void startUp() {
111         allocateCache();
112         retrieveCache();
113         if (routerDB.isEmpty()) {
114             loadConfiguration();
115         }
116
117     }
118
119     /**
120      * Function called by the dependency manager when all the required
121      * dependencies are satisfied
122      *
123      */
124     void init(Component c) {
125         Dictionary<?, ?> props = c.getServiceProperties();
126         if (props != null) {
127             this.containerName = (String) props.get("containerName");
128             logger.debug("Running containerName: {}", this.containerName);
129         } else {
130             // In the Global instance case the containerName is empty
131             this.containerName = "";
132         }
133         fileName = ROOT + FILENAME + "_" + containerName + ".conf";
134         startUp();
135     }
136
137     /**
138      * Function called by the dependency manager when at least one dependency
139      * become unsatisfied or when the component is shutting down because for
140      * example bundle is being stopped.
141      *
142      */
143     void destroy() {
144         destroyCache();
145     }
146
147     /**
148      * Function called by dependency manager after "init ()" is called and after
149      * the services provided by the class are registered in the service registry
150      *
151      */
152     void start() {
153     }
154
155     /**
156      * Function called by the dependency manager before the services exported by
157      * the component are unregistered, this will be followed by a "destroy ()"
158      * calls
159      *
160      */
161     void stop() {
162     }
163
164     // this method uses reflection to update an object from it's delta.
165
166     private boolean overwrite(Object target, Object delta) {
167         Method[] methods = target.getClass().getMethods();
168
169         for(Method toMethod: methods){
170             if(toMethod.getDeclaringClass().equals(target.getClass())
171                     && toMethod.getName().startsWith("set")){
172
173                 String toName = toMethod.getName();
174                 String fromName = toName.replace("set", "get");
175
176                 try {
177                     Method fromMethod = delta.getClass().getMethod(fromName);
178                     Object value = fromMethod.invoke(delta, (Object[])null);
179                     if(value != null){
180                         toMethod.invoke(target, value);
181                     }
182                 } catch (Exception e) {
183                     e.printStackTrace();
184                     return false;
185                 }
186             }
187         }
188         return true;
189     }
190
191
192     // IfNBRouterCRUD Interface methods
193
194     @Override
195     public boolean routerExists(String uuid) {
196         return routerDB.containsKey(uuid);
197     }
198
199     @Override
200     public NeutronRouter getRouter(String uuid) {
201         if (!routerExists(uuid))
202             return null;
203         return routerDB.get(uuid);
204     }
205
206     @Override
207     public List<NeutronRouter> getAllRouters() {
208         Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
209         for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
210             NeutronRouter router = entry.getValue();
211             allRouters.add(router);
212         }
213         logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());
214         List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
215         ans.addAll(allRouters);
216         return ans;
217     }
218
219     @Override
220     public boolean addRouter(NeutronRouter input) {
221         if (routerExists(input.getID()))
222             return false;
223         routerDB.putIfAbsent(input.getID(), input);
224         return true;
225     }
226
227     @Override
228     public boolean removeRouter(String uuid) {
229         if (!routerExists(uuid))
230             return false;
231         routerDB.remove(uuid);
232         return true;
233     }
234
235     @Override
236     public boolean updateRouter(String uuid, NeutronRouter delta) {
237         if (!routerExists(uuid))
238             return false;
239         NeutronRouter target = routerDB.get(uuid);
240         return overwrite(target, delta);
241     }
242
243     @Override
244     public boolean routerInUse(String routerUUID) {
245         if (!routerExists(routerUUID))
246             return true;
247         NeutronRouter target = routerDB.get(routerUUID);
248         return (target.getInterfaces().size() > 0);
249     }
250
251     @SuppressWarnings("unchecked")
252     private void loadConfiguration() {
253         ObjectReader objReader = new ObjectReader();
254         ConcurrentMap<String, NeutronRouter> confList = (ConcurrentMap<String, NeutronRouter>)
255                                                             objReader.read(this, fileName);
256
257         if (confList == null) {
258             return;
259         }
260
261         for (String key : confList.keySet()) {
262             routerDB.put(key, confList.get(key));
263         }
264     }
265
266     @Override
267     public Status saveConfiguration() {
268         ObjectWriter objWriter = new ObjectWriter();
269         return objWriter.write(new ConcurrentHashMap<String, NeutronRouter>(routerDB), fileName);
270     }
271
272     @Override
273     public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
274         return ois.readObject();
275     }
276
277 }