[ONOS-4713]GUI improvement and issue fix
Change-Id: I9cec96584549e841dddf7759873fd7059b5ce2ba
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
index 9af7e86..73fa751 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
@@ -635,7 +635,10 @@
treatment.extension(tunnelDsttreatment, deviceId);
treatment.transition(TUNNEL_SEND_TABLE);
sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
- classifierList.add(deviceIdfromPortPair);
+
+ selector.matchInPort(PortNumber.CONTROLLER);
+ sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
+ classifierList.add(deviceId);
installSfcTunnelSendRule(deviceId, nshSpiId, type);
installSfcTunnelReceiveRule(deviceIdfromPortPair, nshSpiId, type);
@@ -647,6 +650,9 @@
nshSpiId, flowClassifier);
treatment.transition(ENCAP_OUTPUT_TABLE);
sendSfcRule(selector, treatment, deviceIdfromPortPair, type, flowClassifier.priority());
+
+ selector.matchInPort(PortNumber.CONTROLLER);
+ sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
classifierList.add(deviceIdfromPortPair);
}
}
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
index 3292e23..17ca257 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
@@ -507,6 +507,7 @@
int portDst = 0;
byte protocol = 0;
MacAddress macSrc = packet.getSourceMAC();
+ MacAddress macDst = packet.getDestinationMAC();
TenantId tenantId = getTenantId(macSrc);
if (ethType == Ethernet.TYPE_IPV4) {
@@ -539,6 +540,8 @@
.setPortDst(PortNumber.portNumber(portDst))
.setProtocol(protocol)
.setTenantId(tenantId)
+ .setMacSrc(macSrc)
+ .setMacDst(macDst)
.build();
PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple);
@@ -577,13 +580,12 @@
* Send packet back to classifier.
*
* @param context packet context
- * @param connectPoint connect point of first service function
*/
private void sendPacket(PacketContext context) {
ConnectPoint sourcePoint = context.inPacket().receivedFrom();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(sourcePoint.port()).build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(PortNumber.TABLE).build();
OutboundPacket packet = new DefaultOutboundPacket(sourcePoint.deviceId(), treatment, context.inPacket()
.unparsed());
packetService.emit(packet);
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
index cc2c265..e51c699 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
@@ -16,16 +16,17 @@
package org.onosproject.sfc.util;
import java.util.Collection;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
-import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortListener;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
/**
@@ -95,4 +96,12 @@
public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
return true;
}
+
+ @Override
+ public void addListener(VirtualPortListener listener) {
+ }
+
+ @Override
+ public void removeListener(VirtualPortListener listener) {
+ }
}
diff --git a/apps/vtn/sfcweb/pom.xml b/apps/vtn/sfcweb/pom.xml
index c08fdc3..36555c9 100755
--- a/apps/vtn/sfcweb/pom.xml
+++ b/apps/vtn/sfcweb/pom.xml
@@ -53,6 +53,11 @@
<artifactId>onos-app-vtn-rsc</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLink.java b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLink.java
new file mode 100644
index 0000000..3936633
--- /dev/null
+++ b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLink.java
@@ -0,0 +1,42 @@
+/*
+ * 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.sfcweb;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.ui.topo.BiLink;
+import org.onosproject.ui.topo.LinkHighlight;
+import org.onosproject.ui.topo.LinkHighlight.Flavor;
+
+/**
+ * Bi-directional link capable of different highlights.
+ */
+public class SfcLink extends BiLink {
+
+ private boolean primary = false;
+ private boolean secondary = false;
+
+ public SfcLink(LinkKey key, Link link) {
+ super(key, link);
+ }
+
+ @Override
+ public LinkHighlight highlight(Enum<?> anEnum) {
+ Flavor flavor = primary ? Flavor.PRIMARY_HIGHLIGHT :
+ (secondary ? Flavor.SECONDARY_HIGHLIGHT : Flavor.NO_HIGHLIGHT);
+ return new LinkHighlight(this.linkId(), Flavor.PRIMARY_HIGHLIGHT);
+ }
+}
diff --git a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLinkMap.java b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLinkMap.java
new file mode 100644
index 0000000..03c9c3d
--- /dev/null
+++ b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcLinkMap.java
@@ -0,0 +1,30 @@
+/*
+ * 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.sfcweb;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.ui.topo.BiLinkMap;
+
+/**
+ * Sfc concrete link map.
+ */
+public class SfcLinkMap extends BiLinkMap<SfcLink> {
+ @Override
+ protected SfcLink create(LinkKey linkKey, Link link) {
+ return new SfcLink(linkKey, link);
+ }
+}
diff --git a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovMessageHandler.java b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovMessageHandler.java
index df541b3..8319137 100644
--- a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovMessageHandler.java
+++ b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovMessageHandler.java
@@ -15,50 +15,53 @@
*/
package org.onosproject.sfcweb;
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.TimerTask;
+
+import jersey.repackaged.com.google.common.collect.Lists;
+
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.google.common.collect.ImmutableSet;
-
import org.onlab.packet.MacAddress;
-import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.Element;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
import org.onosproject.net.Link;
-import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.link.LinkService;
-import org.onosproject.ui.topo.HostHighlight;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.topo.DeviceHighlight;
import org.onosproject.ui.topo.Highlights;
+import org.onosproject.ui.topo.HostHighlight;
import org.onosproject.ui.topo.NodeBadge;
import org.onosproject.ui.topo.TopoJson;
-import org.onosproject.ui.topo.DeviceHighlight;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.onosproject.vtnrsc.FiveTuple;
+import org.onosproject.vtnrsc.LoadBalanceId;
import org.onosproject.vtnrsc.PortChain;
-import org.onosproject.vtnrsc.portchain.PortChainService;
-import org.onosproject.vtnrsc.portpair.PortPairService;
import org.onosproject.vtnrsc.PortChainId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
-import org.onosproject.vtnrsc.PortPairGroupId;
-import org.onosproject.vtnrsc.PortPairGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import java.util.Collection;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.List;
-import java.util.ListIterator;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
/**
* SFC web gui topology-overlay message handler.
@@ -69,32 +72,27 @@
private static final String SAMPLE_TOPOV_DISPLAY_SFC = "showSfcInfo";
private static final String SAMPLE_TOPOV_DISPLAY_STOP = "sfcTopovClear";
private static final String CONFIG_SFP_MSG = "configSfpMessage";
-
+ private static final String SAMPLE_TOPOV_SHOW_SFC_PATH = "showSfcPath";
private static final String ID = "id";
private static final String MODE = "mode";
- private static final String SFC_ID = "SFC";
-
- private static final long UPDATE_PERIOD_MS = 1000;
+ private static final String CLASSIFIER = "CLS";
+ private static final String FORWARDER = "SFF";
private static final Link[] EMPTY_LINK_SET = new Link[0];
- private enum Mode { IDLE, MOUSE, LINK }
+ private enum Mode {
+ IDLE, MOUSE, LINK
+ }
private final Logger log = LoggerFactory.getLogger(getClass());
- private DeviceService deviceService;
private HostService hostService;
private LinkService linkService;
-
- private final Timer timer = new Timer("sfcweb-overlay");
private TimerTask demoTask = null;
private Mode currentMode = Mode.IDLE;
private Element elementOfNote;
private Link[] linkSet = EMPTY_LINK_SET;
- private int linkIndex;
- private long someNumber = 1;
- private long someIncrement = 1;
protected PortPairService portPairService;
protected VtnRscService vtnRscService;
protected VirtualPortService virtualPortService;
@@ -104,7 +102,6 @@
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- deviceService = directory.get(DeviceService.class);
hostService = directory.get(HostService.class);
linkService = directory.get(LinkService.class);
portChainService = directory.get(PortChainService.class);
@@ -172,7 +169,10 @@
vtnRscService = serviceDirectory.get(VtnRscService.class);
virtualPortService = serviceDirectory.get(VirtualPortService.class);
+ List<String> sfcPathList = Lists.newArrayList();
+
Highlights highlights = new Highlights();
+ SfcLinkMap linkMap = new SfcLinkMap();
PortChainId portChainId = PortChainId.of(id);
boolean portChainIdExist = portChainService.exists(portChainId);
@@ -183,44 +183,111 @@
PortChain portChain = portChainService.getPortChain(portChainId);
- List<PortPairGroupId> llPortPairGroupIdList = portChain.portPairGroups();
- ListIterator<PortPairGroupId> portPairGroupIdListIterator = llPortPairGroupIdList.listIterator();
- while (portPairGroupIdListIterator.hasNext()) {
- PortPairGroupId portPairGroupId = portPairGroupIdListIterator.next();
- PortPairGroup portPairGroup = portPairGroupService.getPortPairGroup(portPairGroupId);
- List<PortPairId> llPortPairIdList = portPairGroup.portPairs();
- ListIterator<PortPairId> portPairListIterator = llPortPairIdList.listIterator();
+ Set<FiveTuple> fiveTupleSet = portChain.getLoadBalanceIdMapKeys();
+ for (FiveTuple fiveTuple : fiveTupleSet) {
+ List<PortPairId> path = portChain.getLoadBalancePath(fiveTuple);
+ LoadBalanceId lbId = portChain.getLoadBalanceId(fiveTuple);
+ ListIterator<PortPairId> pathIterator = path.listIterator();
- while (portPairListIterator.hasNext()) {
- PortPairId portPairId = portPairListIterator.next();
+ // Add source
+ Host srcHost = hostService.getHost(HostId.hostId(fiveTuple.macSrc()));
+
+ HostHighlight hSrc = new HostHighlight(srcHost.id().toString());
+ hSrc.setBadge(NodeBadge.text("SRC"));
+ String sfcPath = "SRC -> ";
+ highlights.add(hSrc);
+
+ DeviceId previousDeviceId = null;
+ while (pathIterator.hasNext()) {
+
+ PortPairId portPairId = pathIterator.next();
PortPair portPair = portPairService.getPortPair(portPairId);
DeviceId deviceId = vtnRscService.getSfToSffMaping(VirtualPortId.portId(portPair.egress()));
- Device device = deviceService.getDevice(deviceId);
- DeviceHighlight dh = new DeviceHighlight(device.id().toString());
- dh.setBadge(NodeBadge.text(SFC_ID));
-
- MacAddress dstMacAddress = virtualPortService.getPort(VirtualPortId
- .portId(portPair.egress())).macAddress();
+ VirtualPort vPort = virtualPortService.getPort(VirtualPortId.portId(portPair.egress()));
+ MacAddress dstMacAddress = vPort.macAddress();
Host host = hostService.getHost(HostId.hostId(dstMacAddress));
- HostHighlight hhDst = new HostHighlight(host.id().toString());
- hhDst.setBadge(NodeBadge.text(SFC_ID));
- MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId
- .portId(portPair.ingress())).macAddress();
- Host hostSrc = hostService.getHost(HostId.hostId(srcMacAddress));
- HostHighlight hhSrc = new HostHighlight(hostSrc.id().toString());
- hhSrc.setBadge(NodeBadge.text(SFC_ID));
+ addEdgeLinks(linkMap, host);
+ log.info("before check");
+ if (previousDeviceId != null) {
+ log.info("pdid not null");
+ if (!deviceId.equals(previousDeviceId)) {
+ // Highlight the link between devices.
+
+ Link link = getLinkBetweenDevices(deviceId, previousDeviceId);
+ if (link != null) {
+ linkMap.add(link);
+ }
+ }
+ }
+
+ DeviceHighlight dh = new DeviceHighlight(deviceId.toString());
+ if (portChain.getSfcClassifiers(lbId).contains(deviceId)) {
+ dh.setBadge(NodeBadge.text(CLASSIFIER));
+ } else {
+ dh.setBadge(NodeBadge.text(FORWARDER));
+ }
highlights.add(dh);
- highlights.add(hhSrc);
+
+ HostHighlight hhDst = new HostHighlight(host.id().toString());
+ hhDst.setBadge(NodeBadge.text(portPair.name()));
+ sfcPath = sfcPath + portPair.name() + "(" + vPort.fixedIps().iterator().next().ip() + ") -> ";
+
+ if (!portPair.ingress().equals(portPair.egress())) {
+ MacAddress srcMacAddress = virtualPortService.getPort(VirtualPortId
+ .portId(portPair.ingress()))
+ .macAddress();
+ Host hostSrc = hostService.getHost(HostId.hostId(srcMacAddress));
+ HostHighlight hhSrc = new HostHighlight(hostSrc.id().toString());
+ hhSrc.setBadge(NodeBadge.text(portPair.name()));
+ highlights.add(hhSrc);
+ }
highlights.add(hhDst);
+ previousDeviceId = deviceId;
}
+
+ // Add destination
+ Host dstHost = hostService.getHost(HostId.hostId(fiveTuple.macDst()));
+
+ HostHighlight hDst = new HostHighlight(dstHost.id().toString());
+ hDst.setBadge(NodeBadge.text("DST"));
+ sfcPath = sfcPath + "DST";
+ highlights.add(hDst);
+ sfcPathList.add(sfcPath);
}
+ for (SfcLink sfcLink : linkMap.biLinks()) {
+ highlights.add(sfcLink.highlight(null));
+ }
sendHighlights(highlights);
+
+ ObjectNode result = objectNode();
+ ArrayNode arrayNode = arrayNode();
+ for (String path : sfcPathList) {
+ arrayNode.add(path);
+ }
+ result.putArray("sfcPathList").addAll(arrayNode);
+
+ sendMessage(SAMPLE_TOPOV_SHOW_SFC_PATH, sid, result);
}
}
+ private Link getLinkBetweenDevices(DeviceId deviceId, DeviceId previousDeviceId) {
+ Set<Link> deviceLinks = linkService.getDeviceEgressLinks(deviceId);
+ Set<Link> previousDeviceLinks = linkService.getDeviceIngressLinks(previousDeviceId);
+ for (Link link : deviceLinks) {
+ previousDeviceLinks.contains(link);
+ return link;
+ }
+ return null;
+ }
+
+ private void addEdgeLinks(SfcLinkMap linkMap, Host host1) {
+ linkMap.add(createEdgeLink(host1, true));
+ linkMap.add(createEdgeLink(host1, false));
+ }
+
private synchronized void cancelTask() {
if (demoTask != null) {
demoTask.cancel();
diff --git a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovOverlay.java b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovOverlay.java
index 6ee1b02..dce4f9c 100644
--- a/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovOverlay.java
+++ b/apps/vtn/sfcweb/src/main/java/org/onosproject/sfcweb/SfcwebUiTopovOverlay.java
@@ -15,11 +15,19 @@
*/
package org.onosproject.sfcweb;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostService;
import org.onosproject.ui.UiTopoOverlay;
import org.onosproject.ui.topo.PropertyPanel;
-
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
/**
* Our sfcweb topology overlay.
@@ -46,6 +54,19 @@
public void modifyHostDetails(PropertyPanel pp, HostId hostId) {
pp.title(MY_HOST_TITLE);
pp.removeAllProps();
+ PortPairService portPairService = AbstractShellCommand.get(PortPairService.class);
+ VirtualPortService virtualPortService = AbstractShellCommand.get(VirtualPortService.class);
+ HostService hostService = AbstractShellCommand.get(HostService.class);
+ Iterable<PortPair> portPairs = portPairService.getPortPairs();
+ for (PortPair portPair : portPairs) {
+ VirtualPort vPort = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress()));
+ MacAddress dstMacAddress = vPort.macAddress();
+ Host host = hostService.getHost(HostId.hostId(dstMacAddress));
+ if (hostId.toString().equals(host.id().toString())) {
+ pp.addProp("SF Name", portPair.name());
+ pp.addProp("SF Ip", vPort.fixedIps().iterator().next().ip());
+ }
+ }
pp.addProp("SF host Address", hostId.toString());
}
diff --git a/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovDemo.js b/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovDemo.js
index ebaf482..78488b3 100755
--- a/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovDemo.js
+++ b/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovDemo.js
@@ -28,31 +28,41 @@
var displayStart = 'sfcwebTopovDisplayStart',
showSfcInf = 'showSfcInfo',
clearMessage = 'sfcTopovClear',
- configSfpMessage = 'configSfpMessage' ;
+ configSfpMessage = 'configSfpMessage',
+ sfcPath = 'showSfcPath' ;
// internal state
var currentMode = null;
+ var sfpInfo;
// === Main API functions
function start() {
handlerMap[showSfcInf] = showSfcInformation;
+ handlerMap[sfcPath] = showSfcPath;
wss.bindHandlers(handlerMap);
wss.sendEvent(displayStart);
}
- function dOk() {
- var sfcId = null;
- sfcId = d3.select('#sfp-value').property("value");
+ function dOkSfp() {
+ var tdString;
+ var i = 0;
- if (sfcId) {
- console.log(sfcId);
+ sfpInfo.a.forEach( function () {
+ var sfpId = d3.select("#sfp-value-id-"+i).property("checked");
+ if (sfpId)
+ {
+ tdString = sfpInfo.a[i];
+ }
+ i++;
+ } );
+
+ if (!tdString) {
+ $log.debug("No SFP ID is selected.");
}
- $log.debug('Dialog OK button clicked');
-
wss.sendEvent(configSfpMessage, {
- id: sfcId
+ id: tdString
});
flash.flash('SFP ID query:');
@@ -62,68 +72,67 @@
$log.debug('Dialog Close button clicked (or Esc pressed)');
}
- function createUserText() {
+ function createUserTextSfp(data) {
+ console.log(data);
+
var content = ds.createDiv();
var form = content.append('form');
var p = form.append('p');
+ var i = 0;
- p.append('input').attr({
- id: 'sfp-value',
- type: 'string',
- name: 'sfp-value-name'
- });
- p.append('span').text('ID');
+ p.append('span').text('SFP IDs');
p.append('br');
+ sfpInfo = data;
+ data.a.forEach( function () {
+
+ p.append('input').attr({
+ id: 'sfp-value-id-'+i,
+ type: 'radio',
+ name: 'sfp-id-name',
+ value: data.a[i]
+ });
+
+ p.append('span').text(data.a[i]);
+ p.append('br');
+ i++;
+ } );
return content;
}
- function configSfp() {
+ function showSfcInformation(data) {
tds.openDialog()
- .setTitle('SFP ID User Input')
- .addContent(createUserText())
- .addOk(dOk, 'OK')
- .addCancel(dClose, 'Close')
- .bindKeys();
+ .setTitle('List of active service functions')
+ .addContent(createUserTextSfp(data))
+ .addOk(dOkSfp, 'Select SFP ID')
+ .addCancel(dClose, 'Close')
+ .bindKeys();
+
}
- function showSfcInformation(data) {
- console.log(data);
- wss.unbindHandlers(handlerMap);
+ function createSfcPathText(data) {
- // Get the modal
- var modal = document.getElementById('myModal');
+ var content = ds.createDiv();
+ var form = content.append('form');
+ var p = form.append('p');
+ var i = 0;
- // Get the button that opens the modal
- var btn = document.getElementById("myBtn");
+ p.append('span').text('SFC Path');
+ p.append('br');
+ data.sfcPathList.forEach( function (val, idx) {
+ p.append('span').text(val);
+ p.append('br')
+ } );
- // Get the <span> element that closes the modal
- var span = document.getElementsByClassName("close")[0];
+ return content;
+ }
- modal.style.display = "block";
-
- var tBody = document.getElementById('sfc-info-body');
-
- var tdString = '' ;
-
- for (var i = 0; i < data.a.length; i++) {
- tdString += '<tr> <td>'+ data.a[i] +'</td></tr>';
- }
-
- tBody.innerHTML = tdString;
-
- // When the user clicks on <span> (x), close the modal
- span.onclick = function() {
- modal.style.display = "none";
- }
-
- // When the user clicks anywhere outside of the modal, close it
- window.onclick = function(event) {
- if (event.target == modal) {
- modal.style.display = "none";
- }
- }
-
+ function showSfcPath(data) {
+ tds.openDialog()
+ .setTitle('Service function path')
+ .addContent(createSfcPathText(data))
+ .addCancel(dClose, 'Close')
+ .bindKeys();
}
function clear() {
@@ -146,8 +155,8 @@
return {
start: start,
showSfcInformation: showSfcInformation,
- clear: clear,
- configSfp: configSfp
+ showSfcPath : showSfcPath,
+ clear: clear
};
}]);
diff --git a/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovOverlay.js b/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovOverlay.js
index 75bccb1..5f5c118 100755
--- a/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovOverlay.js
+++ b/apps/vtn/sfcweb/src/main/resources/app/view/sfcwebTopov/sfcwebTopovOverlay.js
@@ -27,11 +27,6 @@
star4: {
vb: '0 0 8 8',
d: 'M1,4l2,-1l1,-2l1,2l2,1l-2,1l-1,2l-1,-2z'
- },
- jp: {
- vb: '0 0 110 110',
- d: 'M84.3,89.3L58.9,64.2l-1.4,1.4L83,90.7L84.3,89.3z M27,7.6H7.4v19.2H27V7.6z' +
- 'M59.3,47.1H39.8v19.2h19.5V47.1z M102.1,79.5H82.6v19.2h19.5V79.5z M41.7,47.6L19,25.1l-1.2,1.2l22.7,22.5L41.7,47.6z'
}
},
activate: function () {
@@ -53,16 +48,9 @@
tt: 'Query SFP active list information',
gid: 'summary'
},
- 5: {
- cb: function () {
- pps.configSfp();
- },
- tt: 'Highlight SFP active list information',
- gid: '*jp'
- },
_keyOrder: [
- '4' , '5'
+ '4'
]
}
diff --git a/apps/vtn/sfcweb/src/main/resources/sfcwebTopov/js.html b/apps/vtn/sfcweb/src/main/resources/sfcwebTopov/js.html
index ea42c70..4a6ab75 100755
--- a/apps/vtn/sfcweb/src/main/resources/sfcwebTopov/js.html
+++ b/apps/vtn/sfcweb/src/main/resources/sfcwebTopov/js.html
@@ -1,61 +1,2 @@
<script src="app/view/sfcwebTopov/sfcwebTopovDemo.js"></script>
<script src="app/view/sfcwebTopov/sfcwebTopovOverlay.js"></script>
-
-<style>
- /* The Modal (background) */
- .modal {
- display: none;
- position: fixed;
- z-index: 1;
- padding-top: 0px;
- left: 0px;
- top: 0;
- width: 37%;
- height: 25%;
- overflow: auto;
- background-color: none;
- margin: 178px 0px 0px -8px;
- }
-
- /* Modal Content */
- .modal-content {
- background-color: #fefefe;
- margin: auto;
- padding: 20px;
- border: 1px solid #888;
- width: 80%;
- }
-
- /* The Close Button */
- .close {
- color: #aaaaaa;
- float: right;
- font-size: 28px;
- font-weight: bold;
- }
-
- .close:hover,
- .close:focus {
- color: #000;
- text-decoration: none;
- cursor: pointer;
- }
-
-</style>
-
-<!-- The Modal -->
-<div id="myModal" class="modal">
-
- <!-- Modal content -->
- <div class="modal-content">
- <span class="close">×</span>
- <table id='sfc-info'>
- <thead>
- <td>SFP ID information</td>
- </thead>
- <tbody id='sfc-info-body'>
-
- </tbody>
- </table>
- </div>
-</div>
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
index 8f46dbe..502812c 100644
--- a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
@@ -62,6 +62,7 @@
import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicDeviceConfig;
+import org.onosproject.net.config.basics.BasicHostConfig;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
@@ -207,6 +208,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigService networkConfigService;
+
private ApplicationId appId;
private ClassifierService classifierService;
private L2ForwardService l2ForwardService;
@@ -847,13 +851,16 @@
VtnRscEventFeedback l3Feedback = event.subject();
if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
onRouterInterfaceDetected(l3Feedback);
- } else
- if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
+ } else if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
onRouterInterfaceVanished(l3Feedback);
} else if (VtnRscEvent.Type.FLOATINGIP_BIND == event.type()) {
onFloatingIpDetected(l3Feedback);
} else if (VtnRscEvent.Type.FLOATINGIP_UNBIND == event.type()) {
onFloatingIpVanished(l3Feedback);
+ } else if (VtnRscEvent.Type.VIRTUAL_PORT_PUT == event.type()) {
+ onVirtualPortCreated(l3Feedback);
+ } else if (VtnRscEvent.Type.VIRTUAL_PORT_DELETE == event.type()) {
+ onVirtualPortDeleted(l3Feedback);
}
}
@@ -926,6 +933,29 @@
programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_UNBIND);
}
+ public void onVirtualPortCreated(VtnRscEventFeedback l3Feedback) {
+ VirtualPort vPort = l3Feedback.virtualPort();
+ BasicHostConfig basicHostConfig = networkConfigService.addConfig(HostId.hostId(vPort.macAddress()),
+ BasicHostConfig.class);
+ Set<IpAddress> ips = new HashSet<>();
+ for (FixedIp fixedIp : vPort.fixedIps()) {
+ ips.add(fixedIp.ip());
+ }
+ basicHostConfig.setIps(ips).apply();
+ }
+
+ public void onVirtualPortDeleted(VtnRscEventFeedback l3Feedback) {
+ VirtualPort vPort = l3Feedback.virtualPort();
+ HostId hostId = HostId.hostId(vPort.macAddress());
+ BasicHostConfig basicHostConfig = networkConfigService.addConfig(hostId,
+ BasicHostConfig.class);
+ Set<IpAddress> ips = hostService.getHost(hostId).ipAddresses();
+ for (FixedIp fixedIp : vPort.fixedIps()) {
+ ips.remove(fixedIp.ip());
+ }
+ basicHostConfig.setIps(ips).apply();
+ }
+
private void programInterfacesSet(Set<RouterInterface> interfacesSet,
Objective.Operation operation) {
int subnetVmNum = 0;
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFiveTuple.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFiveTuple.java
index fc7fd4f..c13e922 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFiveTuple.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFiveTuple.java
@@ -22,6 +22,7 @@
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import org.onosproject.net.PortNumber;
/**
@@ -29,6 +30,8 @@
*/
public final class DefaultFiveTuple implements FiveTuple {
+ private final MacAddress macSrc;
+ private final MacAddress macDst;
private final IpAddress ipSrc;
private final IpAddress ipDst;
private final PortNumber portSrc;
@@ -46,7 +49,7 @@
* @param portDst destination port of the packet
*/
private DefaultFiveTuple(byte protocol, IpAddress ipSrc, IpAddress ipDst, PortNumber portSrc, PortNumber portDst,
- TenantId tenantId) {
+ TenantId tenantId, MacAddress macSrc, MacAddress macDst) {
this.protocol = protocol;
this.ipSrc = ipSrc;
@@ -54,6 +57,8 @@
this.portSrc = portSrc;
this.portDst = portDst;
this.tenantId = tenantId;
+ this.macSrc = macSrc;
+ this.macDst = macDst;
}
@Override
@@ -82,6 +87,16 @@
}
@Override
+ public MacAddress macSrc() {
+ return macSrc;
+ }
+
+ @Override
+ public MacAddress macDst() {
+ return macDst;
+ }
+
+ @Override
public TenantId tenantId() {
return tenantId;
}
@@ -139,6 +154,8 @@
private PortNumber portDst;
private byte protocol;
private TenantId tenantId;
+ private MacAddress macSrc;
+ private MacAddress macDst;
@Override
public Builder setIpSrc(IpAddress ipSrc) {
@@ -171,17 +188,29 @@
}
@Override
- public org.onosproject.vtnrsc.FiveTuple.Builder setTenantId(TenantId tenantId) {
+ public Builder setTenantId(TenantId tenantId) {
this.tenantId = tenantId;
return this;
}
@Override
+ public Builder setMacSrc(MacAddress macSrc) {
+ this.macSrc = macSrc;
+ return this;
+ }
+
+ @Override
+ public Builder setMacDst(MacAddress macDst) {
+ this.macDst = macDst;
+ return this;
+ }
+
+ @Override
public FiveTuple build() {
checkArgument(protocol == IPv4.PROTOCOL_TCP || protocol == IPv4.PROTOCOL_UDP ||
protocol == IPv4.PROTOCOL_ICMP, "Unsupported value for protocol while creating five tuple");
- return new DefaultFiveTuple(protocol, ipSrc, ipDst, portSrc, portDst, tenantId);
+ return new DefaultFiveTuple(protocol, ipSrc, ipDst, portSrc, portDst, tenantId, macSrc, macDst);
}
}
}
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FiveTuple.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FiveTuple.java
index 557b79f..8946abf 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FiveTuple.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FiveTuple.java
@@ -16,6 +16,7 @@
package org.onosproject.vtnrsc;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import org.onosproject.net.PortNumber;
/**
@@ -61,6 +62,20 @@
PortNumber portDst();
/**
+ * Returns source mac.
+ *
+ * @return srcMac
+ */
+ MacAddress macSrc();
+
+ /**
+ * Returns destination mac.
+ *
+ * @return dstMac
+ */
+ MacAddress macDst();
+
+ /**
* Returns the tenant id.
*
* @return tenantId
@@ -105,6 +120,22 @@
Builder setPortDst(PortNumber portDst);
/**
+ * Assign the source mac address to this object.
+ *
+ * @param macSrc source mac address
+ * @return this the builder object
+ */
+ Builder setMacSrc(MacAddress macSrc);
+
+ /**
+ * Assign the destination mac address to this object.
+ *
+ * @param macDst destination mac address
+ * @return this the builder object
+ */
+ Builder setMacDst(MacAddress macDst);
+
+ /**
* Assign the protocol to this object.
*
* @param protocol packet protocol
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
index e71dc5d..fb8d0d7 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
@@ -107,7 +107,15 @@
/**
* Signifies that port-chain has update.
*/
- PORT_CHAIN_UPDATE
+ PORT_CHAIN_UPDATE,
+ /**
+ * Signifies that virtual-port has created.
+ */
+ VIRTUAL_PORT_PUT,
+ /**
+ * Signifies that virtual-port has removed.
+ */
+ VIRTUAL_PORT_DELETE
}
/**
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
index 4d610b6..c7b463a 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
@@ -15,18 +15,19 @@
*/
package org.onosproject.vtnrsc.event;
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.Objects;
import org.onosproject.vtnrsc.FloatingIp;
-import org.onosproject.vtnrsc.Router;
-import org.onosproject.vtnrsc.RouterInterface;
-import org.onosproject.vtnrsc.PortPair;
-import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.PortChain;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.Router;
+import org.onosproject.vtnrsc.RouterInterface;
+import org.onosproject.vtnrsc.VirtualPort;
/**
* Representation of a VtnRsc event feedback.
@@ -39,6 +40,7 @@
private final PortPairGroup portPairGroup;
private final FlowClassifier flowClassifier;
private final PortChain portChain;
+ private final VirtualPort virtualPort;
/**
* Creates VtnRscEventFeedback object.
@@ -53,6 +55,7 @@
this.portPairGroup = null;
this.flowClassifier = null;
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -68,6 +71,7 @@
this.portPairGroup = null;
this.flowClassifier = null;
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -84,6 +88,7 @@
this.portPairGroup = null;
this.flowClassifier = null;
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -100,6 +105,7 @@
this.portPairGroup = null;
this.flowClassifier = null;
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -113,9 +119,10 @@
this.routerInterface = null;
this.portPair = null;
this.portPairGroup = checkNotNull(portPairGroup,
- "Port-Pair-Group cannot be null");
+ "Port-Pair-Group cannot be null");
this.flowClassifier = null;
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -130,8 +137,9 @@
this.portPair = null;
this.portPairGroup = null;
this.flowClassifier = checkNotNull(flowClassifier,
- "Flow-Classifier cannot be null");
+ "Flow-Classifier cannot be null");
this.portChain = null;
+ this.virtualPort = null;
}
/**
@@ -147,7 +155,25 @@
this.portPairGroup = null;
this.flowClassifier = null;
this.portChain = checkNotNull(portChain,
- "Port-Chain cannot be null");
+ "Port-Chain cannot be null");
+ this.virtualPort = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param virtualPort the Virtual-Port
+ */
+ public VtnRscEventFeedback(VirtualPort virtualPort) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
+ this.virtualPort = checkNotNull(virtualPort,
+ "Virtual-port cannot be null");
}
/**
@@ -213,10 +239,19 @@
return portChain;
}
+ /**
+ * Returns Virtual-Port.
+ *
+ * @return virtualPort the Virtual-Port
+ */
+ public VirtualPort virtualPort() {
+ return virtualPort;
+ }
+
@Override
public int hashCode() {
return Objects.hash(floaingtIp, router, routerInterface, portPair,
- portPairGroup, flowClassifier, portChain);
+ portPairGroup, flowClassifier, portChain, virtualPort);
}
@Override
@@ -232,7 +267,8 @@
&& Objects.equals(this.portPair, that.portPair)
&& Objects.equals(this.portPairGroup, that.portPairGroup)
&& Objects.equals(this.flowClassifier, that.flowClassifier)
- && Objects.equals(this.portChain, that.portChain);
+ && Objects.equals(this.portChain, that.portChain)
+ && Objects.equals(this.virtualPort, that.virtualPort);
}
return false;
}
@@ -247,6 +283,7 @@
.add("portPairGroup", portPairGroup)
.add("flowClassifier", flowClassifier)
.add("portChain", portChain)
+ .add("virtualPort", virtualPort)
.toString();
}
}
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
index 21a3d2d..6d7fe04 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
@@ -97,6 +97,7 @@
@Deactivate
public void deactivate() {
eventDispatcher.removeSink(PortChainEvent.class);
+ portChainStore.removeListener(portChainListener);
portChainStore.destroy();
log.info("Stopped");
}
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
index b39e82c..f6d54a9 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
@@ -87,6 +87,8 @@
import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortEvent;
+import org.onosproject.vtnrsc.virtualport.VirtualPortListener;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
@@ -112,6 +114,7 @@
private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
private PortChainListener portChainListener = new InnerPortChainListener();
+ private VirtualPortListener virtualPortListener = new InnerVirtualPortListener();
private EventuallyConsistentMap<TenantId, SegmentationId> l3vniTenantMap;
private EventuallyConsistentMap<TenantRouter, SegmentationId> l3vniTenantRouterMap;
@@ -165,6 +168,7 @@
portPairGroupService.addListener(portPairGroupListener);
flowClassifierService.addListener(flowClassifierListener);
portChainService.addListener(portChainListener);
+ virtualPortService.addListener(virtualPortListener);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
@@ -205,6 +209,7 @@
portPairGroupService.removeListener(portPairGroupListener);
flowClassifierService.removeListener(flowClassifierListener);
portChainService.removeListener(portChainListener);
+ virtualPortService.removeListener(virtualPortListener);
l3vniTenantMap.destroy();
l3vniTenantRouterMap.destroy();
@@ -401,6 +406,22 @@
}
}
+ private class InnerVirtualPortListener implements VirtualPortListener {
+
+ @Override
+ public void event(VirtualPortEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ VirtualPort virtualPort = event.subject();
+ if (VirtualPortEvent.Type.VIRTUAL_PORT_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(VtnRscEvent.Type.VIRTUAL_PORT_PUT,
+ new VtnRscEventFeedback(virtualPort)));
+ } else if (VirtualPortEvent.Type.VIRTUAL_PORT_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(VtnRscEvent.Type.VIRTUAL_PORT_DELETE,
+ new VtnRscEventFeedback(virtualPort)));
+ }
+ }
+ }
+
@Override
public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
checkNotNull(tenantId, TENANTID_NOT_NULL);
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortEvent.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortEvent.java
new file mode 100644
index 0000000..e0d3aac
--- /dev/null
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.vtnrsc.virtualport;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.vtnrsc.VirtualPort;
+
+/**
+ * Describes virtual port event.
+ */
+public class VirtualPortEvent extends AbstractEvent<VirtualPortEvent.Type, VirtualPort> {
+ /**
+ * Type of virtual port events.
+ */
+ public enum Type {
+ /**
+ * Signifies that virtual port has been created.
+ */
+ VIRTUAL_PORT_PUT,
+ /**
+ * Signifies that virtual port has been deleted.
+ */
+ VIRTUAL_PORT_DELETE,
+ /**
+ * Signifies that virtual port has been updated.
+ */
+ VIRTUAL_PORT_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified virtual port.
+ *
+ * @param type virtual port event type
+ * @param virtualPort virtual port subject
+ */
+ public VirtualPortEvent(Type type, VirtualPort virtualPort) {
+ super(type, virtualPort);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified virtual port.
+ *
+ * @param type virtual port event type
+ * @param virtualPort virtual port subject
+ * @param time occurrence time
+ */
+ public VirtualPortEvent(Type type, VirtualPort virtualPort, long time) {
+ super(type, virtualPort, time);
+ }
+}
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortListener.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortListener.java
new file mode 100644
index 0000000..c2d848d
--- /dev/null
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.vtnrsc.virtualport;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of virtual port related events.
+ */
+public interface VirtualPortListener extends EventListener<VirtualPortEvent> {
+
+}
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
index 25ef028..3808291 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import org.onlab.packet.IpAddress;
+import org.onosproject.event.ListenerService;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.TenantId;
@@ -28,7 +29,7 @@
/**
* Service for interacting with the inventory of virtualPort.
*/
-public interface VirtualPortService {
+public interface VirtualPortService extends ListenerService<VirtualPortEvent, VirtualPortListener> {
/**
* Returns if the virtualPort is existed.
*
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
index 2722123..d352cb3 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
@@ -18,12 +18,10 @@
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
import org.apache.felix.scr.annotations.Activate;
@@ -33,12 +31,18 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
+import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.DeviceId;
import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.MultiValuedTimestamp;
import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultVirtualPort;
@@ -50,6 +54,8 @@
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortEvent;
+import org.onosproject.vtnrsc.virtualport.VirtualPortListener;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -59,7 +65,8 @@
*/
@Component(immediate = true)
@Service
-public class VirtualPortManager implements VirtualPortService {
+public class VirtualPortManager extends AbstractListenerManager<VirtualPortEvent, VirtualPortListener>
+implements VirtualPortService {
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -73,8 +80,9 @@
private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null";
private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null";
private static final String IP_NOT_NULL = "Ip cannot be null";
+ private static final String EVENT_NOT_NULL = "event cannot be null";
- protected Map<VirtualPortId, VirtualPort> vPortStore;
+ protected EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
protected ApplicationId appId;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -86,28 +94,35 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
+ private EventuallyConsistentMapListener<VirtualPortId, VirtualPort> virtualPortListener =
+ new InnerVirtualPortStoreListener();
+
@Activate
public void activate() {
appId = coreService.registerApplication(VTNRSC_APP);
- vPortStore = storageService.<VirtualPortId, VirtualPort>consistentMapBuilder()
+ eventDispatcher.addSink(VirtualPortEvent.class, listenerRegistry);
+
+ vPortStore = storageService.<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
.withName(VIRTUALPORT)
- .withApplicationId(appId)
- .withPurgeOnUninstall()
- .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API),
- VirtualPortId.class,
- TenantNetworkId.class,
- VirtualPort.State.class,
- TenantId.class,
- AllowedAddressPair.class,
- FixedIp.class,
- BindingHostId.class,
- SecurityGroup.class,
- SubnetId.class,
- IpAddress.class,
- DefaultVirtualPort.class))
- .build().asJavaMap();
+ .withSerializer(KryoNamespace.newBuilder().register(KryoNamespaces.API)
+ .register(MultiValuedTimestamp.class)
+ .register(VirtualPortId.class,
+ TenantNetworkId.class,
+ VirtualPort.State.class,
+ TenantId.class,
+ AllowedAddressPair.class,
+ FixedIp.class,
+ BindingHostId.class,
+ SecurityGroup.class,
+ SubnetId.class,
+ IpAddress.class,
+ DefaultVirtualPort.class))
+ .withTimestampProvider((k, v) ->new WallClockTimestamp())
+ .build();
+
+ vPortStore.addListener(virtualPortListener);
log.info("Started");
}
@@ -246,4 +261,35 @@
return true;
}
+ private class InnerVirtualPortStoreListener
+ implements
+ EventuallyConsistentMapListener<VirtualPortId, VirtualPort> {
+
+ @Override
+ public void event(EventuallyConsistentMapEvent<VirtualPortId, VirtualPort> event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ log.info("virtual port event raised");
+ VirtualPort virtualPort = event.value();
+ if (EventuallyConsistentMapEvent.Type.PUT == event.type()) {
+ notifyListeners(new VirtualPortEvent(
+ VirtualPortEvent.Type.VIRTUAL_PORT_PUT,
+ virtualPort));
+ }
+ if (EventuallyConsistentMapEvent.Type.REMOVE == event.type()) {
+ notifyListeners(new VirtualPortEvent(
+ VirtualPortEvent.Type.VIRTUAL_PORT_DELETE,
+ virtualPort));
+ }
+ }
+ }
+
+ /**
+ * Notifies specify event to all listeners.
+ *
+ * @param event virtual port event
+ */
+ private void notifyListeners(VirtualPortEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ post(event);
+ }
}
diff --git a/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/gui/SfcViewMessageHandler.java b/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/gui/SfcViewMessageHandler.java
index 66c84d4..a17ef6c 100644
--- a/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/gui/SfcViewMessageHandler.java
+++ b/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/gui/SfcViewMessageHandler.java
@@ -50,7 +50,7 @@
*/
public class SfcViewMessageHandler extends UiMessageHandler {
- private static final String SLASH = " ; ";
+ private static final String SLASH = " -> ";
private static final String NONE = "none";
private static final String SFCTYPE = "Service Function Chain";
@@ -61,13 +61,13 @@
private static final String ID = "id";
private static final String STATE = "_iconid_state";
private static final String PORTCHAINNAME = "portChainName";
- private static final String HOSTS = "hosts";
+ private static final String SFS = "sfs";
private static final String TYPE = "type";
private static final String SRCIP = "srcIp";
private static final String DSTIP = "dstIp";
private static final String[] COL_IDS = {
- ID, STATE, PORTCHAINNAME, HOSTS, TYPE, SRCIP, DSTIP
+ ID, STATE, PORTCHAINNAME, SFS, TYPE, SRCIP, DSTIP
};
private static final String ICON_ID_ONLINE = "active";
@@ -116,7 +116,7 @@
row.cell(ID, pchain.portChainId().value().toString())
.cell(STATE, sfcState(vpList))
.cell(PORTCHAINNAME, pchain.name())
- .cell(HOSTS, sfcHosts(vpList))
+ .cell(SFS, sfcHosts(vpList))
.cell(TYPE, SFCTYPE)
.cell(SRCIP, portChainIpRange.srcip())
.cell(DSTIP, portChainIpRange.dstip());
diff --git a/apps/vtn/vtnweb/src/main/resources/app/view/sfc/sfc.html b/apps/vtn/vtnweb/src/main/resources/app/view/sfc/sfc.html
index 21697d5..a17aff1 100644
--- a/apps/vtn/vtnweb/src/main/resources/app/view/sfc/sfc.html
+++ b/apps/vtn/vtnweb/src/main/resources/app/view/sfc/sfc.html
@@ -32,7 +32,7 @@
<tr>
<td colId="_iconid_state" class="table-icon" sortable></td>
<td colId="portChainName" sortable>PortChainName </td>
- <td colId="hosts" sortable>Hosts </td>
+ <td colId="sfs" sortable>Sfs </td>
<td colId="type" sortable>Type </td>
<td colId="srcIp" sortable>Source IP Prefix </td>
<td colId="dstIp" sortable>Destination IP Prefix </td>
@@ -54,7 +54,7 @@
<div icon icon-id="{{sfc._iconid_state}}"></div>
</td>
<td>{{sfc.portChainName}}</td>
- <td>{{sfc.hosts}}</td>
+ <td>{{sfc.sfs}}</td>
<td>{{sfc.type}}</td>
<td>{{sfc.srcIp}}</td>
<td>{{sfc.dstIp}}</td>
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
index d305e08..b1ba927 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
@@ -38,7 +38,6 @@
private ExtensionTreatmentType type;
private final KryoNamespace appKryo = new KryoNamespace.Builder()
- .register(byte[].class)
.register(Map.class)
.build("DefaultMoveExtensionTreatment");