/* * 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 com.google.common.annotations.Beta; import org.onosproject.core.ApplicationId; import org.onosproject.core.IdGenerator; import org.onosproject.net.NetworkResource; import org.onosproject.net.ResourceGroup; import java.util.Collection; import static com.google.common.base.Preconditions.*; /** * Abstraction of an application level intent. * <p> * Make sure that an Intent should be immutable when a new type is defined. * </p> */ @Beta public abstract class Intent { private final IntentId id; private final ApplicationId appId; private final Key key; private final int priority; public static final int DEFAULT_INTENT_PRIORITY = 100; public static final int MAX_PRIORITY = (1 << 16) - 1; public static final int MIN_PRIORITY = 1; private final Collection<NetworkResource> resources; private final ResourceGroup resourceGroup; private static IdGenerator idGenerator; /** * Constructor for serializer. */ protected Intent() { this.id = null; this.appId = null; this.key = null; this.resources = null; this.priority = DEFAULT_INTENT_PRIORITY; this.resourceGroup = null; } /** * Creates a new intent. * @param appId application identifier * @param key optional key * @param resources required network resources (optional) * @param priority flow rule priority * @deprecated 1.9.1 */ @Deprecated protected Intent(ApplicationId appId, Key key, Collection<NetworkResource> resources, int priority) { checkState(idGenerator != null, "Id generator is not bound."); checkArgument(priority <= MAX_PRIORITY && priority >= MIN_PRIORITY); this.id = IntentId.valueOf(idGenerator.getNewId()); this.appId = checkNotNull(appId, "Application ID cannot be null"); this.key = (key != null) ? key : Key.of(id.fingerprint(), appId); this.priority = priority; this.resources = checkNotNull(resources); this.resourceGroup = null; } /** * Creates a new intent. * @param appId application identifier * @param key optional key * @param resources required network resources (optional) * @param priority flow rule priority * @param resourceGroup the resource group for intent */ protected Intent(ApplicationId appId, Key key, Collection<NetworkResource> resources, int priority, ResourceGroup resourceGroup) { checkState(idGenerator != null, "Id generator is not bound."); checkArgument(priority <= MAX_PRIORITY && priority >= MIN_PRIORITY); this.id = IntentId.valueOf(idGenerator.getNewId()); this.appId = checkNotNull(appId, "Application ID cannot be null"); this.key = (key != null) ? key : Key.of(id.fingerprint(), appId); this.priority = priority; this.resources = checkNotNull(resources); this.resourceGroup = resourceGroup; } /** * Abstract builder for intents. */ public abstract static class Builder { protected ApplicationId appId; protected Key key; protected int priority = Intent.DEFAULT_INTENT_PRIORITY; protected Collection<NetworkResource> resources; protected ResourceGroup resourceGroup; /** * Creates a new empty builder. */ protected Builder() { } /** * Creates a new builder pre-populated with the information in the given * intent. * * @param intent initial intent */ protected Builder(Intent intent) { this.appId(intent.appId()) .key(intent.key()) .priority(intent.priority()) .resourceGroup(intent.resourceGroup()); } /** * Sets the application id for the intent that will be built. * * @param appId application id to use for built intent * @return this builder */ public Builder appId(ApplicationId appId) { this.appId = appId; return this; } /** * Sets the key for the intent that will be built. * * @param key key to use for built intent * @return this builder */ public Builder key(Key key) { this.key = key; return this; } /** * Sets the priority for the intent that will be built. * * @param priority priority to use for built intent * @return this builder */ public Builder priority(int priority) { this.priority = priority; return this; } /** * Sets the collection of resources required for this intent. * * @param resources collection of resources * @return this builder */ public Builder resources(Collection<NetworkResource> resources) { this.resources = resources; return this; } /** * Sets the resource group for this intent. * * @param resourceGroup the resource group * @return this builder */ public Builder resourceGroup(ResourceGroup resourceGroup) { this.resourceGroup = resourceGroup; return this; } } /** * Returns the intent object identifier. * * @return intent fingerprint */ public IntentId id() { return id; } /** * Returns the identifier of the application that requested the intent. * * @return application identifier */ public ApplicationId appId() { return appId; } /** * Returns the priority of the intent. * * @return intent priority */ public int priority() { return priority; } /** * Returns the collection of resources required for this intent. * * @return collection of resources; may be null */ public Collection<NetworkResource> resources() { return resources; } /** * Returns the resource group for this intent. * * @return the resource group; may be null */ public ResourceGroup resourceGroup() { return resourceGroup; } /** * Indicates whether or not the intent is installable. * * @return true if installable */ public boolean isInstallable() { return false; } @Override public final int hashCode() { return id.hashCode(); } @Override public final boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final Intent other = (Intent) obj; return this.id().equals(other.id()); } /** * Binds an id generator for unique intent id generation. * * Note: A generator cannot be bound if there is already a generator bound. * * @param newIdGenerator id generator */ public static void bindIdGenerator(IdGenerator newIdGenerator) { checkState(idGenerator == null, "Id generator is already bound."); idGenerator = checkNotNull(newIdGenerator); } /** * Unbinds an id generator. * * Note: The caller must provide the old id generator to succeed. * * @param oldIdGenerator the current id generator */ public static void unbindIdGenerator(IdGenerator oldIdGenerator) { if (idGenerator == oldIdGenerator) { idGenerator = null; } } /** * Returns the key to identify an "Intent". * <p> * When an Intent is updated, * (e.g., flow is re-routed in reaction to network topology change) * related Intent object's {@link IntentId} may change, * but the key will remain unchanged. * * @return key */ public Key key() { return key; } }