blob: de97c87022ac220229bc9d63f7790ea07a3a39dd [file] [log] [blame]
Thomas Vachuskaedc944c2014-11-04 15:42:25 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080021import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
Brian O'Connorabafb502014-12-02 22:26:20 -080023import org.onosproject.net.ElementId;
24import org.onosproject.net.Path;
25import org.onosproject.net.intent.ConnectivityIntent;
26import org.onosproject.net.intent.Constraint;
27import org.onosproject.net.intent.IntentCompiler;
28import org.onosproject.net.intent.IntentExtensionService;
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080029import org.onosproject.net.intent.impl.PathNotFoundException;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.provider.ProviderId;
31import org.onosproject.net.resource.LinkResourceService;
32import org.onosproject.net.topology.LinkWeight;
33import org.onosproject.net.topology.PathService;
34import org.onosproject.net.topology.TopologyEdge;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080035
Sho SHIMIZU56531512014-11-10 15:27:49 -080036import java.util.Collections;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080037import java.util.Iterator;
38import java.util.List;
39import java.util.Set;
40
41/**
42 * Base class for compilers of various
Brian O'Connorabafb502014-12-02 22:26:20 -080043 * {@link org.onosproject.net.intent.ConnectivityIntent connectivity intents}.
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080044 */
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080045public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
46 implements IntentCompiler<T> {
47
Brian O'Connorabafb502014-12-02 22:26:20 -080048 private static final ProviderId PID = new ProviderId("core", "org.onosproject.core", true);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080049
50 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected IntentExtensionService intentManager;
52
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected PathService pathService;
55
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected LinkResourceService resourceService;
58
59 /**
60 * Returns an edge-weight capable of evaluating links on the basis of the
61 * specified constraints.
62 *
63 * @param constraints path constraints
64 * @return edge-weight function
65 */
66 protected LinkWeight weight(List<Constraint> constraints) {
67 return new ConstraintBasedLinkWeight(constraints);
68 }
69
70 /**
71 * Validates the specified path against the given constraints.
72 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080073 * @param path path to be checked
74 * @param constraints path constraints
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080075 * @return true if the path passes all constraints
76 */
77 protected boolean checkPath(Path path, List<Constraint> constraints) {
78 for (Constraint constraint : constraints) {
79 if (!constraint.validate(path, resourceService)) {
80 return false;
81 }
82 }
83 return true;
84 }
85
86 /**
87 * Computes a path between two ConnectPoints.
88 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080089 * @param intent intent on which behalf path is being computed
90 * @param one start of the path
91 * @param two end of the path
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080092 * @return Path between the two
93 * @throws PathNotFoundException if a path cannot be found
94 */
95 protected Path getPath(ConnectivityIntent intent,
96 ElementId one, ElementId two) {
97 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
Sho SHIMIZU9909d172014-11-11 18:33:11 -080098 final List<Constraint> constraints = intent.constraints();
99 ImmutableList<Path> filtered = FluentIterable.from(paths)
100 .filter(new Predicate<Path>() {
101 @Override
102 public boolean apply(Path path) {
103 return checkPath(path, constraints);
104 }
105 }).toList();
106 if (filtered.isEmpty()) {
Sho SHIMIZU877ec2c2015-02-09 12:50:36 -0800107 throw new PathNotFoundException(one, two);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800108 }
109 // TODO: let's be more intelligent about this eventually
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800110 return filtered.iterator().next();
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800111 }
112
113 /**
114 * Edge-weight capable of evaluating link cost using a set of constraints.
115 */
116 protected class ConstraintBasedLinkWeight implements LinkWeight {
117
118 private final List<Constraint> constraints;
119
120 /**
121 * Creates a new edge-weight function capable of evaluating links
122 * on the basis of the specified constraints.
123 *
124 * @param constraints path constraints
125 */
126 ConstraintBasedLinkWeight(List<Constraint> constraints) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800127 if (constraints == null) {
128 this.constraints = Collections.emptyList();
129 } else {
130 this.constraints = ImmutableList.copyOf(constraints);
131 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800132 }
133
134 @Override
135 public double weight(TopologyEdge edge) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800136 if (!constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800137 return 1.0;
138 }
139
140 // iterate over all constraints in order and return the weight of
141 // the first one with fast fail over the first failure
142 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800143
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800144 double cost = it.next().cost(edge.link(), resourceService);
145 while (it.hasNext() && cost > 0) {
146 if (it.next().cost(edge.link(), resourceService) < 0) {
147 return -1;
148 }
149 }
150 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800151
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800152 }
153 }
154
155}