--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.switchmanager.internal;
+
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.sal.core.MacAddress;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The class ControllerProperties
+ * provides implementation for the ControllerProperties API
+ */
+public class ControllerProperties implements IControllerProperties {
+
+ private IClusterGlobalServices clusterService = null;
+ private final Logger log = LoggerFactory
+ .getLogger(ControllerProperties.class);
+ private static final String controllerGlobalPropertiesCacheName = "switchmanager.controllerGlobalProperties";
+
+ private ConcurrentMap<String, Property> controllerGlobalProperties;
+
+ private void allocateCaches() {
+ if (this.clusterService == null) {
+ this.nonClusterObjectCreate();
+ log.warn("un-initialized clusterService, can't create cache");
+ return;
+ }
+ try {
+ this.clusterService.createCache(controllerGlobalPropertiesCacheName,
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ log.error("\nCache configuration invalid - check cache mode");
+ } catch (CacheExistException ce) {
+ log.error("\nCache already exits - destroy and recreate if needed");
+ }
+ }
+
+ private void nonClusterObjectCreate() {
+ controllerGlobalProperties = new ConcurrentHashMap<String, Property>();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private void retrieveCaches() {
+ if (this.clusterService == null) {
+ log.warn("un-initialized clusterService, can't create cache");
+ return;
+ }
+ controllerGlobalProperties = (ConcurrentMap<String, Property>) this.clusterService
+ .getCache(controllerGlobalPropertiesCacheName);
+ if (controllerGlobalProperties == null) {
+ log.error("\nFailed to get cache for controllerGlobalProperties");
+ }
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ * @param c Component
+ */
+ void init(Component c) {
+ // Instantiate cluster synced variables
+ allocateCaches();
+ retrieveCaches();
+ }
+
+ private void initializeProperties() {
+ byte controllerMac[] = getHardwareMAC();
+ if (controllerMac != null) {
+ Property existing = controllerGlobalProperties.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
+ if (existing == null && log.isTraceEnabled()) {
+ log.trace("Setting controller MAC address in the cluster: {}", HexEncode.bytesToHexStringFormat(controllerMac));
+ }
+ }
+ }
+
+ private byte[] getHardwareMAC() {
+ Enumeration<NetworkInterface> nis;
+ byte[] macAddress = null;
+
+ try {
+ nis = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e) {
+ log.error("Failed to acquire controller MAC: ", e);
+ return macAddress;
+ }
+
+ while (nis.hasMoreElements()) {
+ NetworkInterface ni = nis.nextElement();
+ try {
+ macAddress = ni.getHardwareAddress();
+ } catch (SocketException e) {
+ log.error("Failed to acquire controller MAC: ", e);
+ }
+ if (macAddress != null && macAddress.length != 0) {
+ break;
+ }
+ }
+ if (macAddress == null) {
+ log.warn("Failed to acquire controller MAC: No physical interface found");
+ // This happens when running controller on windows VM, for example
+ // TODO: Try parsing the OS command output
+ // For now provide a quick fix for the release
+ macAddress = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x0c, (byte) 0x60, (byte) 0x0D, (byte) 0x10 };
+ log.debug("Assigning custom MAC address to controller");
+ }
+ return macAddress;
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ // initialize required properties if first node in the cluster
+ if(this.clusterService.amICoordinator()) {
+ initializeProperties();
+ }
+ }
+
+ /**
+ * Function called after registered the service in OSGi service registry.
+ */
+ void started() {
+ // nothing to do
+ }
+
+ /**
+ * Function called before services of the component are removed
+ * from OSGi service registry.
+ */
+ void stopping() {
+ // nothing to do
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ // nothing to do
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String, Property> getControllerProperties() {
+ return new HashMap<String, Property>(this.controllerGlobalProperties);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Property getControllerProperty(String propertyName) {
+ if (propertyName != null) {
+ return this.controllerGlobalProperties.get(propertyName);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Status setControllerProperty(Property property) {
+ if (property != null) {
+ this.controllerGlobalProperties.put(property.getName(), property);
+ return new Status(StatusCode.SUCCESS);
+ }
+ return new Status(StatusCode.BADREQUEST, "Invalid property provided when setting property");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Status removeControllerProperty(String propertyName) {
+ if (propertyName != null) {
+ this.controllerGlobalProperties.remove(propertyName);
+ return new Status(StatusCode.SUCCESS);
+ }
+ return new Status(StatusCode.BADREQUEST, "Invalid property provided when removing property");
+ }
+
+ /**
+ * setClusterService
+ * @param s
+ */
+ public void setClusterService(IClusterGlobalServices s) {
+ this.clusterService = s;
+ }
+
+ /**
+ * unsetClusterServices
+ * @param s
+ */
+ public void unsetClusterServices(IClusterGlobalServices s) {
+ if (this.clusterService == s) {
+ this.clusterService = null;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.switchmanager.internal;
+
+import java.util.Map;
+
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.utils.Status;
+
+/**
+ * The class ControllerProperties is a global store
+ * for controller properties. Use this api to store/retrieve properties
+ * that are container independent.
+ *
+ * This is visible only to switch manager. Hence its a part of
+ * switch manager internal bundle.
+ */
+public interface IControllerProperties {
+
+ /**
+ * Return all the global properties of the controller
+ *
+ * @return map of {@link org.opendaylight.controller.sal.core.Property} such
+ * as {@link org.opendaylight.controller.sal.core.Description}
+ * and/or {@link org.opendaylight.controller.sal.core.Tier} etc.
+ */
+ public Map<String, Property> getControllerProperties();
+
+ /**
+ * Return a specific property of the controller given the property name
+ *
+ * @param propertyName
+ * the property name specified by
+ * {@link org.opendaylight.controller.sal.core.Property} and its
+ * extended classes
+ * @return {@link org.opendaylight.controller.sal.core.Property}
+ */
+ public Property getControllerProperty(String propertyName);
+
+ /**
+ * Set a specific property of the controller
+ *
+ * @param property
+ * {@link org.opendaylight.controller.sal.core.Property}
+ * @return Status
+ */
+ public Status setControllerProperty(Property property);
+
+ /**
+ * Remove a property of a node
+ *
+ * @param propertyName
+ * the property name specified by
+ * {@link org.opendaylight.controller.sal.core.Property} and its
+ * extended classes
+ * @return success or failed reason
+ */
+ public Status removeControllerProperty(String propertyName);
+
+}
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.EnumSet;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
import org.opendaylight.controller.sal.reader.NodeDescription;
import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.IObjectReader;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
private ConcurrentMap<String, Property> controllerProps;
private IInventoryService inventoryService;
private IStatisticsManager statisticsManager;
+ private IControllerProperties controllerProperties;
private IConfigurationContainerService configurationService;
private final Set<ISwitchManagerAware> switchManagerAware = Collections
.synchronizedSet(new HashSet<ISwitchManagerAware>());
retrieveCaches();
// Add controller MAC, if first node in the cluster
- if (!controllerProps.containsKey(MacAddress.name)) {
- byte controllerMac[] = getHardwareMAC();
+ if ((!controllerProps.containsKey(MacAddress.name)) && (controllerProperties != null)) {
+ Property controllerMac = controllerProperties.getControllerProperty(MacAddress.name);
if (controllerMac != null) {
- Property existing = controllerProps.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
+ Property existing = controllerProps.putIfAbsent(MacAddress.name, controllerMac);
if (existing == null && log.isTraceEnabled()) {
log.trace("Container {}: Setting controller MAC address in the cluster: {}", getContainerName(),
- HexEncode.bytesToHexStringFormat(controllerMac));
+ controllerMac);
}
}
}
return (propMap != null) ? propMap.get(propName) : null;
}
- private byte[] getHardwareMAC() {
- Enumeration<NetworkInterface> nis;
- byte[] macAddress = null;
-
- try {
- nis = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e) {
- log.error("Failed to acquire controller MAC: ", e);
- return macAddress;
- }
-
- while (nis.hasMoreElements()) {
- NetworkInterface ni = nis.nextElement();
- try {
- macAddress = ni.getHardwareAddress();
- } catch (SocketException e) {
- log.error("Failed to acquire controller MAC: ", e);
- }
- if (macAddress != null && macAddress.length != 0) {
- break;
- }
- }
- if (macAddress == null) {
- log.warn("Failed to acquire controller MAC: No physical interface found");
- // This happens when running controller on windows VM, for example
- // Try parsing the OS command output
- }
- return macAddress;
- }
-
@Override
public byte[] getControllerMAC() {
MacAddress macProperty = (MacAddress)controllerProps.get(MacAddress.name);
}
}
+ public void setControllerProperties(IControllerProperties controllerProperties) {
+ log.trace("Got controller properties set request {}", controllerProperties);
+ this.controllerProperties = controllerProperties;
+ }
+
+ public void unsetControllerProperties(IControllerProperties controllerProperties) {
+ log.trace("Got controller properties UNset request");
+ this.controllerProperties = null;
+ }
+
private void getInventories() {
if (inventoryService == null) {
log.trace("inventory service not avaiable");