summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java')
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java327
1 files changed, 327 insertions, 0 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
new file mode 100644
index 00000000..e24e14e0
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2015 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 com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.store.Timestamp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.intent.IntentState.*;
+
+/**
+ * A wrapper class that contains an intents, its state, and other metadata for
+ * internal use.
+ */
+@Beta
+public class IntentData { //FIXME need to make this "immutable"
+ // manager should be able to mutate a local copy while processing
+
+ private static final Logger log = LoggerFactory.getLogger(IntentData.class);
+
+ private final Intent intent;
+
+ private final IntentState request; //TODO perhaps we want a full fledged object for requests
+ private IntentState state;
+ private Timestamp version;
+ private NodeId origin;
+ private int errorCount;
+
+ private List<Intent> installables;
+
+ /**
+ * Creates a new intent data object.
+ *
+ * @param intent intent this metadata references
+ * @param state intent state
+ * @param version version of the intent for this key
+ */
+ public IntentData(Intent intent, IntentState state, Timestamp version) {
+ this.intent = intent;
+ this.state = state;
+ this.request = state;
+ this.version = version;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param intentData intent data to copy
+ */
+ public IntentData(IntentData intentData) {
+ checkNotNull(intentData);
+
+ intent = intentData.intent;
+ state = intentData.state;
+ request = intentData.request;
+ version = intentData.version;
+ origin = intentData.origin;
+ installables = intentData.installables;
+ errorCount = intentData.errorCount;
+ }
+
+ // kryo constructor
+ protected IntentData() {
+ intent = null;
+ request = null;
+ }
+
+ /**
+ * Returns the intent this metadata references.
+ *
+ * @return intent
+ */
+ public Intent intent() {
+ return intent;
+ }
+
+ /**
+ * Returns the state of the intent.
+ *
+ * @return intent state
+ */
+ public IntentState state() {
+ return state;
+ }
+
+ public IntentState request() {
+ return request;
+ }
+
+ /**
+ * Returns the intent key.
+ *
+ * @return intent key
+ */
+ public Key key() {
+ return intent.key();
+ }
+
+ /**
+ * Returns the version of the intent for this key.
+ *
+ * @return intent version
+ */
+ public Timestamp version() {
+ return version;
+ }
+
+ /**
+ * Sets the origin, which is the node that created the intent.
+ *
+ * @param origin origin instance
+ */
+ public void setOrigin(NodeId origin) {
+ this.origin = origin;
+ }
+
+ /**
+ * Returns the origin node that created this intent.
+ *
+ * @return origin node ID
+ */
+ public NodeId origin() {
+ return origin;
+ }
+
+ /**
+ * Updates the state of the intent to the given new state.
+ *
+ * @param newState new state of the intent
+ */
+ public void setState(IntentState newState) {
+ this.state = newState;
+ }
+
+ /**
+ * Sets the version for this intent data.
+ * <p>
+ * The store should call this method only once when the IntentData is
+ * first passed into the pending map. Ideally, an IntentData is timestamped
+ * on the same thread that the called used to submit the intents.
+ * </p>
+ *
+ * @param version the version/timestamp for this intent data
+ */
+ public void setVersion(Timestamp version) {
+ this.version = version;
+ }
+
+ /**
+ * Increments the error count for this intent.
+ */
+ public void incrementErrorCount() {
+ errorCount++;
+ }
+
+ /**
+ * Sets the error count for this intent.
+ *
+ * @param newCount new count
+ */
+ public void setErrorCount(int newCount) {
+ errorCount = newCount;
+ }
+
+ /**
+ * Returns the number of times that this intent has encountered an error
+ * during installation or withdrawal.
+ *
+ * @return error count
+ */
+ public int errorCount() {
+ return errorCount;
+ }
+
+ /**
+ * Sets the intent installables to the given list of intents.
+ *
+ * @param installables list of installables for this intent
+ */
+ public void setInstallables(List<Intent> installables) {
+ this.installables = ImmutableList.copyOf(installables);
+ }
+
+ /**
+ * Returns the installables associated with this intent.
+ *
+ * @return list of installable intents
+ */
+ public List<Intent> installables() {
+ return installables != null ? installables : Collections.emptyList();
+ }
+
+ /**
+ * Determines whether an intent data update is allowed. The update must
+ * either have a higher version than the current data, or the state
+ * transition between two updates of the same version must be sane.
+ *
+ * @param currentData existing intent data in the store
+ * @param newData new intent data update proposal
+ * @return true if we can apply the update, otherwise false
+ */
+ public static boolean isUpdateAcceptable(IntentData currentData, IntentData newData) {
+
+ if (currentData == null) {
+ return true;
+ } else if (currentData.version().isOlderThan(newData.version())) {
+ return true;
+ } else if (currentData.version().isNewerThan(newData.version())) {
+ return false;
+ }
+
+ // current and new data versions are the same
+ IntentState currentState = currentData.state();
+ IntentState newState = newData.state();
+
+ switch (newState) {
+ case INSTALLING:
+ if (currentState == INSTALLING) {
+ return false;
+ }
+ // FALLTHROUGH
+ case INSTALLED:
+ if (currentState == INSTALLED) {
+ return false;
+ } else if (currentState == WITHDRAWING || currentState == WITHDRAWN
+ || currentState == PURGE_REQ) {
+ log.warn("Invalid state transition from {} to {} for intent {}",
+ currentState, newState, newData.key());
+ return false;
+ }
+ return true;
+
+ case WITHDRAWING:
+ if (currentState == WITHDRAWING) {
+ return false;
+ }
+ // FALLTHROUGH
+ case WITHDRAWN:
+ if (currentState == WITHDRAWN) {
+ return false;
+ } else if (currentState == INSTALLING || currentState == INSTALLED
+ || currentState == PURGE_REQ) {
+ log.warn("Invalid state transition from {} to {} for intent {}",
+ currentState, newState, newData.key());
+ return false;
+ }
+ return true;
+
+ case FAILED:
+ if (currentState == FAILED) {
+ return false;
+ }
+ return true;
+
+ case CORRUPT:
+ if (currentState == CORRUPT) {
+ return false;
+ }
+ return true;
+
+ case PURGE_REQ:
+ // TODO we should enforce that only WITHDRAWN intents can be purged
+ return true;
+
+ case COMPILING:
+ case RECOMPILING:
+ case INSTALL_REQ:
+ case WITHDRAW_REQ:
+ default:
+ log.warn("Invalid state {} for intent {}", newState, newData.key());
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(intent, version);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final IntentData other = (IntentData) obj;
+ return Objects.equals(this.intent, other.intent)
+ && Objects.equals(this.version, other.version);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("key", key())
+ .add("state", state())
+ .add("version", version())
+ .add("intent", intent())
+ .add("origin", origin())
+ .add("installables", installables())
+ .toString();
+ }
+
+}