Merge "Add filtering capability to config.ini in order to reference logging bridge...
[controller.git] / opendaylight / switchmanager / implementation / src / main / java / org / opendaylight / controller / switchmanager / internal / ControllerProperties.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  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 package org.opendaylight.controller.switchmanager.internal;
9
10 import java.net.NetworkInterface;
11 import java.net.SocketException;
12 import java.util.EnumSet;
13 import java.util.Enumeration;
14 import java.util.HashMap;
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ConcurrentMap;
18
19 import org.apache.felix.dm.Component;
20 import org.opendaylight.controller.clustering.services.CacheConfigException;
21 import org.opendaylight.controller.clustering.services.CacheExistException;
22 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
23 import org.opendaylight.controller.clustering.services.IClusterServices;
24 import org.opendaylight.controller.sal.core.MacAddress;
25 import org.opendaylight.controller.sal.core.Property;
26 import org.opendaylight.controller.sal.utils.HexEncode;
27 import org.opendaylight.controller.sal.utils.Status;
28 import org.opendaylight.controller.sal.utils.StatusCode;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * The class ControllerProperties
34  * provides implementation for the ControllerProperties API
35  */
36 public class ControllerProperties implements IControllerProperties {
37
38     private IClusterGlobalServices clusterService = null;
39     private final Logger log = LoggerFactory
40             .getLogger(ControllerProperties.class);
41     private static final String controllerGlobalPropertiesCacheName = "switchmanager.controllerGlobalProperties";
42
43     private ConcurrentMap<String, Property> controllerGlobalProperties;
44
45     private void allocateCaches() {
46         if (this.clusterService == null) {
47             this.nonClusterObjectCreate();
48             log.warn("un-initialized clusterService, can't create cache");
49             return;
50         }
51         try {
52             this.clusterService.createCache(controllerGlobalPropertiesCacheName,
53                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
54         } catch (CacheConfigException cce) {
55             log.error("\nCache configuration invalid - check cache mode");
56         } catch (CacheExistException ce) {
57             log.error("\nCache already exits - destroy and recreate if needed");
58         }
59     }
60
61     private void nonClusterObjectCreate() {
62         controllerGlobalProperties = new ConcurrentHashMap<String, Property>();
63     }
64
65     @SuppressWarnings({ "unchecked" })
66     private void retrieveCaches() {
67         if (this.clusterService == null) {
68             log.warn("un-initialized clusterService, can't create cache");
69             return;
70         }
71         controllerGlobalProperties = (ConcurrentMap<String, Property>) this.clusterService
72                 .getCache(controllerGlobalPropertiesCacheName);
73         if (controllerGlobalProperties == null) {
74             log.error("\nFailed to get cache for controllerGlobalProperties");
75         }
76     }
77
78     /**
79      * Function called by the dependency manager when all the required
80      * dependencies are satisfied
81      *
82      * @param c Component
83      */
84     void init(Component c) {
85         // Instantiate cluster synced variables
86         allocateCaches();
87         retrieveCaches();
88     }
89
90     private void initializeProperties() {
91         byte controllerMac[] = getHardwareMAC();
92         if (controllerMac != null) {
93             Property existing = controllerGlobalProperties.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
94             if (existing == null && log.isTraceEnabled()) {
95                 log.trace("Setting controller MAC address in the cluster: {}", HexEncode.bytesToHexStringFormat(controllerMac));
96             }
97         }
98     }
99
100     private byte[] getHardwareMAC() {
101         Enumeration<NetworkInterface> nis;
102         byte[] macAddress = null;
103
104         try {
105             nis = NetworkInterface.getNetworkInterfaces();
106         } catch (SocketException e) {
107             log.error("Failed to acquire controller MAC: ", e);
108             return macAddress;
109         }
110
111         while (nis.hasMoreElements()) {
112             NetworkInterface ni = nis.nextElement();
113             try {
114                 macAddress = ni.getHardwareAddress();
115             } catch (SocketException e) {
116                 log.error("Failed to acquire controller MAC: ", e);
117             }
118             if (macAddress != null && macAddress.length != 0) {
119                 break;
120             }
121         }
122         if (macAddress == null) {
123             log.warn("Failed to acquire controller MAC: No physical interface found");
124             // This happens when running controller on windows VM, for example
125             // TODO: Try parsing the OS command output
126             // For now provide a quick fix for the release
127             macAddress = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x0c, (byte) 0x60, (byte) 0x0D, (byte) 0x10 };
128             log.debug("Assigning custom MAC address to controller");
129         }
130         return macAddress;
131     }
132
133     /**
134      * Function called by dependency manager after "init ()" is called and after
135      * the services provided by the class are registered in the service registry
136      *
137      */
138     void start() {
139         // initialize required properties if first node in the cluster
140         if(this.clusterService.amICoordinator()) {
141             initializeProperties();
142         }
143     }
144
145     /**
146      * Function called after registered the service in OSGi service registry.
147      */
148     void started() {
149         // nothing to do
150     }
151
152     /**
153      * Function called before services of the component are removed
154      * from OSGi service registry.
155      */
156     void stopping() {
157         // nothing to do
158     }
159
160     /**
161      * Function called by the dependency manager before the services exported by
162      * the component are unregistered, this will be followed by a "destroy ()"
163      * calls
164      *
165      */
166     void stop() {
167         // nothing to do
168     }
169
170     /**
171      * Function called by the dependency manager when at least one dependency
172      * become unsatisfied or when the component is shutting down because for
173      * example bundle is being stopped.
174      *
175      */
176     void destroy() {
177         // nothing to do
178     }
179
180     /**
181      * {@inheritDoc}
182      */
183     @Override
184     public Map<String, Property> getControllerProperties() {
185         return new HashMap<String, Property>(this.controllerGlobalProperties);
186     }
187
188     /**
189      * {@inheritDoc}
190      */
191     @Override
192     public Property getControllerProperty(String propertyName) {
193         if (propertyName != null) {
194             return this.controllerGlobalProperties.get(propertyName);
195         }
196         return null;
197     }
198
199     /**
200      * {@inheritDoc}
201      */
202     @Override
203     public Status setControllerProperty(Property property) {
204         if (property != null) {
205             this.controllerGlobalProperties.put(property.getName(), property);
206             return new Status(StatusCode.SUCCESS);
207         }
208         return new Status(StatusCode.BADREQUEST, "Invalid property provided when setting property");
209     }
210
211     /**
212      * {@inheritDoc}
213      */
214     @Override
215     public Status removeControllerProperty(String propertyName) {
216         if (propertyName != null) {
217             this.controllerGlobalProperties.remove(propertyName);
218             return new Status(StatusCode.SUCCESS);
219         }
220         return new Status(StatusCode.BADREQUEST, "Invalid property provided when removing property");
221     }
222
223     /**
224      * setClusterService
225      * @param s
226      */
227     public void setClusterService(IClusterGlobalServices s) {
228         this.clusterService = s;
229     }
230
231     /**
232      * unsetClusterServices
233      * @param s
234      */
235     public void unsetClusterServices(IClusterGlobalServices s) {
236         if (this.clusterService == s) {
237             this.clusterService = null;
238         }
239     }
240
241 }