aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/net/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/net/src/main/java')
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java74
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java24
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java17
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java12
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java17
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java73
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java19
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java45
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java10
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java1
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java2
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java19
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java26
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java53
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java69
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java4
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java8
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java148
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java634
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java103
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java43
21 files changed, 1230 insertions, 171 deletions
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java b/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java
new file mode 100644
index 00000000..6678db27
--- /dev/null
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigLoader.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 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.cfg.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.cfg.ComponentConfigService;
+import org.slf4j.Logger;
+
+import java.io.File;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Component responsible for automatically loading configuration file from
+ * configuration directory.
+ */
+@Component(immediate = true)
+public class ComponentConfigLoader {
+
+ private static final String CFG_JSON = "../config/component-cfg.json";
+ static File cfgFile = new File(CFG_JSON);
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService configService;
+
+ private ObjectNode root;
+
+ @Activate
+ protected void activate() {
+ this.loadConfigs();
+ log.info("Started");
+ }
+
+ // Loads the configurations for each component from the file in
+ // ../config/component-cfg.json, using the preSetProperty method.
+ private void loadConfigs() {
+ try {
+ if (cfgFile.exists()) {
+ root = (ObjectNode) new ObjectMapper().readTree(cfgFile);
+ root.fieldNames().
+ forEachRemaining(component -> root.path(component).fieldNames()
+ .forEachRemaining(k -> configService
+ .preSetProperty(component, k,
+ root.path(component).path(k)
+ .asText())));
+ log.info("Loaded initial component configuration from {}", cfgFile);
+ }
+ } catch (Exception e) {
+ log.warn("Unable to load initial component configuration from {}",
+ cfgFile, e);
+ }
+ }
+}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
index 1933ee55..b3b22c76 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/cfg/impl/ComponentConfigManager.java
@@ -61,6 +61,9 @@ public class ComponentConfigManager implements ComponentConfigService {
private static final String COMPONENT_NULL = "Component name cannot be null";
private static final String PROPERTY_NULL = "Property name cannot be null";
+ private static final String COMPONENT_MISSING = "Component %s is not registered";
+ private static final String PROPERTY_MISSING = "Property %s does not exist for %s";
+
//Symbolic constants for use with the accumulator
private static final int MAX_ITEMS = 100;
@@ -160,6 +163,22 @@ public class ComponentConfigManager implements ComponentConfigService {
checkNotNull(componentName, COMPONENT_NULL);
checkNotNull(name, PROPERTY_NULL);
+
+ checkArgument(properties.containsKey(componentName),
+ COMPONENT_MISSING, componentName);
+ checkArgument(properties.get(componentName).containsKey(name),
+ PROPERTY_MISSING, name, componentName);
+ store.setProperty(componentName, name, value);
+ }
+
+ @Override
+ public void preSetProperty(String componentName, String name, String value) {
+
+ checkPermission(CONFIG_WRITE);
+
+ checkNotNull(componentName, COMPONENT_NULL);
+ checkNotNull(name, PROPERTY_NULL);
+
store.setProperty(componentName, name, value);
}
@@ -169,6 +188,11 @@ public class ComponentConfigManager implements ComponentConfigService {
checkNotNull(componentName, COMPONENT_NULL);
checkNotNull(name, PROPERTY_NULL);
+
+ checkArgument(properties.containsKey(componentName),
+ COMPONENT_MISSING, componentName);
+ checkArgument(properties.get(componentName).containsKey(name),
+ PROPERTY_MISSING, name, componentName);
store.unsetProperty(componentName, name);
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
index 8a441f61..f4d560a4 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
@@ -24,7 +24,6 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.SharedExecutors;
-import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
@@ -38,6 +37,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
@@ -87,9 +90,15 @@ public class CoreManager implements CoreService {
public void activate() {
registerApplication(CORE_APP_NAME);
cfgService.registerProperties(getClass());
- List<String> versionLines = Tools.slurp(VERSION_FILE);
- if (versionLines != null && !versionLines.isEmpty()) {
- version = Version.version(versionLines.get(0));
+ try {
+ Path path = Paths.get(VERSION_FILE.getPath());
+ List<String> versionLines = Files.readAllLines(path);
+ if (versionLines != null && !versionLines.isEmpty()) {
+ version = Version.version(versionLines.get(0));
+ }
+ } catch (IOException e) {
+ // version file not found, using default
+ log.trace("Version file not found", e);
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
index 5cd96cab..db484eea 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/config/impl/NetworkConfigManager.java
@@ -96,7 +96,7 @@ public class NetworkConfigManager
configClasses.put(identifier(configFactory), configFactory.configClass());
SubjectFactory subjectFactory = configFactory.subjectFactory();
- subjectClasses.putIfAbsent(subjectFactory.subjectKey(), subjectFactory);
+ subjectClasses.putIfAbsent(subjectFactory.subjectClassKey(), subjectFactory);
subjectClassKeys.putIfAbsent(subjectFactory.subjectClass(), subjectFactory);
store.addConfigFactory(configFactory);
@@ -145,8 +145,8 @@ public class NetworkConfigManager
}
@Override
- public SubjectFactory getSubjectFactory(String subjectKey) {
- return subjectClasses.get(subjectKey);
+ public SubjectFactory getSubjectFactory(String subjectClassKey) {
+ return subjectClasses.get(subjectClassKey);
}
@Override
@@ -155,8 +155,8 @@ public class NetworkConfigManager
}
@Override
- public Class<? extends Config> getConfigClass(String subjectKey, String configKey) {
- return configClasses.get(new ConfigIdentifier(subjectKey, configKey));
+ public Class<? extends Config> getConfigClass(String subjectClassKey, String configKey) {
+ return configClasses.get(new ConfigIdentifier(subjectClassKey, configKey));
}
@Override
@@ -255,7 +255,7 @@ public class NetworkConfigManager
}
private static ConfigIdentifier identifier(ConfigFactory factory) {
- return new ConfigIdentifier(factory.subjectFactory().subjectKey(), factory.configKey());
+ return new ConfigIdentifier(factory.subjectFactory().subjectClassKey(), factory.configKey());
}
static final class ConfigIdentifier {
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
index 7900d185..fa90eb65 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
@@ -15,21 +15,21 @@
*/
package org.onosproject.net.device.impl;
-import static org.slf4j.LoggerFactory.getLogger;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.net.config.ConfigOperator;
-import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.config.ConfigOperator;
+import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.slf4j.Logger;
import java.util.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Implementations of merge policies for various sources of device configuration
* information. This includes applications, provides, and network configurations.
@@ -46,7 +46,7 @@ public final class BasicDeviceOperator implements ConfigOperator {
* Generates a DeviceDescription containing fields from a DeviceDescription and
* a DeviceConfig.
*
- * @param bdc the device config entity from network config
+ * @param bdc the device config entity from network config
* @param descr a DeviceDescription
* @return DeviceDescription based on both sources
*/
@@ -70,7 +70,7 @@ public final class BasicDeviceOperator implements ConfigOperator {
* Generates an annotation from an existing annotation and DeviceConfig.
*
* @param bdc the device config entity from network config
- * @param an the annotation
+ * @param an the annotation
* @return annotation combining both sources
*/
public static SparseAnnotations combine(BasicDeviceConfig bdc, SparseAnnotations an) {
@@ -93,6 +93,9 @@ public final class BasicDeviceOperator implements ConfigOperator {
if (bdc.owner() != null) {
newBuilder.set(AnnotationKeys.OWNER, bdc.owner());
}
+ if (bdc.managementAddress() != null) {
+ newBuilder.set(AnnotationKeys.MANAGEMENT_ADDRESS, bdc.managementAddress());
+ }
DefaultAnnotations newAnnotations = newBuilder.build();
return DefaultAnnotations.union(an, newAnnotations);
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index b0b3abe2..e35dc0c5 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -15,8 +15,26 @@
*/
package org.onosproject.net.device.impl;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.NONE;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.security.AppGuard.checkPermission;
+import static org.onosproject.security.AppPermission.Type.DEVICE_READ;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -26,12 +44,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
-import org.onosproject.net.provider.AbstractListenerProviderRegistry;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.BasicDeviceConfig;
-import org.onosproject.net.config.basics.OpticalPortConfig;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
@@ -44,6 +56,11 @@ import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.BasicDeviceConfig;
+import org.onosproject.net.config.basics.OpticalPortConfig;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DeviceAdminService;
@@ -58,27 +75,11 @@ import org.onosproject.net.device.DeviceStore;
import org.onosproject.net.device.DeviceStoreDelegate;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.MastershipRole.*;
-import static org.onosproject.security.AppGuard.checkPermission;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.security.AppPermission.Type.*;
+import com.google.common.util.concurrent.Futures;
/**
* Provides implementation of the device SB &amp; NB APIs.
@@ -347,11 +348,15 @@ public class DeviceManager
log.info("Device {} disconnected from this node", deviceId);
List<Port> ports = store.getPorts(deviceId);
- List<PortDescription> descs = Lists.newArrayList();
- ports.forEach(port ->
- descs.add(new DefaultPortDescription(port.number(),
- false, port.type(),
- port.portSpeed())));
+ final Device device = getDevice(deviceId);
+
+ List<PortDescription> descs = ports.stream().map(
+ port -> (!(Device.Type.ROADM.equals(device.type()))) ?
+ new DefaultPortDescription(port.number(), false,
+ port.type(), port.portSpeed()) :
+ OpticalPortOperator.descriptionOf(port, false)
+ ).collect(Collectors.toList());
+
store.updatePorts(this.provider().id(), deviceId, descs);
try {
if (mastershipService.isLocalMaster(deviceId)) {
@@ -430,6 +435,12 @@ public class DeviceManager
portDescription);
return;
}
+ final Device device = getDevice(deviceId);
+ if ((Device.Type.ROADM.equals(device.type()))) {
+ Port port = getPort(deviceId, portDescription.portNumber());
+ portDescription = OpticalPortOperator.descriptionOf(port, portDescription.isEnabled());
+ }
+
portDescription = consolidate(deviceId, portDescription);
final DeviceEvent event = store.updatePortStatus(this.provider().id(),
deviceId, portDescription);
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
index b2fd02c7..8f2bda01 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java
@@ -151,8 +151,25 @@ public final class OpticalPortOperator implements ConfigOperator {
*/
public static PortDescription descriptionOf(Port port) {
checkNotNull(port, "Must supply non-null Port");
+ final boolean isUp = port.isEnabled();
+ return descriptionOfPort(port, isUp);
+ }
+
+ /**
+ * Returns a description built from an existing port and reported status.
+ *
+ * @param port
+ * @param isEnabled
+ * @return a PortDescription based on the port
+ */
+ static PortDescription descriptionOf(Port port, boolean isEnabled) {
+ checkNotNull(port, "Must supply non-null Port");
+ final boolean isup = isEnabled;
+ return descriptionOfPort(port, isup);
+ }
+
+ private static PortDescription descriptionOfPort(Port port, final boolean isup) {
final PortNumber ptn = port.number();
- final boolean isup = port.isEnabled();
final SparseAnnotations an = (SparseAnnotations) port.annotations();
switch (port.type()) {
case OMS:
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index a1d046c5..5958d1f5 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -22,6 +22,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -58,6 +59,7 @@ import org.onosproject.net.flow.FlowRuleProviderService;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.FlowRuleStore;
import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.TableStatisticsEntry;
import org.onosproject.net.provider.AbstractProviderService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -388,6 +390,16 @@ public class FlowRuleManager
@Override
public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+ pushFlowMetricsInternal(deviceId, flowEntries, true);
+ }
+
+ @Override
+ public void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+ pushFlowMetricsInternal(deviceId, flowEntries, false);
+ }
+
+ private void pushFlowMetricsInternal(DeviceId deviceId, Iterable<FlowEntry> flowEntries,
+ boolean useMissingFlow) {
Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
store.getFlowEntries(deviceId).forEach(f -> storedRules.put(f, f));
@@ -415,17 +427,20 @@ public class FlowRuleManager
continue;
}
}
- for (FlowEntry rule : storedRules.keySet()) {
- try {
- // there are rules in the store that aren't on the switch
- log.debug("Adding rule in store, but not on switch {}", rule);
- flowMissing(rule);
- } catch (Exception e) {
- log.debug("Can't add missing flow rule {}", e.getMessage());
- continue;
+
+ // DO NOT reinstall
+ if (useMissingFlow) {
+ for (FlowEntry rule : storedRules.keySet()) {
+ try {
+ // there are rules in the store that aren't on the switch
+ log.debug("Adding rule in store, but not on switch {}", rule);
+ flowMissing(rule);
+ } catch (Exception e) {
+ log.debug("Can't add missing flow rule {}", e.getMessage());
+ continue;
+ }
}
}
-
}
@Override
@@ -435,6 +450,12 @@ public class FlowRuleManager
operation
));
}
+
+ @Override
+ public void pushTableStatistics(DeviceId deviceId,
+ List<TableStatisticsEntry> tableStats) {
+ store.updateTableStatistics(deviceId, tableStats);
+ }
}
// Store delegate to re-post events emitted from the store.
@@ -590,4 +611,10 @@ public class FlowRuleManager
}
}
+
+ @Override
+ public Iterable<TableStatisticsEntry> getFlowTableStatistics(DeviceId deviceId) {
+ checkPermission(FLOWRULE_READ);
+ return store.getTableStatistics(deviceId);
+ }
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
index 43f346b7..1473f33f 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
@@ -236,6 +236,16 @@ public class HostManager
post(event);
}
}
+
+ @Override
+ public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
+ checkNotNull(hostId, HOST_ID_NULL);
+ checkValidity();
+ HostEvent event = store.removeIp(hostId, ipAddress);
+ if (event != null) {
+ post(event);
+ }
+ }
}
// Store delegate to re-post events emitted from the store.
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
index 44f8cbf0..4dc93a51 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostMonitor.java
@@ -84,6 +84,7 @@ public class HostMonitor implements TimerTask {
* @param hostManager host manager used to look up host information and
* probe existing hosts
* @param interfaceService interface service for interface information
+ * @param edgePortService edge port service
*/
public HostMonitor(PacketService packetService, HostManager hostManager,
InterfaceService interfaceService,
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
index d7fa3223..417627ad 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCleanup.java
@@ -196,7 +196,7 @@ public class IntentCleanup implements Runnable, IntentListener {
service.withdraw(intentData.intent());
break;
default:
- log.warn("Trying to resubmit pending intent {} in state {} with request {}",
+ log.warn("Failed to resubmit pending intent {} in state {} with request {}",
intentData.key(), intentData.state(), intentData.request());
break;
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 4c828e77..baa3bf4d 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -256,15 +256,16 @@ public class IntentManager
submit(intent);
}
- // If required, compile all currently failed intents.
- for (Intent intent : getIntents()) {
- IntentState state = getIntentState(intent.key());
- if ((compileAllFailed && RECOMPILE.contains(state))
- || intentAllowsPartialFailure(intent)) {
- if (WITHDRAW.contains(state)) {
- withdraw(intent);
- } else {
- submit(intent);
+ if (compileAllFailed) {
+ // If required, compile all currently failed intents.
+ for (Intent intent : getIntents()) {
+ IntentState state = getIntentState(intent.key());
+ if (RECOMPILE.contains(state) || intentAllowsPartialFailure(intent)) {
+ if (WITHDRAW.contains(state)) {
+ withdraw(intent);
+ } else {
+ submit(intent);
+ }
}
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
index 5710aced..5ebc812e 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
@@ -16,8 +16,8 @@
package org.onosproject.net.intent.impl;
import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -61,7 +61,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -91,8 +90,6 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
private final Logger log = getLogger(getClass());
- private final ConcurrentMap<Key, Intent> intents = Maps.newConcurrentMap();
-
private final SetMultimap<LinkKey, Key> intentsByLink =
//TODO this could be slow as a point of synchronization
synchronizedSetMultimap(HashMultimap.<LinkKey, Key>create());
@@ -378,7 +375,12 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
}
// TODO should we recompile on available==true?
- delegate.triggerCompile(intentsByDevice.get(id), available);
+
+ final ImmutableSet<Key> snapshot;
+ synchronized (intentsByDevice) {
+ snapshot = ImmutableSet.copyOf(intentsByDevice.get(id));
+ }
+ delegate.triggerCompile(snapshot, available);
}
}
@@ -415,9 +417,17 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
@Override
public void event(HostEvent event) {
HostId id = event.subject().id();
- HostEvent.Type type = event.type();
- boolean available = (type == HostEvent.Type.HOST_ADDED);
- executorService.execute(new DeviceAvailabilityHandler(id, available));
+ switch (event.type()) {
+ case HOST_ADDED:
+ case HOST_MOVED:
+ case HOST_REMOVED:
+ executorService.execute(new DeviceAvailabilityHandler(id, false));
+ break;
+ case HOST_UPDATED:
+ default:
+ // DO NOTHING
+ break;
+ }
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
index 99f58df7..c6eb7c5a 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
@@ -15,10 +15,8 @@
*/
package org.onosproject.net.intent.impl.compiler;
-import com.google.common.collect.Sets;
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.Modified;
import org.apache.felix.scr.annotations.Property;
@@ -50,7 +48,10 @@ import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.OpticalCircuitIntent;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.intent.impl.IntentCompilationException;
-import org.onosproject.net.resource.device.DeviceResourceService;
+import org.onosproject.net.newresource.ResourceAllocation;
+import org.onosproject.net.newresource.ResourcePath;
+import org.onosproject.net.newresource.ResourceService;
+import org.onosproject.net.resource.device.IntentSetMultimap;
import org.onosproject.net.resource.link.LinkResourceAllocations;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -60,6 +61,7 @@ import java.util.Collections;
import java.util.Dictionary;
import java.util.LinkedList;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
@@ -67,7 +69,8 @@ import static com.google.common.base.Preconditions.checkArgument;
/**
* An intent compiler for {@link org.onosproject.net.intent.OpticalCircuitIntent}.
*/
-@Component(immediate = true)
+// For now, remove component designation until dependency on the new resource manager is available.
+// @Component(immediate = true)
public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircuitIntent> {
private static final Logger log = LoggerFactory.getLogger(OpticalCircuitIntentCompiler.class);
@@ -92,7 +95,10 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected DeviceResourceService deviceResourceService;
+ protected ResourceService resourceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentSetMultimap intentSetMultimap;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentService intentService;
@@ -153,7 +159,10 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
log.debug("Compiling optical circuit intent between {} and {}", src, dst);
// Reserve OduClt ports
- if (!deviceResourceService.requestPorts(Sets.newHashSet(srcPort, dstPort), intent)) {
+ ResourcePath srcPortPath = new ResourcePath(src.deviceId(), src.port());
+ ResourcePath dstPortPath = new ResourcePath(dst.deviceId(), dst.port());
+ List<ResourceAllocation> allocation = resourceService.allocate(intent.id(), srcPortPath, dstPortPath);
+ if (allocation.isEmpty()) {
throw new IntentCompilationException("Unable to reserve ports for intent " + intent);
}
@@ -199,7 +208,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
circuitIntent = new FlowRuleIntent(appId, rules, intent.resources());
// Save circuit to connectivity intent mapping
- deviceResourceService.requestMapping(connIntent.id(), intent.id());
+ intentSetMultimap.allocateMapping(connIntent.id(), intent.id());
intents.add(circuitIntent);
return intents;
@@ -209,16 +218,15 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
* Checks if current allocations on given resource can satisfy request.
* If the resource is null, return true.
*
- * @param request the intent making the request
* @param resource the resource on which to map the intent
* @return true if the resource can accept the request, false otherwise
*/
- private boolean isAvailable(Intent request, IntentId resource) {
+ private boolean isAvailable(IntentId resource) {
if (resource == null) {
return true;
}
- Set<IntentId> mapping = deviceResourceService.getMapping(resource);
+ Set<IntentId> mapping = intentSetMultimap.getMapping(resource);
if (mapping == null) {
return true;
@@ -271,7 +279,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
continue;
}
- if (isAvailable(circuitIntent, connIntent.id())) {
+ if (isAvailable(connIntent.id())) {
return connIntent;
}
}
@@ -296,14 +304,19 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
return null;
}
- private OchPort findAvailableOchPort(ConnectPoint oduPort, OpticalCircuitIntent circuitIntent) {
+ private OchPort findAvailableOchPort(ConnectPoint oduPort) {
// First see if the port mappings are constrained
ConnectPoint ochCP = staticPort(oduPort);
if (ochCP != null) {
OchPort ochPort = (OchPort) deviceService.getPort(ochCP.deviceId(), ochCP.port());
- IntentId intentId = deviceResourceService.getAllocations(ochPort);
- if (isAvailable(circuitIntent, intentId)) {
+ Optional<IntentId> intentId =
+ resourceService.getResourceAllocation(new ResourcePath(ochCP.deviceId(), ochCP.port()))
+ .map(ResourceAllocation::consumer)
+ .filter(x -> x instanceof IntentId)
+ .map(x -> (IntentId) x);
+
+ if (isAvailable(intentId.orElse(null))) {
return ochPort;
}
}
@@ -316,8 +329,12 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
continue;
}
- IntentId intentId = deviceResourceService.getAllocations(port);
- if (isAvailable(circuitIntent, intentId)) {
+ Optional<IntentId> intentId =
+ resourceService.getResourceAllocation(new ResourcePath(oduPort.deviceId(), port.number()))
+ .map(ResourceAllocation::consumer)
+ .filter(x -> x instanceof IntentId)
+ .map(x -> (IntentId) x);
+ if (isAvailable(intentId.orElse(null))) {
return (OchPort) port;
}
}
@@ -327,12 +344,12 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
private Pair<OchPort, OchPort> findPorts(OpticalCircuitIntent intent) {
- OchPort srcPort = findAvailableOchPort(intent.getSrc(), intent);
+ OchPort srcPort = findAvailableOchPort(intent.getSrc());
if (srcPort == null) {
return null;
}
- OchPort dstPort = findAvailableOchPort(intent.getDst(), intent);
+ OchPort dstPort = findAvailableOchPort(intent.getDst());
if (dstPort == null) {
return null;
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 05a20f96..eb5b4af8 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -16,9 +16,7 @@
package org.onosproject.net.intent.impl.compiler;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
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;
@@ -40,9 +38,9 @@ import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.net.intent.impl.IntentCompilationException;
-import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.newresource.ResourcePath;
+import org.onosproject.net.newresource.ResourceService;
import org.onosproject.net.resource.ResourceType;
-import org.onosproject.net.resource.device.DeviceResourceService;
import org.onosproject.net.resource.link.DefaultLinkResourceRequest;
import org.onosproject.net.resource.link.LambdaResource;
import org.onosproject.net.resource.link.LambdaResourceAllocation;
@@ -57,13 +55,15 @@ import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
/**
* An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}.
*/
-@Component(immediate = true)
+// For now, remove component designation until dependency on the new resource manager is available.
+// @Component(immediate = true)
public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
protected static final Logger log = LoggerFactory.getLogger(OpticalConnectivityIntentCompiler.class);
@@ -78,10 +78,10 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LinkResourceService linkResourceService;
+ protected ResourceService resourceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected DeviceResourceService deviceResourceService;
+ protected LinkResourceService linkResourceService;
@Activate
public void activate() {
@@ -108,7 +108,11 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
log.debug("Compiling optical connectivity intent between {} and {}", src, dst);
// Reserve OCh ports
- if (!deviceResourceService.requestPorts(ImmutableSet.of(srcPort, dstPort), intent)) {
+ ResourcePath srcPortPath = new ResourcePath(src.deviceId(), src.port());
+ ResourcePath dstPortPath = new ResourcePath(dst.deviceId(), dst.port());
+ List<org.onosproject.net.newresource.ResourceAllocation> allocation =
+ resourceService.allocate(intent.id(), srcPortPath, dstPortPath);
+ if (allocation.isEmpty()) {
throw new IntentCompilationException("Unable to reserve ports for intent " + intent);
}
@@ -161,7 +165,7 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
}
// Release port allocations if unsuccessful
- deviceResourceService.releasePorts(intent.id());
+ resourceService.release(intent.id());
throw new IntentCompilationException("Unable to find suitable lightpath for intent " + intent);
}
@@ -174,15 +178,12 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
* @return lambda allocated to the given path
*/
private LambdaResourceAllocation getWavelength(Path path, LinkResourceAllocations linkAllocs) {
- for (Link link : path.links()) {
- for (ResourceAllocation alloc : linkAllocs.getResourceAllocation(link)) {
- if (alloc.type() == ResourceType.LAMBDA) {
- return (LambdaResourceAllocation) alloc;
- }
- }
- }
-
- return null;
+ return path.links().stream()
+ .flatMap(x -> linkAllocs.getResourceAllocation(x).stream())
+ .filter(x -> x.type() == ResourceType.LAMBDA)
+ .findFirst()
+ .map(x -> (LambdaResourceAllocation) x)
+ .orElse(null);
}
/**
@@ -215,23 +216,23 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
return false;
}
- LambdaResource lambda = null;
+ List<LambdaResource> lambdas = path.links().stream()
+ .flatMap(x -> allocations.getResourceAllocation(x).stream())
+ .filter(x -> x.type() == ResourceType.LAMBDA)
+ .map(x -> ((LambdaResourceAllocation) x).lambda())
+ .collect(Collectors.toList());
- for (Link link : path.links()) {
- for (ResourceAllocation alloc : allocations.getResourceAllocation(link)) {
- if (alloc.type() == ResourceType.LAMBDA) {
- LambdaResource nextLambda = ((LambdaResourceAllocation) alloc).lambda();
- if (nextLambda == null) {
- return false;
- }
- if (lambda == null) {
- lambda = nextLambda;
- continue;
- }
- if (!lambda.equals(nextLambda)) {
- return false;
- }
- }
+ LambdaResource lambda = null;
+ for (LambdaResource nextLambda: lambdas) {
+ if (nextLambda == null) {
+ return false;
+ }
+ if (lambda == null) {
+ lambda = nextLambda;
+ continue;
+ }
+ if (!lambda.equals(nextLambda)) {
+ return false;
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java
index ca9ae5cc..2cc45e79 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java
@@ -39,7 +39,6 @@ import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.IntentExtensionService;
import org.onosproject.net.intent.OpticalPathIntent;
import org.onosproject.net.resource.link.LinkResourceAllocations;
-import org.onosproject.net.resource.link.LinkResourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -59,9 +58,6 @@ public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathInte
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LinkResourceService resourceService;
-
private ApplicationId appId;
@Activate
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
index 2cd1a2e0..5226967f 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
@@ -91,6 +91,14 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
}
@Override
+ public Optional<ResourceAllocation> getResourceAllocation(ResourcePath resource) {
+ checkNotNull(resource);
+
+ Optional<ResourceConsumer> consumer = store.getConsumer(resource);
+ return consumer.map(x -> new ResourceAllocation(resource, x));
+ }
+
+ @Override
public <T> Collection<ResourceAllocation> getResourceAllocations(ResourcePath parent, Class<T> cls) {
checkNotNull(parent);
checkNotNull(cls);
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
index a0bc693c..8e87a07d 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
@@ -15,7 +15,8 @@
*/
package org.onosproject.net.packet.impl;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -43,6 +44,7 @@ import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketEvent;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketProcessorEntry;
import org.onosproject.net.packet.PacketProvider;
import org.onosproject.net.packet.PacketProviderRegistry;
import org.onosproject.net.packet.PacketProviderService;
@@ -55,8 +57,6 @@ import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -102,18 +102,18 @@ public class PacketManager
private final DeviceListener deviceListener = new InternalDeviceListener();
- private final Map<Integer, PacketProcessor> processors = new ConcurrentHashMap<>();
+ private final List<ProcessorEntry> processors = Lists.newCopyOnWriteArrayList();
private ApplicationId appId;
@Activate
public void activate() {
eventHandlingExecutor = Executors.newSingleThreadExecutor(
- groupedThreads("onos/net/packet", "event-handler"));
+ groupedThreads("onos/net/packet", "event-handler"));
appId = coreService.getAppId(CoreService.CORE_APP_NAME);
store.setDelegate(delegate);
deviceService.addListener(deviceListener);
- // TODO: Should we request packets for all existing devices? I believe we should.
+ store.existingRequests().forEach(this::pushToAllDevices);
log.info("Started");
}
@@ -129,19 +129,35 @@ public class PacketManager
public void addProcessor(PacketProcessor processor, int priority) {
checkPermission(PACKET_EVENT);
checkNotNull(processor, "Processor cannot be null");
- processors.put(priority, processor);
+ ProcessorEntry entry = new ProcessorEntry(processor, priority);
+
+ // Insert the new processor according to its priority.
+ int i = 0;
+ for (; i < processors.size(); i++) {
+ if (priority < processors.get(i).priority()) {
+ break;
+ }
+ }
+ processors.add(i, entry);
}
@Override
public void removeProcessor(PacketProcessor processor) {
checkPermission(PACKET_EVENT);
checkNotNull(processor, "Processor cannot be null");
- processors.values().remove(processor);
+
+ // Remove the processor entry.
+ for (int i = 0; i < processors.size(); i++) {
+ if (processors.get(i).processor() == processor) {
+ processors.remove(i);
+ break;
+ }
+ }
}
@Override
- public Map<Integer, PacketProcessor> getProcessors() {
- return ImmutableMap.copyOf(processors);
+ public List<PacketProcessorEntry> getProcessors() {
+ return ImmutableList.copyOf(processors);
}
@Override
@@ -152,9 +168,7 @@ public class PacketManager
checkNotNull(appId, "Application ID cannot be null");
PacketRequest request = new DefaultPacketRequest(selector, priority, appId);
- if (store.requestPackets(request)) {
- pushToAllDevices(request);
- }
+ store.requestPackets(request);
}
@Override
@@ -165,9 +179,7 @@ public class PacketManager
checkNotNull(appId, "Application ID cannot be null");
PacketRequest request = new DefaultPacketRequest(selector, priority, appId);
- if (store.cancelPackets(request)) {
- removeFromAllDevices(request);
- }
+ store.cancelPackets(request);
}
@Override
@@ -176,6 +188,18 @@ public class PacketManager
}
/**
+ * Pushes all rules to the specified device.
+ *
+ * @param device device on which to install packet request flows
+ */
+ private void pushRulesToDevice(Device device) {
+ log.debug("Pushing packet requests to device {}", device.id());
+ for (PacketRequest request : store.existingRequests()) {
+ pushRule(device, request);
+ }
+ }
+
+ /**
* Pushes a packet request flow rule to all devices.
*
* @param request the packet request
@@ -187,16 +211,13 @@ public class PacketManager
}
}
-
/**
* Removes packet request flow rule from all devices.
*
* @param request the packet request
*/
private void removeFromAllDevices(PacketRequest request) {
- for (Device device : deviceService.getDevices()) {
- removeRule(device, request);
- }
+ deviceService.getAvailableDevices().forEach(d -> removeRule(d, request));
}
/**
@@ -232,7 +253,6 @@ public class PacketManager
if (!device.type().equals(Device.Type.SWITCH)) {
return;
}
-
ForwardingObjective forwarding = createBuilder(request)
.remove(new ObjectiveContext() {
@Override
@@ -241,7 +261,6 @@ public class PacketManager
request, device.id(), error);
}
});
-
objectiveService.forward(device.id(), forwarding);
}
@@ -263,12 +282,10 @@ public class PacketManager
}
private void localEmit(OutboundPacket packet) {
- final Device device = deviceService.getDevice(packet.sendThrough());
-
+ Device device = deviceService.getDevice(packet.sendThrough());
if (device == null) {
return;
}
-
PacketProvider packetProvider = getProvider(device.providerId());
if (packetProvider != null) {
packetProvider.emit(packet);
@@ -280,7 +297,9 @@ public class PacketManager
return new InternalPacketProviderService(provider);
}
- // Personalized packet provider service issued to the supplied provider.
+ /**
+ * Personalized packet provider service issued to the supplied provider.
+ */
private class InternalPacketProviderService
extends AbstractProviderService<PacketProvider>
implements PacketProviderService {
@@ -292,8 +311,10 @@ public class PacketManager
@Override
public void processPacket(PacketContext context) {
// TODO filter packets sent to processors based on registrations
- for (PacketProcessor processor : processors.values()) {
- processor.process(context);
+ for (ProcessorEntry entry : processors) {
+ long start = System.nanoTime();
+ entry.processor().process(context);
+ entry.addNanos(System.nanoTime() - start);
}
}
@@ -307,6 +328,16 @@ public class PacketManager
public void notify(PacketEvent event) {
localEmit(event.subject());
}
+
+ @Override
+ public void requestPackets(PacketRequest request) {
+ pushToAllDevices(request);
+ }
+
+ @Override
+ public void cancelPackets(PacketRequest request) {
+ removeFromAllDevices(request);
+ }
}
/**
@@ -319,17 +350,14 @@ public class PacketManager
try {
Device device = event.subject();
switch (event.type()) {
- case DEVICE_ADDED:
- case DEVICE_AVAILABILITY_CHANGED:
- if (deviceService.isAvailable(event.subject().id())) {
- log.debug("Pushing packet requests to device {}", event.subject().id());
- for (PacketRequest request : store.existingRequests()) {
- pushRule(device, request);
+ case DEVICE_ADDED:
+ case DEVICE_AVAILABILITY_CHANGED:
+ if (deviceService.isAvailable(event.subject().id())) {
+ pushRulesToDevice(device);
}
- }
- break;
- default:
- break;
+ break;
+ default:
+ break;
}
} catch (Exception e) {
log.warn("Failed to process {}", event, e);
@@ -338,4 +366,48 @@ public class PacketManager
}
}
+ /**
+ * Entity for tracking stats for a packet processor.
+ */
+ private class ProcessorEntry implements PacketProcessorEntry {
+ private final PacketProcessor processor;
+ private final int priority;
+ private long invocations = 0;
+ private long nanos = 0;
+
+ public ProcessorEntry(PacketProcessor processor, int priority) {
+ this.processor = processor;
+ this.priority = priority;
+ }
+
+ @Override
+ public PacketProcessor processor() {
+ return processor;
+ }
+
+ @Override
+ public int priority() {
+ return priority;
+ }
+
+ @Override
+ public long invocations() {
+ return invocations;
+ }
+
+ @Override
+ public long totalNanos() {
+ return nanos;
+ }
+
+ @Override
+ public long averageNanos() {
+ return invocations > 0 ? nanos / invocations : 0;
+ }
+
+ void addNanos(long nanos) {
+ this.nanos += nanos;
+ this.invocations++;
+ }
+ }
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
new file mode 100644
index 00000000..6515ef31
--- /dev/null
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
@@ -0,0 +1,634 @@
+/*
+ * Copyright 2015 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.net.statistic.impl;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+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.cli.Comparators;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTypedFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TypedStoredFlowEntry;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.statistic.DefaultLoad;
+import org.onosproject.net.statistic.FlowStatisticService;
+import org.onosproject.net.statistic.Load;
+import org.onosproject.net.statistic.FlowStatisticStore;
+import org.onosproject.net.statistic.SummaryFlowEntryWithLoad;
+import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
+
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.security.AppGuard.checkPermission;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.security.AppPermission.Type.*;
+
+/**
+ * Provides an implementation of the Flow Statistic Service.
+ */
+@Component(immediate = true, enabled = true)
+@Service
+public class FlowStatisticManager implements FlowStatisticService {
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowRuleService flowRuleService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowStatisticStore flowStatisticStore;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ private final InternalFlowRuleStatsListener frListener = new InternalFlowRuleStatsListener();
+
+ @Activate
+ public void activate() {
+ flowRuleService.addListener(frListener);
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ flowRuleService.removeListener(frListener);
+ log.info("Stopped");
+ }
+
+ @Override
+ public Map<ConnectPoint, SummaryFlowEntryWithLoad> loadSummary(Device device) {
+ checkPermission(STATISTIC_READ);
+
+ Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryLoad = new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
+
+ if (device == null) {
+ return summaryLoad;
+ }
+
+ List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id()));
+
+ for (Port port : ports) {
+ ConnectPoint cp = new ConnectPoint(device.id(), port.number());
+ SummaryFlowEntryWithLoad sfe = loadSummaryPortInternal(cp);
+ summaryLoad.put(cp, sfe);
+ }
+
+ return summaryLoad;
+ }
+
+ @Override
+ public SummaryFlowEntryWithLoad loadSummary(Device device, PortNumber pNumber) {
+ checkPermission(STATISTIC_READ);
+
+ ConnectPoint cp = new ConnectPoint(device.id(), pNumber);
+ return loadSummaryPortInternal(cp);
+ }
+
+ @Override
+ public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadAllByType(Device device,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType) {
+ checkPermission(STATISTIC_READ);
+
+ Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad = new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
+
+ if (device == null) {
+ return allLoad;
+ }
+
+ List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id()));
+
+ for (Port port : ports) {
+ ConnectPoint cp = new ConnectPoint(device.id(), port.number());
+ List<TypedFlowEntryWithLoad> tfel = loadAllPortInternal(cp, liveType, instType);
+ allLoad.put(cp, tfel);
+ }
+
+ return allLoad;
+ }
+
+ @Override
+ public List<TypedFlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType) {
+ checkPermission(STATISTIC_READ);
+
+ ConnectPoint cp = new ConnectPoint(device.id(), pNumber);
+ return loadAllPortInternal(cp, liveType, instType);
+ }
+
+ @Override
+ public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadTopnByType(Device device,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType,
+ int topn) {
+ checkPermission(STATISTIC_READ);
+
+ Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad = new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
+
+ if (device == null) {
+ return allLoad;
+ }
+
+ List<Port> ports = new ArrayList<>(deviceService.getPorts(device.id()));
+
+ for (Port port : ports) {
+ ConnectPoint cp = new ConnectPoint(device.id(), port.number());
+ List<TypedFlowEntryWithLoad> tfel = loadTopnPortInternal(cp, liveType, instType, topn);
+ allLoad.put(cp, tfel);
+ }
+
+ return allLoad;
+ }
+
+ @Override
+ public List<TypedFlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType,
+ int topn) {
+ checkPermission(STATISTIC_READ);
+
+ ConnectPoint cp = new ConnectPoint(device.id(), pNumber);
+ return loadTopnPortInternal(cp, liveType, instType, topn);
+ }
+
+ private SummaryFlowEntryWithLoad loadSummaryPortInternal(ConnectPoint cp) {
+ checkPermission(STATISTIC_READ);
+
+ Set<FlowEntry> currentStats;
+ Set<FlowEntry> previousStats;
+
+ TypedStatistics typedStatistics;
+ synchronized (flowStatisticStore) {
+ currentStats = flowStatisticStore.getCurrentFlowStatistic(cp);
+ if (currentStats == null) {
+ return new SummaryFlowEntryWithLoad(cp, new DefaultLoad());
+ }
+ previousStats = flowStatisticStore.getPreviousFlowStatistic(cp);
+ if (previousStats == null) {
+ return new SummaryFlowEntryWithLoad(cp, new DefaultLoad());
+ }
+ // copy to local flow entry
+ typedStatistics = new TypedStatistics(currentStats, previousStats);
+
+ // Check for validity of this stats data
+ checkLoadValidity(currentStats, previousStats);
+ }
+
+ // current and previous set is not empty!
+ Set<FlowEntry> currentSet = typedStatistics.current();
+ Set<FlowEntry> previousSet = typedStatistics.previous();
+ Load totalLoad = new DefaultLoad(aggregateBytesSet(currentSet), aggregateBytesSet(previousSet),
+ TypedFlowEntryWithLoad.avgPollInterval());
+
+ Map<FlowRule, TypedStoredFlowEntry> currentMap;
+ Map<FlowRule, TypedStoredFlowEntry> previousMap;
+
+ currentMap = typedStatistics.currentImmediate();
+ previousMap = typedStatistics.previousImmediate();
+ Load immediateLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
+ TypedFlowEntryWithLoad.shortPollInterval());
+
+ currentMap = typedStatistics.currentShort();
+ previousMap = typedStatistics.previousShort();
+ Load shortLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
+ TypedFlowEntryWithLoad.shortPollInterval());
+
+ currentMap = typedStatistics.currentMid();
+ previousMap = typedStatistics.previousMid();
+ Load midLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
+ TypedFlowEntryWithLoad.midPollInterval());
+
+ currentMap = typedStatistics.currentLong();
+ previousMap = typedStatistics.previousLong();
+ Load longLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
+ TypedFlowEntryWithLoad.longPollInterval());
+
+ currentMap = typedStatistics.currentUnknown();
+ previousMap = typedStatistics.previousUnknown();
+ Load unknownLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
+ TypedFlowEntryWithLoad.avgPollInterval());
+
+ return new SummaryFlowEntryWithLoad(cp, totalLoad, immediateLoad, shortLoad, midLoad, longLoad, unknownLoad);
+ }
+
+ private List<TypedFlowEntryWithLoad> loadAllPortInternal(ConnectPoint cp,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType) {
+ checkPermission(STATISTIC_READ);
+
+ List<TypedFlowEntryWithLoad> retTFEL = new ArrayList<>();
+
+ Set<FlowEntry> currentStats;
+ Set<FlowEntry> previousStats;
+
+ TypedStatistics typedStatistics;
+ synchronized (flowStatisticStore) {
+ currentStats = flowStatisticStore.getCurrentFlowStatistic(cp);
+ if (currentStats == null) {
+ return retTFEL;
+ }
+ previousStats = flowStatisticStore.getPreviousFlowStatistic(cp);
+ if (previousStats == null) {
+ return retTFEL;
+ }
+ // copy to local flow entry set
+ typedStatistics = new TypedStatistics(currentStats, previousStats);
+
+ // Check for validity of this stats data
+ checkLoadValidity(currentStats, previousStats);
+ }
+
+ // current and previous set is not empty!
+ boolean isAllLiveType = (liveType == null ? true : false); // null is all live type
+ boolean isAllInstType = (instType == null ? true : false); // null is all inst type
+
+ Map<FlowRule, TypedStoredFlowEntry> currentMap;
+ Map<FlowRule, TypedStoredFlowEntry> previousMap;
+
+ if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW) {
+ currentMap = typedStatistics.currentImmediate();
+ previousMap = typedStatistics.previousImmediate();
+
+ List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
+ isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
+ if (fel.size() > 0) {
+ retTFEL.addAll(fel);
+ }
+ }
+
+ if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW) {
+ currentMap = typedStatistics.currentShort();
+ previousMap = typedStatistics.previousShort();
+
+ List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
+ isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
+ if (fel.size() > 0) {
+ retTFEL.addAll(fel);
+ }
+ }
+
+ if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.MID_FLOW) {
+ currentMap = typedStatistics.currentMid();
+ previousMap = typedStatistics.previousMid();
+
+ List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
+ isAllInstType, instType, TypedFlowEntryWithLoad.midPollInterval());
+ if (fel.size() > 0) {
+ retTFEL.addAll(fel);
+ }
+ }
+
+ if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.LONG_FLOW) {
+ currentMap = typedStatistics.currentLong();
+ previousMap = typedStatistics.previousLong();
+
+ List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
+ isAllInstType, instType, TypedFlowEntryWithLoad.longPollInterval());
+ if (fel.size() > 0) {
+ retTFEL.addAll(fel);
+ }
+ }
+
+ if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW) {
+ currentMap = typedStatistics.currentUnknown();
+ previousMap = typedStatistics.previousUnknown();
+
+ List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
+ isAllInstType, instType, TypedFlowEntryWithLoad.avgPollInterval());
+ if (fel.size() > 0) {
+ retTFEL.addAll(fel);
+ }
+ }
+
+ return retTFEL;
+ }
+
+ private List<TypedFlowEntryWithLoad> typedFlowEntryLoadByInstInternal(ConnectPoint cp,
+ Map<FlowRule, TypedStoredFlowEntry> currentMap,
+ Map<FlowRule, TypedStoredFlowEntry> previousMap,
+ boolean isAllInstType,
+ Instruction.Type instType,
+ int liveTypePollInterval) {
+ List<TypedFlowEntryWithLoad> fel = new ArrayList<>();
+
+ for (TypedStoredFlowEntry tfe : currentMap.values()) {
+ if (isAllInstType ||
+ tfe.treatment().allInstructions().stream().
+ filter(i -> i.type() == instType).
+ findAny().isPresent()) {
+ long currentBytes = tfe.bytes();
+ long previousBytes = previousMap.getOrDefault(tfe, new DefaultTypedFlowEntry((FlowRule) tfe)).bytes();
+ Load fLoad = new DefaultLoad(currentBytes, previousBytes, liveTypePollInterval);
+ fel.add(new TypedFlowEntryWithLoad(cp, tfe, fLoad));
+ }
+ }
+
+ return fel;
+ }
+
+ private List<TypedFlowEntryWithLoad> loadTopnPortInternal(ConnectPoint cp,
+ TypedStoredFlowEntry.FlowLiveType liveType,
+ Instruction.Type instType,
+ int topn) {
+ List<TypedFlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType);
+
+ // Sort with descending order of load
+ List<TypedFlowEntryWithLoad> tfel =
+ fel.stream().sorted(Comparators.TYPEFLOWENTRY_WITHLOAD_COMPARATOR).
+ limit(topn).collect(Collectors.toList());
+
+ return tfel;
+ }
+
+ private long aggregateBytesSet(Set<FlowEntry> setFE) {
+ return setFE.stream().mapToLong(FlowEntry::bytes).sum();
+ }
+
+ private long aggregateBytesMap(Map<FlowRule, TypedStoredFlowEntry> mapFE) {
+ return mapFE.values().stream().mapToLong(FlowEntry::bytes).sum();
+ }
+
+ /**
+ * Internal data class holding two set of typed flow entries.
+ */
+ private static class TypedStatistics {
+ private final ImmutableSet<FlowEntry> currentAll;
+ private final ImmutableSet<FlowEntry> previousAll;
+
+ private final Map<FlowRule, TypedStoredFlowEntry> currentImmediate = new HashMap<>();
+ private final Map<FlowRule, TypedStoredFlowEntry> previousImmediate = new HashMap<>();
+
+ private final Map<FlowRule, TypedStoredFlowEntry> currentShort = new HashMap<>();
+ private final Map<FlowRule, TypedStoredFlowEntry> previousShort = new HashMap<>();
+
+ private final Map<FlowRule, TypedStoredFlowEntry> currentMid = new HashMap<>();
+ private final Map<FlowRule, TypedStoredFlowEntry> previousMid = new HashMap<>();
+
+ private final Map<FlowRule, TypedStoredFlowEntry> currentLong = new HashMap<>();
+ private final Map<FlowRule, TypedStoredFlowEntry> previousLong = new HashMap<>();
+
+ private final Map<FlowRule, TypedStoredFlowEntry> currentUnknown = new HashMap<>();
+ private final Map<FlowRule, TypedStoredFlowEntry> previousUnknown = new HashMap<>();
+
+ public TypedStatistics(Set<FlowEntry> current, Set<FlowEntry> previous) {
+ this.currentAll = ImmutableSet.copyOf(checkNotNull(current));
+ this.previousAll = ImmutableSet.copyOf(checkNotNull(previous));
+
+ currentAll.forEach(fe -> {
+ TypedStoredFlowEntry tfe = TypedFlowEntryWithLoad.newTypedStoredFlowEntry(fe);
+
+ switch (tfe.flowLiveType()) {
+ case IMMEDIATE_FLOW:
+ currentImmediate.put(fe, tfe);
+ break;
+ case SHORT_FLOW:
+ currentShort.put(fe, tfe);
+ break;
+ case MID_FLOW:
+ currentMid.put(fe, tfe);
+ break;
+ case LONG_FLOW:
+ currentLong.put(fe, tfe);
+ break;
+ default:
+ currentUnknown.put(fe, tfe);
+ break;
+ }
+ });
+
+ previousAll.forEach(fe -> {
+ TypedStoredFlowEntry tfe = TypedFlowEntryWithLoad.newTypedStoredFlowEntry(fe);
+
+ switch (tfe.flowLiveType()) {
+ case IMMEDIATE_FLOW:
+ if (currentImmediate.containsKey(fe)) {
+ previousImmediate.put(fe, tfe);
+ } else if (currentShort.containsKey(fe)) {
+ previousShort.put(fe, tfe);
+ } else if (currentMid.containsKey(fe)) {
+ previousMid.put(fe, tfe);
+ } else if (currentLong.containsKey(fe)) {
+ previousLong.put(fe, tfe);
+ } else {
+ previousUnknown.put(fe, tfe);
+ }
+ break;
+ case SHORT_FLOW:
+ if (currentShort.containsKey(fe)) {
+ previousShort.put(fe, tfe);
+ } else if (currentMid.containsKey(fe)) {
+ previousMid.put(fe, tfe);
+ } else if (currentLong.containsKey(fe)) {
+ previousLong.put(fe, tfe);
+ } else {
+ previousUnknown.put(fe, tfe);
+ }
+ break;
+ case MID_FLOW:
+ if (currentMid.containsKey(fe)) {
+ previousMid.put(fe, tfe);
+ } else if (currentLong.containsKey(fe)) {
+ previousLong.put(fe, tfe);
+ } else {
+ previousUnknown.put(fe, tfe);
+ }
+ break;
+ case LONG_FLOW:
+ if (currentLong.containsKey(fe)) {
+ previousLong.put(fe, tfe);
+ } else {
+ previousUnknown.put(fe, tfe);
+ }
+ break;
+ default:
+ previousUnknown.put(fe, tfe);
+ break;
+ }
+ });
+ }
+
+ /**
+ * Returns flow entries as the current value.
+ *
+ * @return flow entries as the current value
+ */
+ public ImmutableSet<FlowEntry> current() {
+ return currentAll;
+ }
+
+ /**
+ * Returns flow entries as the previous value.
+ *
+ * @return flow entries as the previous value
+ */
+ public ImmutableSet<FlowEntry> previous() {
+ return previousAll;
+ }
+
+ public Map<FlowRule, TypedStoredFlowEntry> currentImmediate() {
+ return currentImmediate;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> previousImmediate() {
+ return previousImmediate;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> currentShort() {
+ return currentShort;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> previousShort() {
+ return previousShort;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> currentMid() {
+ return currentMid;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> previousMid() {
+ return previousMid;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> currentLong() {
+ return currentLong;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> previousLong() {
+ return previousLong;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> currentUnknown() {
+ return currentUnknown;
+ }
+ public Map<FlowRule, TypedStoredFlowEntry> previousUnknown() {
+ return previousUnknown;
+ }
+
+ /**
+ * Validates values are not empty.
+ *
+ * @return false if either of the sets is empty. Otherwise, true.
+ */
+ public boolean isValid() {
+ return !(currentAll.isEmpty() || previousAll.isEmpty());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(currentAll, previousAll);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof TypedStatistics)) {
+ return false;
+ }
+ final TypedStatistics other = (TypedStatistics) obj;
+ return Objects.equals(this.currentAll, other.currentAll) &&
+ Objects.equals(this.previousAll, other.previousAll);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("current", currentAll)
+ .add("previous", previousAll)
+ .toString();
+ }
+ }
+
+ private void checkLoadValidity(Set<FlowEntry> current, Set<FlowEntry> previous) {
+ current.stream().forEach(c -> {
+ FlowEntry f = previous.stream().filter(p -> c.equals(p)).
+ findAny().orElse(null);
+ if (f != null && c.bytes() < f.bytes()) {
+ log.debug("FlowStatisticManager:checkLoadValidity():" +
+ "Error: " + c + " :Previous bytes=" + f.bytes() +
+ " is larger than current bytes=" + c.bytes() + " !!!");
+ }
+ });
+
+ }
+
+ /**
+ * Creates a predicate that checks the instruction type of a flow entry is the same as
+ * the specified instruction type.
+ *
+ * @param instType instruction type to be checked
+ * @return predicate
+ */
+ private static Predicate<FlowEntry> hasInstructionType(Instruction.Type instType) {
+ return new Predicate<FlowEntry>() {
+ @Override
+ public boolean apply(FlowEntry flowEntry) {
+ List<Instruction> allInstructions = flowEntry.treatment().allInstructions();
+
+ return allInstructions.stream().filter(i -> i.type() == instType).findAny().isPresent();
+ }
+ };
+ }
+
+ /**
+ * Internal flow rule event listener for FlowStatisticManager.
+ */
+ private class InternalFlowRuleStatsListener implements FlowRuleListener {
+
+ @Override
+ public void event(FlowRuleEvent event) {
+ FlowRule rule = event.subject();
+ switch (event.type()) {
+ case RULE_ADDED:
+ if (rule instanceof FlowEntry) {
+ flowStatisticStore.addFlowStatistic((FlowEntry) rule);
+ }
+ break;
+ case RULE_UPDATED:
+ flowStatisticStore.updateFlowStatistic((FlowEntry) rule);
+ break;
+ case RULE_ADD_REQUESTED:
+ break;
+ case RULE_REMOVE_REQUESTED:
+ break;
+ case RULE_REMOVED:
+ flowStatisticStore.removeFlowStatistic(rule);
+ break;
+ default:
+ log.warn("Unknown flow rule event {}", event);
+ }
+ }
+ }
+}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
index a238c7fb..8347ee38 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
@@ -27,6 +27,8 @@ import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultEdgeLink;
import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.DefaultDisjointPath;
import org.onosproject.net.DeviceId;
import org.onosproject.net.EdgeLink;
import org.onosproject.net.ElementId;
@@ -46,6 +48,8 @@ import org.slf4j.Logger;
import java.util.List;
import java.util.Set;
+import java.util.Map;
+
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
@@ -128,6 +132,84 @@ public class PathManager implements PathService {
return edgeToEdgePaths(srcEdge, dstEdge, paths);
}
+ @Override
+ public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
+ return getDisjointPaths(src, dst, (LinkWeight) null);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) {
+ checkNotNull(src, ELEMENT_ID_NULL);
+ checkNotNull(dst, ELEMENT_ID_NULL);
+
+ // Get the source and destination edge locations
+ EdgeLink srcEdge = getEdgeLink(src, true);
+ EdgeLink dstEdge = getEdgeLink(dst, false);
+
+ // If either edge is null, bail with no paths.
+ if (srcEdge == null || dstEdge == null) {
+ return ImmutableSet.of();
+ }
+
+ DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src;
+ DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst;
+
+ // If the source and destination are on the same edge device, there
+ // is just one path, so build it and return it.
+ if (srcDevice.equals(dstDevice)) {
+ return edgeToEdgePathsDisjoint(srcEdge, dstEdge);
+ }
+
+ // Otherwise get all paths between the source and destination edge
+ // devices.
+ Topology topology = topologyService.currentTopology();
+ Set<DisjointPath> paths = weight == null ?
+ topologyService.getDisjointPaths(topology, srcDevice, dstDevice) :
+ topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight);
+
+ return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
+ Map<Link, Object> riskProfile) {
+ return getDisjointPaths(src, dst, null, riskProfile);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
+ Map<Link, Object> riskProfile) {
+ checkNotNull(src, ELEMENT_ID_NULL);
+ checkNotNull(dst, ELEMENT_ID_NULL);
+
+ // Get the source and destination edge locations
+ EdgeLink srcEdge = getEdgeLink(src, true);
+ EdgeLink dstEdge = getEdgeLink(dst, false);
+
+ // If either edge is null, bail with no paths.
+ if (srcEdge == null || dstEdge == null) {
+ return ImmutableSet.of();
+ }
+
+ DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src;
+ DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst;
+
+ // If the source and destination are on the same edge device, there
+ // is just one path, so build it and return it.
+ if (srcDevice.equals(dstDevice)) {
+ return edgeToEdgePathsDisjoint(srcEdge, dstEdge);
+ }
+
+ // Otherwise get all paths between the source and destination edge
+ // devices.
+ Topology topology = topologyService.currentTopology();
+ Set<DisjointPath> paths = weight == null ?
+ topologyService.getDisjointPaths(topology, srcDevice, dstDevice, riskProfile) :
+ topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile);
+
+ return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths);
+ }
+
// Finds the host edge link if the element ID is a host id of an existing
// host. Otherwise, if the host does not exist, it returns null and if
// the element ID is not a host ID, returns NOT_HOST edge link.
@@ -162,6 +244,20 @@ public class PathManager implements PathService {
return endToEndPaths;
}
+ private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink) {
+ Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(1);
+ endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, null));
+ return endToEndPaths;
+ }
+
+ private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink, Set<DisjointPath> paths) {
+ Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size());
+ for (DisjointPath path : paths) {
+ endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, path));
+ }
+ return endToEndPaths;
+ }
+
// Produces a direct edge-to-edge path.
private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) {
List<Link> links = Lists.newArrayListWithCapacity(2);
@@ -179,6 +275,13 @@ public class PathManager implements PathService {
return new DefaultPath(PID, links, 2);
}
+ // Produces a direct edge-to-edge path.
+ private DisjointPath edgeToEdgePathD(EdgeLink srcLink, EdgeLink dstLink, DisjointPath path) {
+ return new DefaultDisjointPath(PID, (DefaultPath) edgeToEdgePath(srcLink, dstLink, path.primary()),
+ (DefaultPath) edgeToEdgePath(srcLink, dstLink, path.backup()));
+ }
+
+
// Special value for edge link to represent that this is really not an
// edge link since the src or dst are really an infrastructure device.
private static class NotHost extends DefaultEdgeLink implements EdgeLink {
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
index 04c4f1c1..4425e1c1 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
@@ -21,6 +21,7 @@ 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.DisjointPath;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.event.Event;
import org.onosproject.net.ConnectPoint;
@@ -46,6 +47,7 @@ import org.slf4j.Logger;
import java.util.List;
import java.util.Set;
+import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.security.AppGuard.checkPermission;
@@ -60,7 +62,7 @@ import static org.onosproject.security.AppPermission.Type.*;
@Service
public class TopologyManager
extends AbstractListenerProviderRegistry<TopologyEvent, TopologyListener,
- TopologyProvider, TopologyProviderService>
+ TopologyProvider, TopologyProviderService>
implements TopologyService, TopologyProviderRegistry {
public static final String TOPOLOGY_NULL = "Topology cannot be null";
@@ -68,6 +70,7 @@ public class TopologyManager
private static final String CLUSTER_ID_NULL = "Cluster ID cannot be null";
private static final String CLUSTER_NULL = "Topology cluster cannot be null";
public static final String CONNECTION_POINT_NULL = "Connection point cannot be null";
+ public static final String LINK_WEIGHT_NULL = "Link weight cannot be null";
private final Logger log = getLogger(getClass());
@@ -162,6 +165,44 @@ public class TopologyManager
}
@Override
+ public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+ checkNotNull(topology, TOPOLOGY_NULL);
+ checkNotNull(src, DEVICE_ID_NULL);
+ checkNotNull(dst, DEVICE_ID_NULL);
+ return store.getDisjointPaths(topology, src, dst);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+ DeviceId dst, LinkWeight weight) {
+ checkNotNull(topology, TOPOLOGY_NULL);
+ checkNotNull(src, DEVICE_ID_NULL);
+ checkNotNull(dst, DEVICE_ID_NULL);
+ checkNotNull(weight, LINK_WEIGHT_NULL);
+ return store.getDisjointPaths(topology, src, dst, weight);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+ Map<Link, Object> riskProfile) {
+ checkNotNull(topology, TOPOLOGY_NULL);
+ checkNotNull(src, DEVICE_ID_NULL);
+ checkNotNull(dst, DEVICE_ID_NULL);
+ return store.getDisjointPaths(topology, src, dst, riskProfile);
+ }
+
+ @Override
+ public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
+ DeviceId dst, LinkWeight weight,
+ Map<Link, Object> riskProfile) {
+ checkNotNull(topology, TOPOLOGY_NULL);
+ checkNotNull(src, DEVICE_ID_NULL);
+ checkNotNull(dst, DEVICE_ID_NULL);
+ checkNotNull(weight, LINK_WEIGHT_NULL);
+ return store.getDisjointPaths(topology, src, dst, weight, riskProfile);
+ }
+
+ @Override
public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
checkPermission(TOPOLOGY_READ);
checkNotNull(topology, TOPOLOGY_NULL);