[ONOS-7566] Implementation of NetconfProxySession
Change-Id: I01cbe0b10ac36cb6db53127555b551f405acdeb1
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/AbstractNetconfSession.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/AbstractNetconfSession.java
index 2254572..7843f7d 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/AbstractNetconfSession.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/AbstractNetconfSession.java
@@ -80,6 +80,21 @@
@Override
public abstract CompletableFuture<String> rpc(String request) throws NetconfException;
+ protected CompletableFuture<CharSequence> executeRpc(String rpcString) throws NetconfException {
+ return rpc(rpcString)
+ .thenApply(msg -> {
+ // crude way of removing rpc-reply envelope
+ int begin = msg.indexOf("<data>");
+ int end = msg.lastIndexOf("</data>");
+ if (begin != -1 && end != -1) {
+ return msg.subSequence(begin, end + "</data>".length());
+ } else {
+ // FIXME probably should exceptionally fail here.
+ return msg;
+ }
+ });
+ }
+
@Override
public CompletableFuture<CharSequence> asyncGetConfig(DatastoreId datastore) throws NetconfException {
StringBuilder rpc = new StringBuilder();
@@ -102,7 +117,6 @@
@Override
public CompletableFuture<CharSequence> asyncGet() throws NetconfException {
StringBuilder rpc = new StringBuilder();
-
rpc.append(RPC_OPEN);
rpc.append(NETCONF_BASE_NAMESPACE).append(">\n");
rpc.append(GET_OPEN).append(NEW_LINE);
@@ -113,22 +127,6 @@
return executeRpc(rpc.toString());
}
- protected CompletableFuture<CharSequence> executeRpc(String rpcString) throws NetconfException {
- return rpc(rpcString)
- .thenApply(msg -> {
- // crude way of removing rpc-reply envelope
- int begin = msg.indexOf("<data>");
- int end = msg.lastIndexOf("</data>");
- if (begin != -1 && end != -1) {
- return msg.subSequence(begin, end + "</data>".length());
- } else {
- // FIXME probably should exceptionally fail here.
- return msg;
- }
- });
-
- }
-
@Override
public String get(String request) throws NetconfException {
return requestSync(request);
@@ -362,10 +360,14 @@
public abstract Set<String> getDeviceCapabilitiesSet();
@Override
- public abstract void addDeviceOutputListener(NetconfDeviceOutputEventListener listener);
+ public void addDeviceOutputListener(NetconfDeviceOutputEventListener listener) throws NetconfException {
+ throw new NetconfException("Only master session can call addDeviceOutputListener");
+ }
@Override
- public abstract void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener);
+ public void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener) throws NetconfException {
+ throw new NetconfException("Only master session can call removeDeviceOutputListener");
+ }
/**
* Checks errors in reply from the session.
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java
index 041c379..45d81d2 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfController.java
@@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
/**
* Abstraction of an NETCONF controller. Serves as a one stop shop for obtaining
@@ -53,6 +54,20 @@
NetconfDevice connectDevice(DeviceId deviceId) throws NetconfException;
/**
+ * Tries to connect to a specific NETCONF device, if the connection is succesful
+ * it creates and adds the device to the ONOS core as a NetconfDevice.
+ * If isMaster true: Will create two sessions for a device : secure transport session and proxy session.
+ * If isMaster false: Will create only proxy session.
+ * @param deviceId deviceId of the device to connect
+ * @param isMaster if the controller is master for the device
+ * @return NetconfDevice Netconf device
+ * @throws NetconfException when device is not available
+ */
+ default NetconfDevice connectDevice(DeviceId deviceId, boolean isMaster) throws NetconfException {
+ return connectDevice(deviceId);
+ }
+
+ /**
* Disconnects a Netconf device and removes it from the core.
*
* @param deviceId id of the device to remove
@@ -107,4 +122,20 @@
* @return NetconfDevice Netconf device
*/
NetconfDevice getNetconfDevice(IpAddress ip, int port, String path);
+
+ /**
+ * If master, will execute the call locally else will use
+ * clusterCommunicationManager to execute at master controller.
+ * Meant only for internal synchronization and not to be used by applications.
+ *
+ * @param proxyMessage proxy message
+ * @param <T> return type
+ * @return Completable future of class T
+ * @throws NetconfException netconf exception
+ */
+ default <T> CompletableFuture<T> executeAtMaster(NetconfProxyMessage proxyMessage) throws NetconfException {
+ CompletableFuture<T> errorFuture = new CompletableFuture<>();
+ errorFuture.completeExceptionally(new NetconfException("Method executeAtMaster not implemented"));
+ return errorFuture;
+ }
}
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java
index 639f0a8..8c756e5 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDevice.java
@@ -24,13 +24,22 @@
/**
* Returns whether a device is a NETCONF device with a capabilities list
- * and is accessible.
+ * and is accessible, through a secure transport session or a proxy session.
*
* @return true if device is accessible, false otherwise
*/
boolean isActive();
/**
+ * Returns whether the device has secure transport session.
+ *
+ * @return true if secure transport session exists, false otherwise
+ */
+ default boolean isMasterSession() {
+ return isActive();
+ }
+
+ /**
* Returns a NETCONF session context for this device.
*
* @return netconf session
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceFactory.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceFactory.java
index 312c7c3..53e5db7 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceFactory.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfDeviceFactory.java
@@ -16,6 +16,8 @@
package org.onosproject.netconf;
+import com.google.common.annotations.Beta;
+
/**
* Abstract interface for the creation of a NETCONF device.
*/
@@ -31,4 +33,19 @@
*/
NetconfDevice createNetconfDevice(NetconfDeviceInfo netconfDeviceInfo)
throws NetconfException;
+
+ /**
+ * Creates a new NETCONF device based on the supplied information.
+ * @param netconfDeviceInfo information of the device to create.
+ * @param isMaster if true create secure transport session with the device,
+ * else just create a proxy session
+ * @return Instance of NetconfDevice.
+ * @throws NetconfException when problems arise creating the device and establishing
+ * the connection.
+ */
+ @Beta
+ default NetconfDevice createNetconfDevice(NetconfDeviceInfo netconfDeviceInfo,
+ boolean isMaster) throws NetconfException {
+ return createNetconfDevice(netconfDeviceInfo);
+ }
}
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessage.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessage.java
new file mode 100644
index 0000000..8ebfbe3
--- /dev/null
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessage.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.netconf;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.List;
+
+/**
+ * Interface representing a NETCONF proxy message.
+ */
+public interface NetconfProxyMessage {
+
+ enum SubjectType {
+ RPC,
+ // FIXME in the final form there should only be (async) RPC
+ // and REQUEST, REQUEST_SYNC should go away
+ // once NetconfSession methods got cleaned up.
+ REQUEST,
+ REQUEST_SYNC,
+ START_SUBSCRIPTION,
+ END_SUBSCRIPTION,
+ GET_SESSION_ID,
+ GET_DEVICE_CAPABILITIES_SET,
+ SET_ONOS_CAPABILITIES
+ }
+
+ /**
+ * Returns the subject of the message.
+ *
+ * @return subject in enum subject type
+ */
+ NetconfProxyMessage.SubjectType subjectType();
+
+ /**
+ * Returns the device id of the device to which the message is intended.
+ * @return device id
+ */
+ DeviceId deviceId();
+
+ /**
+ * Returns the arguments of the intended method call in order.
+ * @return arguments
+ */
+ List<String> arguments();
+}
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessageHandler.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessageHandler.java
new file mode 100644
index 0000000..a1d4d74
--- /dev/null
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfProxyMessageHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.netconf;
+
+/**
+ * Abstract interface for the implementation of proxy message handler.
+ */
+public interface NetconfProxyMessageHandler {
+ /**
+ * Will decode the message on case basis and
+ * call the actual method in Netconf Session implementation bound to secure transport.
+ * @param proxyMessage incoming proxy message
+ * @param <T> return type
+ * @return the value returned by session call
+ * @throws NetconfException netconf exception
+ */
+ <T> T handleIncomingMessage(NetconfProxyMessage proxyMessage) throws NetconfException;
+}
\ No newline at end of file
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
index bc04118..d0c80de 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSession.java
@@ -122,6 +122,19 @@
String requestSync(String request) throws NetconfException;
/**
+ * Executes an synchronous RPC to the server with specific reply TIMEOUT.
+ *
+ * @param request the XML containing the RPC for the server.
+ * @param timeout the reply timeout.
+ * @return Server response or ERROR
+ * @throws NetconfException when there is a problem in the communication process on
+ * the underlying connection
+ */
+ default String requestSync(String request, int timeout) throws NetconfException {
+ return "";
+ }
+
+ /**
* Retrieves the specified configuration.
*
* @param netconfTargetConfig the type of configuration to retrieve.
@@ -341,15 +354,17 @@
* Add a listener to the underlying stream handler implementation.
*
* @param listener event listener.
+ * @throws NetconfException when this method will be called by STANDBY or NONE node.
*/
- void addDeviceOutputListener(NetconfDeviceOutputEventListener listener);
+ void addDeviceOutputListener(NetconfDeviceOutputEventListener listener) throws NetconfException;
/**
* Remove a listener from the underlying stream handler implementation.
*
* @param listener event listener.
+ * @throws NetconfException when this method will be called by STANDBY or NONE node.
*/
- void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener);
+ void removeDeviceOutputListener(NetconfDeviceOutputEventListener listener) throws NetconfException;
/**
* Read the connect timeout that this session was created with.
diff --git a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSessionFactory.java b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSessionFactory.java
index 806eccb..95f32a4 100644
--- a/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSessionFactory.java
+++ b/protocols/netconf/api/src/main/java/org/onosproject/netconf/NetconfSessionFactory.java
@@ -25,9 +25,11 @@
/**
* Creates a new NETCONF session for the specified device.
* @param netconfDeviceInfo information of the device to create the session for.
+ * @param netconfController netconf controller object
* @return Instance of NetconfSession.
* @throws NetconfException when problems arise establishing the connection.
*/
- NetconfSession createNetconfSession(NetconfDeviceInfo netconfDeviceInfo)
+ NetconfSession createNetconfSession(NetconfDeviceInfo netconfDeviceInfo,
+ NetconfController netconfController)
throws NetconfException;
}