use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class OpticalConnectivityIntentCompiler method getOpticalPaths.
/**
* Calculates optical paths in WDM topology.
*
* @param intent optical connectivity intent
* @return set of paths in WDM topology
*/
private Stream<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
// Route in WDM topology
Topology topology = topologyService.currentTopology();
// TODO: refactor with LinkWeigher class Implementation
LinkWeigher weight = new LinkWeigher() {
@Override
public Weight getInitialWeight() {
return ScalarWeight.toWeight(0.0);
}
@Override
public Weight getNonViableWeight() {
return ScalarWeight.NON_VIABLE_WEIGHT;
}
/**
* @param edge edge to be weighed
* @return the metric retrieved from the annotations otherwise 1
*/
@Override
public Weight weight(TopologyEdge edge) {
log.debug("Link {} metric {}", edge.link(), edge.link().annotations().value("metric"));
// Disregard inactive or non-optical links
if (edge.link().state() == Link.State.INACTIVE) {
return ScalarWeight.toWeight(-1);
}
if (edge.link().type() != Link.Type.OPTICAL) {
return ScalarWeight.toWeight(-1);
}
// Adhere to static port mappings
DeviceId srcDeviceId = edge.link().src().deviceId();
if (srcDeviceId.equals(intent.getSrc().deviceId())) {
ConnectPoint srcStaticPort = staticPort(intent.getSrc());
if (srcStaticPort != null) {
return ScalarWeight.toWeight(srcStaticPort.equals(edge.link().src()) ? 1 : -1);
}
}
DeviceId dstDeviceId = edge.link().dst().deviceId();
if (dstDeviceId.equals(intent.getDst().deviceId())) {
ConnectPoint dstStaticPort = staticPort(intent.getDst());
if (dstStaticPort != null) {
return ScalarWeight.toWeight(dstStaticPort.equals(edge.link().dst()) ? 1 : -1);
}
}
Annotations annotations = edge.link().annotations();
if (annotations != null && annotations.value("metric") != null && !annotations.value("metric").isEmpty()) {
double metric = Double.parseDouble(annotations.value("metric"));
return ScalarWeight.toWeight(metric);
} else {
return ScalarWeight.toWeight(1);
}
}
};
ConnectPoint start = intent.getSrc();
ConnectPoint end = intent.getDst();
// 0 hop case
if (start.deviceId().equals(end.deviceId())) {
log.debug("install optical intent for 0 hop i.e srcDeviceId=dstDeviceId");
DefaultLink defaultLink = DefaultLink.builder().providerId(PROVIDER_ID).src(start).dst(end).state(Link.State.ACTIVE).type(Link.Type.DIRECT).isExpected(true).build();
List<Link> links = ImmutableList.<Link>builder().add(defaultLink).build();
Annotations annotations = DefaultAnnotations.builder().build();
DefaultPath defaultPath = new DefaultPath(PROVIDER_ID, links, null, annotations);
return ImmutableList.<Path>builder().add(defaultPath).build().stream();
}
// head link's src port should be same as intent src port and tail link dst port
// should be same as intent dst port in the path.
Stream<Path> paths = topologyService.getKShortestPaths(topology, start.deviceId(), end.deviceId(), weight).filter(p -> p.links().get(0).src().port().equals(start.port()) && p.links().get(p.links().size() - 1).dst().port().equals(end.port()));
if (log.isDebugEnabled()) {
return paths.map(path -> {
// no-op map stage to add debug logging
log.debug("Candidate path: {}", path.links().stream().map(lk -> lk.src() + "-" + lk.dst()).collect(Collectors.toList()));
return path;
});
}
return paths;
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class OpticalPathIntentCompiler method createReverseRules.
/**
* Create rules for the reverse path of the intent.
*
* @param intent the intent
* @return list of flow rules
*/
private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchInPort(reversePort(intent.dst().deviceId(), intent.dst().port()));
List<FlowRule> rules = new LinkedList<>();
/*
* especial case for 0 hop when srcDeviceId = dstDeviceId
* and path contain only one fake default path.
*/
if (intent.src().deviceId().equals(intent.dst().deviceId()) && intent.path().links().size() == 1) {
log.debug("handling 0 hop reverse path case for intent {}", intent);
TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
if (!isTransparent(intent.src().deviceId())) {
treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
}
treatmentBuilder.setOutput(reversePort(intent.src().deviceId(), intent.src().port()));
FlowRule rule = DefaultFlowRule.builder().forDevice(intent.src().deviceId()).withSelector(selectorBuilder.build()).withTreatment(treatmentBuilder.build()).withPriority(intent.priority()).fromApp(appId).makePermanent().build();
rules.add(rule);
return rules;
}
ConnectPoint current = intent.dst();
for (Link link : Lists.reverse(intent.path().links())) {
TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
if (!isTransparent(current.deviceId())) {
treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
}
treatmentBuilder.setOutput(reversePort(link.dst().deviceId(), link.dst().port()));
FlowRule rule = DefaultFlowRule.builder().forDevice(current.deviceId()).withSelector(selectorBuilder.build()).withTreatment(treatmentBuilder.build()).withPriority(intent.priority()).fromApp(appId).makePermanent().build();
selectorBuilder = DefaultTrafficSelector.builder();
if (!isNoFlowRule(current.deviceId())) {
rules.add(rule);
}
current = link.src();
selectorBuilder.matchInPort(reversePort(link.src().deviceId(), link.src().port()));
if (!isTransparent(current.deviceId())) {
selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
}
}
// Build the egress ROADM rule
TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
treatmentLast.setOutput(reversePort(intent.src().deviceId(), intent.src().port()));
FlowRule rule = new DefaultFlowRule.Builder().forDevice(intent.src().deviceId()).withSelector(selectorBuilder.build()).withTreatment(treatmentLast.build()).withPriority(intent.priority()).fromApp(appId).makePermanent().build();
if (!isNoFlowRule(intent.src().deviceId())) {
rules.add(rule);
}
return rules;
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class OpticalIntentsWebResource method decode.
private Intent decode(ObjectNode json) {
JsonNode ingressJson = json.get(INGRESS_POINT);
if (!ingressJson.isObject()) {
throw new IllegalArgumentException(JSON_INVALID);
}
ConnectPoint ingress = codec(ConnectPoint.class).decode((ObjectNode) ingressJson, this);
JsonNode egressJson = json.get(EGRESS_POINT);
if (!egressJson.isObject()) {
throw new IllegalArgumentException(JSON_INVALID);
}
ConnectPoint egress = codec(ConnectPoint.class).decode((ObjectNode) egressJson, this);
JsonNode bidirectionalJson = json.get(BIDIRECTIONAL);
boolean bidirectional = bidirectionalJson != null ? bidirectionalJson.asBoolean() : false;
JsonNode signalJson = json.get(SIGNAL);
OchSignal signal = null;
if (signalJson != null) {
if (!signalJson.isObject()) {
throw new IllegalArgumentException(JSON_INVALID);
} else {
signal = OchSignalCodec.decode((ObjectNode) signalJson);
}
}
String appIdString = nullIsIllegal(json.get(APP_ID), APP_ID + MISSING_MEMBER_MESSAGE).asText();
CoreService service = getService(CoreService.class);
ApplicationId appId = nullIsNotFound(service.getAppId(appIdString), E_APP_ID_NOT_FOUND);
Key key = null;
DeviceService deviceService = get(DeviceService.class);
JsonNode suggestedPathJson = json.get(SUGGESTEDPATH);
DefaultPath suggestedPath = null;
LinkService linkService = get(LinkService.class);
if (suggestedPathJson != null) {
if (!suggestedPathJson.isObject()) {
throw new IllegalArgumentException(JSON_INVALID);
} else {
ArrayNode linksJson = nullIsIllegal((ArrayNode) suggestedPathJson.get("links"), "Suggested path specified without links");
List<Link> listLinks = new ArrayList<>();
for (JsonNode node : linksJson) {
String srcString = node.get("src").asText();
String dstString = node.get("dst").asText();
ConnectPoint srcConnectPoint = ConnectPoint.fromString(srcString);
ConnectPoint dstConnectPoint = ConnectPoint.fromString(dstString);
Link link = linkService.getLink(srcConnectPoint, dstConnectPoint);
if (link == null) {
throw new IllegalArgumentException("Not existing link in the suggested path");
}
listLinks.add(link);
}
if ((!listLinks.get(0).src().deviceId().equals(ingress.deviceId())) || (!listLinks.get(0).src().port().equals(ingress.port())) || (!listLinks.get(listLinks.size() - 1).dst().deviceId().equals(egress.deviceId())) || (!listLinks.get(listLinks.size() - 1).dst().port().equals(egress.port()))) {
throw new IllegalArgumentException("Suggested path not compatible with ingress or egress connect points");
}
if (!isPathContiguous(listLinks)) {
throw new IllegalArgumentException("Links specified in the suggested path are not contiguous");
}
suggestedPath = new DefaultPath(PROVIDER_ID, listLinks, new ScalarWeight(1));
log.debug("OpticalIntent along suggestedPath {}", suggestedPath);
}
}
return createExplicitOpticalIntent(ingress, egress, deviceService, key, appId, bidirectional, signal, suggestedPath);
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class MyTunnelApp method provisionTunnel.
/**
* Provisions a tunnel between the given source and destination host with
* the given tunnel ID. The tunnel is established using a randomly picked
* shortest path based on the given topology snapshot.
*
* @param tunId tunnel ID
* @param srcHost tunnel source host
* @param dstHost tunnel destination host
* @param topo topology snapshot
*/
private void provisionTunnel(int tunId, Host srcHost, Host dstHost, Topology topo) {
// Get all shortest paths between switches connected to source and
// destination hosts.
DeviceId srcSwitch = srcHost.location().deviceId();
DeviceId dstSwitch = dstHost.location().deviceId();
List<Link> pathLinks;
if (srcSwitch.equals(dstSwitch)) {
// Source and dest hosts are connected to the same switch.
pathLinks = Collections.emptyList();
} else {
// Compute shortest path.
Set<Path> allPaths = topologyService.getPaths(topo, srcSwitch, dstSwitch);
if (allPaths.size() == 0) {
log.warn("No paths between {} and {}", srcHost.id(), dstHost.id());
return;
}
// If many shortest paths are available, pick a random one.
pathLinks = pickRandomPath(allPaths).links();
}
// Tunnel ingress rules.
for (IpAddress dstIpAddr : dstHost.ipAddresses()) {
// In ONOS discovered hosts can have multiple IP addresses.
// Insert tunnel ingress rule for each IP address.
// Next switches will forward based only on tunnel ID.
insertTunnelIngressRule(srcSwitch, dstIpAddr, tunId);
}
// last one.
for (Link link : pathLinks) {
DeviceId sw = link.src().deviceId();
PortNumber port = link.src().port();
insertTunnelForwardRule(sw, port, tunId, false);
}
// Tunnel egress rule.
PortNumber egressSwitchPort = dstHost.location().port();
insertTunnelForwardRule(dstSwitch, egressSwitchPort, tunId, true);
log.info("** Completed provisioning of tunnel {} (srcHost={} dstHost={})", tunId, srcHost.id(), dstHost.id());
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class PathPainterTopovMessageHandler method hilightAndSendPaths.
private void hilightAndSendPaths() {
PathLinkMap linkMap = new PathLinkMap();
allPathLinks.forEach(linkMap::add);
Set<Link> selectedPathLinks;
// the other containing all paths links.
if (currentMode.equals(Mode.DISJOINT)) {
DisjointPath dp = (DisjointPath) paths.get(pathIndex);
selectedPathLinks = paths.isEmpty() ? ImmutableSet.of() : Sets.newHashSet(dp.primary().links());
selectedPathLinks.addAll(dp.backup().links());
} else {
selectedPathLinks = paths.isEmpty() ? ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
}
Highlights highlights = new Highlights();
if (highlightDelay > 0) {
highlights.delay(highlightDelay);
}
for (PathLink plink : linkMap.biLinks()) {
plink.computeHilight(selectedPathLinks, allPathLinks);
highlights.add(plink.highlight(null));
}
if (src != null) {
highlights = addBadge(highlights, srcType, src.toString(), SRC);
}
if (dst != null) {
highlights = addBadge(highlights, dstType, dst.toString(), DST);
}
sendMessage(highlightsMessage(highlights));
}
Aggregations