blob: 8a319007fffa63771be68449b711566590b061af [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 */
16package org.onlab.onos.net.intent.impl;
17
18import org.apache.felix.scr.annotations.Component;
19import org.apache.felix.scr.annotations.Reference;
20import org.apache.felix.scr.annotations.ReferenceCardinality;
21import org.onlab.onos.net.ElementId;
22import org.onlab.onos.net.Path;
23import org.onlab.onos.net.intent.ConnectivityIntent;
24import org.onlab.onos.net.intent.Constraint;
25import org.onlab.onos.net.intent.IntentCompiler;
26import org.onlab.onos.net.intent.IntentExtensionService;
27import org.onlab.onos.net.provider.ProviderId;
28import org.onlab.onos.net.resource.LinkResourceService;
29import org.onlab.onos.net.topology.LinkWeight;
30import org.onlab.onos.net.topology.PathService;
31import org.onlab.onos.net.topology.TopologyEdge;
32
33import java.util.Iterator;
34import java.util.List;
35import java.util.Set;
36
37/**
38 * Base class for compilers of various
39 * {@link org.onlab.onos.net.intent.ConnectivityIntent connectivity intents}.
40 */
41@Component(immediate = true)
42public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
43 implements IntentCompiler<T> {
44
45 private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
46
47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 protected IntentExtensionService intentManager;
49
50 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected PathService pathService;
52
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected LinkResourceService resourceService;
55
56 /**
57 * Returns an edge-weight capable of evaluating links on the basis of the
58 * specified constraints.
59 *
60 * @param constraints path constraints
61 * @return edge-weight function
62 */
63 protected LinkWeight weight(List<Constraint> constraints) {
64 return new ConstraintBasedLinkWeight(constraints);
65 }
66
67 /**
68 * Validates the specified path against the given constraints.
69 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080070 * @param path path to be checked
71 * @param constraints path constraints
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080072 * @return true if the path passes all constraints
73 */
74 protected boolean checkPath(Path path, List<Constraint> constraints) {
75 for (Constraint constraint : constraints) {
76 if (!constraint.validate(path, resourceService)) {
77 return false;
78 }
79 }
80 return true;
81 }
82
83 /**
84 * Computes a path between two ConnectPoints.
85 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080086 * @param intent intent on which behalf path is being computed
87 * @param one start of the path
88 * @param two end of the path
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080089 * @return Path between the two
90 * @throws PathNotFoundException if a path cannot be found
91 */
92 protected Path getPath(ConnectivityIntent intent,
93 ElementId one, ElementId two) {
94 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
95 if (paths.isEmpty()) {
96 throw new PathNotFoundException("No packet path from " + one + " to " + two);
97 }
98 // TODO: let's be more intelligent about this eventually
99 return paths.iterator().next();
100 }
101
102 /**
103 * Edge-weight capable of evaluating link cost using a set of constraints.
104 */
105 protected class ConstraintBasedLinkWeight implements LinkWeight {
106
107 private final List<Constraint> constraints;
108
109 /**
110 * Creates a new edge-weight function capable of evaluating links
111 * on the basis of the specified constraints.
112 *
113 * @param constraints path constraints
114 */
115 ConstraintBasedLinkWeight(List<Constraint> constraints) {
116 this.constraints = constraints;
117 }
118
119 @Override
120 public double weight(TopologyEdge edge) {
Ray Milkey460f4022014-11-05 15:41:43 -0800121 if (constraints == null || !constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800122 return 1.0;
123 }
124
125 // iterate over all constraints in order and return the weight of
126 // the first one with fast fail over the first failure
127 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800128
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800129 double cost = it.next().cost(edge.link(), resourceService);
130 while (it.hasNext() && cost > 0) {
131 if (it.next().cost(edge.link(), resourceService) < 0) {
132 return -1;
133 }
134 }
135 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800136
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800137 }
138 }
139
140}