Porting CE app to 4.1
Change-Id: Ic3280ce797f6225773ade789d9793ae445f9f525
diff --git a/global/virtualprovider/pom.xml b/global/virtualprovider/pom.xml
new file mode 100644
index 0000000..0438e93
--- /dev/null
+++ b/global/virtualprovider/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2017-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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opencord.ce</groupId>
+ <artifactId>global</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>virtualprovider</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>Topology provider in the global orchestrator</description>
+
+ <properties>
+ <onos.app.name>org.opencord.ce.global.vprovider</onos.app.name>
+ <onos.version>1.10.6</onos.version>
+ <onos.app.url>http://opencord.org</onos.app.url>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <version>${onos.version}</version>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases><enabled>false</enabled></releases>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases><enabled>false</enabled></releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
new file mode 100644
index 0000000..d1bdefb
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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.apache.felix.scr.annotations.Service;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.opencord.ce.api.services.virtualprovider.DomainVirtualDevice;
+import org.opencord.ce.api.services.virtualprovider.EcordDeviceProviderService;
+import org.onlab.packet.ChassisId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+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.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.domain.DomainId;
+import org.onosproject.net.provider.ProviderId;
+import org.opencord.ce.api.models.CarrierEthernetEnni;
+import org.opencord.ce.api.models.CarrierEthernetGenericNi;
+import org.opencord.ce.api.models.CarrierEthernetInni;
+import org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+import org.opencord.ce.global.virtualdomain.config.EcordDriverConfig;
+import org.opencord.ce.global.virtualdomain.config.XosEndPointConfig;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.AnnotationKeys.DRIVER;
+import static org.onosproject.net.AnnotationKeys.LATITUDE;
+import static org.onosproject.net.AnnotationKeys.LONGITUDE;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.api.models.CarrierEthernetNetworkInterface.Type;
+
+/**
+ * Exposes remote domain devices to the core.
+ */
+@Component(immediate = true)
+@Service(value = EcordDeviceProviderService.class)
+public class VirtualDomainDeviceProvider
+ implements DeviceProvider, EcordDeviceProviderService {
+ private final Logger log = getLogger(getClass());
+ public static final String PROVIDER_NAME = "org.opencord.ce.global.vprovider";
+ public static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
+ private static final String UNKNOWN = "unknown";
+ private static final String NO_LLDP = "no-lldp";
+ private static final String DOMAIN_ID = "domainId";
+ private static final String MEF_IF_TYPE = "mefIfType";
+
+ private ApplicationId appId;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry configRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigService configService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceProviderRegistry deviceProviderRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipAdminService mastershipAdminService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MetroOrchestrationService metroOrchestrationService;
+
+ protected DeviceProviderService deviceProviderService;
+
+ private EcordDriverConfig ecordDriverConfig;
+ private XoSHttpClient xoSHttpClient;
+
+ private final NetworkConfigListener configListener = new InternalConfigListener();
+
+ /*
+ private final ConfigFactory<ApplicationId, EcordDriverConfig> diverConfigFactory =
+ new ConfigFactory<ApplicationId, EcordDriverConfig>(APP_SUBJECT_FACTORY,
+ EcordDriverConfig.class, "driver") {
+ @Override
+ public EcordDriverConfig createConfig() {
+ return new EcordDriverConfig();
+ }
+ };
+ */
+
+ private final ConfigFactory<ApplicationId, XosEndPointConfig> xosEndpointConfigFactory =
+ new ConfigFactory<ApplicationId, XosEndPointConfig>(SubjectFactories.APP_SUBJECT_FACTORY,
+ XosEndPointConfig.class, "xos") {
+ @Override
+ public XosEndPointConfig createConfig() {
+ return new XosEndPointConfig();
+ }
+ };
+
+ private final ExecutorService eventExecutor =
+ newFixedThreadPool(3,
+ groupedThreads("onos/ecord-sb-manager", "event-handler-%d"));
+
+ @Activate
+ public void activate() {
+ appId = coreService.registerApplication(PROVIDER_NAME);
+ // configRegistry.registerConfigFactory(diverConfigFactory);
+ configRegistry.registerConfigFactory(xosEndpointConfigFactory);
+ configService.addListener(configListener);
+ deviceProviderService = deviceProviderRegistry.register(this);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ //configRegistry.unregisterConfigFactory(diverConfigFactory);
+ configRegistry.unregisterConfigFactory(xosEndpointConfigFactory);
+ configService.removeListener(configListener);
+ deviceProviderRegistry.unregister(this);
+ log.info("Stopped");
+ }
+
+ @Override
+ public ProviderId id() {
+ return PROVIDER_ID;
+ }
+
+ // ==== DeviceProvider ====
+ @Override
+ public void triggerProbe(DeviceId deviceId) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
+
+ }
+
+ @Override
+ public boolean isReachable(DeviceId deviceId) {
+ // TODO
+ return true;
+ }
+
+ @Override
+ public void changePortState(DeviceId deviceId, PortNumber portNumber,
+ boolean enable) {
+ // TODO
+ }
+
+ // ===== EcordDeviceProviderService =====
+ @Override
+ public void connectRemoteDevice(DomainVirtualDevice domainDevice) {
+ DomainId domainId = domainDevice.domainId();
+ DeviceId deviceId = domainDevice.deviceId();
+ advertiseDevice(deviceId, domainId);
+ // advertiseDevicePorts(deviceId, domainDevice.ports());
+ }
+
+ @Override
+ public void addOrUpdateRemotePorts(DomainId domainId, DeviceId deviceId,
+ List<PortDescription> ports) {
+ advertiseDevicePorts(deviceId, ports);
+ }
+
+ @Override
+ public void addRemotePort(DomainId domainId, DeviceId deviceId, Port newPort) {
+ }
+
+ @Override
+ public void updateRemotePortState(DomainId domainId, DeviceId deviceId, Port port) {
+ // TODO
+ }
+
+ @Override
+ public void disconnectRemoteDevice(DomainId domainId, DeviceId deviceId) {
+ disconnectDevice(deviceId);
+ }
+
+ @Override
+ public void removeRemotePort(DomainId domainId, DeviceId deviceId, PortNumber portNumber) {
+ // TODO
+ }
+
+ /**
+ * Notify the core system that a new domain device is on.
+ * @param deviceId remote device identifier
+ */
+ private void advertiseDevice(DeviceId deviceId, DomainId domainId) {
+ ChassisId chassisId = new ChassisId();
+ log.info("Notifying ecord virtual device...");
+ mastershipAdminService.setRole(clusterService.getLocalNode().id(), deviceId,
+ MastershipRole.MASTER);
+
+ // disable lldp for this virtual device and annotate it with the proper driver
+ // String driverKey = ecordDriverConfig.manufacturer() + "-" + ecordDriverConfig.hwVersion() + "-" +
+ // ecordDriverConfig.swVersion();
+ String driverKey = "onLab-1.0.0-1.0.0";
+ SparseAnnotations annotations = DefaultAnnotations.builder()
+ .set(NO_LLDP, "any")
+ .set(DOMAIN_ID, domainId.id())
+ .set(DRIVER, driverKey)
+ .build();
+
+ DeviceDescription deviceDescription = new DefaultDeviceDescription(
+ deviceId.uri(),
+ Device.Type.SWITCH,
+ "onLab", "1.0.0",
+ "1.0.0", UNKNOWN,
+ chassisId,
+ annotations);
+ deviceProviderService.deviceConnected(deviceId, deviceDescription);
+ }
+
+ /**
+ * Notify the core system of all ports of a domain device.
+ * @param deviceId device identifier
+ * @param portDescriptions description of ports
+ */
+ private void advertiseDevicePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
+ log.info("Notifying ecord virtual ports...");
+ deviceProviderService.updatePorts(deviceId, portDescriptions);
+ // addGlobalMefLtp(deviceId, portDescriptions);
+ notifyXoS(deviceId, portDescriptions);
+ }
+
+ private void disconnectDevice(DeviceId deviceId) {
+ deviceProviderService.deviceDisconnected(deviceId);
+ }
+
+ private void notifyXoS(DeviceId deviceId, List<PortDescription> portDescriptions) {
+ portDescriptions.forEach(port -> {
+ if (port.annotations().keys().contains(MEF_IF_TYPE)) {
+ Type type = Type.valueOf(
+ port.annotations().value(MEF_IF_TYPE));
+ ConnectPoint cp = new ConnectPoint(deviceId, port.portNumber());
+ switch (type) {
+ case UNI:
+ ObjectNode body = xoSHttpClient.mapper().createObjectNode();
+ body.put("tenant", port.annotations().value(DOMAIN_ID));
+ body.put("name", "UNI:" + cp.toString());
+ body.put("latlng", "[" + port.annotations().value(LATITUDE) + "," +
+ port.annotations().value(LONGITUDE) + "]");
+ body.put("cpe_id", cp.toString());
+ xoSHttpClient.restPut(body.toString(), cp.toString());
+ break;
+ case ENNI:
+
+ break;
+ case INNI:
+
+ break;
+ case GENERIC:
+
+ break;
+ default:
+ return;
+ }
+ }
+ });
+ }
+
+ /**
+ * Adds global {@link CarrierEthernetLogicalTerminationPoint}
+ * to {@link MetroOrchestrationService}.
+ *
+ * @param deviceId subject device ID
+ * @param portDescriptions list of notified ports
+ */
+ private void addGlobalMefLtp(DeviceId deviceId, List<PortDescription> portDescriptions) {
+ portDescriptions.forEach(port -> {
+ if (port.annotations().keys().contains(MEF_IF_TYPE)) {
+ Type type = Type.valueOf(
+ port.annotations().value(MEF_IF_TYPE));
+ CarrierEthernetNetworkInterface ni;
+ ConnectPoint cp = new ConnectPoint(deviceId, port.portNumber());
+ switch (type) {
+ case UNI:
+ ni = CarrierEthernetUni.builder()
+ .cp(cp)
+ .annotations(port.annotations())
+ .build();
+ break;
+ case ENNI:
+ ni = CarrierEthernetEnni.builder()
+ .cp(cp)
+ .build();
+ break;
+ case INNI:
+ ni = CarrierEthernetInni.builder()
+ .cp(cp)
+ .annotations(port.annotations())
+ .build();
+ break;
+ case GENERIC:
+ ni = new CarrierEthernetGenericNi(cp, null, port.annotations());
+ break;
+ default:
+ return;
+ }
+ metroOrchestrationService.addGlobalLtp(
+ new CarrierEthernetLogicalTerminationPoint(null, ni));
+ }
+ });
+ }
+
+ private void readXoSEndPointConfig() {
+ xoSHttpClient =
+ new XoSHttpClient(configRegistry.getConfig(appId, XosEndPointConfig.class).xos());
+ }
+
+ private void readDriverFromConfig() {
+ ecordDriverConfig =
+ configRegistry.getConfig(appId, EcordDriverConfig.class);
+ }
+
+ private class InternalConfigListener implements NetworkConfigListener {
+ @Override
+ public void event(NetworkConfigEvent event) {
+ if (!event.configClass().equals(EcordDriverConfig.class) ||
+ !event.configClass().equals(XosEndPointConfig.class)) {
+ return;
+ }
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ log.info("Network configuration added");
+ if (event.configClass().equals(EcordDriverConfig.class)) {
+ eventExecutor.execute(VirtualDomainDeviceProvider.this::readDriverFromConfig);
+ } else {
+ eventExecutor.execute(VirtualDomainDeviceProvider.this::readXoSEndPointConfig);
+ }
+
+ break;
+ case CONFIG_UPDATED:
+ log.info("Network configuration updated");
+ if (event.configClass().equals(EcordDriverConfig.class)) {
+ eventExecutor.execute(VirtualDomainDeviceProvider.this::readDriverFromConfig);
+ } else {
+ eventExecutor.execute(VirtualDomainDeviceProvider.this::readXoSEndPointConfig);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java
new file mode 100644
index 0000000..361d74c
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+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.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.DefaultLinkDescription;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.provider.ProviderId;
+import org.opencord.ce.api.services.virtualprovider.LinkId;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+import static org.onosproject.net.Link.Type.INDIRECT;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.global.virtualdomain.VirtualDomainDeviceProvider.PROVIDER_NAME;
+
+/**
+ * Domain interlinks provider.
+ */
+@Component(immediate = true)
+public class VirtualLinkProvider implements LinkProvider {
+ public static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
+ public static final String INTERLINK_ID = "interlinkId";
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkProviderRegistry linkProviderRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkService linkService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
+
+ private final Map<LinkId, ConnectPoint> stagedInterlinks = Maps.newConcurrentMap();
+ private final Map<LinkId, Pair<ConnectPoint, ConnectPoint>>
+ committedInterlinks = Maps.newConcurrentMap();
+ private final DeviceListener deviceListener = new InternalDeviceListener();
+ private final LinkListener linkListener = new InternalLinkListener();
+
+ protected LinkProviderService linkProviderService;
+
+ @Activate
+ public void activate() {
+ coreService.registerApplication(PROVIDER_NAME);
+ linkProviderService = linkProviderRegistry.register(this);
+ deviceService.addListener(deviceListener);
+ linkService.addListener(linkListener);
+ log.info("Started");
+
+ }
+
+ @Deactivate
+ public void deactivate() {
+ linkProviderRegistry.unregister(this);
+ deviceService.removeListener(deviceListener);
+ linkService.removeListener(linkListener);
+ log.info("Stopped");
+ }
+
+
+ @Override
+ public ProviderId id() {
+ return PROVIDER_ID;
+ }
+
+ private void addInterLink(ConnectPoint point1, ConnectPoint point2, LinkId linkId) {
+ SparseAnnotations annotations = DefaultAnnotations.builder()
+ .set(INTERLINK_ID, linkId.id())
+ .build();
+ LinkDescription linkDescription = new DefaultLinkDescription(point1, point2,
+ INDIRECT, true, annotations);
+ linkProviderService.linkDetected(linkDescription);
+ }
+
+ private class InternalLinkListener implements LinkListener {
+
+ @Override
+ public void event(LinkEvent event) {
+ Link link = event.subject();
+ switch (event.type()) {
+ case LINK_REMOVED:
+ if (link.annotations().keys().contains(INTERLINK_ID)) {
+ committedInterlinks.remove(LinkId.linkId(
+ link.annotations().value(INTERLINK_ID)
+ ));
+ }
+ case LINK_ADDED:
+ // not relevant for now
+ default:
+ }
+ }
+ }
+
+
+ private class InternalDeviceListener implements DeviceListener {
+ @Override
+ public boolean isRelevant(DeviceEvent event) {
+ return (event.type().equals(DeviceEvent.Type.PORT_ADDED) ||
+ event.type().equals(DeviceEvent.Type.PORT_REMOVED) ||
+ event.type().equals(DeviceEvent.Type.PORT_UPDATED)) &&
+ event.port().annotations().keys().contains(INTERLINK_ID);
+ }
+
+ @Override
+ public void event(DeviceEvent event) {
+
+ Port port = event.port();
+ DeviceId subjectDeviceId = event.subject().id();
+ LinkId linkId = LinkId.linkId(port.annotations().value(INTERLINK_ID));
+
+ switch (event.type()) {
+ case PORT_ADDED:
+ case PORT_UPDATED:
+ if (committedInterlinks.containsKey(linkId)) {
+ // !!!! ===== !!!! //
+ // committed interlinks cannot be subject to changes
+ // unless a port is removed.
+ // Possibly this is an error condition
+ log.info("notified interlinks cannot be subject to changes," +
+ "unless a port of the link is removed. Possibly this is" +
+ "an error condition");
+ return;
+ } else {
+ log.info("Adding virtual inter-links...");
+ if (stagedInterlinks.containsKey(linkId)) {
+ ConnectPoint point1 =
+ stagedInterlinks.get(linkId);
+ ConnectPoint point2 =
+ new ConnectPoint(subjectDeviceId, port.number());
+ if (subjectDeviceId.equals(point1.deviceId())) {
+ return;
+ }
+
+ committedInterlinks.put(linkId, Pair.of(point1, point2));
+ stagedInterlinks.remove(linkId);
+
+ // only the master instance of the destination link can notify the link
+ if (mastershipService.getLocalRole(point2.deviceId())
+ .equals(MastershipRole.MASTER)) {
+ addInterLink(point1, point2, linkId);
+ }
+ if (mastershipService.getLocalRole(point1.deviceId())
+ .equals(MastershipRole.MASTER)) {
+ addInterLink(point2, point1, linkId);
+ }
+ } else {
+ stagedInterlinks.put(linkId,
+ new ConnectPoint(subjectDeviceId, port.number()));
+ }
+ }
+ break;
+ case PORT_REMOVED:
+ if (committedInterlinks.containsKey(linkId)) {
+ Pair<ConnectPoint, ConnectPoint> points =
+ committedInterlinks.get(linkId);
+ committedInterlinks.remove(linkId);
+ if (points.getLeft().deviceId().equals(subjectDeviceId)) {
+ linkProviderService.linksVanished(points.getLeft());
+ stagedInterlinks.put(linkId, points.getRight());
+ } else {
+ linkProviderService.linksVanished(points.getRight());
+ stagedInterlinks.put(linkId, points.getLeft());
+ }
+ } else if (stagedInterlinks.containsKey(linkId)) {
+ stagedInterlinks.remove(linkId);
+ }
+ break;
+ default:
+ }
+ }
+ }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java
new file mode 100644
index 0000000..1d72b40
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.global.virtualdomain.config.XosEndPointConfig.XosEndPoint;
+
+/**
+ * Implementation of REST client for XOS Metro-net service.
+ */
+public class XoSHttpClient extends AbstractWebResource {
+ protected final Logger log = getLogger(getClass());
+
+ private static final int DEFAULT_TIMEOUT_MS = 2000;
+
+ private XosEndPoint xosEndPoint;
+ private final Client client = ClientBuilder.newClient();
+
+
+ public XoSHttpClient(XosEndPoint xosEndPoint) {
+ this.xosEndPoint = xosEndPoint;
+
+ client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_TIMEOUT_MS);
+ client.property(ClientProperties.READ_TIMEOUT, DEFAULT_TIMEOUT_MS);
+ mapper().enable(SerializationFeature.INDENT_OUTPUT);
+ }
+
+ public void restPut(String body, String cpeId) {
+ WebTarget webTarget = client.target("http://" + xosEndPoint.ipAddress().toString() +
+ xosEndPoint.resource() + "/" + cpeId);
+ Response response;
+ response = webTarget.request(MediaType.APPLICATION_JSON)
+ .put(Entity.entity(body, MediaType.APPLICATION_JSON));
+ try {
+ if (response.getStatus() != HTTP_OK) {
+ log.warn("Failed to put resource {}", xosEndPoint.resource());
+ }
+ } catch (javax.ws.rs.ProcessingException e) {
+ log.error("Javax process exception in XoSClientHttp: {}", e.getMessage());
+ }
+ }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java
new file mode 100644
index 0000000..1077993
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain.config;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+/**
+ * ICONA driver configuration class.
+ */
+public class EcordDriverConfig extends Config<ApplicationId> {
+
+ private static final String MANUFACTURER = "manufacturer";
+ private static final String SW_VERSION = "swVersion";
+ private static final String HW_VERSION = "hwVersion";
+
+
+ public String manufacturer() {
+ return object.get(MANUFACTURER).asText();
+ }
+
+ public String swVersion() {
+ return object.get(SW_VERSION).asText();
+ }
+
+ public String hwVersion() {
+ return object.get(HW_VERSION).asText();
+ }
+
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java
new file mode 100644
index 0000000..df0c59e
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+/**
+ * Global XoS endpoint.
+ */
+public class XosEndPointConfig extends Config<ApplicationId> {
+ private static final String USERNAME = "username";
+ private static final String PASSWD = "password";
+ private static final String XOS = "xos";
+ private static final String ADDRESS = "address";
+ private static final String RESOURCE = "resource";
+
+ public XosEndPoint xos() {
+ JsonNode xosNode = object.path(XOS);
+ IpAddress ipAddress = IpAddress.valueOf(xosNode.get(ADDRESS).asText());
+ String username = xosNode.get(USERNAME).asText();
+ String password = xosNode.get(PASSWD).asText();
+ String resource = xosNode.get(RESOURCE).asText();
+ return new XosEndPoint(ipAddress, username, password, resource);
+ }
+
+ public static class XosEndPoint {
+ private IpAddress ipAddress;
+ private String username;
+ private String password;
+ private String resource;
+
+ public XosEndPoint(IpAddress ipAddress, String username,
+ String password, String resource) {
+ this.ipAddress = ipAddress;
+ this.username = username;
+ this.password = password;
+ this.resource = resource;
+ }
+
+ public IpAddress ipAddress() {
+ return ipAddress;
+ }
+
+ public String username() {
+ return username;
+ }
+
+ public String password() {
+ return password;
+ }
+
+ public String resource() {
+ return resource;
+ }
+ }
+
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java
new file mode 100644
index 0000000..62fbacc
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Configuration classes.
+ */
+package org.opencord.ce.global.virtualdomain.config;
\ No newline at end of file
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java
new file mode 100644
index 0000000..c71407e
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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 for domain topology provider.
+ */
+package org.opencord.ce.global.virtualdomain;
\ No newline at end of file