blob: 4b517146ecfe3d5826025dce1d5bf2a8aff5cdf2 [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;
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;
Sho SHIMIZUa6b4dc72016-03-11 19:00:20 -080030import org.onosproject.net.resource.ResourceQueryService;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.provider.ProviderId;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import 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 */
Brian O'Connor023a1c72015-03-20 01:11:29 +000045@Component(immediate = true)
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080046public abstract class ConnectivityIntentCompiler<T extends ConnectivityIntent>
47 implements IntentCompiler<T> {
48
Brian O'Connorabafb502014-12-02 22:26:20 -080049 private static final ProviderId PID = new ProviderId("core", "org.onosproject.core", true);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080050
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected IntentExtensionService intentManager;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected PathService pathService;
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Sho SHIMIZUa6b4dc72016-03-11 19:00:20 -080058 protected ResourceQueryService resourceService;
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080059
60 /**
61 * Returns an edge-weight capable of evaluating links on the basis of the
62 * specified constraints.
63 *
64 * @param constraints path constraints
65 * @return edge-weight function
66 */
67 protected LinkWeight weight(List<Constraint> constraints) {
68 return new ConstraintBasedLinkWeight(constraints);
69 }
70
71 /**
72 * Validates the specified path against the given constraints.
73 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080074 * @param path path to be checked
75 * @param constraints path constraints
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080076 * @return true if the path passes all constraints
77 */
78 protected boolean checkPath(Path path, List<Constraint> constraints) {
79 for (Constraint constraint : constraints) {
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -080080 if (!constraint.validate(path, resourceService::isAvailable)) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080081 return false;
82 }
83 }
84 return true;
85 }
86
87 /**
88 * Computes a path between two ConnectPoints.
89 *
Thomas Vachuskab14c77a2014-11-04 18:08:01 -080090 * @param intent intent on which behalf path is being computed
91 * @param one start of the path
92 * @param two end of the path
Thomas Vachuskaedc944c2014-11-04 15:42:25 -080093 * @return Path between the two
94 * @throws PathNotFoundException if a path cannot be found
95 */
96 protected Path getPath(ConnectivityIntent intent,
97 ElementId one, ElementId two) {
98 Set<Path> paths = pathService.getPaths(one, two, weight(intent.constraints()));
Sho SHIMIZU9909d172014-11-11 18:33:11 -080099 final List<Constraint> constraints = intent.constraints();
100 ImmutableList<Path> filtered = FluentIterable.from(paths)
Sho SHIMIZU8b7b3b22015-09-04 16:04:50 -0700101 .filter(path -> checkPath(path, constraints))
102 .toList();
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800103 if (filtered.isEmpty()) {
Sho SHIMIZU877ec2c2015-02-09 12:50:36 -0800104 throw new PathNotFoundException(one, two);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800105 }
106 // TODO: let's be more intelligent about this eventually
Sho SHIMIZU9909d172014-11-11 18:33:11 -0800107 return filtered.iterator().next();
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800108 }
109
110 /**
111 * Edge-weight capable of evaluating link cost using a set of constraints.
112 */
113 protected class ConstraintBasedLinkWeight implements LinkWeight {
114
115 private final List<Constraint> constraints;
116
117 /**
118 * Creates a new edge-weight function capable of evaluating links
119 * on the basis of the specified constraints.
120 *
121 * @param constraints path constraints
122 */
123 ConstraintBasedLinkWeight(List<Constraint> constraints) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800124 if (constraints == null) {
125 this.constraints = Collections.emptyList();
126 } else {
127 this.constraints = ImmutableList.copyOf(constraints);
128 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800129 }
130
131 @Override
132 public double weight(TopologyEdge edge) {
Sho SHIMIZU56531512014-11-10 15:27:49 -0800133 if (!constraints.iterator().hasNext()) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800134 return 1.0;
135 }
136
137 // iterate over all constraints in order and return the weight of
138 // the first one with fast fail over the first failure
139 Iterator<Constraint> it = constraints.iterator();
Ray Milkey460f4022014-11-05 15:41:43 -0800140
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800141 double cost = it.next().cost(edge.link(), resourceService::isAvailable);
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800142 while (it.hasNext() && cost > 0) {
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800143 if (it.next().cost(edge.link(), resourceService::isAvailable) < 0) {
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800144 return -1;
145 }
146 }
147 return cost;
Ray Milkey460f4022014-11-05 15:41:43 -0800148
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800149 }
150 }
151
152}