/* * Copyright 2014-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.net.intent; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import com.google.common.annotations.Beta; import org.onosproject.core.ApplicationId; import org.onosproject.net.ConnectPoint; import org.onosproject.net.FilteredConnectPoint; import org.onosproject.net.Link; import org.onosproject.net.NetworkResource; import org.onosproject.net.ResourceGroup; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import org.slf4j.Logger; import static org.slf4j.LoggerFactory.getLogger; /** * Abstraction of a connectivity intent that is implemented by a set of path * segments. */ @Beta public final class LinkCollectionIntent extends ConnectivityIntent { private final Set<Link> links; private final Set<FilteredConnectPoint> ingressPoints; private final Set<FilteredConnectPoint> egressPoints; private final boolean egressTreatmentFlag; private final double cost; private static final int DEFAULT_COST = 1; /** * Creates a new actionable intent capable of funneling the selected * traffic along the specified convergent tree and out the given egress * point satisfying the specified constraints. * * @param appId application identifier * @param key key to use for the intent * @param selector traffic match * @param treatment action * @param links traversed links * @param ingressPoints filtered ingress points * @param egressPoints filtered egress points * @param constraints optional list of constraints * @param priority priority to use for the flows generated by this intent * @param egressTreatment true if treatment should be applied by the egress device * @param cost the cost of the links * @param resourceGroup resource group for this intent * @throws NullPointerException {@code path} is null */ private LinkCollectionIntent(ApplicationId appId, Key key, TrafficSelector selector, TrafficTreatment treatment, Collection<NetworkResource> resources, Set<Link> links, Set<FilteredConnectPoint> ingressPoints, Set<FilteredConnectPoint> egressPoints, List<Constraint> constraints, int priority, boolean egressTreatment, double cost, ResourceGroup resourceGroup) { super(appId, key, resources(resources, links), selector, treatment, constraints, priority, resourceGroup); this.links = links; this.ingressPoints = ingressPoints; this.egressPoints = egressPoints; this.egressTreatmentFlag = egressTreatment; this.cost = cost; } /** * Constructor for serializer. */ protected LinkCollectionIntent() { this.links = null; this.ingressPoints = null; this.egressPoints = null; this.egressTreatmentFlag = false; this.cost = DEFAULT_COST; } /** * Returns a new link collection intent builder. The application id, * ingress point and egress points are required fields. If they are * not set by calls to the appropriate methods, an exception will * be thrown. * * @return single point to multi point builder */ public static Builder builder() { return new Builder(); } /** * Builder of a single point to multi point intent. */ public static final class Builder extends ConnectivityIntent.Builder { private final Logger log = getLogger(getClass()); private Set<Link> links; private Set<FilteredConnectPoint> ingressPoints; private Set<FilteredConnectPoint> egressPoints; private boolean egressTreatmentFlag; private double cost; private Builder() { // Hide constructor } @Override public Builder appId(ApplicationId appId) { return (Builder) super.appId(appId); } @Override public Builder key(Key key) { return (Builder) super.key(key); } @Override public Builder selector(TrafficSelector selector) { return (Builder) super.selector(selector); } @Override public Builder treatment(TrafficTreatment treatment) { return (Builder) super.treatment(treatment); } @Override public Builder constraints(List<Constraint> constraints) { return (Builder) super.constraints(constraints); } @Override public Builder priority(int priority) { return (Builder) super.priority(priority); } @Override public Builder resources(Collection<NetworkResource> resources) { return (Builder) super.resources(resources); } @Override public Builder resourceGroup(ResourceGroup resourceGroup) { return (Builder) super.resourceGroup(resourceGroup); } /** * Sets the ingress point of the single point to multi point intent * that will be built. * * @param ingressPoints ingress connect points * @return this builder */ @Deprecated public Builder ingressPoints(Set<ConnectPoint> ingressPoints) { if (this.ingressPoints != null) { log.warn("Ingress points are already set, " + "this will override original ingress points."); } this.ingressPoints = ingressPoints.stream() .map(FilteredConnectPoint::new) .collect(Collectors.toSet()); return this; } /** * Sets the egress points of the single point to multi point intent * that will be built. * * @param egressPoints egress connect points * @return this builder */ @Deprecated public Builder egressPoints(Set<ConnectPoint> egressPoints) { if (this.egressPoints != null) { log.warn("Egress points are already set, " + "this will override original egress points."); } this.egressPoints = egressPoints.stream() .map(FilteredConnectPoint::new) .collect(Collectors.toSet()); return this; } /** * Sets the filtered ingress point of the single point to multi point intent * that will be built. * * @param ingressPoints ingress connect points * @return this builder */ public Builder filteredIngressPoints(Set<FilteredConnectPoint> ingressPoints) { this.ingressPoints = ImmutableSet.copyOf(ingressPoints); return this; } /** * Sets the filtered egress points of the single point to multi point intent * that will be built. * * @param egressPoints egress connect points * @return this builder */ public Builder filteredEgressPoints(Set<FilteredConnectPoint> egressPoints) { this.egressPoints = ImmutableSet.copyOf(egressPoints); return this; } /** * Sets the links of the link collection intent * that will be built. * * @param links links for the intent * @return this builder */ public Builder links(Set<Link> links) { this.links = ImmutableSet.copyOf(links); return this; } /** * Sets the intent to apply treatment at the egress rather than the * ingress. * * @param treatmentOnEgress true applies treatment on egress device * @return this builder */ public Builder applyTreatmentOnEgress(boolean treatmentOnEgress) { this.egressTreatmentFlag = treatmentOnEgress; return this; } /** * Sets the cost for the links of the Intent. * * @param cost the cost of the links * @return this builder */ public Builder cost(double cost) { this.cost = cost; return this; } /** * Builds a single point to multi point intent from the * accumulated parameters. * * @return point to point intent */ public LinkCollectionIntent build() { return new LinkCollectionIntent( appId, key, selector, treatment, resources, links, ingressPoints, egressPoints, constraints, priority, egressTreatmentFlag, cost, resourceGroup ); } } /** * Returns the set of links that represent the network connections needed * by this intent. * * @return Set of links for the network hops needed by this intent */ public Set<Link> links() { return links; } /** * Returns the ingress points of the intent. * * @return the ingress points */ public Set<ConnectPoint> ingressPoints() { if (this.ingressPoints == null) { return null; } return ingressPoints.stream() .map(FilteredConnectPoint::connectPoint) .collect(Collectors.toSet()); } /** * Returns the egress points of the intent. * * @return the egress points */ public Set<ConnectPoint> egressPoints() { if (this.egressPoints == null) { return null; } return egressPoints.stream() .map(FilteredConnectPoint::connectPoint) .collect(Collectors.toSet()); } /** * Returns the filtered ingress points of the intent. * * @return the ingress points */ public Set<FilteredConnectPoint> filteredIngressPoints() { return ingressPoints; } /** * Returns the egress points of the intent. * * @return the egress points */ public Set<FilteredConnectPoint> filteredEgressPoints() { return egressPoints; } /** * Returns whether treatment should be applied on egress. * * @return the egress treatment flag */ public boolean applyTreatmentOnEgress() { return egressTreatmentFlag; } /** * Returns the cost of the links of this intent. * * @return the cost of the links */ public double cost() { return cost; } @Override public String toString() { return MoreObjects.toStringHelper(getClass()) .add("id", id()) .add("key", key()) .add("appId", appId()) .add("priority", priority()) .add("resources", resources()) .add("selector", selector()) .add("treatment", treatment()) .add("links", links()) .add("ingress", ingressPoints()) .add("egress", egressPoints()) .add("treatmentOnEgress", applyTreatmentOnEgress()) .add("resourceGroup", resourceGroup()) .add("cost", cost()) .toString(); } }