blob: 6dd4ebda9779592afcbd857c6d91a4778f94fb87 [file] [log] [blame]
Thomas Vachuskaedc944c2014-11-04 15:42:25 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuskaedc944c2014-11-04 15:42:25 -08003 *
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;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080017
Sho SHIMIZU9909d172014-11-11 18:33:11 -080018import com.google.common.collect.FluentIterable;
Sho SHIMIZU56531512014-11-10 15:27:49 -080019import com.google.common.collect.ImmutableList;
Brian O'Connor023a1c72015-03-20 01:11:29 +000020import org.apache.felix.scr.annotations.Component;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080021import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
helenyrwu2a674902016-07-20 09:48:04 -070023import org.onosproject.net.DisjointPath;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.net.ElementId;
25import org.onosproject.net.Path;
26import org.onosproject.net.intent.ConnectivityIntent;
27import org.onosproject.net.intent.Constraint;
28import org.onosproject.net.intent.IntentCompiler;
29import org.onosproject.net.intent.IntentExtensionService;
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080030import org.onosproject.net.intent.impl.PathNotFoundException;
Sho SHIMIZUa6b4dc72016-03-11 19:00:20 -080031import org.onosproject.net.resource.ResourceQueryService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.provider.ProviderId;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.topology.LinkWeight;
34import org.onosproject.net.topology.PathService;
35import org.onosproject.net.topology.TopologyEdge;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080036
Sho SHIMIZU56531512014-11-10 15:27:49 -080037import java.util.Collections;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080038import java.util.Iterator;
39import java.util.List;
40import java.util.Set;
41
42/**
43 * Base class for compilers of various
Brian O'Connorabafb502014-12-02 22:26:20 -080044 * {@link org.onosproject.net.intent.ConnectivityIntent connectivity intents}.
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080045 */
Brian O'Connor023a1c72015-03-20 01:11:29 +000046@Component(immediate = true)
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080047public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
48 implements IntentCompiler<T> {
49
Brian O'Connorabafb502014-12-02 22:26:20 -080050 private static final ProviderId PID = new ProviderId("core", "org.onosproject.core", true);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080051
52 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected IntentExtensionService intentManager;
54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected PathService pathService;
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sho SHIMIZUa6b4dc72016-03-11 19:00:20 -080059 protected ResourceQueryService resourceService;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080060
61 /**
62 * Returns an edge-weight capable of evaluating links on the basis of the
63 * specified constraints.
64 *
65 * @param constraints path constraints
66 * @return edge-weight function
67 */
68 protected LinkWeight weight(List<Constraint> constraints) {
69 return new ConstraintBasedLinkWeight(constraints);
70 }
71
72 /**
73 * Validates the specified path against the given constraints.
74 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080075 * @param path path to be checked
76 * @param constraints path constraints
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080077 * @return true if the path passes all constraints
78 */
79 protected boolean checkPath(Path path, List<Constraint> constraints) {
80 for (Constraint constraint : constraints) {
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -080081 if (!constraint.validate(path, resourceService::isAvailable)) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080082 return false;
83 }
84 }
85 return true;
86 }
87
88 /**
89 * Computes a path between two ConnectPoints.
90 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080091 * @param intent intent on which behalf path is being computed
92 * @param one start of the path
93 * @param two end of the path
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080094 * @return Path between the two
95 * @throws PathNotFoundException if a path cannot be found
96 */
97 protected Path getPath(ConnectivityIntent intent,
98 ElementId one, ElementId two) {
99 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800100 final List<Constraint> constraints = intent.constraints();
101 ImmutableList<Path> filtered = FluentIterable.from(paths)
Sho SHIMIZU8b7b3b22015-09-04 16:04:50 -0700102 .filter(path -> checkPath(path, constraints))
103 .toList();
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800104 if (filtered.isEmpty()) {
Sho SHIMIZU877ec2c2015-02-09 12:50:36 -0800105 throw new PathNotFoundException(one, two);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800106 }
107 // TODO: let's be more intelligent about this eventually
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800108 return filtered.iterator().next();
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800109 }
110
111 /**
helenyrwu2a674902016-07-20 09:48:04 -0700112 * Computes a disjoint path between two ConnectPoints.
113 *
114 * @param intent intent on which behalf path is being computed
115 * @param one start of the path
116 * @param two end of the path
117 * @return DisjointPath between the two
118 * @throws PathNotFoundException if two paths cannot be found
119 */
120 protected DisjointPath getDisjointPath(ConnectivityIntent intent,
121 ElementId one, ElementId two) {
122 Set<DisjointPath> paths = pathService.getDisjointPaths(one, two, weight(intent.constraints()));
123 final List<Constraint> constraints = intent.constraints();
124 ImmutableList<DisjointPath> filtered = FluentIterable.from(paths)
125 .filter(path -> checkPath(path, constraints))
126 .toList();
127 if (filtered.isEmpty()) {
128 throw new PathNotFoundException(one, two);
129 }
130 // TODO: let's be more intelligent about this eventually
131 return filtered.iterator().next();
132 }
133
134 /**
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800135 * Edge-weight capable of evaluating link cost using a set of constraints.
136 */
137 protected class ConstraintBasedLinkWeight implements LinkWeight {
138
139 private final List<Constraint> constraints;
140
141 /**
142 * Creates a new edge-weight function capable of evaluating links
143 * on the basis of the specified constraints.
144 *
145 * @param constraints path constraints
146 */
147 ConstraintBasedLinkWeight(List<Constraint> constraints) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800148 if (constraints == null) {
149 this.constraints = Collections.emptyList();
150 } else {
151 this.constraints = ImmutableList.copyOf(constraints);
152 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800153 }
154
155 @Override
156 public double weight(TopologyEdge edge) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800157 if (!constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800158 return 1.0;
159 }
160
161 // iterate over all constraints in order and return the weight of
162 // the first one with fast fail over the first failure
163 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800164
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800165 double cost = it.next().cost(edge.link(), resourceService::isAvailable);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800166 while (it.hasNext() && cost > 0) {
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800167 if (it.next().cost(edge.link(), resourceService::isAvailable) < 0) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800168 return -1;
169 }
170 }
171 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800172
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800173 }
174 }
175
176}