Brian O'Connor

Initial sketch of intent domains.

Change-Id: I08cb6f9a8c8f83763a2026c1ab9d3e69e0f5d83c
......@@ -28,7 +28,7 @@ public final class IntentId implements ResourceConsumer {
private final long value;
/**
* Creates an intent identifier from the specified string representation.
* Creates an intent identifier from the specified long representation.
*
* @param value long value
* @return intent identifier
......
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import org.onlab.graph.AbstractEdge;
import org.onosproject.net.ConnectPoint;
import java.util.Objects;
/**
* Representation of a connection between an intent domain and a device. This
* must happen using a connect point that is part of both the domain and the
* device.
*/
@Beta
public class DomainEdge extends AbstractEdge<DomainVertex> {
ConnectPoint connectPoint;
public DomainEdge(DomainVertex src, DomainVertex dst, ConnectPoint connectPoint) {
super(src, dst);
this.connectPoint = connectPoint;
}
@Override
public int hashCode() {
return 43 * super.hashCode() + Objects.hash(connectPoint);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof DomainEdge) {
final DomainEdge other = (DomainEdge) obj;
return super.equals(other) &&
Objects.equals(this.connectPoint, other.connectPoint);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("src", src())
.add("dst", dst())
.add("connectPoint", connectPoint)
.toString();
}
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onlab.graph.Vertex;
import org.onosproject.net.DeviceId;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Representation of the intent domain or a device that is part of the intent
* domain graph.
*/
@Beta
public class DomainVertex implements Vertex {
// FIXME we will want to add a type enum or subclasses for the two different types
// A domain vertex is either an intent domain or a device:
private final IntentDomainId id;
// ----- or -----
private final DeviceId deviceId;
// Serialization constructor
private DomainVertex() {
this.id = null;
this.deviceId = null;
}
DomainVertex(IntentDomainId id) {
this.id = checkNotNull(id, "Intent domain ID cannot be null.");
this.deviceId = null;
}
DomainVertex(DeviceId id) {
this.id = null;
this.deviceId = checkNotNull(id, "Device ID cannot be null.");
}
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import java.util.Objects;
import java.util.Set;
/**
* Representation of an intent domain which includes the set of internal devices,
* the set of edge ports, and the implementation of the domain provider.
*/
@Beta
public class IntentDomain {
private final IntentDomainId id;
private String name;
private Set<DeviceId> internalDevices;
private Set<ConnectPoint> edgePorts;
private IntentDomainProvider provider;
IntentDomain(IntentDomainId id, String name,
Set<DeviceId> internalDevices,
Set<ConnectPoint> edgePorts) {
this.id = id;
this.name = name;
this.internalDevices = internalDevices;
this.edgePorts = edgePorts;
}
/**
* Returns the id for the intent domain.
*
* @return intent domain id
*/
public IntentDomainId id() {
return id;
}
/**
* Returns the friendly name for the intent domain.
*
* @return intent domain name
*/
public String name() {
return name;
}
/**
* Returns the set of internal devices for the intent domain (devices under
* exclusive control of the intent domain).
*
* @return set of internal devices
*/
public Set<DeviceId> internalDevices() {
return internalDevices;
}
/**
* Returns the set of edge ports for the intent domain.
*
* @return set of edge ports
*/
public Set<ConnectPoint> edgePorts() {
return edgePorts;
}
/**
* Returns the provider for the intent domain.
*
* @return intent domain provider
*/
IntentDomainProvider provider() {
return provider;
}
/**
* Returns the status of the intent domain. An intent domain is active if it
* has an intent domain provider bound, and it is inactive if one is not bound.
*
* @return true if active; false otherwise
*/
public boolean isActive() {
return provider != null;
}
/**
* Sets the provider for the intent domain if one is not already set.
*
* @param provider new intent domain provider
*/
public void setProvider(IntentDomainProvider provider) {
// TODO consider checkState depending on caller
if (this.provider == null) {
this.provider = provider;
}
}
/**
* Unsets the provider for the intent domain if the given provider matches
* the existing provider.
*
* @param provider provider to unset
*/
public void unsetProvider(IntentDomainProvider provider) {
// TODO consider checkState depending on caller
if (Objects.equals(this.provider, provider)) {
this.provider = null;
}
}
//TODO add remaining setters (we will probably want to link this to the network config)
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onosproject.core.ApplicationId;
/**
* Administrative interface for the intent domain service.
*/
@Beta
public interface IntentDomainAdminService {
/**
* Register an application that provides intent domain service.
*
* @param applicationId application id
* @param provider intent domain provider
*/
void registerApplication(ApplicationId applicationId, IntentDomainProvider provider);
/**
* Unregisters an application that provides intent domain service.
*
* @param applicationId application id
*/
void unregisterApplication(ApplicationId applicationId);
/* TODO we may be able to accomplish the following through network config:
void createDomain(String domainId);
void removeDomain(String domainId);
void addInternalDeviceToDomain(IntentDomain domain, DeviceId deviceId);
void addPortToDomain(IntentDomain domain, ConnectPoint port);
void bindApplicationToDomain(String domain, IntentDomain implementation);
void unbindApplicationToDomain(String domain, IntentDomain implementation);
*/
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onosproject.incubator.net.config.Config;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import java.util.Set;
/**
* Configuration for an intent domain including a name, set of internal devices,
* set of edge ports, and the application bound to control the domain.
*/
@Beta
public abstract class IntentDomainConfig extends Config<IntentDomainId> {
private static final String DOMAIN_NAME = "domainName";
private static final String APPLICATION_NAME = "applicationName";
/**
* Returns the friendly name for the domain.
*
* @return domain name
*/
public String domainName() {
return get(DOMAIN_NAME, subject.toString());
}
/**
* Sets the friendly name for the domain.
*
* @param domainName new name for the domain; null to clear
* @return self
*/
public IntentDomainConfig domainName(String domainName) {
return (IntentDomainConfig) setOrClear(DOMAIN_NAME, domainName);
}
/**
* Returns the friendly name for the domain.
*
* @return domain name
*/
public String applicationName() {
return get(APPLICATION_NAME, null); //TODO maybe not null?
}
/**
* Sets the friendly name for the domain.
*
* @param applicationName new name for the domain; null to clear
* @return self
*/
public IntentDomainConfig applicationName(String applicationName) {
return (IntentDomainConfig) setOrClear(APPLICATION_NAME, applicationName);
}
//TODO sets
abstract Set<DeviceId> internalDevices();
abstract Set<ConnectPoint> edgePorts();
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Intent domain identifier.
*/
@Beta
public class IntentDomainId {
private final String id;
/**
* Creates an intent domain identifier from the specified string representation.
*
* @param value string value
* @return intent identifier
*/
public static IntentDomainId valueOf(String value) {
return new IntentDomainId(value);
}
/**
* Constructor for serializer.
*/
IntentDomainId() {
this.id = null;
}
/**
* Constructs the ID corresponding to a given string value.
*
* @param value the underlying value of this ID
*/
IntentDomainId(String value) {
this.id = checkNotNull(value, "Intent domain ID cannot be null.");
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof IntentDomainId)) {
return false;
}
IntentDomainId that = (IntentDomainId) obj;
return Objects.equals(this.id, that.id);
}
@Override
public String toString() {
return id;
}
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
/**
* Listener for intent domain events.
*/
@Beta
public interface IntentDomainListener {
//TODO create event types
//extends EventListener<IntentDomainEvent>
}
\ No newline at end of file
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import java.util.List;
import java.util.Set;
/**
* FIXME.
*/
@Beta
public interface IntentDomainProvider {
/**
* Requests that the provider attempt to satisfy the intent primitive.
* The application must apply the context before the intent resource
* can be used. Request contexts can be explictly cancelled, or they will
* eventually time out so that resources can be reused.
*
* @param primitive intent primitive
* @return request contexts that contain resources to satisfy the intent
*/
//TODO Consider an iterable and/or holds (only hold one or two reservation(s) at a time)
List<RequestContext> request(IntentPrimitive primitive);
/**
* Request that the provider attempt to modify an existing resource to satisfy
* a new intent primitive. The application must apply the context before
* the intent resource can be used.
*
* @param resource existing resource
* @param newPrimitive intent primitive
* @return request contexts that contain resources to satisfy the intent
*/
List<RequestContext> modify(IntentResource resource, IntentPrimitive newPrimitive);
/**
* Requests that the provider release an intent resource.
*
* @param resource intent resource
*/
void release(IntentResource resource);
/**
* Requests that the provider apply the intent resource in the request context.
*
* @param context request context
* @return intent resource that satisfies the intent
*/
IntentResource apply(RequestContext context);
/**
* Requests that the provider cancel the request. Requests that are not applied
* will be eventually timed out by the provider.
*
* @param context request context
*/
void cancel(RequestContext context);
/**
* Returns all intent resources held by the provider.
*
* @return set of intent resources
*/
Set<IntentResource> getResources();
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onlab.graph.Graph;
import org.onosproject.net.DeviceId;
import java.util.Set;
/**
* Service for that maintains a graph of intent domains and a registry of intent
* domain providers.
*/
@Beta
public interface IntentDomainService {
/**
* Returns the intent domain for the given id.
*
* @param id id to look up
* @return the intent domain; null if none found
*/
IntentDomain getDomain(IntentDomainId id);
/**
* Returns a set of all intent domains.
*
* @return set of intent domains
*/
Set<IntentDomain> getDomains();
/**
* Returns any network domains associated with the given device id.
*
* @param deviceId device id to look up
* @return set of intent domain
*/
Set<IntentDomain> getDomains(DeviceId deviceId);
/**
* Returns the graph of intent domains and connection devices.
*
* @return graph of network domains
*/
Graph<DomainVertex, DomainEdge> getDomainGraph();
/**
* Adds the specified listener for intent domain events.
*
* @param listener listener to be added
*/
void addListener(IntentDomainListener listener);
/**
* Removes the specified listener for intent domain events.
*
* @param listener listener to be removed
*/
void removeListener(IntentDomainListener listener);
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
import org.onosproject.core.ApplicationId;
/**
* Abstract base class for intent primitives.
*/
@Beta
public abstract class IntentPrimitive {
private final ApplicationId appId;
IntentPrimitive(ApplicationId appId) {
this.appId = appId;
}
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
/**
* The abstract base class for the resource that satisfies an intent primitive.
*/
@Beta
public abstract class IntentResource {
private final IntentPrimitive primitive;
// TODO add other common fields
//String ingressTag;
//String egressTag;
//etc.
IntentResource(IntentPrimitive primitive) {
this.primitive = primitive;
}
public IntentPrimitive primitive() {
return primitive;
}
}
/*
* 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.incubator.net.domain;
import com.google.common.annotations.Beta;
/**
* Context for intent primitive requests to an intent domain provider. A context
* must be explicitly applied before it can be used. The purpose of the request
* context is so that an application can coordinate multiple requests across multiple
* domains before committing. Contexts can be explicitly cancelled if they are not
* needed (due to a better context or incomplete path across domains); they can
* also be automatically cancelled by a provider after a short timeout.
*/
@Beta
class RequestContext {
IntentDomain domain;
IntentResource resource;
//TODO other common parameters:
//String cost;
//TODO getters/setters
}
/*
* 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.
*/
/**
* Subsystem for network intent domains.
*/
package org.onosproject.incubator.net.domain;
\ No newline at end of file