ONOS-7451 ODTN TAPI connectivity service.
(still JSON cannot be converted to DataNode)
Completed with RPC PoC for ONOS-7451
Fixed style errors (import Yang classes > 120)
Change-Id: Ie565576a604ee1ccf3d046e7e461c1d132234e8f
diff --git a/apps/odtn/BUCK b/apps/odtn/BUCK
index 15eb273..60c82cb 100644
--- a/apps/odtn/BUCK
+++ b/apps/odtn/BUCK
@@ -10,6 +10,7 @@
'org.onosproject.drivers.netconf',
'org.onosproject.netconf',
'org.onosproject.configsync-netconf',
+ 'org.onosproject.protocols.restconfserver'
]
COMPILE_DEPS = [
@@ -19,6 +20,9 @@
'//apps/config:onos-apps-config',
'//models/tapi:onos-models-tapi',
'//models/openconfig:onos-models-openconfig',
+ '//apps/yang:onos-apps-yang',
+ '//incubator/api:onos-incubator-api',
+ '//lib:COMPILE'
]
TEST_DEPS = [
diff --git a/apps/odtn/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java b/apps/odtn/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
index 1facc0c..12b5e51 100644
--- a/apps/odtn/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
+++ b/apps/odtn/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
@@ -12,21 +12,65 @@
* 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.
+ *
+ *
+ * This work was partially supported by EC H2020 project METRO-HAUL (761727).
+ * Contact: Ramon Casellas <ramon.casellas@cttc.es>
*/
+
package org.onosproject.odtn.impl;
+import java.util.List;
+
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.config.DynamicConfigService;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.yang.model.SchemaContextProvider;
import org.onosproject.yang.runtime.YangRuntimeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.onosproject.config.DynamicConfigListener;
+import org.onosproject.config.DynamicConfigService;
+import org.onosproject.config.DynamicConfigEvent;
+import org.onosproject.config.Filter;
+import org.onosproject.config.FailedException;
+import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
+import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
+
+// import org.onosproject.yang.gen.v1.tapiconnectivity.rev20180216.TapiConnectivity;
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20180216.TapiConnectivityService;
+
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20180216.
+ tapiconnectivity.createconnectivityservice.CreateConnectivityServiceInput;
+
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20180216.
+ tapiconnectivity.createconnectivityservice.createconnectivityserviceinput.EndPoint;
+
+
+
+// onos-yang-tools
+import org.onosproject.yang.model.DataNode;
+
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.DefaultResourceData;
+import org.onosproject.yang.model.ModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelConverter;
+
+import org.onosproject.yang.model.ResourceId;
+import org.onosproject.yang.model.SchemaId;
+
+import org.onosproject.yang.model.RpcRegistry;
+import org.onosproject.yang.model.RpcService;
+import org.onosproject.yang.model.RpcInput;
+import org.onosproject.yang.model.RpcOutput;
+
+
/**
* OSGi Component for ODTN Service application.
*/
@@ -47,14 +91,254 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected SchemaContextProvider schemaContextProvider;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RpcRegistry rpcRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ModelConverter modelConverter;
+
+
+
+ // Listener for events from the DCS
+ private final DynamicConfigListener dynamicConfigServiceListener =
+ new InternalDynamicConfigListener();
+
+ // Rpc Service for TAPI Connectivity
+ private final RpcService rpcTapiConnectivity =
+ new TapiConnectivityRpc();
+
+
@Activate
protected void activate() {
log.info("Started");
+ dynConfigService.addListener(dynamicConfigServiceListener);
+ rpcRegistry.registerRpcService(rpcTapiConnectivity);
}
+
@Deactivate
protected void deactivate() {
log.info("Stopped");
+ rpcRegistry.unregisterRpcService(rpcTapiConnectivity);
+ dynConfigService.removeListener(dynamicConfigServiceListener);
}
+
+
+
+ /**
+ * Representation of internal listener, listening for dynamic config event.
+ */
+ private class InternalDynamicConfigListener implements DynamicConfigListener {
+
+ /**
+ * Check if the DCS event should be further processed.
+ *
+ * @param event config event
+ * @return true if event is supported; false otherwise
+ */
+ @Override
+ public boolean isRelevant(DynamicConfigEvent event) {
+ // Only care about add and delete
+ if ((event.type() != NODE_ADDED) &&
+ (event.type() != NODE_DELETED)) {
+ return false;
+ }
+ return true;
+ }
+
+
+
+
+ /**
+ * Process an Event from the Dynamic Configuration Store.
+ *
+ * @param event config event
+ */
+ @Override
+ public void event(DynamicConfigEvent event) {
+ ResourceId rsId = event.subject();
+ DataNode node;
+ try {
+ Filter filter = Filter.builder().addCriteria(rsId).build();
+ node = dynConfigService.readNode(rsId, filter);
+ } catch (FailedException e) {
+ node = null;
+ }
+ switch (event.type()) {
+ case NODE_ADDED:
+ onDcsNodeAdded(rsId, node);
+ break;
+
+ case NODE_DELETED:
+ onDcsNodeDeleted(node);
+ break;
+
+ default:
+ log.warn("Unknown Event", event.type());
+ break;
+ }
+ }
+
+
+
+ /**
+ * Process the event that a node has been added to the DCS.
+ *
+ * @param rsId ResourceId of the added node
+ * @param node added node. Access the key and value
+ */
+ private void onDcsNodeAdded(ResourceId rsId, DataNode node) {
+ switch (node.type()) {
+ case SINGLE_INSTANCE_NODE:
+ break;
+ case MULTI_INSTANCE_NODE:
+ break;
+ case SINGLE_INSTANCE_LEAF_VALUE_NODE:
+ break;
+ case MULTI_INSTANCE_LEAF_VALUE_NODE:
+ break;
+ default:
+ break;
+ }
+
+ NodeKey dataNodeKey = node.key();
+ SchemaId schemaId = dataNodeKey.schemaId();
+ if (!schemaId.namespace().contains("tapi")) {
+ return;
+ }
+
+ // Consolidate events
+ log.info("namespace {}", schemaId.namespace());
+ }
+
+
+ /**
+ * Process the event that a node has been deleted from the DCS.
+ *
+ * @param dataNode data node
+ */
+ private void onDcsNodeDeleted(DataNode dataNode) {
+ // TODO: Implement release logic
+ }
+
+ }
+
+
+
+
+
+ private class TapiConnectivityRpc implements TapiConnectivityService {
+
+
+ /**
+ * Service interface of createConnectivityService.
+ *
+ * @param inputVar input of service interface createConnectivityService
+ * @return rpcOutput output of service interface createConnectivityService
+ */
+ public RpcOutput createConnectivityService(RpcInput inputVar) {
+ DataNode data = inputVar.data();
+ ResourceId rid = inputVar.id();
+
+ log.info("RpcInput Data {}", data);
+ log.info("RpcInput ResourceId {}", rid);
+
+ for (ModelObject mo : getModelObjects(data, rid)) {
+ if (mo instanceof CreateConnectivityServiceInput) {
+ CreateConnectivityServiceInput i = (CreateConnectivityServiceInput) mo;
+ log.info("i {}", i);
+ List<EndPoint> epl = i.endPoint();
+ for (EndPoint ep : epl) {
+ log.info("ep {}", ep);
+ }
+ }
+ }
+
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+ }
+
+
+
+ /**
+ * Service interface of deleteConnectivityService.
+ *
+ * @param inputVar input of service interface deleteConnectivityService
+ * @return rpcOutput output of service interface deleteConnectivityService
+ */
+ public RpcOutput deleteConnectivityService(RpcInput inputVar) {
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+ }
+
+
+
+ /**
+ * Service interface of getConnectionDetails.
+ *
+ * @param inputVar input of service interface getConnectionDetails
+ * @return rpcOutput output of service interface getConnectionDetails
+ */
+ public RpcOutput getConnectionDetails(RpcInput inputVar) {
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+
+ }
+
+ /**
+ * Service interface of getConnectivityServiceList.
+ *
+ * @param inputVar input of service interface getConnectivityServiceList
+ * @return rpcOutput output of service interface getConnectivityServiceList
+ */
+ public RpcOutput getConnectivityServiceList(RpcInput inputVar) {
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+
+ }
+
+ /**
+ * Service interface of getConnectivityServiceDetails.
+ *
+ * @param inputVar input of service interface getConnectivityServiceDetails
+ * @return rpcOutput output of service interface getConnectivityServiceDetails
+ */
+ public RpcOutput getConnectivityServiceDetails(RpcInput inputVar) {
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+
+ }
+
+
+ /**
+ * Service interface of updateConnectivityService.
+ *
+ * @param inputVar input of service interface updateConnectivityService
+ * @return rpcOutput output of service interface updateConnectivityService
+ */
+ public RpcOutput updateConnectivityService(RpcInput inputVar) {
+ return new RpcOutput(RpcOutput.Status.RPC_FAILURE, null);
+
+ }
+
+
+ private ResourceData createResourceData(DataNode dataNode, ResourceId resId) {
+ return DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .resourceId(resId)
+ .build();
+ }
+
+ /**
+ * Returns model objects of the store.
+ *
+ * @param dataNode data node from store
+ * @param resId parent resource id
+ * @return model objects
+ */
+ private List<ModelObject> getModelObjects(DataNode dataNode, ResourceId resId) {
+ ResourceData data = createResourceData(dataNode, resId);
+ ModelObjectData modelData = modelConverter.createModel(data);
+ return modelData.modelObjects();
+ }
+
+
+
+ }
}
diff --git a/apps/odtn/src/test/resources/create-connectivity.json b/apps/odtn/src/test/resources/create-connectivity.json
new file mode 100644
index 0000000..ce3cf20
--- /dev/null
+++ b/apps/odtn/src/test/resources/create-connectivity.json
@@ -0,0 +1,52 @@
+{
+ "tapi-connectivity:input":
+ {
+ "end-point" : [
+ {
+ "layer-protocol-name" : "OTSiA",
+ "service-interface-point": "00000000-0000-4200-0001-110000000000",
+ "capacity" : {
+ },
+ "direction" : "BIDIRECTIONAL",
+ "role" : "UNKNOWN",
+ "protection-role" : "WORK",
+ "local-id": "00000000-0000-4100-0001-110000000000",
+ "name" : [
+ {
+ "value-name" : "main",
+ "value" : "sep11"
+ }
+ ],
+ "administrative-state" : "UNLOCKED",
+ "operational-state" : "ENABLED",
+ "lifecycle-state" : "INSTALLED"
+ }
+ ,
+ {
+ "layer-protocol-name" : "OTSiA",
+ "service-interface-point": "00000000-0000-4200-0001-210000000000",
+ "capacity" : {
+ },
+ "direction" : "BIDIRECTIONAL",
+ "role" : "UNKNOWN",
+ "protection-role" : "WORK",
+ "local-id": "00000000-0000-4100-0001-210000000000",
+ "name" : [
+ {
+ "value-name" : "main",
+ "value" : "sep21"
+ }
+ ],
+ "administrative-state" : "UNLOCKED",
+ "operational-state" : "ENABLED",
+ "lifecycle-state" : "INSTALLED"
+ }
+ ],
+
+ "conn-constraint" : {},
+ "topo-constraint" : {},
+ "resilience-constraint" : [ ],
+ "state" : "operational-state"
+ }
+}
+
diff --git a/apps/odtn/src/test/resources/nbi-tapi-sample.json b/apps/odtn/src/test/resources/nbi-tapi-sample.json
new file mode 100644
index 0000000..e0bd960
--- /dev/null
+++ b/apps/odtn/src/test/resources/nbi-tapi-sample.json
@@ -0,0 +1,51 @@
+{
+ "tapi-common:context": {
+ "service-interface-point": [
+ {
+ "uuid": "9F759964-2410-44AF-8522-4FCE2C3ED464",
+ "layer-protocol-name": ["DSR"],
+ "name": [
+ {
+ "value-name": "port",
+ "value": "1"
+ },
+ {
+ "value-name": "transponder",
+ "value": "TRPN_A"
+ }
+ ]
+ },
+ {
+ "uuid": "FBDDC006-8913-4509-BA71-485CFAC89567",
+ "layer-protocol-name": ["DSR"],
+ "name": [
+ {
+ "value-name": "port",
+ "value": "1"
+ },
+ {
+ "value-name": "transponder",
+ "value": "TRPN_B"
+ }
+ ]
+ }
+ ],
+ "tapi-connectivity:connectivity-service": [
+ {
+ "uuid" : "D0BF25C8-B20C-49C3-9030-1C5AEC993E44",
+ "end-point": [
+ {
+ "local-id" : "TRPN_A-1",
+ "layer-protocol-name": "DSR",
+ "service-interface-point": "9F759964-2410-44AF-8522-4FCE2C3ED464"
+ },
+ {
+ "local-id" : "TRPN_B-1",
+ "layer-protocol-name": "DSR",
+ "service-interface-point": "FBDDC006-8913-4509-BA71-485CFAC89567"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/apps/odtn/src/test/resources/post-nbi-tapi-rpc b/apps/odtn/src/test/resources/post-nbi-tapi-rpc
new file mode 100644
index 0000000..45bdb17
--- /dev/null
+++ b/apps/odtn/src/test/resources/post-nbi-tapi-rpc
@@ -0,0 +1 @@
+curl -X POST http://localhost:8181/onos/restconf/operations/tapi-connectivity:create-connectivity-service -H 'cache-control: no-cache' -H 'content-type: application/json' -d @create-connectivity.json
diff --git a/apps/odtn/src/test/resources/post-nbi-tapi-sample b/apps/odtn/src/test/resources/post-nbi-tapi-sample
new file mode 100644
index 0000000..ffdd3d9
--- /dev/null
+++ b/apps/odtn/src/test/resources/post-nbi-tapi-sample
@@ -0,0 +1,2 @@
+curl -X POST http://localhost:8181/onos/restconf/data -H 'cache-control: no-cache' -H 'content-type: application/json' -d @nbi-tapi-sample.json
+
diff --git a/models/tapi/src/main/yang/tapi-connectivity@2018-02-16.yang b/models/tapi/src/main/yang/tapi-connectivity@2018-02-16.yang
index 45f89de..f5bc637 100644
--- a/models/tapi/src/main/yang/tapi-connectivity@2018-02-16.yang
+++ b/models/tapi/src/main/yang/tapi-connectivity@2018-02-16.yang
@@ -676,6 +676,7 @@
description "none";
input {
list end-point {
+ key 'local-id';
min-elements 2;
uses connectivity-service-end-point;
description "none";