All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.onosproject.net.intent.IntentData Maven / Gradle / Ivy

There is a newer version: 2.7.0
Show newest version
/*
 * 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 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.
     * 

* 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. *

* * @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 installables) { this.installables = ImmutableList.copyOf(installables); } /** * Returns the installables associated with this intent. * * @return list of installable intents */ public List 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(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy