ONOS-7827 TAPI Phot. OpticalConnectivity intent.
Change-Id: I34bcc2a2bce4dbd6cca5c99f96e78cee0a53d690
diff --git a/apps/odtn/service/BUILD b/apps/odtn/service/BUILD
index d8cd167..abf6ee6 100644
--- a/apps/odtn/service/BUILD
+++ b/apps/odtn/service/BUILD
@@ -3,6 +3,7 @@
"//apps/config:onos-apps-config",
"//models/tapi:onos-models-tapi",
"//apps/yang:onos-apps-yang",
+ "//apps/optical-model:onos-apps-optical-model",
"//protocols/netconf/api:onos-protocols-netconf-api",
]
@@ -24,6 +25,7 @@
"org.onosproject.drivers.netconf", # will need if using TemplateManager
"org.onosproject.drivers.odtn-driver",
"org.onosproject.netconf",
+ "org.onosproject.optical-model",
"org.onosproject.configsync-netconf",
"org.onosproject.protocols.restconfserver",
]
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityConfig.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityConfig.java
new file mode 100644
index 0000000..580dd2a
--- /dev/null
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityConfig.java
@@ -0,0 +1,129 @@
+/*
+ * 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.odtn;
+
+import org.onosproject.net.ConnectPoint;
+import java.util.Objects;
+
+/**
+ * Configuration related to a TAPI Connectivity.
+ *
+ * At this point, the class only conveys the
+ * Connectivity service uuid, the ConnectPoints
+ * obtained from the TAPI SIP and a boolean that
+ * means setup or release. Additional attributes
+ * may be needed when we further parse the TAPI
+ * request, this class will grow accordingly.
+ */
+public final class TapiConnectivityConfig {
+
+ private final String uuid;
+ private final ConnectPoint left;
+ private final ConnectPoint right;
+ private final boolean setup;
+
+
+ /**
+ * Constructor with the Connection uuid and endpoints.
+ *
+ * @param uuid - TAPI uuid of the connection.
+ * @param leftCp Left (ingress) ConnectPoint.
+ * @param rightCp Right (egress) ConnectPoint.
+ * @param setup True or false (setup or release).
+ */
+ public TapiConnectivityConfig(String uuid, ConnectPoint leftCp,
+ ConnectPoint rightCp, Boolean setup) {
+ this.uuid = uuid;
+ this.left = leftCp;
+ this.right = rightCp;
+ this.setup = setup;
+ }
+
+ /**
+ * Get the UUID associated to this TAPI connectivity rquest.
+ *
+ * @return the UUID.
+ */
+ public String uuid() {
+ return uuid;
+ }
+
+
+ /**
+ * Get the left (first) ConnectPoint of the request.
+ * The left CP corresponds to the first endpoint in the TAPI
+ * request.
+ *
+ * @return the connect point.
+ */
+ public ConnectPoint leftCp() {
+ return left;
+ }
+
+
+ /**
+ * Get the right (second) ConnectPoint of the request.
+ * The right CP corresponds to the second endpoint in the TAPI
+ * request.
+ *
+ * @return the connect point.
+ */
+ public ConnectPoint rightCp() {
+ return right;
+ }
+
+ /**
+ * Check if the request is for a setup or release.
+ *
+ * @return True for a setup request, False otherwise.
+ */
+ public Boolean isSetup() {
+ return setup;
+ }
+
+
+ /**
+ * Equals comparison.
+ *
+ * @return True if this:Object.equals(o)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof TapiConnectivityConfig)) {
+ return false;
+ }
+ TapiConnectivityConfig that = (TapiConnectivityConfig) o;
+ return Objects.equals(uuid, that.uuid) &&
+ Objects.equals(left, that.left) &&
+ Objects.equals(right, that.right) &&
+ Objects.equals(setup, that.setup);
+ }
+
+
+ /**
+ * Get the hashcode for the TapiConnectivityConfig Object.
+ *
+ * @return the result of Objects.hash
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(uuid, left, right, setup);
+ }
+}
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityService.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityService.java
new file mode 100644
index 0000000..1c4fb18
--- /dev/null
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/TapiConnectivityService.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.odtn;
+
+/**
+ * TAPI ConnectivityService Processor.
+ */
+public interface TapiConnectivityService {
+
+ /**
+ * Process a Setup or Release of a Connectivity Service.
+ *
+ * @param config TAPI configuration data
+ */
+ void processTapiEvent(TapiConnectivityConfig config);
+
+}
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
index 9e4bed3..e9985c6 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/impl/ServiceApplicationComponent.java
@@ -25,27 +25,39 @@
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
+
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.Port;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
+
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
-import org.onosproject.net.device.DeviceService;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REMOVED;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
+import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+
+
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
+
import org.onosproject.odtn.TapiResolver;
+import org.onosproject.odtn.TapiConnectivityConfig;
+import org.onosproject.odtn.TapiConnectivityService;
import org.onosproject.odtn.TapiTopologyManager;
import org.onosproject.odtn.config.TerminalDeviceConfig;
import org.onosproject.odtn.internal.DcsBasedTapiCommonRpc;
import org.onosproject.odtn.internal.DcsBasedTapiConnectivityRpc;
-import org.onosproject.odtn.internal.DcsBasedTapiDataProducer;
-import org.onosproject.odtn.internal.TapiDataProducer;
import org.onosproject.odtn.internal.DefaultOdtnTerminalDeviceDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,16 +70,33 @@
import static org.onosproject.config.DynamicConfigEvent.Type.NODE_ADDED;
import static org.onosproject.config.DynamicConfigEvent.Type.NODE_DELETED;
-import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
-import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REMOVED;
-import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
-import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
+
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import static org.onosproject.net.intent.IntentState.FAILED;
+import static org.onosproject.net.intent.IntentState.WITHDRAWN;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+import org.onosproject.net.optical.OchPort;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduSignalType;
+
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* OSGi Component for ODTN Service application.
*/
-@Component(immediate = true)
-public class ServiceApplicationComponent {
+@Component(immediate = true, service = TapiConnectivityService.class)
+public class ServiceApplicationComponent implements TapiConnectivityService {
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -78,9 +107,15 @@
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected IntentService intentService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
protected LinkService linkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
protected NetworkConfigService netcfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -95,6 +130,12 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected TapiResolver resolver;
+ private static final int WITHDRAW_EVENT_TIMEOUT_SECONDS = 5;
+
+ private static final String APP_ID = "org.onosproject.odtn-service";
+
+ private ApplicationId appId;
+
// Listener for events from the DCS
private final DynamicConfigListener dynamicConfigServiceListener =
new InternalDynamicConfigListener();
@@ -102,7 +143,6 @@
private DeviceListener deviceListener = new InternalDeviceListener();
private final LinkListener linkListener = new InternalLinkListener();
private final NetworkConfigListener netcfgListener = new InternalNetCfgListener();
- private TapiDataProducer dataProvider = new DcsBasedTapiDataProducer();
// Rpc Service for TAPI Connectivity
private final DcsBasedTapiConnectivityRpc rpcTapiConnectivity = new DcsBasedTapiConnectivityRpc();
@@ -112,16 +152,17 @@
private final ConfigFactory<ConnectPoint, TerminalDeviceConfig> factory =
new ConfigFactory<ConnectPoint, TerminalDeviceConfig>(CONNECT_POINT_SUBJECT_FACTORY,
TerminalDeviceConfig.class, TerminalDeviceConfig.CONFIG_KEY) {
+
@Override
public TerminalDeviceConfig createConfig() {
return new TerminalDeviceConfig();
}
};
-
@Activate
protected void activate() {
log.info("Started");
+ appId = coreService.registerApplication(APP_ID);
dynConfigService.addListener(dynamicConfigServiceListener);
deviceService.addListener(deviceListener);
linkService.addListener(linkListener);
@@ -134,7 +175,6 @@
rpcTapiCommon.init();
}
-
@Deactivate
protected void deactivate() {
log.info("Stopped");
@@ -149,10 +189,105 @@
/**
+ * Process TAPI Event from NBI.
+ *
+ * @param config TAPI Connectivity config for the event
+ */
+ public void processTapiEvent(TapiConnectivityConfig config) {
+ checkNotNull(config, "Config can't be null");
+ Key key = Key.of(config.uuid(), appId);
+ // Setup the Intent
+ if (config.isSetup()) {
+ log.debug("TAPI config: {} to setup intent", config);
+ Intent intent = createOpticalIntent(config.leftCp(), config.rightCp(), key, appId);
+ intentService.submit(intent);
+ } else {
+ // Release the intent
+ Intent intent = intentService.getIntent(key);
+ if (intent == null) {
+ log.error("Intent for uuid {} does not exist", config.uuid());
+ return;
+ }
+ log.debug("TAPI config: {} to purge intent {}", config, intent);
+ CountDownLatch latch = new CountDownLatch(1);
+ IntentListener listener = new DeleteListener(key, latch);
+ intentService.addListener(listener);
+ try {
+ /*
+ * RCAS: Note, withdraw is asynchronous. We cannot call purge
+ * directly, because at this point it remains in the "INSTALLED"
+ * state.
+ */
+ intentService.withdraw(intent);
+
+ /*
+ * org.onosproject.onos-core-net - 2.1.0.SNAPSHOT |
+ * Purge for intent 0x0 is rejected because intent state is INSTALLED
+ * intentService.purge(intent);
+ */
+ try {
+ latch.await(WITHDRAW_EVENT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ // double check the state
+ IntentState state = intentService.getIntentState(key);
+ if (state == WITHDRAWN || state == FAILED) {
+ intentService.purge(intent);
+ }
+ } finally {
+ intentService.removeListener(listener);
+ }
+ }
+ }
+
+ /**
+ * Returns a new optical intent created from the method parameters.
+ *
+ * @param ingress ingress description (device/port)
+ * @param egress egress description (device/port)
+ * @param key intent key
+ * @param appId application id. As per Intent class, it cannot be null
+ *
+ * @return created intent
+ */
+ protected Intent createOpticalIntent(ConnectPoint ingress, ConnectPoint egress,
+ Key key, ApplicationId appId) {
+ Intent intent = null;
+ if (ingress == null || egress == null) {
+ log.error("Invalid endpoint(s) for optical intent: ingress {}, egress {}",
+ ingress, egress);
+ return null;
+ }
+ DeviceService ds = opticalView(deviceService);
+ Port srcPort = ds.getPort(ingress.deviceId(), ingress.port());
+ Port dstPort = ds.getPort(egress.deviceId(), egress.port());
+ if (srcPort == null || dstPort == null) {
+ log.error("Invalid port(s) for optical intent: src {}, dst {}",
+ srcPort, dstPort);
+ return null;
+ }
+
+ // OchSignal signal = new OchSignal(GridType.FLEX, ChannelSpacing.CHL_6P25GHZ, 1, 1);
+ OchSignal signal = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1);
+ OduSignalType signalType = ((OchPort) srcPort).signalType();
+ intent = OpticalConnectivityIntent.builder()
+ .appId(appId)
+ .key(key)
+ .src(ingress)
+ .dst(egress)
+ .signalType(signalType)
+ .bidirectional(true)
+ .ochSignal(signal)
+ .build();
+ return intent;
+ }
+
+
+ /**
* Representation of internal listener, listening for device event.
*/
private class InternalDeviceListener implements DeviceListener {
-
/**
* Process an Event from the Device Service.
*
@@ -188,7 +323,6 @@
* Representation of internal listener, listening for link event.
*/
private class InternalLinkListener implements LinkListener {
-
/**
* Process an Event from the Device Service.
*
@@ -212,11 +346,11 @@
}
}
+
/**
* Representation of internal listener, listening for netcfg event.
*/
private class InternalNetCfgListener implements NetworkConfigListener {
-
/**
* Check if the netcfg event should be further processed.
*
@@ -225,7 +359,6 @@
*/
@Override
public boolean isRelevant(NetworkConfigEvent event) {
-
if (event.type() == CONFIG_ADDED || event.type() == CONFIG_UPDATED) {
if (event.config().orElse(null) instanceof TerminalDeviceConfig) {
return true;
@@ -246,23 +379,18 @@
*/
@Override
public void event(NetworkConfigEvent event) {
-
log.debug("Event type: {}, subject: {}", event.type(), event.subject());
DeviceId did = ((ConnectPoint) event.subject()).deviceId();
-
+ TerminalDeviceConfig config = (TerminalDeviceConfig) event.config().get();
DefaultOdtnTerminalDeviceDriver driver = DefaultOdtnTerminalDeviceDriver.create();
- TerminalDeviceConfig config;
-
+ log.debug("config: {}", config);
switch (event.type()) {
case CONFIG_ADDED:
case CONFIG_UPDATED:
- config = (TerminalDeviceConfig) event.config().get();
- log.debug("config: {}", config);
driver.apply(did, config.clientCp().port(), config.subject().port(), config.isEnabled());
break;
+
case CONFIG_REMOVED:
- config = (TerminalDeviceConfig) event.prevConfig().get();
- log.debug("config: {}", config);
driver.apply(did, config.clientCp().port(), config.subject().port(), false);
break;
default:
@@ -271,6 +399,35 @@
}
}
+
+ /**
+ * Internal listener for tracking the intent deletion events.
+ */
+ private class DeleteListener implements IntentListener {
+ final Key key;
+ final CountDownLatch latch;
+
+ /**
+ * Default constructor.
+ *
+ * @param key key
+ * @param latch count down latch
+ */
+ DeleteListener(Key key, CountDownLatch latch) {
+ this.key = key;
+ this.latch = latch;
+ }
+
+ @Override
+ public void event(IntentEvent event) {
+ if (Objects.equals(event.subject().key(), key) &&
+ (event.type() == IntentEvent.Type.WITHDRAWN ||
+ event.type() == IntentEvent.Type.FAILED)) {
+ latch.countDown();
+ }
+ }
+ }
+
/**
* Representation of internal listener, listening for dynamic config event.
*/
@@ -301,69 +458,7 @@
@Override
public void event(DynamicConfigEvent event) {
resolver.makeDirty();
-// 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();
-
- // Consolidate events
-// if (!schemaId.namespace().contains("tapi")) {
-// return;
-// }
-// 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
-// }
-
}
}
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
index b585506..daf31e1 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectionManager.java
@@ -22,8 +22,9 @@
import java.util.concurrent.atomic.AtomicReference;
import org.onosproject.config.FailedException;
-import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.odtn.TapiResolver;
+import org.onosproject.odtn.TapiConnectivityConfig;
+import org.onosproject.odtn.TapiConnectivityService;
import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
import org.onosproject.odtn.utils.tapi.DcsBasedTapiObjectRefFactory;
import org.onosproject.odtn.utils.tapi.TapiCepPair;
@@ -32,6 +33,11 @@
import org.onosproject.odtn.utils.tapi.TapiCepRefHandler;
import org.onosproject.odtn.utils.tapi.TapiConnectionHandler;
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20181210.tapiconnectivity.connectivitycontext.DefaultConnection;
+import org.onosproject.yang.gen.v1.tapiconnectivity.rev20181210.tapiconnectivity.connection.ConnectionEndPoint;
+
+import org.onosproject.net.ConnectPoint;
+
import org.onosproject.odtn.utils.tapi.TapiNepRef;
import org.onosproject.odtn.utils.tapi.TapiRouteHandler;
import org.slf4j.Logger;
@@ -39,55 +45,108 @@
import static org.onlab.osgi.DefaultServiceDirectory.getService;
+
+
/**
* DCS-dependent Tapi connection manager implementation.
*/
public final class DcsBasedTapiConnectionManager implements TapiConnectionManager {
private final Logger log = LoggerFactory.getLogger(getClass());
+
protected TapiPathComputer connectionController;
private TapiResolver resolver;
- private NetworkConfigService netcfgService;
+ private TapiConnectivityService processor;
private List<DcsBasedTapiConnectionManager> connectionManagerList = new ArrayList<>();
private TapiConnection connection = null;
private TapiConnectionHandler connectionHandler = TapiConnectionHandler.create();
private Operation op = null;
-
enum Operation {
CREATE,
DELETE
}
private DcsBasedTapiConnectionManager() {
+ connectionController = DefaultTapiPathComputer.create();
+ resolver = getService(TapiResolver.class);
+ processor = getService(TapiConnectivityService.class);
}
public static DcsBasedTapiConnectionManager create() {
- DcsBasedTapiConnectionManager self = new DcsBasedTapiConnectionManager();
- self.connectionController = DefaultTapiPathComputer.create();
- self.resolver = getService(TapiResolver.class);
- self.netcfgService = getService(NetworkConfigService.class);
- return self;
+ return new DcsBasedTapiConnectionManager();
}
+
@Override
public TapiConnectionHandler createConnection(TapiNepPair neps) {
// Calculate route
TapiConnection connection = connectionController.pathCompute(neps);
- log.info("Calculated path: {}", connection);
-
+ log.debug("Calculated path: {}", connection);
createConnectionRecursively(connection);
+
+ /*
+ * RCAS Create Intent: Assume that if the result of the pathCompute is flat
+ * and there are no lower connections, it has to be mapped to an intent
+ * It is a connection between line ports (OCh) with an OpticalConnectivity
+ * Intent.
+ */
+ if (connection.getLowerConnections().isEmpty()) {
+ TapiNepRef left = neps.left();
+ TapiNepRef right = neps.right();
+ ConnectPoint leftConnectPoint = left.getConnectPoint();
+ ConnectPoint rightConnectPoint = right.getConnectPoint();
+ log.debug("Creating Intent from {} to {} {}",
+ leftConnectPoint,
+ rightConnectPoint,
+ connectionHandler.getId());
+ notifyTapiConnectivityChange(connectionHandler.getId().toString(),
+ leftConnectPoint,
+ rightConnectPoint,
+ true);
+ }
return connectionHandler;
}
@Override
public void deleteConnection(TapiConnectionHandler connectionHandler) {
+ // Retrieve the target to be deleted (right now we have the uuid)
+ connectionHandler.read();
+ // Remove Intent if exists
+ if (connectionHandler.getLowerConnections().isEmpty()) {
+ // Connection object
+ DefaultConnection connection = connectionHandler.getModelObject();
+ // These are two connection.ConnectionEndpoint (Actually Refs, mainly UUID)
+ ConnectionEndPoint cepLeft = connection.connectionEndPoint().get(0);
+ ConnectionEndPoint cepRight = connection.connectionEndPoint().get(1);
+
+ TapiNepRef left = TapiNepRef.create(
+ cepLeft.topologyUuid().toString(),
+ cepLeft.nodeUuid().toString(),
+ cepLeft.nodeEdgePointUuid().toString());
+
+ TapiNepRef right = TapiNepRef.create(
+ cepRight.topologyUuid().toString(),
+ cepRight.nodeUuid().toString(),
+ cepRight.nodeEdgePointUuid().toString());
+
+ // update with latest data in DCS
+ left = resolver.getNepRef(left);
+ right = resolver.getNepRef(right);
+ log.debug("Removing intent connection: {}", connection);
+ notifyTapiConnectivityChange(
+ connectionHandler.getId().toString(),
+ left.getConnectPoint(),
+ right.getConnectPoint(),
+ false);
+ }
deleteConnectionRecursively(connectionHandler);
}
+
@Override
public void apply() {
connectionManagerList.forEach(DcsBasedTapiConnectionManager::apply);
@@ -106,6 +165,8 @@
}
}
+
+
/**
* Emit NetworkConfig event with parameters for device config,
* to notify configuration change to device drivers.
@@ -137,6 +198,16 @@
eventEmitter.emit(line.get(), client.get(), enable);
}
+
+
+ /**
+ * Request Application to setup / release Intent.
+ */
+ private void notifyTapiConnectivityChange(String uuid, ConnectPoint left, ConnectPoint right, boolean enable) {
+ TapiConnectivityConfig cfg = new TapiConnectivityConfig(uuid, left, right, enable);
+ processor.processTapiEvent(cfg);
+ }
+
/**
* Generate TAPI connection and its under connections recursively
* and add them to creation queue.
@@ -179,10 +250,7 @@
op = Operation.DELETE;
connectionManagerList.clear();
- // read target to be deleted
- connectionHandler.read();
log.info("model: {}", connectionHandler.getModelObject());
-
this.connection = TapiConnection.create(
TapiCepPair.create(
DcsBasedTapiObjectRefFactory.create(connectionHandler.getCeps().get(0)),
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
index 82c8ee2..d5f2962 100755
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DcsBasedTapiConnectivityRpc.java
@@ -65,6 +65,7 @@
resolver = getService(TapiResolver.class);
}
+
/**
* Service interface of createConnectivityService.
*
@@ -89,19 +90,21 @@
List<TapiNepRef> nepRefs = input.getSips().stream()
.map(sipId -> resolver.getNepRef(sipId))
.collect(Collectors.toList());
- // for test
-// Map<String, String> filter = new HashMap<>();
-// filter.put(ODTN_PORT_TYPE, OdtnDeviceDescriptionDiscovery.OdtnPortType.CLIENT.value());
-// List<TapiNepRef> nepRefs = resolver.getNepRefs(filter);
// setup connections
TapiNepPair neps = TapiNepPair.create(nepRefs.get(0), nepRefs.get(1));
- DcsBasedTapiConnectionManager connectionManager = DcsBasedTapiConnectionManager.create();
- connectionManager.createConnection(neps);
- // setup connectivity service
+ // Allocate a connectivity Service
TapiConnectivityServiceHandler connectivityServiceHandler = TapiConnectivityServiceHandler.create();
- connectivityServiceHandler.addConnection(connectionManager.getConnectionHandler().getModelObject().uuid());
+
+ // This connectivity service will be supported over a single end-to-end connection
+ // Allocate a manager for that connection
+ DcsBasedTapiConnectionManager connectionManager = DcsBasedTapiConnectionManager.create();
+ TapiConnectionHandler connectionHandler = connectionManager.createConnection(neps);
+
+ // Add the supporting connection uuid to the service
+ connectivityServiceHandler.addConnection(connectionHandler.getModelObject().uuid());
+
neps.stream()
.map(nepRef -> TapiSepHandler.create().setSip(nepRef.getSipId()))
.forEach(sepBuilder -> {
@@ -113,7 +116,9 @@
connectivityServiceHandler.add();
// output
- TapiCreateConnectivityOutputHandler output = TapiCreateConnectivityOutputHandler.create()
+ TapiCreateConnectivityOutputHandler output =
+ TapiCreateConnectivityOutputHandler
+ .create()
.addService(connectivityServiceHandler.getModelObject());
return new RpcOutput(RpcOutput.Status.RPC_SUCCESS, output.getDataNode());
@@ -136,17 +141,20 @@
try {
TapiDeleteConnectivityInputHandler input = new TapiDeleteConnectivityInputHandler();
input.setRpcInput(inputVar);
- log.info("input serviceId: {}", input.getId());
+ log.info("deleteConnectivityService - serviceId: {}", input.getId());
+ // Retrieve the Connectivity Service from the DCS, based on Id
TapiConnectivityServiceHandler serviceHandler = TapiConnectivityServiceHandler.create();
serviceHandler.setId(input.getId());
-
DefaultConnectivityService service = serviceHandler.read();
+ // For each top-most connection of the service handler, delete that connection
+ // using a manager
service.connection().stream().forEach(connection -> {
TapiConnectionHandler connectionHandler = TapiConnectionHandler.create();
connectionHandler.setId(Uuid.fromString(connection.connectionUuid().toString()));
DcsBasedTapiConnectionManager manager = DcsBasedTapiConnectionManager.create();
+ log.info("deleteConnectivityService - connectionId: {}", connectionHandler.getId());
manager.deleteConnection(connectionHandler);
manager.apply();
});
diff --git a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
index f7688cc..c26f26e 100644
--- a/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
+++ b/apps/odtn/service/src/main/java/org/onosproject/odtn/internal/DefaultTapiPathComputer.java
@@ -30,6 +30,7 @@
import static org.onosproject.odtn.utils.tapi.TapiObjectHandler.DEVICE_ID;
import static org.onosproject.odtn.utils.tapi.TapiObjectHandler.ODTN_PORT_TYPE;
import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.CONNECTION_ID;
+import static org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +65,24 @@
* as list of Cep pair for each connection to be created
*/
private TapiConnection pathComputeDetail(TapiNepPair neps) {
- return mockPathCompute(neps);
+ log.debug("TapiNepPair {}", neps);
+ log.debug("Nep0 {}", neps.left());
+ log.debug("Nep1 {}", neps.right());
+
+ /*
+ * RCAS: 20190117 - We assume that if port type is LINE, it relies on intents.
+ * We construct just a single top-most connection object.
+ */
+ if (neps.left().getPortType() == LINE) {
+ log.info("Connection between line ports");
+ TapiConnection connection = TapiConnection.create(
+ TapiCepRef.create(neps.left(), neps.left().getCepIds().get(0)),
+ TapiCepRef.create(neps.right(), neps.right().getCepIds().get(0))
+ );
+ return connection;
+ } else {
+ return mockPathCompute(neps);
+ }
}