blob: 4d6270a7fd8b000a8bd4bb3715feb348ae26b4d2 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080016package org.onosproject.net.intent.impl.compiler;
Brian O'Connor66630c82014-10-02 21:08:19 -070017
Thomas Vachuskaab753e12016-06-13 19:41:05 -070018import com.google.common.collect.ImmutableList;
Pier Ventre98308ab2016-10-12 14:35:05 -070019import com.google.common.collect.ImmutableSet;
Brian O'Connor66630c82014-10-02 21:08:19 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Luca Pretede10c782017-01-05 17:23:08 -080025import org.onosproject.net.ConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.DefaultLink;
27import org.onosproject.net.DefaultPath;
Pier Ventre98308ab2016-10-12 14:35:05 -070028import org.onosproject.net.DeviceId;
29import org.onosproject.net.FilteredConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.Host;
31import org.onosproject.net.Link;
32import org.onosproject.net.Path;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.host.HostService;
35import org.onosproject.net.intent.HostToHostIntent;
36import org.onosproject.net.intent.Intent;
Pier Ventre98308ab2016-10-12 14:35:05 -070037import org.onosproject.net.intent.IntentCompilationException;
38import org.onosproject.net.intent.LinkCollectionIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
Pier Ventre98308ab2016-10-12 14:35:05 -070040import org.slf4j.Logger;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080041
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080042import java.util.ArrayList;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080043import java.util.Arrays;
44import java.util.List;
Thomas Vachuskaab753e12016-06-13 19:41:05 -070045import java.util.Objects;
Pier Ventre98308ab2016-10-12 14:35:05 -070046import java.util.Set;
47import java.util.stream.Collectors;
Luca Pretede10c782017-01-05 17:23:08 -080048import java.util.stream.Stream;
Brian O'Connor66630c82014-10-02 21:08:19 -070049
Pier Ventre98308ab2016-10-12 14:35:05 -070050import static org.onosproject.net.Link.Type.EDGE;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import static org.onosproject.net.flow.DefaultTrafficSelector.builder;
Pier Ventre98308ab2016-10-12 14:35:05 -070052import static org.slf4j.LoggerFactory.getLogger;
tomf5c9d922014-10-03 15:22:03 -070053
Brian O'Connor66630c82014-10-02 21:08:19 -070054/**
55 * A intent compiler for {@link HostToHostIntent}.
56 */
57@Component(immediate = true)
58public class HostToHostIntentCompiler
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080059 extends ConnectivityIntentCompiler<HostToHostIntent> {
Brian O'Connor66630c82014-10-02 21:08:19 -070060
Pier Ventre98308ab2016-10-12 14:35:05 -070061 private final Logger log = getLogger(getClass());
62
63 private static final String DEVICE_ID_NOT_FOUND = "Didn't find device id in the link";
64
tomf5c9d922014-10-03 15:22:03 -070065 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 protected HostService hostService;
67
Brian O'Connor66630c82014-10-02 21:08:19 -070068 @Activate
69 public void activate() {
Brian O'Connor66630c82014-10-02 21:08:19 -070070 intentManager.registerCompiler(HostToHostIntent.class, this);
71 }
72
73 @Deactivate
74 public void deactivate() {
75 intentManager.unregisterCompiler(HostToHostIntent.class);
76 }
77
78 @Override
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -080079 public List<Intent> compile(HostToHostIntent intent, List<Intent> installable) {
Thomas Vachuskaab753e12016-06-13 19:41:05 -070080 // If source and destination are the same, there are never any installables.
81 if (Objects.equals(intent.one(), intent.two())) {
82 return ImmutableList.of();
83 }
84
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080085 boolean isAsymmetric = intent.constraints().contains(new AsymmetricPathConstraint());
Luca Preted26ea652017-01-03 15:59:30 -080086 Path pathOne = getPathOrException(intent, intent.one(), intent.two());
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080087 Path pathTwo = isAsymmetric ?
Luca Preted26ea652017-01-03 15:59:30 -080088 getPathOrException(intent, intent.two(), intent.one()) : invertPath(pathOne);
Brian O'Connor66630c82014-10-02 21:08:19 -070089
tomf5c9d922014-10-03 15:22:03 -070090 Host one = hostService.getHost(intent.one());
91 Host two = hostService.getHost(intent.two());
92
Pier Ventre98308ab2016-10-12 14:35:05 -070093 return Arrays.asList(createLinkCollectionIntent(pathOne, one, two, intent),
94 createLinkCollectionIntent(pathTwo, two, one, intent));
tomf5c9d922014-10-03 15:22:03 -070095 }
96
Thomas Vachuska5dd52f72014-11-28 19:27:45 -080097 // Inverts the specified path. This makes an assumption that each link in
98 // the path has a reverse link available. Under most circumstances, this
99 // assumption will hold.
100 private Path invertPath(Path path) {
101 List<Link> reverseLinks = new ArrayList<>(path.links().size());
102 for (Link link : path.links()) {
103 reverseLinks.add(0, reverseLink(link));
104 }
105 return new DefaultPath(path.providerId(), reverseLinks, path.cost());
106 }
107
108 // Produces a reverse variant of the specified link.
109 private Link reverseLink(Link link) {
Ray Milkey2693bda2016-01-22 16:08:14 -0800110 return DefaultLink.builder().providerId(link.providerId())
111 .src(link.dst())
112 .dst(link.src())
113 .type(link.type())
114 .state(link.state())
115 .isExpected(link.isExpected())
116 .build();
Thomas Vachuska5dd52f72014-11-28 19:27:45 -0800117 }
118
Pier Ventre98308ab2016-10-12 14:35:05 -0700119 private FilteredConnectPoint getFilteredPointFromLink(Link link) {
120 FilteredConnectPoint filteredConnectPoint;
121 if (link.src().elementId() instanceof DeviceId) {
122 filteredConnectPoint = new FilteredConnectPoint(link.src());
123 } else if (link.dst().elementId() instanceof DeviceId) {
124 filteredConnectPoint = new FilteredConnectPoint(link.dst());
125 } else {
126 throw new IntentCompilationException(DEVICE_ID_NOT_FOUND);
127 }
128 return filteredConnectPoint;
129 }
130
131 private Intent createLinkCollectionIntent(Path path,
132 Host src,
133 Host dst,
134 HostToHostIntent intent) {
Luca Pretede10c782017-01-05 17:23:08 -0800135 // Try to allocate bandwidth
136 List<ConnectPoint> pathCPs =
137 path.links().stream()
138 .flatMap(l -> Stream.of(l.src(), l.dst()))
139 .collect(Collectors.toList());
140
141 allocateBandwidth(intent, pathCPs);
Pier Ventre98308ab2016-10-12 14:35:05 -0700142
143 Link ingressLink = path.links().get(0);
144 Link egressLink = path.links().get(path.links().size() - 1);
145
146 FilteredConnectPoint ingressPoint = getFilteredPointFromLink(ingressLink);
147 FilteredConnectPoint egressPoint = getFilteredPointFromLink(egressLink);
148
149 TrafficSelector selector = builder(intent.selector())
150 .matchEthSrc(src.mac())
151 .matchEthDst(dst.mac())
152 .build();
153
Luca Pretede10c782017-01-05 17:23:08 -0800154 /*
155 * The path contains also the edge links, these are not necessary
156 * for the LinkCollectionIntent.
157 */
158 Set<Link> coreLinks = path.links()
159 .stream()
160 .filter(link -> !link.type().equals(EDGE))
161 .collect(Collectors.toSet());
162
Pier Ventre98308ab2016-10-12 14:35:05 -0700163 return LinkCollectionIntent.builder()
164 .key(intent.key())
165 .appId(intent.appId())
166 .selector(selector)
167 .treatment(intent.treatment())
168 .links(coreLinks)
169 .filteredIngressPoints(ImmutableSet.of(
170 ingressPoint
171 ))
172 .filteredEgressPoints(ImmutableSet.of(
173 egressPoint
174 ))
175 .applyTreatmentOnEgress(true)
176 .constraints(intent.constraints())
177 .priority(intent.priority())
Luca Prete670ac5d2017-02-03 15:55:43 -0800178 .resourceGroup(intent.resourceGroup())
Pier Ventre98308ab2016-10-12 14:35:05 -0700179 .build();
180 }
181
Brian O'Connor66630c82014-10-02 21:08:19 -0700182}