Add config service for loading cfg file 23/55123/6
authorShakib Ahmed <sheikahm@cisco.com>
Mon, 17 Apr 2017 17:56:33 +0000 (10:56 -0700)
committerShakib Ahmed <sheikahm@cisco.com>
Fri, 21 Apr 2017 09:21:04 +0000 (02:21 -0700)
The existing way of using configs in vpp-renderer is to use blueprint
and pass the config as bean constructor parameter. The problem with
that is, when there are a lot of configs in the cfg file, we can
possibly pass all of them as bean constructor parameter. Hence, this
patch implements a Config Service which dynamically reads the config
and incase there is any update of config on runtime, the update is
propagated to the service too.

Change-Id: I015f61040a23d472db2a6e9eb23de94625fccb3c
Signed-off-by: Shakib Ahmed <sheikahm@cisco.com>
renderers/vpp/pom.xml
renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/GbpVppProviderInstance.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigUtil.java [new file with mode: 0644]
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigurationService.java [new file with mode: 0644]
renderers/vpp/src/main/resources/startup.cfg

index b04cb6ff3dc20dce6cf013a3606c64375a2f9282..a8158bc84467f4ab357b05fb3562725dfdb7c6b7 100644 (file)
       <version>0.5.0-SNAPSHOT</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>[4.2.0,)</version>
+    </dependency>
   </dependencies>
 
   <!-- project build -->
index 970e590ac2638f7f137efb93d88a60103537188d..32e428a8fa825077631441cc6fc3e63bd9f79565 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.renderer.vpp.adapter.VppRpcServiceImpl;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigurationService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
@@ -50,6 +51,7 @@ public class GbpVppProviderInstance implements ClusterSingletonService, VppAdapt
     private VppRpcServiceImpl vppRpcService;
     private VppRenderer renderer;
     private BindingAwareBroker.RpcRegistration<VppAdapterService> vppRpcServiceRegistration;
+    private ConfigurationService configurationService;
 
     public GbpVppProviderInstance(final DataBroker dataBroker,
                                   final BindingAwareBroker bindingAwareBroker,
@@ -60,6 +62,7 @@ public class GbpVppProviderInstance implements ClusterSingletonService, VppAdapt
         this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService);
         this.publicInterfaces = publicInterfaces;
         this.rpcProviderRegistry = Preconditions.checkNotNull(rpcProviderRegistry);
+        configurationService = new ConfigurationService();
     }
 
     public void initialize() {
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigUtil.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigUtil.java
new file mode 100644 (file)
index 0000000..fe2209d
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 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.groupbasedpolicy.renderer.vpp.config;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by Shakib Ahmed on 4/13/17.
+ */
+public class ConfigUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigUtil.class);
+
+    private static boolean DEFAULT_LISP_OVERLAY_ENABLED = false;
+    private static boolean DEFAULT_LISP_MAPREGISTER_ENABLED = true;
+
+    private IpAddress odlTenantIp;
+    private boolean lispOverlayEnabled = DEFAULT_LISP_OVERLAY_ENABLED;
+    private boolean lispMapRegisterEnbled = DEFAULT_LISP_MAPREGISTER_ENABLED;
+
+    public static String ODL_TENANT_IP = "odl.ip.tenant";
+    public static String LISP_OVERLAY_ENABLED = "gbp.lisp.enabled";
+    public static String LISP_MAPREGISTER_ENABLED = "vpp.lisp.mapregister.enabled";
+
+    private static ConfigUtil INSTANCE = new ConfigUtil();
+
+    private ConfigUtil() {
+        configureDefaults();
+    }
+
+    public static ConfigUtil getInstance() {
+        return INSTANCE;
+    }
+
+    private void configureDefaults() {
+        configureOdlTenantIp(null);
+        configureLispOverlayEnabled(null);
+        configureMapRegister(null);
+    }
+
+    public void configureLispOverlayEnabled(String configStr) {
+        if (configStr == null) {
+            configStr = System.getProperty(LISP_OVERLAY_ENABLED);
+
+            if (configStr == null) {
+                lispOverlayEnabled = DEFAULT_LISP_OVERLAY_ENABLED;
+                LOG.debug("Configuration variable {} is being unset. Setting the variable to {}",
+                        LISP_OVERLAY_ENABLED, DEFAULT_LISP_OVERLAY_ENABLED);
+                return;
+            }
+        }
+
+        configStr = configStr.trim();
+
+        if (configStr.equalsIgnoreCase("true")) {
+            lispOverlayEnabled = true;
+        } else {
+            lispOverlayEnabled = false;
+        }
+    }
+
+    public void configureOdlTenantIp(String configStr) {
+        if (configStr == null) {
+            odlTenantIp = null;
+            LOG.debug("Configuration variable {} is being unset. Setting the variable to null",
+                    ODL_TENANT_IP);
+            return;
+        }
+
+        configStr = configStr.trim();
+        odlTenantIp = new IpAddress(configStr.toCharArray());
+    }
+
+    public void configureMapRegister(String configStr) {
+        if (configStr == null) {
+            lispMapRegisterEnbled = DEFAULT_LISP_MAPREGISTER_ENABLED;
+            LOG.debug("Configuration variable {} is being unset. Setting the variable to {}",
+                    LISP_MAPREGISTER_ENABLED, DEFAULT_LISP_MAPREGISTER_ENABLED);
+            return;
+        }
+
+        configStr = configStr.trim();
+
+        if (configStr.equalsIgnoreCase("true")) {
+            lispMapRegisterEnbled = true;
+        } else {
+            lispOverlayEnabled = false;
+        }
+    }
+
+    public IpAddress getOdlTenantIp() {
+        return odlTenantIp;
+    }
+
+    public boolean isLispOverlayEnabled() {
+        if (lispOverlayEnabled) {
+            Preconditions.checkNotNull(odlTenantIp, "Configuration variable {} is not set. " +
+                    "So, {} can't be used for chances of invalid config!", LISP_OVERLAY_ENABLED);
+        }
+        return lispOverlayEnabled;
+    }
+
+    public boolean isLispMapRegisterEnbled() {
+        return lispMapRegisterEnbled;
+    }
+}
diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigurationService.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/config/ConfigurationService.java
new file mode 100644 (file)
index 0000000..4041a94
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 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.groupbasedpolicy.renderer.vpp.config;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.function.Consumer;
+
+/**
+ * Created by Shakib Ahmed on 4/17/17.
+ */
+public class ConfigurationService implements ManagedService{
+    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationService.class);
+
+    HashMap<String, Consumer> configMethods;
+
+    ConfigUtil configUtil = ConfigUtil.getInstance();
+
+    public ConfigurationService() {
+        Hashtable<String, Object> properties = new Hashtable<>();
+        properties.put(Constants.SERVICE_PID, "org.opendaylight.groupbasedpolicy.renderer.vpp.startup");
+        Bundle bundle = FrameworkUtil.getBundle(this.getClass());
+        BundleContext context = null;
+        if (bundle != null) {
+            context = bundle.getBundleContext();
+        }
+
+        //this function needs to be called before context.registerService() method
+        mapConfigMethods();
+
+        context.registerService(ManagedService.class.getName(), this, properties);
+    }
+
+    @Override
+    public void updated(Dictionary dictionary) throws ConfigurationException {
+        if (dictionary == null) {
+            return;
+        }
+
+        Enumeration keys = dictionary.keys();
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+
+            if (configMethods.containsKey(key)) {
+                configMethods.get(key).accept(dictionary.get(key));
+                LOG.info("Property {} being updated", key);
+            } else {
+                LOG.debug("Configuration {} = {} being ignored because no consumer for this " +
+                        "configuration key has been mapped", keys, dictionary.get(key));
+            }
+        }
+    }
+
+    private void mapConfigMethods() {
+        configMethods = new HashMap<>();
+
+        configMethods.put(ConfigUtil.ODL_TENANT_IP,
+                ip -> configUtil.configureOdlTenantIp((String) ip));
+        configMethods.put(ConfigUtil.LISP_MAPREGISTER_ENABLED,
+                mrConfig -> configUtil.configureMapRegister((String) mrConfig));
+        configMethods.put(ConfigUtil.LISP_OVERLAY_ENABLED,
+                overlayConfig -> configUtil.configureLispOverlayEnabled((String) overlayConfig));
+    }
+}
index 0ebb53ad8df911bd589ece9106c8692e59988fb9..b58f5597bbced1a10464db660bacb4cf7d291e35 100644 (file)
@@ -7,3 +7,22 @@
 # as public interface, uncomment and modify next line. Specifying one physical
 # interface per node is currently supported.
 #public-interfaces = compute1:TenGigabitEthernet8/0/0,compute2:TenGigabitEthernet8/0/0
+
+# This property should be  set to the Ip address the ODL can be reached from tenant network.
+# Valid config: Ip Address (IPv4/ IPv6)
+odl.ip.tenant = 10.0.0.1
+
+# This property should be true if L3 overlay is desired. If `true`, GBP will
+# push LISP configurations in VPP.
+# Valid config: true/false
+# Required config: odl.ip.tenant to be set.
+# Default value: false
+gbp.lisp.enabled = true
+
+# This property determines whether VPP makes the map request directly to the map server.
+# If true, VPP will register the mappings in the Map server and no LISP feature will
+# be needed for supporting L3 LISP overlay.
+# Valid config: true/false
+# Required config: gbp.lisp.enabled is set to be true.
+# Default value: true
+vpp.lisp.mapregister.enabled = true
\ No newline at end of file