[ONOS-5688] Make LISP authKey and authKeyId be configurable

Change-Id: I8262cc1791e064547e79cb9a3cb58e99feec50b1
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
index 5f809bf..2a7b740 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
@@ -57,7 +57,7 @@
             }
 
             if (msg instanceof LispMapRegister) {
-                LispMapServer mapServer = new LispMapServer();
+                LispMapServer mapServer = LispMapServer.getInstance();
                 LispMapNotify mapNotify =
                         mapServer.processMapRegister((LispMapRegister) msg);
 
@@ -65,7 +65,7 @@
             }
 
             if (msg instanceof LispInfoRequest) {
-                LispMapServer mapServer = new LispMapServer();
+                LispMapServer mapServer = LispMapServer.getInstance();
                 LispInfoReply infoReply = mapServer.processInfoRequest((LispInfoRequest) msg);
 
                 ctx.writeAndFlush(infoReply);
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java
index 502a3b4..a483957 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java
@@ -15,19 +15,29 @@
  */
 package org.onosproject.lisp.ctl;
 
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Deactivate;
-
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.CoreService;
 import org.onosproject.lisp.LispController;
+import org.onosproject.lisp.msg.authentication.LispAuthenticationConfig;
 import org.onosproject.net.device.DeviceService;
+import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Dictionary;
+
+import static org.onlab.util.Tools.get;
+import static org.onlab.util.Tools.getIntegerProperty;
+
 /**
  * LISP controller initiation class.
  */
@@ -40,24 +50,85 @@
     private static final Logger log =
             LoggerFactory.getLogger(LispControllerImpl.class);
 
+    private static final String DEFAULT_LISP_AUTH_KEY = "onos";
+    private static final short DEFAULT_LISP_AUTH_KEY_ID = 1;
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService cfgService;
+
+    @Property(name = "lispAuthKey", value = DEFAULT_LISP_AUTH_KEY,
+            label = "Authentication key which is used to calculate authentication " +
+                    "data for LISP control message; default value is onos")
+    protected String lispAuthKey = DEFAULT_LISP_AUTH_KEY;
+
+    @Property(name = "lispAuthKeyId", intValue = DEFAULT_LISP_AUTH_KEY_ID,
+            label = "Authentication key id which denotes the authentication method " +
+                    "that ONOS uses to calculate the authentication data; " +
+                    "1 denotes HMAC SHA1 encryption, 2 denotes HMAC SHA256 encryption; " +
+                    "default value is 1")
+    protected int lispAuthKeyId = DEFAULT_LISP_AUTH_KEY_ID;
+
     private final LispControllerBootstrap bootstrap = new LispControllerBootstrap();
+    private final LispAuthenticationConfig authConfig = LispAuthenticationConfig.getInstance();
 
     @Activate
-    public void activate() {
+    public void activate(ComponentContext context) {
+        cfgService.registerProperties(getClass());
         coreService.registerApplication(APP_ID);
+        initAuthConfig(context.getProperties());
         bootstrap.start();
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        cfgService.unregisterProperties(getClass(), false);
         bootstrap.stop();
         log.info("Stopped");
     }
+
+    @Modified
+    public void modified(ComponentContext context) {
+        readComponentConfiguration(context);
+    }
+
+    /**
+     * Initializes authentication key and authentication method.
+     *
+     * @param properties a set of properties that contained in component context
+     */
+    private void initAuthConfig(Dictionary<?, ?> properties) {
+        authConfig.updateLispAuthKey(get(properties, "lispAuthKey"));
+        authConfig.updateLispAuthKeyId(getIntegerProperty(properties, "lispAuthKeyId"));
+    }
+
+    /**
+     * Extracts properties from the component configuration context.
+     *
+     * @param context the component context
+     */
+    private void readComponentConfiguration(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+
+        String lispAuthKeyStr = Tools.get(properties, "lispAuthKey");
+        lispAuthKey = lispAuthKeyStr != null ? lispAuthKeyStr : DEFAULT_LISP_AUTH_KEY;
+        authConfig.updateLispAuthKey(lispAuthKey);
+        log.info("Configured. LISP authentication key is {}", lispAuthKey);
+
+        Integer lispAuthMethodInt = Tools.getIntegerProperty(properties, "lispAuthKeyId");
+        if (lispAuthMethodInt == null) {
+            lispAuthKeyId = DEFAULT_LISP_AUTH_KEY_ID;
+            log.info("LISP authentication method is not configured, default value is {}", lispAuthKeyId);
+        } else {
+            lispAuthKeyId = lispAuthMethodInt;
+            log.info("Configured. LISP authentication method is configured to {}", lispAuthKeyId);
+        }
+        authConfig.updateLispAuthKeyId(lispAuthKeyId);
+    }
 }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
index f664c4c..ffabf79 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
@@ -16,6 +16,7 @@
 package org.onosproject.lisp.ctl;
 
 import org.onlab.packet.IpAddress;
+import org.onosproject.lisp.msg.authentication.LispAuthenticationConfig;
 import org.onosproject.lisp.msg.protocols.DefaultLispInfoReply;
 import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
 import org.onosproject.lisp.msg.protocols.DefaultLispMapRegister.DefaultRegisterBuilder;
@@ -49,23 +50,22 @@
  * LISP map server class.
  * Handles map-register message and acknowledges with map-notify message.
  */
-public class LispMapServer {
+public final class LispMapServer {
 
     private static final int MAP_NOTIFY_PORT = 4342;
     private static final int INFO_REPLY_PORT = 4342;
 
-    // TODO: need to be configurable
-    private static final String AUTH_KEY = "onos";
-
-    // TODO: need to be configurable
-    private static final short AUTH_METHOD = 1;
-
     private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
 
-    private LispEidRlocMap mapInfo;
+    private LispEidRlocMap eidRlocMap = LispEidRlocMap.getInstance();
+    private LispAuthenticationConfig authConfig = LispAuthenticationConfig.getInstance();
 
-    public LispMapServer() {
-        mapInfo = LispEidRlocMap.getInstance();
+    public static LispMapServer getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    // non-instantiable (except for our Singleton)
+    private LispMapServer() {
     }
 
     /**
@@ -84,9 +84,9 @@
         }
 
         NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
-        notifyBuilder.withKeyId(AUTH_METHOD);
-        notifyBuilder.withAuthDataLength(valueOf(AUTH_METHOD).getHashLength());
-        notifyBuilder.withAuthKey(AUTH_KEY);
+        notifyBuilder.withKeyId(authConfig.lispAuthKeyId());
+        notifyBuilder.withAuthDataLength(valueOf(authConfig.lispAuthKeyId()).getHashLength());
+        notifyBuilder.withAuthKey(authConfig.lispAuthKey());
         notifyBuilder.withNonce(register.getNonce());
         notifyBuilder.withMapRecords(register.getMapRecords());
 
@@ -99,7 +99,7 @@
         register.getMapRecords().forEach(record -> {
             LispEidRecord eidRecord =
                     new LispEidRecord(record.getMaskLength(), record.getEidPrefixAfi());
-            mapInfo.insertMapRecord(eidRecord, record);
+            eidRlocMap.insertMapRecord(eidRecord, record);
         });
 
         return notify;
@@ -146,8 +146,8 @@
 
         InfoReplyBuilder replyBuilder = new DefaultLispInfoReply.DefaultInfoReplyBuilder();
         replyBuilder.withKeyId(request.getKeyId());
-        replyBuilder.withAuthDataLength(valueOf(AUTH_METHOD).getHashLength());
-        replyBuilder.withAuthKey(AUTH_KEY);
+        replyBuilder.withAuthDataLength(valueOf(authConfig.lispAuthKeyId()).getHashLength());
+        replyBuilder.withAuthKey(authConfig.lispAuthKey());
         replyBuilder.withNonce(request.getNonce());
         replyBuilder.withEidPrefix(request.getPrefix());
         replyBuilder.withMaskLength(request.getMaskLength());
@@ -171,7 +171,7 @@
     private boolean checkMapRegisterAuthData(LispMapRegister register) {
         RegisterBuilder registerBuilder = new DefaultRegisterBuilder();
         registerBuilder.withKeyId(register.getKeyId());
-        registerBuilder.withAuthKey(AUTH_KEY);
+        registerBuilder.withAuthKey(authConfig.lispAuthKey());
         registerBuilder.withNonce(register.getNonce());
         registerBuilder.withIsProxyMapReply(register.isProxyMapReply());
         registerBuilder.withIsWantMapNotify(register.isWantMapNotify());
@@ -192,7 +192,7 @@
     private boolean checkInfoRequestAuthData(LispInfoRequest request) {
         InfoRequestBuilder requestBuilder = new DefaultInfoRequestBuilder();
         requestBuilder.withKeyId(request.getKeyId());
-        requestBuilder.withAuthKey(AUTH_KEY);
+        requestBuilder.withAuthKey(authConfig.lispAuthKey());
         requestBuilder.withNonce(request.getNonce());
         requestBuilder.withTtl(request.getTtl());
         requestBuilder.withEidPrefix(request.getPrefix());
@@ -203,4 +203,11 @@
 
         return Arrays.equals(authRequest.getAuthData(), request.getAuthData());
     }
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private static class SingletonHelper {
+        private static final LispMapServer INSTANCE = new LispMapServer();
+    }
 }
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/authentication/LispAuthenticationConfig.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/authentication/LispAuthenticationConfig.java
new file mode 100644
index 0000000..b527c9c
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/authentication/LispAuthenticationConfig.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.lisp.msg.authentication;
+
+/**
+ * A singleton class that Stores LISP authentication information.
+ */
+public final class LispAuthenticationConfig {
+
+    private String lispAuthKey;
+    private short lispAuthKeyId;
+
+    /**
+     * Obtains an authentication info singleton instance.
+     *
+     * @return authentication info singleton instance
+     */
+    public static LispAuthenticationConfig getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    // non-instantiable (except for our Singleton)
+    private LispAuthenticationConfig() {
+    }
+
+    /**
+     * Updates LISP authentication key.
+     *
+     * @param lispAuthKey LISP authentication key
+     */
+    public void updateLispAuthKey(String lispAuthKey) {
+        this.lispAuthKey = lispAuthKey;
+    }
+
+    /**
+     * Updates LISP authentication key identifier.
+     *
+     * @param lispAuthKeyId LISP authentication key identifier
+     */
+    public void updateLispAuthKeyId(int lispAuthKeyId) {
+        this.lispAuthKeyId = (short) lispAuthKeyId;
+    }
+
+    /**
+     * Obtains LISP authentication key.
+     *
+     * @return LISP authentication key
+     */
+    public String lispAuthKey() {
+        return lispAuthKey;
+    }
+
+    /**
+     * Obtains LISP authentication key identifier.
+     *
+     * @return LISP authentication key identifier
+     */
+    public short lispAuthKeyId() {
+        return lispAuthKeyId;
+    }
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private static class SingletonHelper {
+        private static final LispAuthenticationConfig INSTANCE =
+                new LispAuthenticationConfig();
+    }
+}