blob: 0a73d9abde42b93bec3ff86a47ec0958bfb1aa06 [file] [log] [blame]
Thomas Vachuskaedc944c2014-11-04 15:42:25 -08001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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.base.Predicate;
19import com.google.common.collect.FluentIterable;
Sho SHIMIZU56531512014-11-10 15:27:49 -080020import com.google.common.collect.ImmutableList;
Brian O'Connor023a1c72015-03-20 01:11:29 +000021import org.apache.felix.scr.annotations.Component;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080022import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
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;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.provider.ProviderId;
Brian O'Connor6de2e202015-05-21 14:30:41 -070032import org.onosproject.net.resource.link.LinkResourceService;
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)
59 protected LinkResourceService resourceService;
60
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) {
81 if (!constraint.validate(path, resourceService)) {
82 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)
102 .filter(new Predicate<Path>() {
103 @Override
104 public boolean apply(Path path) {
105 return checkPath(path, constraints);
106 }
107 }).toList();
108 if (filtered.isEmpty()) {
Sho SHIMIZU877ec2c2015-02-09 12:50:36 -0800109 throw new PathNotFoundException(one, two);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800110 }
111 // TODO: let's be more intelligent about this eventually
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800112 return filtered.iterator().next();
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800113 }
114
115 /**
116 * Edge-weight capable of evaluating link cost using a set of constraints.
117 */
118 protected class ConstraintBasedLinkWeight implements LinkWeight {
119
120 private final List<Constraint> constraints;
121
122 /**
123 * Creates a new edge-weight function capable of evaluating links
124 * on the basis of the specified constraints.
125 *
126 * @param constraints path constraints
127 */
128 ConstraintBasedLinkWeight(List<Constraint> constraints) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800129 if (constraints == null) {
130 this.constraints = Collections.emptyList();
131 } else {
132 this.constraints = ImmutableList.copyOf(constraints);
133 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800134 }
135
136 @Override
137 public double weight(TopologyEdge edge) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800138 if (!constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800139 return 1.0;
140 }
141
142 // iterate over all constraints in order and return the weight of
143 // the first one with fast fail over the first failure
144 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800145
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800146 double cost = it.next().cost(edge.link(), resourceService);
147 while (it.hasNext() && cost > 0) {
148 if (it.next().cost(edge.link(), resourceService) < 0) {
149 return -1;
150 }
151 }
152 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800153
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800154 }
155 }
156
157}