diff options
Diffstat (limited to 'framework/src/onos/core/common')
11 files changed, 285 insertions, 28 deletions
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java index eb53152e..3433b3b7 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/CodecManager.java @@ -16,6 +16,7 @@ package org.onosproject.codec.impl; 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; @@ -36,6 +37,7 @@ import org.onosproject.net.Port; import org.onosproject.net.driver.Driver; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.flow.FlowRule; +import org.onosproject.net.flow.TableStatisticsEntry; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.flow.criteria.Criterion; @@ -99,6 +101,7 @@ public class CodecManager implements CodecService { registerCodec(Driver.class, new DriverCodec()); registerCodec(GroupBucket.class, new GroupBucketCodec()); registerCodec(Load.class, new LoadCodec()); + registerCodec(TableStatisticsEntry.class, new TableStatisticsEntryCodec()); log.info("Started"); } diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java index d61cf38b..d12e4ad8 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/EncodeInstructionCodecHelper.java @@ -215,6 +215,7 @@ public final class EncodeInstructionCodecHelper { break; case DROP: + case NOACTION: break; case L0MODIFICATION: diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java new file mode 100644 index 00000000..7834ceb1 --- /dev/null +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java @@ -0,0 +1,46 @@ +/* + * 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.codec.impl; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; +import org.onosproject.net.flow.TableStatisticsEntry; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Table statistics entry JSON codec. + */ +public final class TableStatisticsEntryCodec extends JsonCodec<TableStatisticsEntry> { + + @Override + public ObjectNode encode(TableStatisticsEntry entry, CodecContext context) { + checkNotNull(entry, "Table Statistics entry cannot be null"); + + final ObjectNode result = context.mapper().createObjectNode() + .put("tableId", entry.tableId()) + .put("deviceId", entry.deviceId().toString()) + .put("activeEntries", entry.activeFlowEntries()) + .put("packetsLookedUp", entry.packetsLookedup()) + .put("packetsMatched", entry.packetsMatched()); + + return result; + } + +} + diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java index bdf7d732..3c5c540d 100644 --- a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java +++ b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java @@ -23,14 +23,19 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.ImmutableSetMultimap.Builder; import org.onlab.graph.DijkstraGraphSearch; +import org.onlab.graph.DisjointPathPair; import org.onlab.graph.GraphPathSearch; import org.onlab.graph.GraphPathSearch.Result; +import org.onlab.graph.SRLGGraphSearch; +import org.onlab.graph.SuurballeGraphSearch; import org.onlab.graph.TarjanGraphSearch; import org.onlab.graph.TarjanGraphSearch.SCCResult; import org.onosproject.net.AbstractModel; import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DefaultDisjointPath; import org.onosproject.net.DefaultPath; import org.onosproject.net.DeviceId; +import org.onosproject.net.DisjointPath; import org.onosproject.net.Link; import org.onosproject.net.Path; import org.onosproject.net.provider.ProviderId; @@ -45,10 +50,11 @@ import org.onosproject.net.topology.TopologyEdge; import org.onosproject.net.topology.TopologyGraph; import org.onosproject.net.topology.TopologyVertex; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import static com.google.common.base.MoreObjects.toStringHelper; import static com.google.common.base.Preconditions.checkArgument; @@ -67,6 +73,9 @@ public class DefaultTopology extends AbstractModel implements Topology { private static final DijkstraGraphSearch<TopologyVertex, TopologyEdge> DIJKSTRA = new DijkstraGraphSearch<>(); private static final TarjanGraphSearch<TopologyVertex, TopologyEdge> TARJAN = new TarjanGraphSearch<>(); + private static final SuurballeGraphSearch<TopologyVertex, TopologyEdge> SUURBALLE = + new SuurballeGraphSearch<>(); + private final long time; private final long creationTime; @@ -315,15 +324,135 @@ public class DefaultTopology extends AbstractModel implements Topology { return builder.build(); } + /** + * /** + * Returns the set of pre-computed shortest disjoint path pairs between source and + * destination devices. + * + * @param src source device + * @param dst destination device + * @return set of shortest disjoint path pairs + */ + public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) { + return getDisjointPaths(src, dst, (LinkWeight) null); + } + + /** + * Computes on-demand the set of shortest disjoint path pairs between source and + * destination devices. + * + * @param src source device + * @param dst destination device + * @param weight link weight function + * @return set of disjoint shortest path pairs + */ + public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) { + final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); + final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); + Set<TopologyVertex> vertices = graph.getVertexes(); + if (!vertices.contains(srcV) || !vertices.contains(dstV)) { + // src or dst not part of the current graph + return ImmutableSet.of(); + } + + GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = + SUURBALLE.search(graph, srcV, dstV, weight, ALL_PATHS); + ImmutableSet.Builder<DisjointPath> builder = ImmutableSet.builder(); + for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) { + builder.add(networkDisjointPath((org.onlab.graph.DisjointPathPair<TopologyVertex, TopologyEdge>) path)); + } + return builder.build(); + } + + /** + * Computes on-demand the set of shortest disjoint risk groups path pairs between source and + * destination devices. + * + * @param src source device + * @param dst destination device + * @param weight edge weight object + * @param riskProfile map representing risk groups for each edge + * @return set of shortest disjoint paths + */ + private Set<DisjointPath> disjointPaths(DeviceId src, DeviceId dst, LinkWeight weight, + Map<TopologyEdge, Object> riskProfile) { + DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); + DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); + + Set<TopologyVertex> vertices = graph.getVertexes(); + if (!vertices.contains(srcV) || !vertices.contains(dstV)) { + // src or dst not part of the current graph + return ImmutableSet.of(); + } + + SRLGGraphSearch<TopologyVertex, TopologyEdge> srlg = new SRLGGraphSearch<>(riskProfile); + GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = + srlg.search(graph, srcV, dstV, weight, ALL_PATHS); + ImmutableSet.Builder<DisjointPath> builder = ImmutableSet.builder(); + for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) { + builder.add(networkDisjointPath((org.onlab.graph.DisjointPathPair<TopologyVertex, TopologyEdge>) path)); + } + return builder.build(); + } + + /** + * Computes on-demand the set of shortest disjoint risk groups path pairs between source and + * destination devices. + * + * @param src source device + * @param dst destination device + * @param weight edge weight object + * @param riskProfile map representing risk groups for each link + * @return set of shortest disjoint paths + */ + public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight, + Map<Link, Object> riskProfile) { + Map<TopologyEdge, Object> riskProfile2 = new HashMap<>(); + for (Link l : riskProfile.keySet()) { + riskProfile2.put(new TopologyEdge() { + Link cur = l; + + public Link link() { + return cur; + } + + public TopologyVertex src() { + return () -> src; + } + + public TopologyVertex dst() { + return () -> dst; + } + }, riskProfile.get(l)); + } + return disjointPaths(src, dst, weight, riskProfile2); + } + + /** + * Computes on-demand the set of shortest disjoint risk groups path pairs between source and + * destination devices. + * + * @param src source device + * @param dst destination device + * @param riskProfile map representing risk groups for each link + * @return set of shortest disjoint paths + */ + public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) { + return getDisjointPaths(src, dst, null, riskProfile); + } + // Converts graph path to a network path with the same cost. private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) { - List<Link> links = new ArrayList<>(); - for (TopologyEdge edge : path.edges()) { - links.add(edge.link()); - } + List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList()); return new DefaultPath(CORE_PROVIDER_ID, links, path.cost()); } + private DisjointPath networkDisjointPath(DisjointPathPair<TopologyVertex, TopologyEdge> path) { + return new DefaultDisjointPath(CORE_PROVIDER_ID, + (DefaultPath) networkPath(path.primary()), + (DefaultPath) networkPath(path.secondary())); + } + // Searches for SCC clusters in the network topology graph using Tarjan // algorithm. private SCCResult<TopologyVertex, TopologyEdge> searchForClusters() { @@ -334,6 +463,7 @@ public class DefaultTopology extends AbstractModel implements Topology { private ImmutableMap<ClusterId, TopologyCluster> buildTopologyClusters() { ImmutableMap.Builder<ClusterId, TopologyCluster> clusterBuilder = ImmutableMap.builder(); SCCResult<TopologyVertex, TopologyEdge> results = clusterResults.get(); + // Extract both vertexes and edges from the results; the lists form // pairs along the same index. List<Set<TopologyVertex>> clusterVertexes = results.clusterVertexes(); diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionCodecTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionCodecTest.java index 6bf46803..54e1146b 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionCodecTest.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/CriterionCodecTest.java @@ -38,10 +38,8 @@ import org.onosproject.net.flow.criteria.Criterion; import com.fasterxml.jackson.databind.node.ObjectNode; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.onlab.junit.TestUtils.getField; -import static org.onlab.junit.TestUtils.setField; import static org.onosproject.codec.impl.CriterionJsonMatcher.matchesCriterion; /** @@ -429,17 +427,4 @@ public class CriterionCodecTest { ObjectNode result = criterionCodec.encode(criterion, context); assertThat(result, matchesCriterion(criterion)); } - - /** - * Tests that an unimplemented criterion type only returns the type and - * no other data. - */ - @Test - public void matchUnknownTypeTest() throws Exception { - Criterion criterion = Criteria.matchOpticalSignalType((byte) 250); - setField(criterion, "type", Criterion.Type.UNASSIGNED_40); - ObjectNode result = criterionCodec.encode(criterion, context); - assertThat(result.get("type").textValue(), is(criterion.type().toString())); - assertThat(result.size(), is(1)); - } } diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java index 72081e6c..c3cdca0f 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/InstructionJsonMatcher.java @@ -416,6 +416,8 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json description); } else if (instruction instanceof ModMplsLabelInstruction) { return matchModMplsLabelInstruction(jsonInstruction, description); + } else if (instruction instanceof NoActionInstruction) { + return true; } return false; diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/common/DefaultTopologyTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/common/DefaultTopologyTest.java index 4d435cfe..ef0f3324 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/common/DefaultTopologyTest.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/common/DefaultTopologyTest.java @@ -73,7 +73,7 @@ public class DefaultTopologyTest { link("1", 3, "4", 3), link("4", 3, "1", 3), link("3", 4, "4", 4), link("4", 4, "3", 4)); GraphDescription graphDescription = - new DefaultGraphDescription(now, devices, links); + new DefaultGraphDescription(now, System.currentTimeMillis(), devices, links); dt = new DefaultTopology(PID, graphDescription); assertEquals("incorrect supplier", PID, dt.providerId()); diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java index c8c92aa5..bed32a2d 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleFlowRuleStore.java @@ -20,8 +20,10 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Sets; import com.google.common.util.concurrent.SettableFuture; + import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -44,6 +46,7 @@ import org.onosproject.net.flow.FlowRuleEvent.Type; import org.onosproject.net.flow.FlowRuleStore; import org.onosproject.net.flow.FlowRuleStoreDelegate; import org.onosproject.net.flow.StoredFlowEntry; +import org.onosproject.net.flow.TableStatisticsEntry; import org.onosproject.store.AbstractStore; import org.slf4j.Logger; @@ -79,6 +82,9 @@ public class SimpleFlowRuleStore private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>> flowEntries = new ConcurrentHashMap<>(); + private final ConcurrentMap<DeviceId, List<TableStatisticsEntry>> + deviceTableStats = new ConcurrentHashMap<>(); + private final AtomicInteger localBatchIdGen = new AtomicInteger(); // TODO: make this configurable @@ -97,6 +103,7 @@ public class SimpleFlowRuleStore @Deactivate public void deactivate() { + deviceTableStats.clear(); flowEntries.clear(); log.info("Stopped"); } @@ -315,4 +322,20 @@ public class SimpleFlowRuleStore } } } + + @Override + public FlowRuleEvent updateTableStatistics(DeviceId deviceId, + List<TableStatisticsEntry> tableStats) { + deviceTableStats.put(deviceId, tableStats); + return null; + } + + @Override + public Iterable<TableStatisticsEntry> getTableStatistics(DeviceId deviceId) { + List<TableStatisticsEntry> tableStats = deviceTableStats.get(deviceId); + if (tableStats == null) { + return Collections.emptyList(); + } + return ImmutableList.copyOf(tableStats); + } } diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java index 264d0493..72ec98ca 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java @@ -160,6 +160,11 @@ public class SimpleHostStore } @Override + public HostEvent removeIp(HostId hostId, IpAddress ipAddress) { + return null; + } + + @Override public int getHostCount() { return hosts.size(); } diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimplePacketStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimplePacketStore.java index f8359262..7dda12c8 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimplePacketStore.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimplePacketStore.java @@ -15,10 +15,13 @@ */ package org.onosproject.store.trivial; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Service; +import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.packet.OutboundPacket; import org.onosproject.net.packet.PacketEvent; import org.onosproject.net.packet.PacketEvent.Type; @@ -27,7 +30,9 @@ import org.onosproject.net.packet.PacketStore; import org.onosproject.net.packet.PacketStoreDelegate; import org.onosproject.store.AbstractStore; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -39,7 +44,7 @@ public class SimplePacketStore extends AbstractStore<PacketEvent, PacketStoreDelegate> implements PacketStore { - private Set<PacketRequest> requests = Sets.newConcurrentHashSet(); + private Map<TrafficSelector, Set<PacketRequest>> requests = Maps.newConcurrentMap(); @Override public void emit(OutboundPacket packet) { @@ -47,18 +52,50 @@ public class SimplePacketStore } @Override - public boolean requestPackets(PacketRequest request) { - return requests.add(request); + public void requestPackets(PacketRequest request) { + requests.compute(request.selector(), (s, existingRequests) -> { + if (existingRequests == null) { + return ImmutableSet.of(request); + } else if (!existingRequests.contains(request)) { + if (delegate != null) { + delegate.requestPackets(request); + } + return ImmutableSet.<PacketRequest>builder() + .addAll(existingRequests) + .add(request) + .build(); + } else { + return existingRequests; + } + }); } @Override - public boolean cancelPackets(PacketRequest request) { - return requests.remove(request); + public void cancelPackets(PacketRequest request) { + requests.computeIfPresent(request.selector(), (s, existingRequests) -> { + if (existingRequests.contains(request)) { + HashSet<PacketRequest> newRequests = Sets.newHashSet(existingRequests); + newRequests.remove(request); + if (newRequests.size() > 0) { + return ImmutableSet.copyOf(newRequests); + } else { + if (delegate != null) { + delegate.cancelPackets(request); + } + return null; + } + } else { + return existingRequests; + } + }); } @Override public List<PacketRequest> existingRequests() { - return ImmutableList.copyOf(requests); + List<PacketRequest> list = Lists.newArrayList(); + requests.values().forEach(list::addAll); + list.sort((o1, o2) -> o1.priority().priorityValue() - o2.priority().priorityValue()); + return list; } } diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java index 6a89c019..29c5d844 100644 --- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java +++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java @@ -23,6 +23,7 @@ import org.onosproject.common.DefaultTopology; import org.onosproject.event.Event; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; +import org.onosproject.net.DisjointPath; import org.onosproject.net.Link; import org.onosproject.net.Path; import org.onosproject.net.provider.ProviderId; @@ -39,6 +40,7 @@ import org.onosproject.store.AbstractStore; import org.slf4j.Logger; import java.util.List; +import java.util.Map; import java.util.Set; import static org.slf4j.LoggerFactory.getLogger; @@ -114,6 +116,29 @@ public class SimpleTopologyStore } @Override + public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) { + return defaultTopology(topology).getDisjointPaths(src, dst); + } + + @Override + public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, + LinkWeight weight) { + return defaultTopology(topology).getDisjointPaths(src, dst, weight); + } + + @Override + public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, + Map<Link, Object> riskProfile) { + return defaultTopology(topology).getDisjointPaths(src, dst, riskProfile); + } + + @Override + public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, + LinkWeight weight, Map<Link, Object> riskProfile) { + return defaultTopology(topology).getDisjointPaths(src, dst, weight, riskProfile); + } + + @Override public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) { return defaultTopology(topology).isInfrastructure(connectPoint); } |