diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/core/api/src/main | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff) |
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/core/api/src/main')
624 files changed, 52804 insertions, 0 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationAdminService.java new file mode 100644 index 00000000..3713e218 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationAdminService.java @@ -0,0 +1,70 @@ +/* + * 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.app; + +import org.onosproject.core.Application; +import org.onosproject.core.ApplicationId; +import org.onosproject.security.Permission; + +import java.io.InputStream; +import java.util.Set; + +/** + * Service for managing network control applications. + */ +public interface ApplicationAdminService extends ApplicationService { + + /** + * Installs the application contained in the specified application archive + * input stream. This can be either a ZIP stream containing a compressed + * application archive or a plain XML stream containing just the + * {@code app.xml} application descriptor file. + * + * @param appDescStream application descriptor input stream + * @return installed application descriptor + * @throws org.onosproject.app.ApplicationException if unable to read the app archive stream + */ + Application install(InputStream appDescStream); + + /** + * Uninstalls the specified application. + * + * @param appId application identifier + */ + void uninstall(ApplicationId appId); + + /** + * Activates the specified application. + * + * @param appId application identifier + */ + void activate(ApplicationId appId); + + /** + * Deactivates the specified application. + * + * @param appId application identifier + */ + void deactivate(ApplicationId appId); + + /** + * Updates the permissions granted to the applications. + * + * @param appId application identifier + * @param permissions set of granted permissions + */ + void setPermissions(ApplicationId appId, Set<Permission> permissions); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java new file mode 100644 index 00000000..2561280b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java @@ -0,0 +1,89 @@ +/* + * 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.app; + +import org.onosproject.core.ApplicationRole; +import org.onosproject.core.Version; +import org.onosproject.security.Permission; + +import java.net.URI; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +/** + * Description of a network control/management application. + */ +public interface ApplicationDescription { + + /** + * Returns the application name id. + * + * @return application identifier + */ + String name(); + + /** + * Returns the application version. + * + * @return application version + */ + Version version(); + + /** + * Returns description of the application. + * + * @return application description text + */ + String description(); + + /** + * Returns the name of the application origin, group or company. + * + * @return application origin + */ + String origin(); + + /** + * Returns the role of the application. + * + * @return application role + */ + ApplicationRole role(); + + /** + * Returns the permissions requested by the application. + * + * @return requested permissions + */ + Set<Permission> permissions(); + + /** + * Returns the feature repository URI. Null value signifies that the + * application did not provide its own features repository. + * + * @return optional feature repo URL + */ + Optional<URI> featuresRepo(); + + /** + * Returns the list of features comprising the application. At least one + * feature must be given. + * + * @return application features + */ + List<String> features(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationEvent.java new file mode 100644 index 00000000..5bf1323d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationEvent.java @@ -0,0 +1,75 @@ +/* + * 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.app; + +import org.onosproject.core.Application; +import org.onosproject.event.AbstractEvent; + +/** + * Describes application lifecycle event. + */ +public class ApplicationEvent extends AbstractEvent<ApplicationEvent.Type, Application> { + + public enum Type { + /** + * Signifies that an application has been installed. + */ + APP_INSTALLED, + + /** + * Signifies that an application has been activated. + */ + APP_ACTIVATED, + + /** + * Signifies that an application has been deactivated. + */ + APP_DEACTIVATED, + + /** + * Signifies that an application has been uninstalled. + */ + APP_UNINSTALLED, + + /** + * Signifies that application granted permissions have changed. + */ + APP_PERMISSIONS_CHANGED + } + + /** + * Creates an event of a given type and for the specified app and the + * current time. + * + * @param type app event type + * @param app event app subject + */ + public ApplicationEvent(Type type, Application app) { + super(type, app); + } + + /** + * Creates an event of a given type and for the specified app and time. + * + * @param type app event type + * @param app event app subject + * @param time occurrence time + */ + public ApplicationEvent(Type type, Application app, long time) { + super(type, app, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationException.java new file mode 100644 index 00000000..2888c70b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationException.java @@ -0,0 +1,49 @@ +/* + * 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.app; + +/** + * Represents class of errors related to application management. + */ +public class ApplicationException extends RuntimeException { + + private static final long serialVersionUID = -2287403908433720122L; + + /** + * Constructs an exception with no message and no underlying cause. + */ + public ApplicationException() { + } + + /** + * Constructs an exception with the specified message. + * + * @param message the message describing the specific nature of the error + */ + public ApplicationException(String message) { + super(message); + } + + /** + * Constructs an exception with the specified message and the underlying cause. + * + * @param message the message describing the specific nature of the error + * @param cause the underlying cause of this error + */ + public ApplicationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationListener.java new file mode 100644 index 00000000..7a680572 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationListener.java @@ -0,0 +1,24 @@ +/* + * 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.app; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving application related events. + */ +public interface ApplicationListener extends EventListener<ApplicationEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java new file mode 100644 index 00000000..73dcc86c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java @@ -0,0 +1,70 @@ +/* + * 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.app; + +import org.onosproject.core.Application; +import org.onosproject.core.ApplicationId; +import org.onosproject.event.ListenerService; +import org.onosproject.security.Permission; + +import java.util.Set; + +/** + * Service for inspecting inventory of network control applications. + */ +public interface ApplicationService + extends ListenerService<ApplicationEvent, ApplicationListener> { + + /** + * Returns the set of all installed applications. + * + * @return set of installed apps + */ + Set<Application> getApplications(); + + /** + * Returns the registered id of the application with the given name. + * + * @param name application name + * @return registered application id + */ + ApplicationId getId(String name); + + /** + * Returns the application with the supplied application identifier. + * + * @param appId application identifier + * @return application descriptor + */ + Application getApplication(ApplicationId appId); + + /** + * Return the application state. + * + * @param appId application identifier + * @return application state + */ + ApplicationState getState(ApplicationId appId); + + /** + * Returns the permissions currently granted to the applications. + * + * @param appId application identifier + * @return set of granted permissions + */ + Set<Permission> getPermissions(ApplicationId appId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationState.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationState.java new file mode 100644 index 00000000..c480a0c7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationState.java @@ -0,0 +1,33 @@ +/* + * 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.app; + +/** + * Representation of an application state. + */ +public enum ApplicationState { + + /** + * Indicates that application has been installed, but is not running. + */ + INSTALLED, + + /** + * Indicates that application is active. + */ + ACTIVE + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java new file mode 100644 index 00000000..b3cdc43e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java @@ -0,0 +1,108 @@ +/* + * 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.app; + +import org.onosproject.core.Application; +import org.onosproject.core.ApplicationId; +import org.onosproject.security.Permission; +import org.onosproject.store.Store; + +import java.io.InputStream; +import java.util.Set; + +/** + * Service for managing network control applications. + */ +public interface ApplicationStore extends Store<ApplicationEvent, ApplicationStoreDelegate> { + + /** + * Returns the set of all installed applications. + * + * @return set of installed apps + */ + Set<Application> getApplications(); + + /** + * Returns the registered id of the application with the given name. + * + * @param name application name + * @return registered application id + */ + ApplicationId getId(String name); + + /** + * Returns the application with the supplied application identifier. + * + * @param appId application identifier + * @return application descriptor + */ + Application getApplication(ApplicationId appId); + + /** + * Returns the current application state. + * + * @param appId application identifier + * @return application state + */ + ApplicationState getState(ApplicationId appId); + + /** + * Creates the application from the specified application descriptor + * input stream. + * + * @param appDescStream application archive input stream + * @return application descriptor + */ + Application create(InputStream appDescStream); + + /** + * Removes the specified application. + * + * @param appId application identifier + */ + void remove(ApplicationId appId); + + /** + * Mark the application as actived. + * + * @param appId application identifier + */ + void activate(ApplicationId appId); + + /** + * Mark the application as deactivated. + * + * @param appId application identifier + */ + void deactivate(ApplicationId appId); + + /** + * Returns the permissions granted to the applications. + * + * @param appId application identifier + * @return set of granted permissions + */ + Set<Permission> getPermissions(ApplicationId appId); + + /** + * Updates the permissions granted to the applications. + * + * @param appId application identifier + * @param permissions set of granted permissions + */ + void setPermissions(ApplicationId appId, Set<Permission> permissions); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStoreDelegate.java new file mode 100644 index 00000000..f339e685 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * 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.app; + +import org.onosproject.store.StoreDelegate; + +/** + * Application store delegate abstraction. + */ +public interface ApplicationStoreDelegate extends StoreDelegate<ApplicationEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java new file mode 100644 index 00000000..710d0f9c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java @@ -0,0 +1,125 @@ +/* + * 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.app; + +import org.onosproject.core.ApplicationRole; +import org.onosproject.core.Version; +import org.onosproject.security.Permission; + +import java.net.URI; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of network control/management application descriptor. + */ +public class DefaultApplicationDescription implements ApplicationDescription { + + private final String name; + private final Version version; + private final String description; + private final String origin; + private final ApplicationRole role; + private final Set<Permission> permissions; + private final Optional<URI> featuresRepo; + private final List<String> features; + + /** + * Creates a new application descriptor using the supplied data. + * + * @param name application name + * @param version application version + * @param description application description + * @param origin origin company + * @param role application role + * @param permissions requested permissions + * @param featuresRepo optional features repo URI + * @param features application features + */ + public DefaultApplicationDescription(String name, Version version, + String description, String origin, + ApplicationRole role, Set<Permission> permissions, + URI featuresRepo, List<String> features) { + this.name = checkNotNull(name, "Name cannot be null"); + this.version = checkNotNull(version, "Version cannot be null"); + this.description = checkNotNull(description, "Description cannot be null"); + this.origin = checkNotNull(origin, "Origin cannot be null"); + this.role = checkNotNull(role, "Role cannot be null"); + this.permissions = checkNotNull(permissions, "Permissions cannot be null"); + this.featuresRepo = Optional.ofNullable(featuresRepo); + this.features = checkNotNull(features, "Features cannot be null"); + checkArgument(!features.isEmpty(), "There must be at least one feature"); + } + + @Override + public String name() { + return name; + } + + @Override + public Version version() { + return version; + } + + @Override + public String description() { + return description; + } + + @Override + public String origin() { + return origin; + } + + @Override + public ApplicationRole role() { + return role; + } + + @Override + public Set<Permission> permissions() { + return permissions; + } + + @Override + public Optional<URI> featuresRepo() { + return featuresRepo; + } + + @Override + public List<String> features() { + return features; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("name", name) + .add("version", version) + .add("description", description) + .add("origin", origin) + .add("role", role) + .add("permissions", permissions) + .add("featuresRepo", featuresRepo) + .add("features", features) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/package-info.java new file mode 100644 index 00000000..f8e5465d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Set of abstractions for managing network control applications. + */ +package org.onosproject.app;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigEvent.java new file mode 100644 index 00000000..0f5a2ee5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigEvent.java @@ -0,0 +1,74 @@ +/* + * 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.cfg; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes a component configuration event. + */ +public class ComponentConfigEvent extends AbstractEvent<ComponentConfigEvent.Type, String> { + + private final String name; + private final String value; + + public enum Type { + /** + * Signifies that a configuration property has set. + */ + PROPERTY_SET, + + /** + * Signifies that a configuration property has been unset. + */ + PROPERTY_UNSET + } + + /** + * Creates an event of a given type and for the specified app and the + * current time. + * + * @param type config property event type + * @param componentName component name event subject + * @param name config property name + * @param value config property value + */ + public ComponentConfigEvent(Type type, String componentName, + String name, String value) { + super(type, componentName); + this.name = name; + this.value = value; + } + + /** + * Returns the property name. + * + * @return property name + */ + public String name() { + return name; + } + + /** + * Returns the property value as a string. + * + * @return string value + */ + public String value() { + return value; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java new file mode 100644 index 00000000..a311002f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigService.java @@ -0,0 +1,74 @@ +/* + * 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.cfg; + +import java.util.Set; + +/** + * Service for tracking system-wide configurations for various software components. + */ +public interface ComponentConfigService { + + /** + * Returns names of all components that have registered their + * configuration properties. + * + * @return set of component names + */ + Set<String> getComponentNames(); + + /** + * Registers configuration properties for the specified component. + * + * @param componentClass class of configurable component + */ + void registerProperties(Class<?> componentClass); + + /** + * Unregisters configuration properties for the specified component. + * + * @param componentClass class of configurable component + * @param clear true indicates any settings should be cleared + */ + void unregisterProperties(Class<?> componentClass, boolean clear); + + /** + * Returns configuration properties of the named components. + * + * @param componentName component name + * @return set of configuration properties + */ + Set<ConfigProperty> getProperties(String componentName); + + /** + * Sets the value of the specified configuration property. + * + * @param componentName component name + * @param name property name + * @param value new property value + */ + void setProperty(String componentName, String name, String value); + + /** + * Clears the value of the specified configuration property thus making + * the property take on its default value. + * + * @param componentName component name + * @param name property name + */ + void unsetProperty(String componentName, String name); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java new file mode 100644 index 00000000..05f58a4c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStore.java @@ -0,0 +1,45 @@ +/* + * 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.cfg; + +import org.onosproject.store.Store; + +/** + * Service for storing and distributing system-wide configurations for various + * software components. + */ +public interface ComponentConfigStore + extends Store<ComponentConfigEvent, ComponentConfigStoreDelegate> { + + /** + * Sets the value of the specified configuration property. + * + * @param componentName component name + * @param name property name + * @param value new property value + */ + void setProperty(String componentName, String name, String value); + + /** + * Clears the value of the specified configuration property thus making + * the property take on its default value. + * + * @param componentName component name + * @param name property name + */ + void unsetProperty(String componentName, String name); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStoreDelegate.java new file mode 100644 index 00000000..da262789 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ComponentConfigStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * 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.cfg; + +import org.onosproject.store.StoreDelegate; + +/** + * Configuration property store delegate abstraction. + */ +public interface ComponentConfigStoreDelegate extends StoreDelegate<ComponentConfigEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java new file mode 100644 index 00000000..36cd22b5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java @@ -0,0 +1,279 @@ +/* + * 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.cfg; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +/** + * Component configuration property. + */ +public final class ConfigProperty { + + private final String name; + private final Type type; + private final String value; + private final String defaultValue; + private final String description; + private final boolean isSet; + + /** + * Representation of the type of property value. + */ + public enum Type { + /** + * Indicates the value is a string. + */ + STRING, + + /** + * Indicates the value is an integer. + */ + INTEGER, + + /** + * Indicates the value is a long. + */ + LONG, + + /** + * Indicates the value is a float. + */ + FLOAT, + + /** + * Indicates the value is a double. + */ + DOUBLE, + + /** + * Indicates the value is a boolean. + */ + BOOLEAN + } + + /** + * Creates a new configuration property with its default value. + * + * @param name property name + * @param type value type + * @param defaultValue default value as a string + * @param description property description + * @return newly defined property + */ + public static ConfigProperty defineProperty(String name, Type type, + String defaultValue, + String description) { + return new ConfigProperty(name, type, description, defaultValue, defaultValue, false); + } + + /** + * Creates a new configuration property as a copy of an existing one, but + * with a new value. + * + * @param property property to be changed + * @param newValue new value as a string + * @return newly updated property + */ + public static ConfigProperty setProperty(ConfigProperty property, String newValue) { + return new ConfigProperty(property.name, property.type, property.description, + property.defaultValue, newValue, true); + } + + /** + * Creates a new configuration property as a copy of an existing one, but + * without a specific value, thus making it take its default value. + * + * @param property property to be reset + * @return newly reset property + */ + public static ConfigProperty resetProperty(ConfigProperty property) { + return new ConfigProperty(property.name, property.type, property.description, + property.defaultValue, property.defaultValue, false); + } + + /** + * Creates a new configuration property with its default value. + * + * @param name property name + * @param type value type + * @param defaultValue default value as a string + * @param description property description + * @param value property value + * @param isSet indicates whether the property is set or not + */ + private ConfigProperty(String name, Type type, String description, + String defaultValue, String value, boolean isSet) { + this.name = checkNotNull(name, "Property name cannot be null"); + this.type = checkNotNull(type, "Property type cannot be null"); + this.description = checkNotNull(description, "Property description cannot be null"); + this.defaultValue = defaultValue; + this.value = value; + this.isSet = isSet; + } + + /** + * Returns the property name. + * + * @return property name + */ + public String name() { + return name; + } + + /** + * Returns the property type. + * + * @return property type + */ + public Type type() { + return type; + } + + /** + * Returns the property description. + * + * @return string value + */ + public String description() { + return description; + } + + /** + * Returns the property default value as a string. + * + * @return string default value + */ + public String defaultValue() { + return defaultValue; + } + + /** + * Returns the property value as a string. + * + * @return string value + */ + public String value() { + return value; + } + + /** + * Indicates whether the property is set or whether it assumes its + * default value. + * + * @return true if the property is set + */ + public boolean isSet() { + return isSet; + } + + /** + * Returns the property value as a string. + * + * @return string value + */ + public String asString() { + return value; + } + + /** + * Returns the property value as an integer. + * + * @return integer value + */ + public int asInteger() { + checkState(type == Type.INTEGER, "Value is not an integer"); + return Integer.parseInt(value); + } + + /** + * Returns the property value as a long. + * + * @return long value + */ + public long asLong() { + checkState(type == Type.INTEGER || type == Type.LONG, "Value is not a long or integer"); + return Long.parseLong(value); + } + + /** + * Returns the property value as a float. + * + * @return float value + */ + public float asFloat() { + checkState(type == Type.FLOAT, "Value is not a float"); + return Float.parseFloat(value); + } + + /** + * Returns the property value as a double. + * + * @return double value + */ + public double asDouble() { + checkState(type == Type.FLOAT || type == Type.DOUBLE, "Value is not a float or double"); + return Double.parseDouble(value); + } + + /** + * Returns the property value as a boolean. + * + * @return string value + */ + public boolean asBoolean() { + checkState(type == Type.BOOLEAN, "Value is not a boolean"); + return Boolean.parseBoolean(value); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + /** + * {@inheritDoc} + * + * Equality is considered only on the basis of property name. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ConfigProperty) { + final ConfigProperty other = (ConfigProperty) obj; + return Objects.equals(this.name, other.name); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .add("type", type) + .add("value", value) + .add("defaultValue", defaultValue) + .add("description", description) + .add("isSet", isSet) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/package-info.java new file mode 100644 index 00000000..99fd5be4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/** + * Set of abstractions for centrally managing component configurations. + * Configuration properties are registered for a component resource which is + * auto-generated during the build process based on information specified in + * the @Property annotations. This provides an overall inventory of all + * supported component configurations. + */ +package org.onosproject.cfg;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java new file mode 100644 index 00000000..5f2b5fff --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014-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.cluster; + +import org.onlab.packet.IpAddress; + +import java.util.Set; + +/** + * Service for administering the cluster node membership. + */ +public interface ClusterAdminService { + + /** + * Forms cluster configuration based on the specified set of node + * information. This method resets and restarts the controller + * instance. + * + * @param nodes set of nodes that form the cluster + * @param ipPrefix IP address prefix, e.g. 10.0.1.* + */ + void formCluster(Set<ControllerNode> nodes, String ipPrefix); + + /** + * Adds a new controller node to the cluster. + * + * @param nodeId controller node identifier + * @param ip node IP listen address + * @param tcpPort tcp listen port + * @return newly added node + */ + ControllerNode addNode(NodeId nodeId, IpAddress ip, int tcpPort); + + /** + * Removes the specified node from the cluster node list. + * + * @param nodeId controller node identifier + */ + void removeNode(NodeId nodeId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterDefinitionService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterDefinitionService.java new file mode 100644 index 00000000..dbe5f71c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterDefinitionService.java @@ -0,0 +1,32 @@ +package org.onosproject.cluster; + +import java.util.Set; + +/** + * Service for obtaining the static definition of a controller cluster. + */ +public interface ClusterDefinitionService { + + /** + * Returns the local controller node. + * @return local controller node + */ + ControllerNode localNode(); + + /** + * Returns the set of seed nodes that should be used for discovering other members + * of the cluster. + * @return set of seed controller nodes + */ + Set<ControllerNode> seedNodes(); + + /** + * Forms cluster configuration based on the specified set of node + * information. Assumes subsequent restart for the new configuration to + * take hold. + * + * @param nodes set of nodes that form the cluster + * @param ipPrefix IP address prefix, e.g. 10.0.1.* + */ + void formCluster(Set<ControllerNode> nodes, String ipPrefix); +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEvent.java new file mode 100644 index 00000000..7bdc1d7d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEvent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2014 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.cluster; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes cluster-related event. + */ +public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerNode> { + + /** + * Type of cluster-related events. + */ + public enum Type { + /** + * Signifies that a new cluster instance has been administratively added. + */ + INSTANCE_ADDED, + + /** + * Signifies that a cluster instance has been administratively removed. + */ + INSTANCE_REMOVED, + + /** + * Signifies that a cluster instance became active. + */ + INSTANCE_ACTIVATED, + + /** + * Signifies that a cluster instance became inactive. + */ + INSTANCE_DEACTIVATED + } + + /** + * Creates an event of a given type and for the specified instance and the + * current time. + * + * @param type cluster event type + * @param instance cluster device subject + */ + public ClusterEvent(Type type, ControllerNode instance) { + super(type, instance); + } + + /** + * Creates an event of a given type and for the specified device and time. + * + * @param type device event type + * @param instance event device subject + * @param time occurrence time + */ + public ClusterEvent(Type type, ControllerNode instance, long time) { + super(type, instance, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEventListener.java new file mode 100644 index 00000000..79ff06ec --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterEventListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.cluster; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving device cluster-related events. + */ +public interface ClusterEventListener extends EventListener<ClusterEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterService.java new file mode 100644 index 00000000..015a6482 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterService.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014-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.cluster; + +import java.util.Set; + +import org.joda.time.DateTime; +import org.onosproject.event.ListenerService; + +/** + * Service for obtaining information about the individual nodes within + * the controller cluster. + */ +public interface ClusterService + extends ListenerService<ClusterEvent, ClusterEventListener> { + + /** + * Returns the local controller node. + * + * @return local controller node + */ + ControllerNode getLocalNode(); + + /** + * Returns the set of current cluster members. + * + * @return set of cluster members + */ + Set<ControllerNode> getNodes(); + + /** + * Returns the specified controller node. + * + * @param nodeId controller node identifier + * @return controller node + */ + ControllerNode getNode(NodeId nodeId); + + /** + * Returns the availability state of the specified controller node. + * + * @param nodeId controller node identifier + * @return availability state + */ + ControllerNode.State getState(NodeId nodeId); + + /** + * Returns the system time when the availability state was last updated. + * + * @param nodeId controller node identifier + * @return system time when the availability state was last updated. + */ + DateTime getLastUpdated(NodeId nodeId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java new file mode 100644 index 00000000..0481d510 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStore.java @@ -0,0 +1,84 @@ +/* + * Copyright 2014-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.cluster; + +import org.joda.time.DateTime; +import org.onlab.packet.IpAddress; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Manages inventory of controller cluster nodes; not intended for direct use. + */ +public interface ClusterStore extends Store<ClusterEvent, ClusterStoreDelegate> { + + /** + * Returns the local controller node. + * + * @return local controller instance + */ + ControllerNode getLocalNode(); + + /** + * Returns the set of current cluster members. + * + * @return set of cluster members + */ + Set<ControllerNode> getNodes(); + + /** + * Returns the specified controller node. + * + * @param nodeId controller instance identifier + * @return controller instance + */ + ControllerNode getNode(NodeId nodeId); + + /** + * Returns the availability state of the specified controller node. + * + * @param nodeId controller instance identifier + * @return availability state + */ + ControllerNode.State getState(NodeId nodeId); + + /** + * Returns the system when the availability state was last updated. + * + * @param nodeId controller node identifier + * @return system time when the availability state was last updated. + */ + DateTime getLastUpdated(NodeId nodeId); + + /** + * Adds a new controller node to the cluster. + * + * @param nodeId controller node identifier + * @param ip node IP listen address + * @param tcpPort tcp listen port + * @return newly added node + */ + ControllerNode addNode(NodeId nodeId, IpAddress ip, int tcpPort); + + /** + * Removes the specified node from the inventory of cluster nodes. + * + * @param nodeId controller instance identifier + */ + void removeNode(NodeId nodeId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStoreDelegate.java new file mode 100644 index 00000000..50d44305 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ClusterStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.cluster; + +import org.onosproject.store.StoreDelegate; + +/** + * Cluster store delegate abstraction. + */ +public interface ClusterStoreDelegate extends StoreDelegate<ClusterEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNode.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNode.java new file mode 100644 index 00000000..3cfc9367 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNode.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 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.cluster; + +import org.onlab.packet.IpAddress; + +/** + * Represents a controller instance as a member in a cluster. + */ +public interface ControllerNode { + + /** Represents the operational state of the instance. */ + public enum State { + /** + * Signifies that the instance is active and operating normally. + */ + ACTIVE, + + /** + * Signifies that the instance is inactive, which means either down or + * up, but not operational. + */ + INACTIVE + } + + /** + * Returns the instance identifier. + * + * @return instance identifier + */ + NodeId id(); + + /** + * Returns the IP address of the controller instance. + * + * @return IP address + */ + IpAddress ip(); + + + /** + * Returns the TCP port on which the node listens for connections. + * + * @return TCP port + */ + int tcpPort(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNodeToNodeId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNodeToNodeId.java new file mode 100644 index 00000000..4cde8b29 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/ControllerNodeToNodeId.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014 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.cluster; + +import com.google.common.base.Function; + +/** + * Function to convert ControllerNode to NodeId. + */ +public final class ControllerNodeToNodeId + implements Function<ControllerNode, NodeId> { + + private static final ControllerNodeToNodeId INSTANCE = new ControllerNodeToNodeId(); + + @Override + public NodeId apply(ControllerNode input) { + if (input == null) { + return null; + } else { + return input.id(); + } + } + + /** + * Returns a Function to convert ControllerNode to NodeId. + * + * @return ControllerNodeToNodeId instance. + */ + public static ControllerNodeToNodeId toNodeId() { + return INSTANCE; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java new file mode 100644 index 00000000..5f3e0e19 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java @@ -0,0 +1,103 @@ +/* + * Copyright 2014-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.cluster; + +import org.onlab.packet.IpAddress; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of a controller instance descriptor. + */ +public class DefaultControllerNode implements ControllerNode { + + public static final int DEFAULT_PORT = 9876; + + private final NodeId id; + private final IpAddress ip; + private final int tcpPort; + + // For serialization + private DefaultControllerNode() { + this.id = null; + this.ip = null; + this.tcpPort = 0; + } + + /** + * Creates a new instance with the specified id and IP address. + * + * @param id instance identifier + * @param ip instance IP address + */ + public DefaultControllerNode(NodeId id, IpAddress ip) { + this(id, ip, DEFAULT_PORT); + } + + /** + * Creates a new instance with the specified id and IP address and TCP port. + * + * @param id instance identifier + * @param ip instance IP address + * @param tcpPort TCP port + */ + public DefaultControllerNode(NodeId id, IpAddress ip, int tcpPort) { + this.id = id; + this.ip = ip; + this.tcpPort = tcpPort; + } + + @Override + public NodeId id() { + return id; + } + + @Override + public IpAddress ip() { + return ip; + } + + @Override + public int tcpPort() { + return tcpPort; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o instanceof DefaultControllerNode) { + DefaultControllerNode that = (DefaultControllerNode) o; + return Objects.equals(this.id, that.id); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("id", id) + .add("ip", ip).add("tcpPort", tcpPort).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/Leadership.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/Leadership.java new file mode 100644 index 00000000..113e19cb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/Leadership.java @@ -0,0 +1,164 @@ +/* + * Copyright 2014-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.cluster; + +import java.util.Objects; +import java.util.List; +import java.util.Optional; + +import org.joda.time.DateTime; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; + +/** + * Abstract leadership concept. The information carried by this construct + * include the topic of contention, the {@link NodeId}s of Nodes that could + * become leader for the topic, the epoch when the term for a given leader + * began, and the system time when the term began. Note: + * <ul> + * <li>The list of NodeIds may include the current leader at index 0, and the + * rest in decreasing preference order.</li> + * <li>The epoch is the logical age of a Leadership construct, and should be + * used for comparing two Leaderships, but only of the same topic.</li> + * <li>The leader may be null if its accuracy can't be guaranteed. This applies + * to CANDIDATES_CHANGED events and candidate board contents.</li> + * </ul> + */ +public class Leadership { + + private final String topic; + private final Optional<NodeId> leader; + private final List<NodeId> candidates; + private final long epoch; + private final long electedTime; + + public Leadership(String topic, NodeId leader, long epoch, long electedTime) { + this.topic = topic; + this.leader = Optional.of(leader); + this.candidates = ImmutableList.of(leader); + this.epoch = epoch; + this.electedTime = electedTime; + } + + public Leadership(String topic, NodeId leader, List<NodeId> candidates, + long epoch, long electedTime) { + this.topic = topic; + this.leader = Optional.of(leader); + this.candidates = ImmutableList.copyOf(candidates); + this.epoch = epoch; + this.electedTime = electedTime; + } + + public Leadership(String topic, List<NodeId> candidates, + long epoch, long electedTime) { + this.topic = topic; + this.leader = Optional.empty(); + this.candidates = ImmutableList.copyOf(candidates); + this.epoch = epoch; + this.electedTime = electedTime; + } + + /** + * The topic for which this leadership applies. + * + * @return leadership topic. + */ + public String topic() { + return topic; + } + + /** + * The nodeId of leader for this topic. + * + * @return leader node. + */ + // This will return Optional<NodeId> in the future. + public NodeId leader() { + return leader.orElse(null); + } + + /** + * Returns an preference-ordered list of nodes that are in the leadership + * race for this topic. + * + * @return a list of NodeIds in priority-order, or an empty list. + */ + public List<NodeId> candidates() { + return candidates; + } + + /** + * The epoch when the leadership was assumed. + * <p> + * Comparing epochs is only appropriate for leadership events for the same + * topic. The system guarantees that for any given topic the epoch for a new + * term is higher (not necessarily by 1) than the epoch for any previous + * term. + * + * @return leadership epoch + */ + public long epoch() { + return epoch; + } + + /** + * The system time when the term started. + * <p> + * The elected time is initially set on the node coordinating + * the leader election using its local system time. Due to possible + * clock skew, relying on this value for determining event ordering + * is discouraged. Epoch is more appropriate for determining + * event ordering. + * + * @return elected time. + */ + public long electedTime() { + return electedTime; + } + + @Override + public int hashCode() { + return Objects.hash(topic, leader, candidates, epoch, electedTime); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Leadership) { + final Leadership other = (Leadership) obj; + return Objects.equals(this.topic, other.topic) && + Objects.equals(this.leader, other.leader) && + Objects.equals(this.candidates, other.candidates) && + Objects.equals(this.epoch, other.epoch) && + Objects.equals(this.electedTime, other.electedTime); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this.getClass()) + .add("topic", topic) + .add("leader", leader) + .add("candidates", candidates) + .add("epoch", epoch) + .add("electedTime", new DateTime(electedTime)) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java new file mode 100644 index 00000000..faf6dd45 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014-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.cluster; + +import java.util.Objects; + +import org.onosproject.event.AbstractEvent; + +import com.google.common.base.MoreObjects; + +/** + * Describes leadership-related event. + */ +public class LeadershipEvent extends AbstractEvent<LeadershipEvent.Type, Leadership> { + + /** + * Type of leadership-related events. + */ + public enum Type { + /** + * Signifies that the leader has been elected. The event subject is the + * new leader. + */ + LEADER_ELECTED, + + /** + * Signifies that the leader has been re-elected. The event subject is the + * leader. + */ + LEADER_REELECTED, + + /** + * Signifies that the leader has been booted and lost leadership. The + * event subject is the former leader. + */ + LEADER_BOOTED, + + /** + * Signifies that the list of candidates for leadership for a topic has + * changed. This event does not guarantee accurate leader information. + */ + CANDIDATES_CHANGED + } + + /** + * Creates an event of a given type and for the specified instance and the + * current time. + * + * @param type leadership event type + * @param leadership event subject + */ + public LeadershipEvent(Type type, Leadership leadership) { + super(type, leadership); + } + + /** + * Creates an event of a given type and for the specified subject and time. + * + * @param type leadership event type + * @param leadership event subject + * @param time occurrence time + */ + public LeadershipEvent(Type type, Leadership leadership, long time) { + super(type, leadership, time); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subject(), time()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof LeadershipEvent) { + final LeadershipEvent other = (LeadershipEvent) obj; + return Objects.equals(this.type(), other.type()) && + Objects.equals(this.subject(), other.subject()) && + Objects.equals(this.time(), other.time()); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this.getClass()) + .add("type", type()) + .add("subject", subject()) + .add("time", time()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEventListener.java new file mode 100644 index 00000000..53d84b1b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipEventListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.cluster; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving device leadership-related events. + */ +public interface LeadershipEventListener extends EventListener<LeadershipEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java new file mode 100644 index 00000000..7d1f6079 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java @@ -0,0 +1,124 @@ +/* + * Copyright 2014-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.cluster; + +import org.onosproject.event.ListenerService; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +/** + * Service for leader election. + * Leadership contests are organized around topics. A instance can join the + * leadership race for a topic or withdraw from a race it has previously joined. + * Listeners can be added to receive notifications asynchronously for various + * leadership contests. + */ +public interface LeadershipService + extends ListenerService<LeadershipEvent, LeadershipEventListener> { + + /** + * Returns the current leader for the topic. + * + * @param path topic + * @return nodeId of the leader, null if so such topic exists. + */ + NodeId getLeader(String path); + + /** + * Returns the current leadership info for the topic. + * + * @param path topic + * @return leadership info or null if so such topic exists. + */ + Leadership getLeadership(String path); + + /** + * Returns the set of topics owned by the specified node. + * + * @param nodeId node Id. + * @return set of topics for which this node is the current leader. + */ + Set<String> ownedTopics(NodeId nodeId); + + /** + * Joins the leadership contest. + * + * @param path topic for which this controller node wishes to be a leader + * @return {@code Leadership} future + */ + CompletableFuture<Leadership> runForLeadership(String path); + + /** + * Withdraws from a leadership contest. + * + * @param path topic for which this controller node no longer wishes to be a leader + * @return future that is successfully completed when withdraw is done + */ + CompletableFuture<Void> withdraw(String path); + + /** + * If the local nodeId is the leader for specified topic, this method causes it to + * step down temporarily from leadership. + * <p> + * The node will continue to be in contention for leadership and can + * potentially become the leader again if and when it becomes the highest + * priority candidate + * <p> + * If the local nodeId is not the leader, this method will make no changes and + * simply return false. + * + * @param path topic for which this controller node should give up leadership + * @return true if this node stepped down from leadership, false otherwise + */ + boolean stepdown(String path); + + /** + * Moves the specified nodeId to the top of the candidates list for the topic. + * <p> + * If the node is not a candidate for this topic, this method will be a noop. + * + * @param path leadership topic + * @param nodeId nodeId to make the top candidate + * @return true if nodeId is now the top candidate, false otherwise + */ + boolean makeTopCandidate(String path, NodeId nodeId); + + /** + * Returns the current leader board. + * + * @return mapping from topic to leadership info. + */ + Map<String, Leadership> getLeaderBoard(); + + /** + * Returns the candidates for all known topics. + * + * @return A mapping from topics to corresponding list of candidates. + */ + Map<String, List<NodeId>> getCandidates(); + + /** + * Returns the candidates for a given topic. + * + * @param path topic + * @return A lists of NodeIds, which may be empty. + */ + List<NodeId> getCandidates(String path); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java new file mode 100644 index 00000000..68b490f2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014 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.cluster; + +import java.util.Objects; + +/** + * Controller cluster identity. + */ +public class NodeId { + + private final String id; + + /** + * Creates a new cluster node identifier from the specified string. + * + * @param id string identifier + */ + public NodeId(String id) { + this.id = id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof NodeId) { + final NodeId other = (NodeId) obj; + return Objects.equals(this.id, other.id); + } + return false; + } + + @Override + public String toString() { + return id; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/RoleInfo.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/RoleInfo.java new file mode 100644 index 00000000..081a6ba2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/RoleInfo.java @@ -0,0 +1,80 @@ +/* + * Copyright 2014-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.cluster; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; + +/** + * An immutable container for role information for a device, + * within the current cluster. Role attributes include current + * master and a preference-ordered list of backup nodes. + */ +public class RoleInfo { + private final Optional<NodeId> master; + private final List<NodeId> backups; + + public RoleInfo(NodeId master, List<NodeId> backups) { + this.master = Optional.ofNullable(master); + this.backups = ImmutableList.copyOf(backups); + } + + public RoleInfo() { + this.master = Optional.empty(); + this.backups = ImmutableList.of(); + } + + // This will return a Optional<NodeId> in the future. + public NodeId master() { + return master.orElseGet(() -> null); + } + + public List<NodeId> backups() { + return backups; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof RoleInfo)) { + return false; + } + RoleInfo that = (RoleInfo) other; + + return Objects.equals(this.master, that.master) + && Objects.equals(this.backups, that.backups); + } + + @Override + public int hashCode() { + return Objects.hash(master, backups); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this.getClass()) + .add("master", master.orElseGet(() -> null)) + .add("backups", backups) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/package-info.java new file mode 100644 index 00000000..d5ae40c2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Set of abstractions for dealing with controller cluster related topics. + */ +package org.onosproject.cluster; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecContext.java new file mode 100644 index 00000000..272c3e90 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecContext.java @@ -0,0 +1,50 @@ +/* + * Copyright 2014 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.codec; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Context for codecs to use while encoding/decoding. + */ +public interface CodecContext { + + /** + * Returns the JSON object mapper. + * + * @return object mapper + */ + ObjectMapper mapper(); + + /** + * Returns the JSON codec for the specified entity class. + * + * @param entityClass entity class + * @param <T> entity type + * @return JSON codec; null if no codec available for the class + */ + <T> JsonCodec<T> codec(Class<T> entityClass); + + /** + * Returns reference to the specified service implementation. + * + * @param serviceClass service class + * @param <T> service type + * @return JSON codec; null if no codec available for the class + */ + <T> T getService(Class<T> serviceClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecService.java new file mode 100644 index 00000000..2705569d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/CodecService.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 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.codec; + +import java.util.Set; + +/** + * Service for registering and retrieving JSON codecs for various entities. + */ +public interface CodecService { + + /** + * Returns the set of classes with currently registered codecs. + * + * @return set of entity classes + */ + Set<Class<?>> getCodecs(); + + /** + * Returns the JSON codec for the specified entity class. + * + * @param entityClass entity class + * @param <T> entity type + * @return JSON codec; null if no codec available for the class + */ + <T> JsonCodec<T> getCodec(Class<T> entityClass); + + /** + * Registers the specified JSON codec for the given entity class. + * + * @param entityClass entity class + * @param codec JSON codec + * @param <T> entity type + */ + <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec); + + /** + * Unregisters the JSON codec for the specified entity class. + * + * @param entityClass entity class + */ + void unregisterCodec(Class<?> entityClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/codec/JsonCodec.java b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/JsonCodec.java new file mode 100644 index 00000000..6df8f117 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/JsonCodec.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014 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.codec; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Abstraction of a codec capable for encoding/decoding arbitrary objects to/from JSON. + */ +public abstract class JsonCodec<T> { + + /** + * Encodes the specified entity into JSON. + * + * @param entity entity to encode + * @param context encoding context + * @return JSON node + * @throws java.lang.UnsupportedOperationException if the codec does not + * support encode operations + */ + public ObjectNode encode(T entity, CodecContext context) { + throw new UnsupportedOperationException("encode() not supported"); + } + + /** + * Decodes the specified entity from JSON. + * + * @param json JSON to decode + * @param context decoding context + * @return decoded entity + * @throws java.lang.UnsupportedOperationException if the codec does not + * support decode operations + */ + public T decode(ObjectNode json, CodecContext context) { + throw new UnsupportedOperationException("decode() not supported"); + } + + /** + * Encodes the collection of the specified entities. + * + * @param entities collection of entities to encode + * @param context encoding context + * @return JSON array + * @throws java.lang.UnsupportedOperationException if the codec does not + * support encode operations + */ + public ArrayNode encode(Iterable<T> entities, CodecContext context) { + ArrayNode result = context.mapper().createArrayNode(); + for (T entity : entities) { + result.add(encode(entity, context)); + } + return result; + } + + /** + * Decodes the specified JSON array into a collection of entities. + * + * @param json JSON array to decode + * @param context decoding context + * @return collection of decoded entities + * @throws java.lang.UnsupportedOperationException if the codec does not + * support decode operations + */ + public List<T> decode(ArrayNode json, CodecContext context) { + List<T> result = new ArrayList<>(); + for (JsonNode node : json) { + result.add(decode((ObjectNode) node, context)); + } + return result; + } + + /** + * Gets a child Object Node from a parent by name. If the child is not found + * or does nor represent an object, null is returned. + * + * @param parent parent object + * @param childName name of child to query + * @return child object if found, null if not found or if not an object + */ + protected static ObjectNode get(ObjectNode parent, String childName) { + JsonNode node = parent.path(childName); + return node.isObject() && !node.isNull() ? (ObjectNode) node : null; + } + + /** + * Gets a child Object Node from a parent by index. If the child is not found + * or does nor represent an object, null is returned. + * + * @param parent parent object + * @param childIndex index of child to query + * @return child object if found, null if not found or if not an object + */ + protected static ObjectNode get(JsonNode parent, int childIndex) { + JsonNode node = parent.path(childIndex); + return node.isObject() && !node.isNull() ? (ObjectNode) node : null; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/codec/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/package-info.java new file mode 100644 index 00000000..0aa063f5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/codec/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Base JSON codec abstraction and a service for tracking various JSON codecs. + */ +package org.onosproject.codec; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java new file mode 100644 index 00000000..fca53843 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java @@ -0,0 +1,87 @@ +/* + * 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.core; + +import org.onosproject.security.Permission; + +import java.net.URI; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +/** + * Abstraction of a network control/management application. + */ +public interface Application { + + /** + * Returns the application name id. + * + * @return application identifier + */ + ApplicationId id(); + + /** + * Returns the application version. + * + * @return application version + */ + Version version(); + + /** + * Returns description of the application. + * + * @return application description text + */ + String description(); + + /** + * Returns the name of the application origin, group or company. + * + * @return application origin + */ + String origin(); + + /** + * Returns the role of the application. + * + * @return application role + */ + ApplicationRole role(); + + /** + * Returns the permissions requested by the application. + * + * @return requested permissions + */ + Set<Permission> permissions(); + + /** + * Returns the feature repository URI. Null value signifies that the + * application did not provide its own features repository. + * + * @return optional feature repo URL + */ + Optional<URI> featuresRepo(); + + /** + * Returns the list of features comprising the application. At least one + * feature must be given. + * + * @return application features + */ + List<String> features(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationId.java new file mode 100644 index 00000000..25bc8ce7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationId.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014 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.core; + + +/** + * Application identifier. + */ +public interface ApplicationId { + + /** + * Returns the application id. + * @return a short value + */ + short id(); + + /** + * Returns the applications supplied identifier. + * @return a string identifier + */ + String name(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationIdStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationIdStore.java new file mode 100644 index 00000000..f857fbdc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationIdStore.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.core; +// FIXME: Move to org.onosproject.app package + +import java.util.Set; + +/** + * Manages application IDs. + */ +public interface ApplicationIdStore { + + /** + * Returns the set of currently registered application identifiers. + * + * @return set of application ids + */ + Set<ApplicationId> getAppIds(); + + /** + * Returns an existing application id from a given id. + * + * @param id the short value of the id + * @return an application id; null if no such app registered + */ + ApplicationId getAppId(Short id); + + /** + * Returns registered application id from the given name. + * + * @param name application name + * @return an application id; null if no such app registered + */ + ApplicationId getAppId(String name); + + /** + * Registers a new application by its name, which is expected + * to follow the reverse DNS convention, e.g. + * {@code org.flying.circus.app} + * + * @param identifier string identifier + * @return the application id + */ + ApplicationId registerApplication(String identifier); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationRole.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationRole.java new file mode 100644 index 00000000..5fcb80ba --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/ApplicationRole.java @@ -0,0 +1,38 @@ +/* + * 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.core; + +public enum ApplicationRole { + /** + * Indicates that an application has an ADMIN role. + */ + ADMIN, + + /** + * Indicates that an application has a USER role. + */ + USER, + + /** + * Indicates that an application role has not been specified. + */ + UNSPECIFIED, + + /** + * More useful roles may be defined. + */ +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java new file mode 100644 index 00000000..3dfc6b26 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014-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.core; + +import org.onosproject.net.provider.ProviderId; + +import java.util.Set; + +/** + * Service for interacting with the core system of the controller. + */ +public interface CoreService { + + /** + * Name of the core "application". + */ + static final String CORE_APP_NAME = "org.onosproject.core"; + + /** + * Identifier of the core "provider". + */ + static final ProviderId CORE_PROVIDER_ID = new ProviderId("core", CORE_APP_NAME); + + /** + * Returns the product version. + * + * @return product version + */ + Version version(); + + /** + * Returns the set of currently registered application identifiers. + * + * @return set of application ids + */ + Set<ApplicationId> getAppIds(); + + /** + * Returns an existing application id from a given id. + * @param id the short value of the id + * @return an application id + */ + ApplicationId getAppId(Short id); + + /** + * Returns an existing application id from a given id. + * @param name the name portion of the ID to look up + * @return an application id + */ + ApplicationId getAppId(String name); + + /** + * Registers a new application by its name, which is expected + * to follow the reverse DNS convention, e.g. + * {@code org.flying.circus.app} + * + * @param identifier string identifier + * @return the application id + */ + ApplicationId registerApplication(String identifier); + + /** + * Returns an id generator for a given topic. + * + * @param topic topic identified + * @return the id generator + */ + IdGenerator getIdGenerator(String topic); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java new file mode 100644 index 00000000..d8062ddf --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java @@ -0,0 +1,149 @@ +/* + * 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.core; + +import org.onosproject.security.Permission; + +import java.net.URI; +import java.util.Set; +import java.util.Optional; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of network control/management application descriptor. + */ +public class DefaultApplication implements Application { + + private final ApplicationId appId; + private final Version version; + private final String description; + private final String origin; + private final ApplicationRole role; + private final Set<Permission> permissions; + private final Optional<URI> featuresRepo; + private final List<String> features; + + /** + * Creates a new application descriptor using the supplied data. + * + * @param appId application identifier + * @param version application version + * @param description application description + * @param origin origin company + * @param role application role + * @param permissions requested permissions + * @param featuresRepo optional features repo URI + * @param features application features + */ + public DefaultApplication(ApplicationId appId, Version version, + String description, String origin, + ApplicationRole role, Set<Permission> permissions, + Optional<URI> featuresRepo, List<String> features) { + this.appId = checkNotNull(appId, "ID cannot be null"); + this.version = checkNotNull(version, "Version cannot be null"); + this.description = checkNotNull(description, "Description cannot be null"); + this.origin = checkNotNull(origin, "Origin cannot be null"); + this.role = checkNotNull(role, "Role cannot be null"); + this.permissions = checkNotNull(permissions, "Permissions cannot be null"); + this.featuresRepo = checkNotNull(featuresRepo, "Features repo cannot be null"); + this.features = checkNotNull(features, "Features cannot be null"); + checkArgument(!features.isEmpty(), "There must be at least one feature"); + } + + @Override + public ApplicationId id() { + return appId; + } + + @Override + public Version version() { + return version; + } + + @Override + public String description() { + return description; + } + + @Override + public String origin() { + return origin; + } + + @Override + public ApplicationRole role() { + return role; + } + + @Override + public Set<Permission> permissions() { + return permissions; + } + + @Override + public Optional<URI> featuresRepo() { + return featuresRepo; + } + + @Override + public List<String> features() { + return features; + } + + @Override + public int hashCode() { + return Objects.hash(appId, version, description, origin, role, permissions, + featuresRepo, features); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final DefaultApplication other = (DefaultApplication) obj; + return Objects.equals(this.appId, other.appId) && + Objects.equals(this.version, other.version) && + Objects.equals(this.description, other.description) && + Objects.equals(this.origin, other.origin) && + Objects.equals(this.role, other.role) && + Objects.equals(this.permissions, other.permissions) && + Objects.equals(this.featuresRepo, other.featuresRepo) && + Objects.equals(this.features, other.features); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("appId", appId) + .add("version", version) + .add("description", description) + .add("origin", origin) + .add("role", role) + .add("permissions", permissions) + .add("featuresRepo", featuresRepo) + .add("features", features) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java new file mode 100644 index 00000000..c7b5b2da --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java @@ -0,0 +1,81 @@ +/* + * Copyright 2014-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.core; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Application identifier. + */ +public class DefaultApplicationId implements ApplicationId { + + private final short id; + private final String name; + + /** + * Creates a new application ID. + * + * @param id application identifier + * @param name application name + */ + public DefaultApplicationId(int id, String name) { + checkArgument(0 <= id && id <= Short.MAX_VALUE, "id is outside range"); + this.id = (short) id; + this.name = name; + } + + // Constructor for serializers. + private DefaultApplicationId() { + this.id = 0; + this.name = null; + } + + @Override + public short id() { + return id; + } + + @Override + public String name() { + return name; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultApplicationId) { + DefaultApplicationId other = (DefaultApplicationId) obj; + return Objects.equals(this.id, other.id); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("id", id).add("name", name).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java new file mode 100644 index 00000000..9fa8d2b6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java @@ -0,0 +1,66 @@ +/* + * Copyright 2014-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.core; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Default implementation of {@link GroupId}. + */ +public class DefaultGroupId implements GroupId { + + private final int id; + + public DefaultGroupId(int id) { + this.id = id; + } + + // Constructor for serialization + private DefaultGroupId() { + this.id = 0; + } + + @Override + public int id() { + return this.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DefaultGroupId)) { + return false; + } + final DefaultGroupId other = (DefaultGroupId) obj; + return Objects.equals(this.id, other.id); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/GroupId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/GroupId.java new file mode 100644 index 00000000..739fc7ff --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/GroupId.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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.core; + +/** + * Group identifier. + */ +public interface GroupId { + + /** + * Returns a group ID as an integer value. + * The method is not intended for use by application developers. + * Return data type may change in the future release. + * + * @return a group ID as integer value + */ + int id(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlock.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlock.java new file mode 100644 index 00000000..f4088603 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlock.java @@ -0,0 +1,102 @@ +/* + * Copyright 2014 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.core; + +import com.google.common.base.MoreObjects; + +import java.util.concurrent.atomic.AtomicLong; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * A class representing an ID space. + */ +public final class IdBlock { + private final long start; + private final long size; + + private final AtomicLong currentId; + + /** + * Constructs a new ID block with the specified size and initial value. + * + * @param start initial value of the block + * @param size size of the block + * @throws IllegalArgumentException if the size is less than or equal to 0 + */ + public IdBlock(long start, long size) { + checkArgument(size > 0, "size should be more than 0, but %s", size); + + this.start = start; + this.size = size; + + this.currentId = new AtomicLong(start); + } + + /** + * Returns the initial value. + * + * @return initial value + */ + private long getStart() { + return start; + } + + /** + * Returns the last value. + * + * @return last value + */ + private long getEnd() { + return start + size - 1; + } + + /** + * Returns the block size. + * + * @return block size + */ + public long getSize() { + return size; + } + + /** + * Returns the next ID in the block. + * + * @return next ID + * @throws UnavailableIdException if there is no available ID in the block. + */ + public long getNextId() { + final long id = currentId.getAndIncrement(); + if (id > getEnd()) { + throw new UnavailableIdException(String.format( + "used all IDs in allocated space (size: %d, end: %d, current: %d)", + size, getEnd(), id + )); + } + + return id; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("start", start) + .add("size", size) + .add("currentId", currentId) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlockStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlockStore.java new file mode 100644 index 00000000..8ed58ae7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdBlockStore.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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.core; + +/** + * Manages id blocks. + */ +public interface IdBlockStore { + + /** + * Returns a topic-unique block of ids. + * + * @param topic topic name + * @return id block + */ + IdBlock getIdBlock(String topic); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdGenerator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdGenerator.java new file mode 100644 index 00000000..149c834b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/IdGenerator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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.core; + +/** + * A generalized interface for ID generation + * + * {@link #getNewId()} generates a globally unique ID instance on + * each invocation. + */ +public interface IdGenerator { + /** + * Returns a globally unique ID instance. + * + * @return globally unique ID instance + */ + long getNewId(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/MetricsHelper.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/MetricsHelper.java new file mode 100644 index 00000000..b5be0944 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/MetricsHelper.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014 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.core; + +import org.onlab.metrics.MetricsComponent; +import org.onlab.metrics.MetricsFeature; +import org.onlab.metrics.MetricsService; + +import com.codahale.metrics.Timer; + +/** + * Collection of utility methods used for providing Metrics. + */ +public interface MetricsHelper { + + /** + * Returns MetricService instance. + * + * @return MetricService instance + */ + abstract MetricsService metricsService(); + + + /** + * Creates a Timer instance with given name. + * + * @param component component name + * @param feature feature name + * @param name timer name + * @return Timer instance + */ + default Timer createTimer(String component, String feature, String name) { + final MetricsService metricsService = metricsService(); + if (metricsService != null) { + MetricsComponent c = metricsService.registerComponent(component); + MetricsFeature f = c.registerFeature(feature); + return metricsService.createTimer(c, f, name); + } + return null; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/UnavailableIdException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/UnavailableIdException.java new file mode 100644 index 00000000..2e4af264 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/UnavailableIdException.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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.core; + +/** + * Represents that there is no available IDs. + */ +public class UnavailableIdException extends RuntimeException { + + private static final long serialVersionUID = -2287403908433720122L; + + /** + * Constructs an exception with no message and no underlying cause. + */ + public UnavailableIdException() { + } + + /** + * Constructs an exception with the specified message. + * + * @param message the message describing the specific nature of the error + */ + public UnavailableIdException(String message) { + super(message); + } + + /** + * Constructs an exception with the specified message and the underlying cause. + * + * @param message the message describing the specific nature of the error + * @param cause the underlying cause of this error + */ + public UnavailableIdException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java new file mode 100644 index 00000000..a5377016 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java @@ -0,0 +1,144 @@ +/* + * Copyright 2014-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.core; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Strings.isNullOrEmpty; +import static java.lang.Integer.parseInt; + +/** + * Representation of the product version. + */ +public final class Version { + + public static final String FORMAT_MINIMAL = "%d.%d"; + public static final String FORMAT_SHORT = "%d.%d.%s"; + public static final String FORMAT_LONG = "%d.%d.%s.%s"; + + private static final String NEGATIVE = "Version segment cannot be negative"; + public static final String TOO_SHORT = "Version must have at least major and minor numbers"; + + private final int major; + private final int minor; + private final String patch; + private final String build; + + private final String format; + + // Creates a new version descriptor + private Version(int major, int minor, String patch, String build) { + this.major = major; + this.minor = minor; + this.patch = patch; + this.build = build; + this.format = + isNullOrEmpty(patch) ? + String.format(FORMAT_MINIMAL, major, minor) : + (isNullOrEmpty(build) ? + String.format(FORMAT_SHORT, major, minor, patch) : + String.format(FORMAT_LONG, major, minor, patch, build)); + } + + + /** + * Creates a new version from the specified constituent numbers. + * + * @param major major version number + * @param minor minor version number + * @param patch version patch segment + * @param build optional build string + * @return version descriptor + */ + public static Version version(int major, int minor, String patch, String build) { + checkArgument(major >= 0, NEGATIVE); + checkArgument(minor >= 0, NEGATIVE); + return new Version(major, minor, patch, build); + } + + /** + * Creates a new version by parsing the specified string. + * + * @param string version string + * @return version descriptor + */ + public static Version version(String string) { + String[] fields = string.split("[.-]"); + checkArgument(fields.length >= 2, TOO_SHORT); + return new Version(parseInt(fields[0]), parseInt(fields[1]), + fields.length >= 3 ? fields[2] : null, + fields.length >= 4 ? fields[3] : null); + } + + /** + * Returns the major version number. + * + * @return major version number + */ + public int major() { + return major; + } + + /** + * Returns the minor version number. + * + * @return minor version number + */ + public int minor() { + return minor; + } + + /** + * Returns the version patch segment. + * + * @return patch number + */ + public String patch() { + return patch; + } + + /** + * Returns the version build string. + * + * @return build string + */ + public String build() { + return build; + } + + @Override + public String toString() { + return format; + } + + @Override + public int hashCode() { + return Objects.hash(format); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Version) { + final Version other = (Version) obj; + return Objects.equals(this.format, other.format); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/package-info.java new file mode 100644 index 00000000..3766d49f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * ONOS Core API definitions. + */ +package org.onosproject.core; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractEvent.java new file mode 100644 index 00000000..67b10292 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractEvent.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-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.event; + +import org.joda.time.LocalDateTime; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Base event implementation. + */ +public class AbstractEvent<T extends Enum, S> implements Event<T, S> { + + private final long time; + private final T type; + private final S subject; + + /** + * Creates an event of a given type and for the specified subject and the + * current time. + * + * @param type event type + * @param subject event subject + */ + protected AbstractEvent(T type, S subject) { + this(type, subject, System.currentTimeMillis()); + } + + /** + * Creates an event of a given type and for the specified subject and time. + * + * @param type event type + * @param subject event subject + * @param time occurrence time + */ + protected AbstractEvent(T type, S subject, long time) { + this.type = type; + this.subject = subject; + this.time = time; + } + + @Override + public long time() { + return time; + } + + @Override + public T type() { + return type; + } + + @Override + public S subject() { + return subject; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("time", new LocalDateTime(time)) + .add("type", type()) + .add("subject", subject()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractListenerManager.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractListenerManager.java new file mode 100644 index 00000000..cbe7421f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/AbstractListenerManager.java @@ -0,0 +1,58 @@ +/* + * 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.event; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; + +/** + * Basis for components which need to export listener mechanism. + */ +@Component(componentAbstract = true) +public abstract class AbstractListenerManager<E extends Event, L extends EventListener<E>> + implements ListenerService<E, L> { + + protected final ListenerRegistry<E, L> listenerRegistry = new ListenerRegistry<>(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected EventDeliveryService eventDispatcher; + + @Override + public void addListener(L listener) { + listenerRegistry.addListener(listener); + } + + @Override + public void removeListener(L listener) { + listenerRegistry.removeListener(listener); + } + + + /** + * Safely posts the specified event to the local event dispatcher. + * If there is no event dispatcher or if the event is null, this method + * is a noop. + * + * @param event event to be posted; may be null + */ + protected void post(E event) { + if (event != null && eventDispatcher != null) { + eventDispatcher.post(event); + } + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/DefaultEventSinkRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/DefaultEventSinkRegistry.java new file mode 100644 index 00000000..be6ddb61 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/DefaultEventSinkRegistry.java @@ -0,0 +1,62 @@ +/* + * Copyright 2014 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.event; + +import com.google.common.collect.ImmutableSet; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Base implementation of event sink registry. + */ +public class DefaultEventSinkRegistry implements EventSinkRegistry { + + private final Map<Class<? extends Event>, EventSink<? extends Event>> + sinks = new ConcurrentHashMap<>(); + + @Override + public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) { + checkNotNull(eventClass, "Event class cannot be null"); + checkNotNull(sink, "Event sink cannot be null"); + checkArgument(!sinks.containsKey(eventClass), + "Event sink already registered for %s", eventClass.getName()); + sinks.put(eventClass, sink); + } + + @Override + public <E extends Event> void removeSink(Class<E> eventClass) { + checkNotNull(eventClass, "Event class cannot be null"); + checkArgument(sinks.remove(eventClass) != null, + "Event sink not registered for %s", eventClass.getName()); + } + + @Override + @SuppressWarnings("unchecked") + public <E extends Event> EventSink<E> getSink(Class<E> eventClass) { + checkNotNull(eventClass, "Event class cannot be null"); + return (EventSink<E>) sinks.get(eventClass); + } + + @Override + public Set<Class<? extends Event>> getSinks() { + return ImmutableSet.copyOf(sinks.keySet()); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/Event.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/Event.java new file mode 100644 index 00000000..e7cbb60f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/Event.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014-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.event; + +/** + * Abstraction of an of a time-stamped event pertaining to an arbitrary subject. + */ +public interface Event<T extends Enum, S> { + + /** + * Returns the timestamp of when the event occurred, given in milliseconds + * since the start of epoch. + * + * @return timestamp in milliseconds + */ + long time(); + + /** + * Returns the type of the event. + * + * @return event type + */ + T type(); + + /** + * Returns the subject of the event. + * + * @return subject to which this event pertains + */ + S subject(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDeliveryService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDeliveryService.java new file mode 100644 index 00000000..ff268935 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDeliveryService.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014 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.event; + +/** + * Abstraction of an entity capable of accepting events to be posted and + * then dispatching them to the appropriate event sink. + */ +public interface EventDeliveryService extends EventDispatcher, EventSinkRegistry { + + /** + * Sets the number of millis that an event sink has to process an event. + * + * @param millis number of millis allowed per sink per event + */ + void setDispatchTimeLimit(long millis); + + /** + * Returns the number of millis that an event sink has to process an event. + * + * @return number of millis allowed per sink per event + */ + long getDispatchTimeLimit(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDispatcher.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDispatcher.java new file mode 100644 index 00000000..daebd8b0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventDispatcher.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.event; + +/** + * Abstraction of a mechanism capable of accepting and dispatching events to + * appropriate event sinks. Where the event sinks are obtained is unspecified. + * Similarly, whether the events are accepted and dispatched synchronously + * or asynchronously is unspecified as well. + */ +public interface EventDispatcher { + + /** + * Posts the specified event for dispatching. + * + * @param event event to be posted + */ + void post(Event event); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventFilter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventFilter.java new file mode 100644 index 00000000..3b2498f6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventFilter.java @@ -0,0 +1,34 @@ +/* + * 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.event; + +/** + * Entity capable of filtering events. + */ +public interface EventFilter<E extends Event> { + + /** + * Indicates whether the specified event is of interest or not. + * Default implementation always returns true. + * + * @param event event to be inspected + * @return true if event is relevant; false otherwise + */ + default boolean isRelevant(E event) { + return true; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventListener.java new file mode 100644 index 00000000..e77369fc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventListener.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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.event; + +/** + * Entity capable of receiving events. + */ +public interface EventListener<E extends Event> extends EventFilter<E> { + + /** + * Reacts to the specified event. + * + * @param event event to be processed + */ + void event(E event); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSink.java new file mode 100644 index 00000000..221b3224 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSink.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014 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.event; + +/** + * Abstraction of an event sink capable of processing the specified event types. + */ +public interface EventSink<E extends Event> { + + /** + * Processes the specified event. + * + * @param event event to be processed + */ + void process(E event); + + /** + * Handles notification that event processing time limit has been exceeded. + */ + default void onProcessLimit() { + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSinkRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSinkRegistry.java new file mode 100644 index 00000000..bb054a30 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/EventSinkRegistry.java @@ -0,0 +1,60 @@ +/* + * Copyright 2014 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.event; + +import java.util.Set; + +/** + * Abstraction of an event sink registry capable of tracking sinks based on + * their event class. + */ +public interface EventSinkRegistry { + + /** + * Adds the specified sink for the given event class. + * + * @param eventClass event class + * @param sink event sink + * @param <E> type of event + */ + <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink); + + /** + * Removes the sink associated with the given event class. + * + * @param eventClass event class + * @param <E> type of event + */ + <E extends Event> void removeSink(Class<E> eventClass); + + /** + * Returns the event sink associated with the specified event class. + * + * @param eventClass event class + * @param <E> type of event + * @return event sink or null if none found + */ + <E extends Event> EventSink<E> getSink(Class<E> eventClass); + + /** + * Returns the set of all event classes for which sinks are presently + * registered. + * + * @return set of event classes + */ + Set<Class<? extends Event>> getSinks(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerRegistry.java new file mode 100644 index 00000000..ef02af06 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerRegistry.java @@ -0,0 +1,99 @@ +/* + * Copyright 2014 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.event; + +import org.slf4j.Logger; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Base implementation of an event sink and a registry capable of tracking + * listeners and dispatching events to them as part of event sink processing. + */ +public class ListenerRegistry<E extends Event, L extends EventListener<E>> + implements ListenerService<E, L>, EventSink<E> { + + private static final long LIMIT = 1_800; // ms + + private final Logger log = getLogger(getClass()); + + private long lastStart; + private L lastListener; + + /** + * Set of listeners that have registered. + */ + protected final Set<L> listeners = new CopyOnWriteArraySet<>(); + + @Override + public void addListener(L listener) { + checkNotNull(listener, "Listener cannot be null"); + listeners.add(listener); + } + + @Override + public void removeListener(L listener) { + checkNotNull(listener, "Listener cannot be null"); + if (!listeners.remove(listener)) { + log.warn("Listener {} not registered", listener); + } + } + + @Override + public void process(E event) { + for (L listener : listeners) { + try { + lastListener = listener; + lastStart = System.currentTimeMillis(); + if (listener.isRelevant(event)) { + listener.event(event); + } + lastStart = 0; + } catch (Exception error) { + reportProblem(event, error); + } + } + } + + @Override + public void onProcessLimit() { + if (lastStart > 0) { + long duration = System.currentTimeMillis() - lastStart; + if (duration > LIMIT) { + log.error("Listener {} exceeded execution time limit: {} ms; ejected", + lastListener.getClass().getName(), + duration); + removeListener(lastListener); + } + lastStart = 0; + } + } + + /** + * Reports a problem encountered while processing an event. + * + * @param event event being processed + * @param error error encountered while processing + */ + protected void reportProblem(E event, Throwable error) { + log.warn("Exception encountered while processing event " + event, error); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerService.java new file mode 100644 index 00000000..a4a36319 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/ListenerService.java @@ -0,0 +1,38 @@ +/* + * 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.event; + +/** + * Abstraction of a service capable of asynchronously notifying listeners. + */ +public interface ListenerService<E extends Event, L extends EventListener<E>> { + + /** + * Adds the specified listener. + * + * @param listener listener to be added + */ + void addListener(L listener); + + /** + * Removes the specified listener. + * + * @param listener listener to be removed + */ + void removeListener(L listener); + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/event/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/event/package-info.java new file mode 100644 index 00000000..6b10bcf5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/event/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Local event delivery subsystem interfaces & supporting abstractions. + */ +package org.onosproject.event; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipAdminService.java new file mode 100644 index 00000000..a8835fc7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipAdminService.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014 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.mastership; + +import java.util.concurrent.CompletableFuture; + +import org.onosproject.cluster.NodeId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; + +/** + * Service for administering the inventory of device masterships. + */ +public interface MastershipAdminService { + + /** + * Applies the current mastership role for the specified device. + * + * @param instance controller instance identifier + * @param deviceId device identifier + * @param role requested role + * @return future that is completed when the role is set + */ + CompletableFuture<Void> setRole(NodeId instance, DeviceId deviceId, MastershipRole role); + + /** + * Balances the mastership to be shared as evenly as possibly by all + * online instances. + */ + void balanceRoles(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipEvent.java new file mode 100644 index 00000000..35c32e79 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipEvent.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 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.mastership; + +import org.joda.time.LocalDateTime; +import org.onosproject.cluster.RoleInfo; +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.DeviceId; + +import com.google.common.base.MoreObjects; + +/** + * Describes a device mastership event. + */ +public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceId> { + + //Contains master and standby information. + RoleInfo roleInfo; + + /** + * Type of mastership events. + */ + public enum Type { + /** + * Signifies that the master for a device has changed. + */ + MASTER_CHANGED, + + /** + * Signifies that the list of backup nodes has changed. If + * the change in the backups list is accompanied by a change in + * master, the event is subsumed by MASTER_CHANGED. + */ + BACKUPS_CHANGED + } + + /** + * Creates an event of a given type and for the specified device, + * role information, and the current time. + * + * @param type mastership event type + * @param device event device subject + * @param info mastership role information + */ + public MastershipEvent(Type type, DeviceId device, RoleInfo info) { + super(type, device); + this.roleInfo = info; + } + + /** + * Creates an event of a given type and for the specified device, master, + * and time. + * + * @param type mastership event type + * @param device event device subject + * @param info role information + * @param time occurrence time + */ + public MastershipEvent(Type type, DeviceId device, RoleInfo info, long time) { + super(type, device, time); + this.roleInfo = info; + } + + /** + * Returns the current role state for the subject. + * + * @return RoleInfo associated with Device ID subject + */ + public RoleInfo roleInfo() { + return roleInfo; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("time", new LocalDateTime(time())) + .add("type", type()) + .add("subject", subject()) + .add("roleInfo", roleInfo) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipListener.java new file mode 100644 index 00000000..9c5690e2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.mastership; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving device mastership-related events. + */ +public interface MastershipListener extends EventListener<MastershipEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipService.java new file mode 100644 index 00000000..a709f5cf --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipService.java @@ -0,0 +1,101 @@ +/* + * Copyright 2014 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.mastership; + +import static org.onosproject.net.MastershipRole.MASTER; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +import org.onosproject.cluster.NodeId; +import org.onosproject.cluster.RoleInfo; +import org.onosproject.event.ListenerService; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; + +/** + * Service responsible for determining the controller instance mastership of + * a device in a clustered environment. This is the central authority for + * determining mastership, but is not responsible for actually applying it + * to the devices; this falls on the device service. + */ +public interface MastershipService + extends ListenerService<MastershipEvent, MastershipListener> { + + /** + * Returns the role of the local node for the specified device, without + * triggering master selection. + * + * @param deviceId the the identifier of the device + * @return role of the current node + */ + MastershipRole getLocalRole(DeviceId deviceId); + + /** + * Returns true if the local controller is the Master for the specified deviceId. + * + * @param deviceId the the identifier of the device + * @return true if local node is master; false otherwise + */ + default boolean isLocalMaster(DeviceId deviceId) { + return getLocalRole(deviceId) == MASTER; + } + + /** + * Returns the mastership status of the local controller for a given + * device forcing master selection if necessary. + * + * @param deviceId the the identifier of the device + * @return the role of this controller instance + */ + CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId); + + /** + * Abandons mastership of the specified device on the local node thus + * forcing selection of a new master. If the local node is not a master + * for this device, no master selection will occur. + * + * @param deviceId the identifier of the device + * @return future that is completed when relinquish is complete + */ + CompletableFuture<Void> relinquishMastership(DeviceId deviceId); + + /** + * Returns the current master for a given device. + * + * @param deviceId the identifier of the device + * @return the ID of the master controller for the device + */ + NodeId getMasterFor(DeviceId deviceId); + + /** + * Returns controllers connected to a given device, in order of + * preference. The first entry in the list is the current master. + * + * @param deviceId the identifier of the device + * @return a list of controller IDs + */ + RoleInfo getNodesFor(DeviceId deviceId); + + /** + * Returns the devices for which a controller is master. + * + * @param nodeId the ID of the controller + * @return a set of device IDs + */ + Set<DeviceId> getDevicesOf(NodeId nodeId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStore.java new file mode 100644 index 00000000..81c2d8b6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStore.java @@ -0,0 +1,125 @@ +/* + * Copyright 2014-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.mastership; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +import org.onosproject.cluster.NodeId; +import org.onosproject.cluster.RoleInfo; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.store.Store; + +/** + * Manages inventory of mastership roles for devices, across controller + * instances; not intended for direct use. + */ +public interface MastershipStore extends Store<MastershipEvent, MastershipStoreDelegate> { + + // three things to map: NodeId, DeviceId, MastershipRole + + /** + * Requests role of the local node for the specified device. + * + * @param deviceId device identifier + * @return established or newly negotiated mastership role + */ + CompletableFuture<MastershipRole> requestRole(DeviceId deviceId); + + /** + * Returns the role of a device for a specific controller instance. + * + * @param nodeId the instance identifier + * @param deviceId the device identifiers + * @return the role + */ + MastershipRole getRole(NodeId nodeId, DeviceId deviceId); + + /** + * Returns the master for a device. + * + * @param deviceId the device identifier + * @return the instance identifier of the master + */ + NodeId getMaster(DeviceId deviceId); + + /** + * Returns the master and backup nodes for a device. + * + * @param deviceId the device identifier + * @return a RoleInfo containing controller IDs + */ + RoleInfo getNodes(DeviceId deviceId); + + /** + * Returns the devices that a controller instance is master of. + * + * @param nodeId the instance identifier + * @return a set of device identifiers + */ + Set<DeviceId> getDevices(NodeId nodeId); + + + /** + * Sets a device's role for a specified controller instance. + * + * @param nodeId controller instance identifier + * @param deviceId device identifier + * @return a mastership event + */ + CompletableFuture<MastershipEvent> setMaster(NodeId nodeId, DeviceId deviceId); + + /** + * Returns the current master and number of past mastership hand-offs + * (terms) for a device. + * + * @param deviceId the device identifier + * @return the current master's ID and the term value for device, or null + */ + MastershipTerm getTermFor(DeviceId deviceId); + + /** + * Sets a controller instance's mastership role to STANDBY for a device. + * If the role is MASTER, another controller instance will be selected + * as a candidate master. + * + * @param nodeId the controller instance identifier + * @param deviceId device to revoke mastership role for + * @return a mastership event + */ + CompletableFuture<MastershipEvent> setStandby(NodeId nodeId, DeviceId deviceId); + + /** + * Allows a controller instance to give up its current role for a device. + * If the role is MASTER, another controller instance will be selected + * as a candidate master. + * + * @param nodeId the controller instance identifier + * @param deviceId device to revoke mastership role for + * @return a mastership event + */ + CompletableFuture<MastershipEvent> relinquishRole(NodeId nodeId, DeviceId deviceId); + + /** + * Removes all the roles for the specified controller instance. + * If the role was MASTER, another controller instance will be selected + * as a candidate master. + * + * @param nodeId the controller instance identifier + */ + void relinquishAllRole(NodeId nodeId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStoreDelegate.java new file mode 100644 index 00000000..c71f4ed0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.mastership; + +import org.onosproject.store.StoreDelegate; + +/** + * Mastership store delegate abstraction. + */ +public interface MastershipStoreDelegate extends StoreDelegate<MastershipEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTerm.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTerm.java new file mode 100644 index 00000000..049d1d2b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTerm.java @@ -0,0 +1,71 @@ +/* + * Copyright 2014-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.mastership; + +import java.util.Objects; + +import org.onosproject.cluster.NodeId; + +import com.google.common.base.MoreObjects; + +public final class MastershipTerm { + + private final NodeId master; + private final long termNumber; + + private MastershipTerm(NodeId master, long term) { + this.master = master; + this.termNumber = term; + } + + public static MastershipTerm of(NodeId master, long term) { + return new MastershipTerm(master, term); + } + + public NodeId master() { + return master; + } + + public long termNumber() { + return termNumber; + } + + @Override + public int hashCode() { + return Objects.hash(master, termNumber); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other instanceof MastershipTerm) { + MastershipTerm that = (MastershipTerm) other; + return Objects.equals(this.master, that.master) && + Objects.equals(this.termNumber, that.termNumber); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("master", this.master) + .add("termNumber", this.termNumber) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTermService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTermService.java new file mode 100644 index 00000000..1725ee03 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/MastershipTermService.java @@ -0,0 +1,35 @@ +/* + * Copyright 2014 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.mastership; + +import org.onosproject.net.DeviceId; + +// TODO give me a better name +/** + * Service to obtain mastership term information. + */ +public interface MastershipTermService { + + // TBD: manage/increment per device mastership change + // or increment on any change + /** + * Returns the term number of mastership change occurred for given device. + * + * @param deviceId the identifier of the device + * @return current master's term. + */ + MastershipTerm getMastershipTerm(DeviceId deviceId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/package-info.java new file mode 100644 index 00000000..0040680a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/mastership/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Set of abstractions for dealing with controller mastership related topics. + */ +package org.onosproject.mastership; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractAnnotated.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractAnnotated.java new file mode 100644 index 00000000..e0407e27 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractAnnotated.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014-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; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.onosproject.net.DefaultAnnotations.EMPTY; + +/** + * Base abstraction of an annotated entity. + */ +public abstract class AbstractAnnotated implements Annotated { + + private final Annotations annotations; + + // For serialization + protected AbstractAnnotated() { + this.annotations = null; + } + + /** + * Creates a new entity, annotated with the specified annotations. + * + * @param annotations optional key/value annotations map + */ + protected AbstractAnnotated(Annotations... annotations) { + checkArgument(annotations.length <= 1, "Only one set of annotations is expected"); + this.annotations = annotations.length == 1 ? annotations[0] : EMPTY; + } + + @Override + public Annotations annotations() { + return annotations; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java new file mode 100644 index 00000000..d81b83cc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Base implementation of an annotated model description. + */ +public abstract class AbstractDescription implements Annotated { + + private static final SparseAnnotations EMPTY = DefaultAnnotations.builder().build(); + + private final SparseAnnotations annotations; + + // For serialization + protected AbstractDescription() { + this.annotations = null; + } + + /** + * Creates a new entity, annotated with the specified annotations. + * + * @param annotations optional key/value annotations map + */ + protected AbstractDescription(SparseAnnotations... annotations) { + checkArgument(annotations.length <= 1, "Only one set of annotations is expected"); + this.annotations = annotations.length == 1 ? annotations[0] : EMPTY; + } + + @Override + public SparseAnnotations annotations() { + return annotations; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractElement.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractElement.java new file mode 100644 index 00000000..595e7b9c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractElement.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; + +/** + * Base implementation of network elements, i.e. devices or hosts. + */ +public abstract class AbstractElement extends AbstractModel implements Element { + + protected final ElementId id; + + // For serialization + public AbstractElement() { + id = null; + } + + /** + * Creates a network element attributed to the specified provider. + * + * @param providerId identity of the provider + * @param id element identifier + * @param annotations optional key/value annotations + */ + protected AbstractElement(ProviderId providerId, ElementId id, + Annotations... annotations) { + super(providerId, annotations); + this.id = id; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractModel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractModel.java new file mode 100644 index 00000000..f3cd5efe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractModel.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; + +/** + * Base implementation of a network model entity. + */ +public abstract class AbstractModel extends AbstractAnnotated implements Provided { + + private final ProviderId providerId; + + // For serialization + public AbstractModel() { + providerId = null; + } + + /** + * Creates a model entity attributed to the specified provider and + * optionally annotated. + * + * @param providerId identity of the provider + * @param annotations optional key/value annotations + */ + protected AbstractModel(ProviderId providerId, Annotations... annotations) { + super(annotations); + this.providerId = providerId; + } + + @Override + public ProviderId providerId() { + return providerId; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotated.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotated.java new file mode 100644 index 00000000..ac4545ac --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotated.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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; + +/** + * Represents an entity that carries arbitrary annotations. + */ +public interface Annotated { + + /** + * Returns the key/value annotations. + * + * @return key/value annotations + */ + Annotations annotations(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java new file mode 100644 index 00000000..4949bc40 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationKeys.java @@ -0,0 +1,145 @@ +/* + * Copyright 2014-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; + +/** + * Collection of keys for annotation. + * <p> + * Number of the annotation keys have been deprecated as the use of annotations + * is being phased out and instead network configuration subsystem is being + * phased-in for majority of model meta-data. + * </p> + */ +public final class AnnotationKeys { + + // Prohibit instantiation + private AnnotationKeys() {} + + /** + * Annotation key for instance name. + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String NAME = "name"; + + /** + * Annotation key for instance type (e.g. host type). + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String TYPE = "type"; + + /** + * Annotation key for latitude (e.g. latitude of device). + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String LATITUDE = "latitude"; + + /** + * Annotation key for longitute (e.g. longitude of device). + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String LONGITUDE = "longitude"; + + /** + * Annotation key for southbound protocol. + */ + public static final String PROTOCOL = "protocol"; + + /** + * Annotation key for the device driver name. + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String DRIVER = "driver"; + + /** + * Annotation key for durable links. + */ + public static final String DURABLE = "durable"; + + /** + * Annotation key for latency. + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String LATENCY = "latency"; + + /** + * Annotation key for bandwidth. + * The value for this key is interpreted as Mbps. + * + * @deprecated since Cardinal + */ + @Deprecated + public static final String BANDWIDTH = "bandwidth"; + + /** + * Annotation key for the number of optical waves. + */ + public static final String OPTICAL_WAVES = "optical.waves"; + + /** + * Annotation key for the port name. + */ + public static final String PORT_NAME = "portName"; + + /** + * Annotation key for the router ID. + */ + public static final String ROUTER_ID = "routerId"; + + public static final String STATIC_LAMBDA = "staticLambda"; + + public static final String STATIC_PORT = "staticPort"; + + /** + * Annotation key for device location. + */ + public static final String RACK_ADDRESS = "rackAddress"; + + /** + * Annotation key for device owner. + */ + public static final String OWNER = "owner"; + + /** + * Returns the value annotated object for the specified annotation key. + * The annotated value is expected to be String that can be parsed as double. + * If parsing fails, the returned value will be 1.0. + * + * @param annotated annotated object whose annotated value is obtained + * @param key key of annotation + * @return double value of annotated object for the specified key + */ + public static double getAnnotatedValue(Annotated annotated, String key) { + double value; + try { + value = Double.parseDouble(annotated.annotations().value(key)); + } catch (NumberFormatException e) { + value = 1.0; + } + return value; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotations.java new file mode 100644 index 00000000..4ed70601 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Annotations.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 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; + +import java.util.Set; + +/** + * Represents an set of simple key/value string annotations. + */ +public interface Annotations { + + /** + * Returns the set of keys for available annotations. + * + * @return annotation keys + */ + Set<String> keys(); + + /** + * Returns the value of the specified annotation. + * + * @param key annotation key + * @return annotation value + */ + String value(String key); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationsUtil.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationsUtil.java new file mode 100644 index 00000000..d43a304d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AnnotationsUtil.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014 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; + +/** + * Utility for processing annotations. + */ +public final class AnnotationsUtil { + + public static boolean isEqual(Annotations lhs, Annotations rhs) { + if (lhs == rhs) { + return true; + } + if (lhs == null || rhs == null) { + return false; + } + + if (!lhs.keys().equals(rhs.keys())) { + return false; + } + + for (String key : lhs.keys()) { + if (!lhs.value(key).equals(rhs.value(key))) { + return false; + } + } + return true; + } + + // not to be instantiated + private AnnotationsUtil() {} +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java new file mode 100644 index 00000000..4da9d6b3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ChannelSpacing.java @@ -0,0 +1,44 @@ +/* + * 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; + +import org.onlab.util.Frequency; + +/** + * Represents interval frequency between two neighboring wavelengths. + */ +public enum ChannelSpacing { + CHL_100GHZ(100), // 100 GHz + CHL_50GHZ(50), // 50 GHz + CHL_25GHZ(25), // 25 GHz + CHL_12P5GHZ(12.5), // 12.5 GHz + CHL_6P25GHZ(6.5); // 6.25 GHz + + private final Frequency frequency; + + /** + * Creates an instance with the specified interval in GHz. + * + * @param value interval of neighboring wavelengths in GHz. + */ + ChannelSpacing(double value) { + this.frequency = Frequency.ofGHz(value); + } + + public Frequency frequency() { + return frequency; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/ConnectPoint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ConnectPoint.java new file mode 100644 index 00000000..0d13f4aa --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ConnectPoint.java @@ -0,0 +1,175 @@ +/* + * Copyright 2014 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; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of a network connection point expressed as a pair of the + * network element identifier and port number. + */ +public class ConnectPoint { + + private final ElementId elementId; + private final PortNumber portNumber; + + /** + * Creates a new connection point. + * + * @param elementId network element identifier + * @param portNumber port number + */ + public ConnectPoint(ElementId elementId, PortNumber portNumber) { + this.elementId = elementId; + this.portNumber = portNumber; + } + + /** + * Returns the network element identifier. + * + * @return element identifier + */ + public ElementId elementId() { + return elementId; + } + + /** + * Returns the identifier of the infrastructure device if the connection + * point belongs to a network element which is indeed an infrastructure + * device. + * + * @return network element identifier as a device identifier + * @throws java.lang.IllegalStateException if connection point is not + * associated with a device + */ + public DeviceId deviceId() { + if (elementId instanceof DeviceId) { + return (DeviceId) elementId; + } + throw new IllegalStateException("Connection point not associated " + + "with an infrastructure device"); + } + + /** + * Returns the identifier of the infrastructure device if the connection + * point belongs to a network element which is indeed an end-station host. + * + * @return network element identifier as a host identifier + * @throws java.lang.IllegalStateException if connection point is not + * associated with a host + */ + public HostId hostId() { + if (elementId instanceof HostId) { + return (HostId) elementId; + } + throw new IllegalStateException("Connection point not associated " + + "with an end-station host"); + } + + /** + * Returns the identifier of the infrastructure device if the connection + * point belongs to a network element which is indeed an ip of pcc + * client identifier. + * + * @return network element identifier as a pcc client identifier + * @throws java.lang.IllegalStateException if connection point is not + * associated with a pcc client + */ + public IpElementId ipElementId() { + if (elementId instanceof IpElementId) { + return (IpElementId) elementId; + } + throw new IllegalStateException("Connection point not associated " + + "with an pcc client"); + } + + /** + * Returns the connection port number. + * + * @return port number + */ + public PortNumber port() { + return portNumber; + } + + /** + * Parse a device connect point from a string. + * The connect point should be in the format "deviceUri/portNumber". + * + * @param string string to parse + * @return a ConnectPoint based on the information in the string. + */ + public static ConnectPoint deviceConnectPoint(String string) { + checkNotNull(string); + String[] splitted = string.split("/"); + checkArgument(splitted.length == 2, + "Connect point must be in \"deviceUri/portNumber\" format"); + + return new ConnectPoint(DeviceId.deviceId(splitted[0]), + PortNumber.portNumber(splitted[1])); + } + + /** + * Parse a host connect point from a string. + * The connect point should be in the format "hostId/vlanId/portNumber". + * + * @param string string to parse + * @return a ConnectPoint based on the information in the string. + */ + public static ConnectPoint hostConnectPoint(String string) { + checkNotNull(string); + String[] splitted = string.split("/"); + checkArgument(splitted.length == 3, + "Connect point must be in \"hostId/vlanId/portNumber\" format"); + + int lastSlash = string.lastIndexOf("/"); + + return new ConnectPoint(HostId.hostId(string.substring(0, lastSlash)), + PortNumber.portNumber(string.substring(lastSlash + 1, string.length()))); + } + + @Override + public int hashCode() { + return Objects.hash(elementId, portNumber); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ConnectPoint) { + final ConnectPoint other = (ConnectPoint) obj; + return Objects.equals(this.elementId, other.elementId) && + Objects.equals(this.portNumber, other.portNumber); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("elementId", elementId) + .add("portNumber", portNumber) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultAnnotations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultAnnotations.java new file mode 100644 index 00000000..7c97ecdd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultAnnotations.java @@ -0,0 +1,254 @@ +/* + * Copyright 2014-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; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import com.google.common.collect.Maps; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a set of simple annotations that can be used to add arbitrary + * attributes to various parts of the data model. + */ +public final class DefaultAnnotations implements SparseAnnotations { + + public static final SparseAnnotations EMPTY = DefaultAnnotations.builder().build(); + + private final Map<String, String> map; + + // For serialization + private DefaultAnnotations() { + this.map = null; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + DefaultAnnotations that = (DefaultAnnotations) o; + + return Objects.equals(this.map, that.map); + + } + + @Override + public int hashCode() { + return Objects.hashCode(this.map); + } + + /** + * Returns the annotations as a map. + * + * @return a copy of the contents of the annotations as a map. + */ + public HashMap<String, String> asMap() { + return Maps.newHashMap(this.map); + } + + /** + * Creates a new set of annotations using clone of the specified hash map. + * + * @param map hash map of key/value pairs + */ + private DefaultAnnotations(Map<String, String> map) { + this.map = map; + } + + /** + * Creates a new annotations builder. + * + * @return new annotations builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Merges the specified base set of annotations and additional sparse + * annotations into new combined annotations. If the supplied sparse + * annotations are empty, the original base annotations are returned. + * Any keys tagged for removal in the sparse annotations will be omitted + * in the resulting merged annotations. + * + * @param annotations base annotations + * @param sparseAnnotations additional sparse annotations + * @return combined annotations or the original base annotations if there + * are not additional annotations + */ + public static DefaultAnnotations merge(DefaultAnnotations annotations, + SparseAnnotations sparseAnnotations) { + checkNotNull(annotations, "Annotations cannot be null"); + if (sparseAnnotations == null || sparseAnnotations.keys().isEmpty()) { + return annotations; + } + + // Merge the two maps. Yes, this is not very efficient, but the + // use-case implies small maps and infrequent merges, so we opt for + // simplicity. + Map<String, String> merged = copy(annotations.map); + for (String key : sparseAnnotations.keys()) { + if (sparseAnnotations.isRemoved(key)) { + merged.remove(key); + } else { + merged.put(key, sparseAnnotations.value(key)); + } + } + return new DefaultAnnotations(merged); + } + + /** + * Creates the union of two given SparseAnnotations. + * Unlike the {@link #merge(DefaultAnnotations, SparseAnnotations)} method, + * result will be {@link SparseAnnotations} instead of {@link Annotations}. + * + * A key tagged for removal will remain in the output SparseAnnotations, + * if the counterpart of the input does not contain the same key. + * + * @param annotations base annotations + * @param sparseAnnotations additional sparse annotations + * @return combined annotations or the original base annotations if there + * are not additional annotations + */ + public static SparseAnnotations union(SparseAnnotations annotations, + SparseAnnotations sparseAnnotations) { + + if (sparseAnnotations == null || sparseAnnotations.keys().isEmpty()) { + return annotations; + } + + final HashMap<String, String> newMap; + if (annotations instanceof DefaultAnnotations) { + newMap = copy(((DefaultAnnotations) annotations).map); + } else { + newMap = new HashMap<>(annotations.keys().size() + + sparseAnnotations.keys().size()); + putAllSparseAnnotations(newMap, annotations); + } + + putAllSparseAnnotations(newMap, sparseAnnotations); + return new DefaultAnnotations(newMap); + } + + // adds the key-values contained in sparseAnnotations to + // newMap, if sparseAnnotations had a key tagged for removal, + // and corresponding key exist in newMap, entry will be removed. + // if corresponding key does not exist, removal tag will be added to + // the newMap. + private static void putAllSparseAnnotations( + final HashMap<String, String> newMap, + SparseAnnotations sparseAnnotations) { + + for (String key : sparseAnnotations.keys()) { + if (sparseAnnotations.isRemoved(key)) { + if (newMap.containsKey(key)) { + newMap.remove(key); + } else { + newMap.put(key, Builder.REMOVED); + } + } else { + String value = sparseAnnotations.value(key); + newMap.put(key, value); + } + } + } + + @Override + public Set<String> keys() { + return Collections.unmodifiableSet(map.keySet()); + } + + @Override + public String value(String key) { + String value = map.get(key); + return Objects.equals(Builder.REMOVED, value) ? null : value; + } + + @Override + public boolean isRemoved(String key) { + return Objects.equals(Builder.REMOVED, map.get(key)); + } + + @SuppressWarnings("unchecked") + private static HashMap<String, String> copy(Map<String, String> original) { + if (original instanceof HashMap) { + return (HashMap<String, String>) ((HashMap<?, ?>) original).clone(); + } + throw new IllegalArgumentException("Expecting HashMap instance"); + } + + @Override + public String toString() { + return (map == null) ? "null" : map.toString(); + } + + /** + * Facility for gradually building model annotations. + */ + public static final class Builder { + + private static final String REMOVED = "~rEmOvEd~"; + private final Map<String, String> builder = new HashMap<>(); + + // Private construction is forbidden. + private Builder() { + } + + /** + * Adds the specified annotation. Any previous value associated with + * the given annotation key will be overwritten. + * + * @param key annotation key + * @param value annotation value + * @return self + */ + public Builder set(String key, String value) { + builder.put(key, value); + return this; + } + + /** + * Adds the specified annotation. Any previous value associated with + * the given annotation key will be tagged for removal. + * + * @param key annotation key + * @return self + */ + public Builder remove(String key) { + builder.put(key, REMOVED); + return this; + } + + /** + * Returns immutable annotations built from the accrued key/values pairs. + * + * @return annotations + */ + public DefaultAnnotations build() { + return new DefaultAnnotations(copy(builder)); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultDevice.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultDevice.java new file mode 100644 index 00000000..f3f0fe74 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultDevice.java @@ -0,0 +1,142 @@ +/* + * Copyright 2014-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; + +import org.onosproject.net.provider.ProviderId; +import org.onlab.packet.ChassisId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default infrastructure device model implementation. + */ +public class DefaultDevice extends AbstractElement implements Device { + + private final Type type; + private final String manufacturer; + private final String serialNumber; + private final String hwVersion; + private final String swVersion; + private final ChassisId chassisId; + + // For serialization + private DefaultDevice() { + this.type = null; + this.manufacturer = null; + this.hwVersion = null; + this.swVersion = null; + this.serialNumber = null; + this.chassisId = null; + } + + /** + * Creates a network element attributed to the specified provider. + * + * @param providerId identity of the provider + * @param id device identifier + * @param type device type + * @param manufacturer device manufacturer + * @param hwVersion device HW version + * @param swVersion device SW version + * @param serialNumber device serial number + * @param chassisId chassis id + * @param annotations optional key/value annotations + */ + public DefaultDevice(ProviderId providerId, DeviceId id, Type type, + String manufacturer, String hwVersion, String swVersion, + String serialNumber, ChassisId chassisId, + Annotations... annotations) { + super(providerId, id, annotations); + this.type = type; + this.manufacturer = manufacturer; + this.hwVersion = hwVersion; + this.swVersion = swVersion; + this.serialNumber = serialNumber; + this.chassisId = chassisId; + } + + @Override + public DeviceId id() { + return (DeviceId) id; + } + + @Override + public Type type() { + return type; + } + + @Override + public String manufacturer() { + return manufacturer; + } + + @Override + public String hwVersion() { + return hwVersion; + } + + @Override + public String swVersion() { + return swVersion; + } + + @Override + public String serialNumber() { + return serialNumber; + } + + @Override + public ChassisId chassisId() { + return chassisId; + } + + @Override + public int hashCode() { + return Objects.hash(id, type, manufacturer, hwVersion, swVersion, serialNumber); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultDevice) { + final DefaultDevice other = (DefaultDevice) obj; + return Objects.equals(this.id, other.id) && + Objects.equals(this.type, other.type) && + Objects.equals(this.manufacturer, other.manufacturer) && + Objects.equals(this.hwVersion, other.hwVersion) && + Objects.equals(this.swVersion, other.swVersion) && + Objects.equals(this.serialNumber, other.serialNumber); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", id) + .add("type", type) + .add("manufacturer", manufacturer) + .add("hwVersion", hwVersion) + .add("swVersion", swVersion) + .add("serialNumber", serialNumber) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultEdgeLink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultEdgeLink.java new file mode 100644 index 00000000..67ceef7a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultEdgeLink.java @@ -0,0 +1,96 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default edge link model implementation. + */ +public class DefaultEdgeLink extends DefaultLink implements EdgeLink { + + private final HostId hostId; + private final HostLocation hostLocation; + + /** + * Creates an edge link using the supplied information. + * + * @param providerId provider identity + * @param hostPoint host-side connection point + * @param hostLocation location where host attaches to the network + * @param isIngress true to indicate host-to-network direction; false + * for network-to-host direction + * @param annotations optional key/value annotations + */ + public DefaultEdgeLink(ProviderId providerId, ConnectPoint hostPoint, + HostLocation hostLocation, boolean isIngress, + Annotations... annotations) { + super(providerId, isIngress ? hostPoint : hostLocation, + isIngress ? hostLocation : hostPoint, Type.EDGE, annotations); + checkArgument(hostPoint.elementId() instanceof HostId, + "Host point does not refer to a host ID"); + this.hostId = (HostId) hostPoint.elementId(); + this.hostLocation = hostLocation; + } + + @Override + public HostId hostId() { + return hostId; + } + + @Override + public HostLocation hostLocation() { + return hostLocation; + } + + /** + * Creates a phantom edge link, to an unspecified end-station. This link + * does not represent any actually discovered link stored in the system. + * + * @param edgePort network edge port + * @param isIngress true to indicate host-to-network direction; false + * for network-to-host direction + * @return new phantom edge link + */ + public static DefaultEdgeLink createEdgeLink(ConnectPoint edgePort, + boolean isIngress) { + checkNotNull(edgePort, "Edge port cannot be null"); + HostLocation location = (edgePort instanceof HostLocation) ? + (HostLocation) edgePort : new HostLocation(edgePort, 0); + return new DefaultEdgeLink(ProviderId.NONE, + new ConnectPoint(HostId.NONE, PortNumber.P0), + location, isIngress); + } + + /** + * Creates a an edge link, to the specified end-station. + * + * @param host host + * @param isIngress true to indicate host-to-network direction; false + * for network-to-host direction + * @return new phantom edge link + */ + public static DefaultEdgeLink createEdgeLink(Host host, boolean isIngress) { + checkNotNull(host, "Host cannot be null"); + return new DefaultEdgeLink(ProviderId.NONE, + new ConnectPoint(host.id(), PortNumber.P0), + host.location(), isIngress); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java new file mode 100644 index 00000000..2877701e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * A basic implementation of a Host. + */ +public class DefaultHost extends AbstractElement implements Host { + + private final MacAddress mac; + private final VlanId vlan; + private final HostLocation location; + private final Set<IpAddress> ips; + + /** + * Creates an end-station host using the supplied information. + * + * @param providerId provider identity + * @param id host identifier + * @param mac host MAC address + * @param vlan host VLAN identifier + * @param location host location + * @param ips host IP addresses + * @param annotations optional key/value annotations + */ + public DefaultHost(ProviderId providerId, HostId id, MacAddress mac, + VlanId vlan, HostLocation location, Set<IpAddress> ips, + Annotations... annotations) { + super(providerId, id, annotations); + this.mac = mac; + this.vlan = vlan; + this.location = location; + this.ips = new HashSet<>(ips); + } + + @Override + public HostId id() { + return (HostId) id; + } + + @Override + public MacAddress mac() { + return mac; + } + + @Override + public Set<IpAddress> ipAddresses() { + return Collections.unmodifiableSet(ips); + } + + @Override + public HostLocation location() { + return location; + } + + @Override + public VlanId vlan() { + return vlan; + } + + @Override + public int hashCode() { + return Objects.hash(id, mac, vlan, location); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultHost) { + final DefaultHost other = (DefaultHost) obj; + return Objects.equals(this.id, other.id) && + Objects.equals(this.mac, other.mac) && + Objects.equals(this.vlan, other.vlan) && + Objects.equals(this.location, other.location); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", id) + .add("mac", mac) + .add("vlan", vlan) + .add("location", location) + .add("ipAddresses", ips) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultLink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultLink.java new file mode 100644 index 00000000..4d1ca6de --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultLink.java @@ -0,0 +1,131 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static org.onosproject.net.Link.State.ACTIVE; + +/** + * Default infrastructure link model implementation. + */ +public class DefaultLink extends AbstractModel implements Link { + + private final ConnectPoint src; + private final ConnectPoint dst; + private final Type type; + private final State state; + private final boolean isDurable; + + /** + * Creates an active infrastructure link using the supplied information. + * + * @param providerId provider identity + * @param src link source + * @param dst link destination + * @param type link type + * @param annotations optional key/value annotations + */ + public DefaultLink(ProviderId providerId, ConnectPoint src, ConnectPoint dst, + Type type, Annotations... annotations) { + this(providerId, src, dst, type, ACTIVE, false, annotations); + } + + /** + * Creates an infrastructure link using the supplied information. + * Links marked as durable will remain in the inventory when a vanish + * message is received and instead will be marked as inactive. + * + * @param providerId provider identity + * @param src link source + * @param dst link destination + * @param type link type + * @param state link state + * @param isDurable indicates if the link is to be considered durable + * @param annotations optional key/value annotations + */ + public DefaultLink(ProviderId providerId, ConnectPoint src, ConnectPoint dst, + Type type, State state, + boolean isDurable, Annotations... annotations) { + super(providerId, annotations); + this.src = src; + this.dst = dst; + this.type = type; + this.state = state; + this.isDurable = isDurable; + } + + @Override + public ConnectPoint src() { + return src; + } + + @Override + public ConnectPoint dst() { + return dst; + } + + @Override + public Type type() { + return type; + } + + @Override + public State state() { + return state; + } + + @Override + public boolean isDurable() { + return isDurable; + } + + // Note: Durability & state are purposefully omitted form equality & hashCode. + + @Override + public int hashCode() { + return Objects.hash(src, dst, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultLink) { + final DefaultLink other = (DefaultLink) obj; + return Objects.equals(this.src, other.src) && + Objects.equals(this.dst, other.dst) && + Objects.equals(this.type, other.type); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("src", src) + .add("dst", dst) + .add("type", type) + .add("state", state) + .add("durable", isDurable) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java new file mode 100644 index 00000000..a4789cac --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java @@ -0,0 +1,105 @@ +/* + * Copyright 2014 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; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import org.onosproject.net.provider.ProviderId; + +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of a network path. + */ +public class DefaultPath extends DefaultLink implements Path { + + private final List<Link> links; + private final double cost; + + /** + * Creates a path from the specified source and destination using the + * supplied list of links. + * + * @param providerId provider identity + * @param links contiguous links that comprise the path + * @param cost unit-less path cost + * @param annotations optional key/value annotations + */ + public DefaultPath(ProviderId providerId, List<Link> links, double cost, + Annotations... annotations) { + super(providerId, source(links), destination(links), Type.INDIRECT, annotations); + this.links = ImmutableList.copyOf(links); + this.cost = cost; + } + + @Override + public List<Link> links() { + return links; + } + + @Override + public double cost() { + return cost; + } + + // Returns the source of the first link. + private static ConnectPoint source(List<Link> links) { + checkNotNull(links, "List of path links cannot be null"); + checkArgument(!links.isEmpty(), "List of path links cannot be empty"); + return links.get(0).src(); + } + + // Returns the destination of the last link. + private static ConnectPoint destination(List<Link> links) { + checkNotNull(links, "List of path links cannot be null"); + checkArgument(!links.isEmpty(), "List of path links cannot be empty"); + return links.get(links.size() - 1).dst(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("src", src()) + .add("dst", dst()) + .add("type", type()) + .add("state", state()) + .add("durable", isDurable()) + .add("links", links) + .add("cost", cost) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(links); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultPath) { + final DefaultPath other = (DefaultPath) obj; + return Objects.equals(this.links, other.links); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPort.java new file mode 100644 index 00000000..a6b8441a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPort.java @@ -0,0 +1,127 @@ +/* + * Copyright 2014 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; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default port implementation. + */ +public class DefaultPort extends AbstractAnnotated implements Port { + + /** Default port speed in Mbps. */ + public static final long DEFAULT_SPEED = 1_000; + + private final Element element; + private final PortNumber number; + private final boolean isEnabled; + private final Type type; + private final long portSpeed; + + /** + * Creates a network element attributed to the specified provider. + * + * @param element parent network element + * @param number port number + * @param isEnabled indicator whether the port is up and active + * @param annotations optional key/value annotations + */ + public DefaultPort(Element element, PortNumber number, boolean isEnabled, + Annotations... annotations) { + this(element, number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations); + } + + /** + * Creates a network element attributed to the specified provider. + * + * @param element parent network element + * @param number port number + * @param isEnabled indicator whether the port is up and active + * @param type port type + * @param portSpeed port speed in Mbs + * @param annotations optional key/value annotations + */ + public DefaultPort(Element element, PortNumber number, boolean isEnabled, + Type type, long portSpeed, Annotations... annotations) { + super(annotations); + this.element = element; + this.number = number; + this.isEnabled = isEnabled; + this.type = type; + this.portSpeed = portSpeed; + } + + @Override + public Element element() { + return element; + } + + @Override + public PortNumber number() { + return number; + } + + @Override + public boolean isEnabled() { + return isEnabled; + } + + @Override + public Type type() { + return type; + } + + @Override + public long portSpeed() { + return portSpeed; + } + + @Override + public int hashCode() { + return Objects.hash(number, isEnabled, type, portSpeed, annotations()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultPort) { + final DefaultPort other = (DefaultPort) obj; + return Objects.equals(this.element.id(), other.element.id()) && + Objects.equals(this.number, other.number) && + Objects.equals(this.isEnabled, other.isEnabled) && + Objects.equals(this.type, other.type) && + Objects.equals(this.portSpeed, other.portSpeed) && + Objects.equals(this.annotations(), other.annotations()); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("element", element.id()) + .add("number", number) + .add("isEnabled", isEnabled) + .add("type", type) + .add("portSpeed", portSpeed) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Description.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Description.java new file mode 100644 index 00000000..c01af549 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Description.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014 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; + +/** + * Base abstraction of a piece of information about network elements. + */ +public interface Description extends Annotated { + + @Override + SparseAnnotations annotations(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Device.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Device.java new file mode 100644 index 00000000..d9001825 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Device.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014-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; + +import org.onlab.packet.ChassisId; + +/** + * Representation of a network infrastructure device. + */ +public interface Device extends Element { + + /** + * Coarse classification of the type of the infrastructure device. + */ + public enum Type { + SWITCH, ROUTER, ROADM, OTN, ROADM_OTN, FIREWALL, BALANCER, IPS, IDS, CONTROLLER, + VIRTUAL, FIBER_SWITCH, MICROWAVE, OTHER + } + + /** + * Returns the device identifier. + * + * @return device id + */ + @Override + DeviceId id(); + + /** + * Returns the type of the infrastructure device. + * + * @return type of the device + */ + Type type(); + + /** + * Returns the device manufacturer name. + * + * @return manufacturer name + */ + String manufacturer(); + + /** + * Returns the device hardware version. + * + * @return hardware version + */ + String hwVersion(); + + /** + * Returns the device software version. + * + * @return software version + */ + String swVersion(); + + /** + * Returns the device serial number. + * + * @return serial number + */ + String serialNumber(); + + /** + * Returns the device chassis id. + * + * @return chassis id + */ + ChassisId chassisId(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java new file mode 100644 index 00000000..5331342e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java @@ -0,0 +1,99 @@ +/* + * Copyright 2014 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; + +import java.net.URI; +import java.util.Objects; + +/** + * Immutable representation of a device identity. + */ +public final class DeviceId extends ElementId { + + /** + * Represents either no device, or an unspecified device. + */ + public static final DeviceId NONE = deviceId("none:none"); + + private final URI uri; + private final String str; + + // Public construction is prohibited + private DeviceId(URI uri) { + this.uri = uri; + this.str = uri.toString().toLowerCase(); + } + + + // Default constructor for serialization + protected DeviceId() { + this.uri = null; + this.str = null; + } + + /** + * Creates a device id using the supplied URI. + * + * @param uri device URI + * @return DeviceId + */ + public static DeviceId deviceId(URI uri) { + return new DeviceId(uri); + } + + /** + * Creates a device id using the supplied URI string. + * + * @param string device URI string + * @return DeviceId + */ + public static DeviceId deviceId(String string) { + return deviceId(URI.create(string)); + } + + /** + * Returns the backing URI. + * + * @return backing URI + */ + public URI uri() { + return uri; + } + + @Override + public int hashCode() { + return Objects.hash(str); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DeviceId) { + final DeviceId that = (DeviceId) obj; + return this.getClass() == that.getClass() && + Objects.equals(this.str, that.str); + } + return false; + } + + @Override + public String toString() { + return str; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/EdgeLink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EdgeLink.java new file mode 100644 index 00000000..73b916b2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EdgeLink.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014 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; + +/** + * Abstraction of a link between an end-station host and the network + * infrastructure. + */ +public interface EdgeLink extends Link { + + /** + * Returns the host identification. + * + * @return host identifier + */ + HostId hostId(); + + /** + * Returns the connection point where the host attaches to the + * network infrastructure. + * + * @return host location point + */ + HostLocation hostLocation(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Element.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Element.java new file mode 100644 index 00000000..6cdab9e4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Element.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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; + +/** + * Base abstraction of a network element, i.e. an infrastructure device or an end-station host. + */ +public interface Element extends Annotated, Provided { + + /** + * Returns the network element identifier. + * + * @return element identifier + */ + ElementId id(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/ElementId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ElementId.java new file mode 100644 index 00000000..87defb26 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/ElementId.java @@ -0,0 +1,22 @@ +/* + * Copyright 2014-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; + +/** + * Immutable representation of a network element identity. + */ +public abstract class ElementId implements NetworkResource { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/GridType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/GridType.java new file mode 100644 index 00000000..8e9bc5b9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/GridType.java @@ -0,0 +1,29 @@ +/* + * 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; + +/** + * Represents type of wavelength grid. + * + * <p> + * See Open Networking Foundation "Optical Transport Protocol Extensions Version 1.0". + * </p> + */ +public enum GridType { + DWDM, // Dense Wavelength Division Multiplexing + CWDM, // Coarse WDM + FLEX // Flex Grid +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Host.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Host.java new file mode 100644 index 00000000..646f2283 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Host.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 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; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; + +import java.util.Set; + +/** + * Abstraction of an end-station host on the network, essentially a NIC. + */ +public interface Host extends Element { + + /** + * Host identification. + * + * @return host id + */ + @Override + HostId id(); + + /** + * Returns the host MAC address. + * + * @return mac address + */ + MacAddress mac(); + + /** + * Returns the VLAN ID tied to this host. + * + * @return VLAN ID value + */ + VlanId vlan(); + + /** + * Returns set of IP addresses currently bound to the host MAC address. + * + * @return set of IP addresses; empty if no IP address is bound + */ + Set<IpAddress> ipAddresses(); + + /** + * Returns the most recent host location where the host attaches to the + * network edge. + * + * @return host location + */ + HostLocation location(); + + // TODO: explore capturing list of recent locations to aid in mobility + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostId.java new file mode 100644 index 00000000..3e0d2b24 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostId.java @@ -0,0 +1,129 @@ +/* + * Copyright 2014 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; + +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Immutable representation of a host identity. + */ +public final class HostId extends ElementId { + + /** + * Represents either no host, or an unspecified host; used for creating + * open ingress/egress edge links. + */ + public static final HostId NONE = new HostId(MacAddress.ZERO, VlanId.NONE); + + private static final int MAC_LENGTH = 17; + private static final int MIN_ID_LENGTH = 19; + + private final MacAddress mac; + private final VlanId vlanId; + + // Public construction is prohibited + private HostId(MacAddress mac, VlanId vlanId) { + this.mac = mac; + this.vlanId = vlanId; + } + + // Default constructor for serialization + private HostId() { + this.mac = null; + this.vlanId = null; + } + + /** + * Returns the host MAC address. + * + * @return MAC address + */ + public MacAddress mac() { + return mac; + } + + /** + * Returns the host vlan Id. + * + * @return vlan Id + */ + public VlanId vlanId() { + return vlanId; + } + + /** + * Creates a device id using the supplied ID string. + * + * @param string device URI string + * @return host identifier + */ + public static HostId hostId(String string) { + checkArgument(string.length() >= MIN_ID_LENGTH, + "Host ID must be at least %s characters", MIN_ID_LENGTH); + MacAddress mac = MacAddress.valueOf(string.substring(0, MAC_LENGTH)); + VlanId vlanId = VlanId.vlanId(Short.parseShort(string.substring(MAC_LENGTH + 1))); + return new HostId(mac, vlanId); + } + + /** + * Creates a device id using the supplied MAC & VLAN ID. + * + * @param mac mac address + * @param vlanId vlan identifier + * @return host identifier + */ + public static HostId hostId(MacAddress mac, VlanId vlanId) { + return new HostId(mac, vlanId); + } + + /** + * Creates a device id using the supplied MAC and default VLAN. + * + * @param mac mac address + * @return host identifier + */ + public static HostId hostId(MacAddress mac) { + return hostId(mac, VlanId.vlanId(VlanId.UNTAGGED)); + } + + public String toString() { + return mac + "/" + vlanId; + } + + @Override + public int hashCode() { + return Objects.hash(mac, vlanId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof HostId) { + final HostId other = (HostId) obj; + return Objects.equals(this.mac, other.mac) && + Objects.equals(this.vlanId, other.vlanId); + } + return false; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostLocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostLocation.java new file mode 100644 index 00000000..b0553a2b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/HostLocation.java @@ -0,0 +1,67 @@ +/* + * Copyright 2014 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; + +import static org.onosproject.net.PortNumber.P0; + +/** + * Representation of a network edge location where an end-station host is + * connected. + */ +public class HostLocation extends ConnectPoint { + + /** + * Represents a no location or an unknown location. + */ + public static final HostLocation NONE = new HostLocation(DeviceId.NONE, P0, 0L); + + // Note that time is explicitly excluded from the notion of equality. + private final long time; + + /** + * Creates a new host location using the supplied device & port. + * + * @param deviceId device identity + * @param portNumber device port number + * @param time time when detected, in millis since start of epoch + */ + public HostLocation(DeviceId deviceId, PortNumber portNumber, long time) { + super(deviceId, portNumber); + this.time = time; + } + + /** + * Creates a new host location derived from the supplied connection point. + * + * @param connectPoint connection point + * @param time time when detected, in millis since start of epoch + */ + public HostLocation(ConnectPoint connectPoint, long time) { + super(connectPoint.deviceId(), connectPoint.port()); + this.time = time; + } + + /** + * Returns the time when the location was established, given in + * milliseconds since start of epoch. + * + * @return time in milliseconds since start of epoch + */ + public long time() { + return time; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/IndexedLambda.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/IndexedLambda.java new file mode 100644 index 00000000..6b5fa652 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/IndexedLambda.java @@ -0,0 +1,71 @@ +/* + * 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; + +import com.google.common.base.MoreObjects; + +/** + * Implementation of Lambda simply designated by an index number of wavelength. + */ +public class IndexedLambda implements Lambda { + + private final long index; + + /** + * Creates an instance representing the wavelength specified by the given index number. + * It is recommended to use {@link Lambda#indexedLambda(long)} unless you want to use the + * concrete type, IndexedLambda, directly. + * + * @param index index number of wavelength + */ + public IndexedLambda(long index) { + this.index = index; + } + + /** + * Returns the index number of lambda. + * + * @return the index number of lambda + */ + public long index() { + return index; + } + + @Override + public int hashCode() { + return Long.hashCode(index); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof IndexedLambda)) { + return false; + } + + final IndexedLambda that = (IndexedLambda) obj; + return this.index == that.index; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("lambda", index) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/IpElementId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/IpElementId.java new file mode 100644 index 00000000..9e19b624 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/IpElementId.java @@ -0,0 +1,61 @@ +package org.onosproject.net; + +import java.util.Objects; +import org.onlab.packet.IpAddress; +import com.google.common.base.MoreObjects; + +/** + * Represent for a Element ID using ip address. + */ +public final class IpElementId extends ElementId { + + private final IpAddress ipAddress; + + /** + * Public construction is prohibited. + * @param ipAddress ip address + */ + private IpElementId(IpAddress ipAddress) { + this.ipAddress = ipAddress; + } + + /** + * Create a IP Element ID. + * @param ipAddress IP address + * @return IpElementId + */ + public static IpElementId ipElement(IpAddress ipAddress) { + return new IpElementId(ipAddress); + } + + /** + * Returns the ip address. + * + * @return ipAddress + */ + public IpAddress ipAddress() { + return ipAddress; + } + + @Override + public int hashCode() { + return Objects.hash(ipAddress); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IpElementId) { + final IpElementId other = (IpElementId) obj; + return Objects.equals(this.ipAddress, other.ipAddress); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("ipAddress", ipAddress).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Lambda.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Lambda.java new file mode 100644 index 00000000..47d0d5f0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Lambda.java @@ -0,0 +1,45 @@ +/* + * 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; + +/** + * Abstraction of wavelength. Currently, this is just a marker interface + */ +public interface Lambda { + /** + * Create an Lambda instance with the specified wavelength index number. + * + * @param lambda index number + * @return an instance + */ + static Lambda indexedLambda(long lambda) { + return new IndexedLambda(lambda); + } + + /** + * Creates a Lambda instance with the specified arguments. + * + * @param gridType grid type + * @param channelSpacing channel spacing + * @param spacingMultiplier channel spacing multiplier + * @param slotGranularity slot width granularity + * @return new lambda with specified arguments + */ + static Lambda ochSignal(GridType gridType, ChannelSpacing channelSpacing, + int spacingMultiplier, int slotGranularity) { + return new OchSignal(gridType, channelSpacing, spacingMultiplier, slotGranularity); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Link.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Link.java new file mode 100644 index 00000000..7541f751 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Link.java @@ -0,0 +1,114 @@ +/* + * Copyright 2014 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; + +/** + * Abstraction of a network infrastructure link. + */ +public interface Link extends Annotated, Provided, NetworkResource { + + /** + * Coarse representation of the link type. + */ + enum Type { + /** + * Signifies that this is a direct single-segment link. + */ + DIRECT, + + /** + * Signifies that this link is potentially comprised from multiple + * underlying segments or hops, and as such should be used to tag + * links traversing optical paths, tunnels or intervening 'dark' + * switches. + */ + INDIRECT, + + /** + * Signifies that this link is an edge, i.e. host link. + */ + EDGE, + + /** + * Signifies that this link represents a logical link backed by + * some form of a tunnel, e.g., GRE, MPLS, ODUk, OCH. + */ + TUNNEL, + + /** + * Signifies that this link is realized by fiber (either single channel or WDM). + */ + OPTICAL, + + /** + * Signifies that this link is a virtual link or a pseudo-wire. + */ + VIRTUAL + } + + /** + * Representation of the link state, which applies primarily only to + * configured durable links, i.e. those that need to remain present, + * but instead be marked as inactive. + */ + enum State { + /** + * Signifies that a link is currently active. + */ + ACTIVE, + + /** + * Signifies that a link is currently active. + */ + INACTIVE + } + + /** + * Returns the link source connection point. + * + * @return link source connection point + */ + ConnectPoint src(); + + /** + * Returns the link destination connection point. + * + * @return link destination connection point + */ + ConnectPoint dst(); + + /** + * Returns the link type. + * + * @return link type + */ + Type type(); + + /** + * Returns the link state. + * + * @return link state + */ + State state(); + + /** + * Indicates if the link is to be considered durable. + * + * @return true if the link is durable + */ + boolean isDurable(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/LinkKey.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/LinkKey.java new file mode 100644 index 00000000..9cb66492 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/LinkKey.java @@ -0,0 +1,110 @@ +/* + * Copyright 2014 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; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +// TODO Consider renaming. +// it's an identifier for a Link, but it's not ElementId, so not using LinkId. + +/** + * Immutable representation of a link identity. + */ +public final class LinkKey { + + private final ConnectPoint src; + private final ConnectPoint dst; + + /** + * Returns source connection point. + * + * @return source connection point + */ + public ConnectPoint src() { + return src; + } + + /** + * Returns destination connection point. + * + * @return destination connection point + */ + public ConnectPoint dst() { + return dst; + } + + /** + * Creates a link identifier with source and destination connection point. + * + * @param src source connection point + * @param dst destination connection point + */ + private LinkKey(ConnectPoint src, ConnectPoint dst) { + this.src = checkNotNull(src); + this.dst = checkNotNull(dst); + } + + /** + * Creates a link identifier with source and destination connection point. + * + * @param src source connection point + * @param dst destination connection point + * @return a link identifier + */ + public static LinkKey linkKey(ConnectPoint src, ConnectPoint dst) { + return new LinkKey(src, dst); + } + + /** + * Creates a link identifier for the specified link. + * + * @param link link descriptor + * @return a link identifier + */ + public static LinkKey linkKey(Link link) { + return new LinkKey(link.src(), link.dst()); + } + + @Override + public int hashCode() { + return Objects.hash(src, dst); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof LinkKey) { + final LinkKey other = (LinkKey) obj; + return Objects.equals(this.src, other.src) && + Objects.equals(this.dst, other.dst); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("src", src) + .add("dst", dst) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/MastershipRole.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/MastershipRole.java new file mode 100644 index 00000000..78f65864 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/MastershipRole.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014 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; + +/** + * Representation of a relationship role of a controller instance to a device + * or a region of network environment. + */ +public enum MastershipRole { + + /** + * Represents a relationship where the controller instance is the master + * to a device or a region of network environment. + */ + MASTER, + + /** + * Represents a relationship where the controller instance is the standby, + * i.e. potential master to a device or a region of network environment. + */ + STANDBY, + + /** + * Represents that the controller instance is not eligible to be the master + * to a device or a region of network environment. + */ + NONE + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/MutableAnnotations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/MutableAnnotations.java new file mode 100644 index 00000000..9b7f328e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/MutableAnnotations.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Represents an mutable set of simple key/value string annotations. + */ +public interface MutableAnnotations extends Annotations { + + /** + * Returns the value of the specified annotation. + * + * @param key annotation key + * @param value annotation value + * @return self + */ + MutableAnnotations set(String key, String value); + + /** + * Clears the specified keys or the all keys if none were specified. + * + * @param keys keys to be cleared + * @return self + */ + MutableAnnotations clear(String... keys); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetTools.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetTools.java new file mode 100644 index 00000000..fc561884 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetTools.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** + * Networking domain tools. + */ +public final class NetTools { + + private NetTools() { + } + + /** + * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider + * device URIs. The is helpful for converting DPIDs coming from configuration + * or REST to URIs that the core understands. + * + * @param dpid the DPID string to convert + * @return the URI string for this device + */ + public static String dpidToUri(String dpid) { + return "of:" + dpid.replace(":", ""); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetworkResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetworkResource.java new file mode 100644 index 00000000..502208a0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/NetworkResource.java @@ -0,0 +1,22 @@ +/* + * Copyright 2014 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; + +/** + * Representation of a network resource, e.g. a link, lambda, MPLS tag. + */ +public interface NetworkResource { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java new file mode 100644 index 00000000..eb956f2a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchPort.java @@ -0,0 +1,115 @@ +/* + * 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; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of OCh port (Optical Channel). + * Also referred to as a line side port (L-port) or narrow band port. + * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)" + */ +public class OchPort extends DefaultPort { + + private final OduSignalType signalType; + private final boolean isTunable; + private final OchSignal lambda; + + /** + * Creates an OCh port in the specified network element. + * + * @param element parent network element + * @param number port number + * @param isEnabled port enabled state + * @param signalType ODU signal type + * @param isTunable tunable wavelength capability + * @param lambda OCh signal + * @param annotations optional key/value annotations + */ + public OchPort(Element element, PortNumber number, boolean isEnabled, OduSignalType signalType, + boolean isTunable, OchSignal lambda, Annotations... annotations) { + super(element, number, isEnabled, Type.OCH, 0, annotations); + this.signalType = signalType; + this.isTunable = isTunable; + this.lambda = checkNotNull(lambda); + } + + /** + * Returns ODU signal type. + * + * @return ODU signal type + */ + public OduSignalType signalType() { + return signalType; + } + + /** + * Returns true if port is wavelength tunable. + * + * @return tunable wavelength capability + */ + public boolean isTunable() { + return isTunable; + } + + /** + * Returns OCh signal. + * + * @return OCh signal + */ + public OchSignal lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(number(), isEnabled(), type(), signalType, isTunable, lambda, annotations()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OchPort) { + final OchPort other = (OchPort) obj; + return Objects.equals(this.element().id(), other.element().id()) && + Objects.equals(this.number(), other.number()) && + Objects.equals(this.isEnabled(), other.isEnabled()) && + Objects.equals(this.signalType, other.signalType) && + Objects.equals(this.isTunable, other.isTunable) && + Objects.equals(this.lambda, other.lambda) && + Objects.equals(this.annotations(), other.annotations()); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("element", element().id()) + .add("number", number()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("signalType", signalType) + .add("isTunable", isTunable) + .add("lambda", lambda) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java new file mode 100644 index 00000000..5a5af34a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignal.java @@ -0,0 +1,176 @@ +/* + * 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; + +import com.google.common.base.MoreObjects; +import org.onlab.util.Frequency; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of Lambda representing OCh (Optical Channel) Signal. + * + * <p> + * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)". + * </p> + */ +public class OchSignal implements Lambda { + + public static final Frequency CENTER_FREQUENCY = Frequency.ofTHz(193.1); + public static final Frequency FLEX_GRID_SLOT = Frequency.ofGHz(12.5); + private static final GridType DEFAULT_OCH_GRIDTYPE = GridType.DWDM; + private static final ChannelSpacing DEFAULT_CHANNEL_SPACING = ChannelSpacing.CHL_50GHZ; + + + private final GridType gridType; + private final ChannelSpacing channelSpacing; + // Frequency = 193.1 THz + spacingMultiplier * channelSpacing + private final int spacingMultiplier; + // Slot width = slotGranularity * 12.5 GHz + private final int slotGranularity; + + /** + * Creates an instance with the specified arguments. + * It it recommended to use {@link Lambda#ochSignal(GridType, ChannelSpacing, int, int)} + * unless you want to use the concrete type, OchSignal, directly. + * + * @param gridType grid type + * @param channelSpacing channel spacing + * @param spacingMultiplier channel spacing multiplier + * @param slotGranularity slot width granularity + */ + public OchSignal(GridType gridType, ChannelSpacing channelSpacing, + int spacingMultiplier, int slotGranularity) { + this.gridType = checkNotNull(gridType); + this.channelSpacing = checkNotNull(channelSpacing); + // Negative values are permitted for spacingMultiplier + this.spacingMultiplier = spacingMultiplier; + checkArgument(slotGranularity > 0, "slotGranularity must be larger than 0, received %s", slotGranularity); + this.slotGranularity = slotGranularity; + } + + /** + * Create OCh signal from channel number. + * + * @param channel channel number + * @param maxFrequency maximum frequency + * @param grid grid spacing frequency + */ + public OchSignal(int channel, Frequency maxFrequency, Frequency grid) { + // Calculate center frequency + Frequency centerFrequency = maxFrequency.subtract(grid.multiply(channel - 1)); + + this.gridType = DEFAULT_OCH_GRIDTYPE; + this.channelSpacing = DEFAULT_CHANNEL_SPACING; + this.spacingMultiplier = (int) (centerFrequency.subtract(OchSignal.CENTER_FREQUENCY).asHz() / grid.asHz()); + this.slotGranularity = (int) Math.round((double) grid.asHz() / ChannelSpacing.CHL_12P5GHZ.frequency().asHz()); + } + + public OchSignal(Frequency centerFrequency, ChannelSpacing channelSpacing, int slotGranularity) { + this.gridType = DEFAULT_OCH_GRIDTYPE; + this.channelSpacing = channelSpacing; + this.spacingMultiplier = (int) Math.round((double) centerFrequency. + subtract(OchSignal.CENTER_FREQUENCY).asHz() / channelSpacing().frequency().asHz()); + this.slotGranularity = slotGranularity; + } + + /** + * Returns grid type. + * + * @return grid type + */ + public GridType gridType() { + return gridType; + } + + /** + * Returns channel spacing. + * + * @return channel spacing + */ + public ChannelSpacing channelSpacing() { + return channelSpacing; + } + + /** + * Returns spacing multiplier. + * + * @return spacing multiplier + */ + public int spacingMultiplier() { + return spacingMultiplier; + } + + /** + * Returns slow width granularity. + * + * @return slow width granularity + */ + public int slotGranularity() { + return slotGranularity; + } + + /** + * Returns central frequency in MHz. + * + * @return frequency in MHz + */ + public Frequency centralFrequency() { + return CENTER_FREQUENCY.add(channelSpacing().frequency().multiply(spacingMultiplier)); + } + + /** + * Returns slot width. + * + * @return slot width + */ + public Frequency slotWidth() { + return FLEX_GRID_SLOT.multiply(slotGranularity); + } + + @Override + public int hashCode() { + return Objects.hash(gridType, channelSpacing, spacingMultiplier, slotGranularity); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof OchSignal)) { + return false; + } + final OchSignal other = (OchSignal) obj; + return Objects.equals(this.gridType, other.gridType) + && Objects.equals(this.channelSpacing, other.channelSpacing) + && Objects.equals(this.spacingMultiplier, other.spacingMultiplier) + && Objects.equals(this.slotGranularity, other.slotGranularity); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("gridType", gridType) + .add("channelSpacing", channelSpacing) + .add("spacingMultiplier", spacingMultiplier) + .add("slotGranularity", slotGranularity) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignalType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignalType.java new file mode 100644 index 00000000..9caf3f34 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OchSignalType.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * Represents OCh (Optical Channel) signal type defined in + * Open Networking Foundation "Optical Transport Protocol Extensions Version 1.0". + */ +public enum OchSignalType { + /** + * Represents fixed grid. + */ + FIXED_GRID, + + /** + * Represents flex grid. + */ + FLEX_GRID +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java new file mode 100644 index 00000000..e5602f36 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduCltPort.java @@ -0,0 +1,97 @@ +/* + * 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; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of ODU client port (Optical channel Data Unit). + * Also referred to as a T-port or wide band port. + * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)" + */ + +public class OduCltPort extends DefaultPort { + + public enum SignalType { + CLT_1GBE, + CLT_10GBE, + CLT_40GBE, + CLT_100GBE + } + + private final SignalType signalType; + + + /** + * Creates an ODU client port in the specified network element. + * + * @param element parent network element + * @param number port number + * @param isEnabled port enabled state + * @param signalType ODU client signal type + * @param annotations optional key/value annotations + */ + public OduCltPort(Element element, PortNumber number, boolean isEnabled, + SignalType signalType, Annotations... annotations) { + super(element, number, isEnabled, Type.ODUCLT, 0, annotations); + this.signalType = signalType; + } + + /** + * Returns ODU client signal type. + * + * @return ODU client signal type + */ + public SignalType signalType() { + return signalType; + } + + @Override + public int hashCode() { + return Objects.hash(number(), isEnabled(), type(), signalType, annotations()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OduCltPort) { + final OduCltPort other = (OduCltPort) obj; + return Objects.equals(this.element().id(), other.element().id()) && + Objects.equals(this.number(), other.number()) && + Objects.equals(this.isEnabled(), other.isEnabled()) && + Objects.equals(this.signalType, other.signalType) && + Objects.equals(this.annotations(), other.annotations()); + } + return false; + } + + + @Override + public String toString() { + return toStringHelper(this) + .add("element", element().id()) + .add("number", number()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("signalType", signalType) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduSignalType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduSignalType.java new file mode 100644 index 00000000..014c893b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OduSignalType.java @@ -0,0 +1,33 @@ +/* + * 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; + +/** + * Represents ODU (Optical channel Data Unit) signal type. + * + * <p> + * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)" and + * Open Networking Foundation "Optical Transport Protocol Extensions Version 1.0". + * </p> + */ +public enum OduSignalType { + ODU0, + ODU1, + ODU2, + ODU2e, + ODU3, + ODU4 +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java new file mode 100644 index 00000000..753834b5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/OmsPort.java @@ -0,0 +1,131 @@ +/* + * 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; + +import org.onlab.util.Frequency; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of OMS port (Optical Multiplexing Section). + * Also referred to as a WDM port or W-port. + * See ITU G.709 "Interfaces for the Optical Transport Network (OTN)" + * + * Assumes we only support fixed grid for now. + */ +public class OmsPort extends DefaultPort { + + private final Frequency minFrequency; // Minimum frequency + private final Frequency maxFrequency; // Maximum frequency + private final Frequency grid; // Grid spacing frequency + + + /** + * Creates an OMS port in the specified network element. + * + * @param element parent network element + * @param number port number + * @param isEnabled port enabled state + * @param minFrequency minimum frequency + * @param maxFrequency maximum frequency + * @param grid grid spacing frequency + * @param annotations optional key/value annotations + */ + public OmsPort(Element element, PortNumber number, boolean isEnabled, + Frequency minFrequency, Frequency maxFrequency, Frequency grid, Annotations... annotations) { + super(element, number, isEnabled, Type.OMS, 0, annotations); + this.minFrequency = minFrequency; + this.maxFrequency = maxFrequency; + this.grid = grid; + } + + /** + * Returns the total number of channels on the port. + * + * @return total number of channels + */ + public short totalChannels() { + Frequency diff = maxFrequency.subtract(minFrequency); + return (short) (diff.asHz() / (grid.asHz() + 1)); + } + + /** + * Returns the minimum frequency. + * + * @return minimum frequency + */ + public Frequency minFrequency() { + return minFrequency; + } + + /** + * Returns the maximum frequency. + * + * @return maximum frequency + */ + public Frequency maxFrequency() { + return maxFrequency; + } + + /** + * Returns the grid spacing frequency. + * + * @return grid spacing frequency + */ + public Frequency grid() { + return grid; + } + + @Override + public int hashCode() { + return Objects.hash(number(), isEnabled(), type(), + minFrequency, maxFrequency, grid, annotations()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OmsPort) { + final OmsPort other = (OmsPort) obj; + return Objects.equals(this.element().id(), other.element().id()) && + Objects.equals(this.number(), other.number()) && + Objects.equals(this.isEnabled(), other.isEnabled()) && + Objects.equals(this.minFrequency, other.minFrequency) && + Objects.equals(this.maxFrequency, other.maxFrequency) && + Objects.equals(this.grid, other.grid) && + Objects.equals(this.annotations(), other.annotations()); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("element", element().id()) + .add("number", number()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("minFrequency", minFrequency) + .add("maxFrequency", maxFrequency) + .add("grid", grid) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Path.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Path.java new file mode 100644 index 00000000..c9c20c4c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Path.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014 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; + +import java.util.List; + +/** + * Representation of a contiguous directed path in a network. Path comprises + * of a sequence of links, where adjacent links must share the same device, + * meaning that destination of the source of one link must coincide with the + * destination of the previous link. + */ +public interface Path extends Link { + + /** + * Returns sequence of links comprising the path. + * + * @return list of links + */ + List<Link> links(); + + /** + * Returns the path cost as a unit-less value. + * + * @return unit-less path cost + */ + double cost(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Port.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Port.java new file mode 100644 index 00000000..d70b1e17 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Port.java @@ -0,0 +1,100 @@ +/* + * Copyright 2014 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; + + +/** + * Abstraction of a network port. + */ +public interface Port extends Annotated { + + /** Represents coarse port type classification. */ + enum Type { + /** + * Signifies copper-based connectivity. + */ + COPPER, + + /** + * Signifies optical fiber-based connectivity. + */ + FIBER, + + /** + * Signifies optical fiber-based packet port. + */ + PACKET, + + /** + * Signifies optical fiber-based optical tributary port (called T-port). + * The signal from the client side will be formed into a ITU G.709 (OTN) frame. + */ + ODUCLT, + + /** + * Signifies optical fiber-based Line-side port (called L-port). + */ + OCH, + + /** + * Signifies optical fiber-based WDM port (called W-port). + * Optical Multiplexing Section (See ITU G.709). + */ + OMS, + + /** + * Signifies virtual port. + */ + VIRTUAL + } + + /** + * Returns the parent network element to which this port belongs. + * + * @return parent network element + */ + Element element(); + + /** + * Returns the port number. + * + * @return port number + */ + PortNumber number(); + + /** + * Indicates whether or not the port is currently up and active. + * + * @return true if the port is operational + */ + boolean isEnabled(); + + /** + * Returns the port type. + * + * @return port type + */ + Type type(); + + /** + * Returns the current port speed in Mbps. + * + * @return current port speed + */ + long portSpeed(); + + // TODO: more attributes? +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java new file mode 100644 index 00000000..03e6dba9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java @@ -0,0 +1,182 @@ +/* + * Copyright 2014-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; + +import com.google.common.primitives.UnsignedLongs; + +/** + * Representation of a port number. + */ +public final class PortNumber { + + public static final PortNumber P0 = portNumber(0); + + // TODO: revisit the max and the logical port value assignments + + private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1; + + + static final long IN_PORT_NUMBER = -8L; + static final long TABLE_NUMBER = -7L; + static final long NORMAL_NUMBER = -6L; + static final long FLOOD_NUMBER = -5L; + static final long ALL_NUMBER = -4L; + static final long LOCAL_NUMBER = -2L; + static final long CONTROLLER_NUMBER = -3L; + + public static final PortNumber IN_PORT = new PortNumber(IN_PORT_NUMBER); + public static final PortNumber TABLE = new PortNumber(TABLE_NUMBER); + public static final PortNumber NORMAL = new PortNumber(NORMAL_NUMBER); + public static final PortNumber FLOOD = new PortNumber(FLOOD_NUMBER); + public static final PortNumber ALL = new PortNumber(ALL_NUMBER); + public static final PortNumber LOCAL = new PortNumber(LOCAL_NUMBER); + public static final PortNumber CONTROLLER = new PortNumber(CONTROLLER_NUMBER); + + private final long number; + private final String name; + private final boolean hasName; + + // Public creation is prohibited + private PortNumber(long number) { + this.number = number; + this.name = UnsignedLongs.toString(number); + this.hasName = false; + } + + private PortNumber(long number, String name) { + this.number = number; + this.name = name; + this.hasName = true; + } + + /** + * Returns the port number representing the specified long value. + * + * @param number port number as long value + * @return port number + */ + public static PortNumber portNumber(long number) { + return new PortNumber(number); + } + + /** + * Returns the port number representing the specified string value. + * + * @param string port number as string value + * @return port number + */ + public static PortNumber portNumber(String string) { + return new PortNumber(UnsignedLongs.decode(string)); + } + + /** + * Returns the port number representing the specified long value and name. + * + * @param number port number as long value + * @param name port name as string value + * @return port number + */ + public static PortNumber portNumber(long number, String name) { + return new PortNumber(number, name); + } + + /** + * Indicates whether or not this port number is a reserved logical one or + * whether it corresponds to a normal physical port of a device or NIC. + * + * @return true if logical port number + */ + public boolean isLogical() { + if (hasName) { + return false; + } else { + return (number < 0 || number > MAX_NUMBER); + } + } + + /** + * Returns the backing long value. + * + * @return port number as long + */ + public long toLong() { + return number; + } + + /** + * Returns the backing string value. + * + * @return port name as string value + */ + public String name() { + return name; + } + + /** + * Indicates whether this port number was created with a port name, + * or only with a number. + * + * @return true if port was created with name + */ + public boolean hasName() { + return hasName; + } + + private String decodeLogicalPort() { + if (number == CONTROLLER_NUMBER) { + return "CONTROLLER"; + } else if (number == LOCAL_NUMBER) { + return "LOCAL"; + } else if (number == ALL_NUMBER) { + return "ALL"; + } else if (number == FLOOD_NUMBER) { + return "FLOOD"; + } else if (number == NORMAL_NUMBER) { + return "NORMAL"; + } else if (number == TABLE_NUMBER) { + return "TABLE"; + } else if (number == IN_PORT_NUMBER) { + return "IN_PORT"; + } + return "UNKNOWN"; + } + + @Override + public String toString() { + if (!isLogical()) { + return name; + } else { + return decodeLogicalPort(); + } + } + + @Override + public int hashCode() { + return Long.hashCode(number); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PortNumber) { + final PortNumber other = (PortNumber) obj; + return this.number == other.number; + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/Provided.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Provided.java new file mode 100644 index 00000000..daf85e75 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/Provided.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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; + +import org.onosproject.net.provider.ProviderId; + +/** + * Abstraction of an entity supplied by a provider. + */ +public interface Provided { + + /** + * Returns the identifier of the provider which supplied the entity. + * + * @return provider identification + */ + ProviderId providerId(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/SparseAnnotations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/SparseAnnotations.java new file mode 100644 index 00000000..97961b3a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/SparseAnnotations.java @@ -0,0 +1,44 @@ +/* + * Copyright 2014 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; + +import java.util.Set; + +/** + * Represents an set of sparse key/value string annotations capable of carrying + * annotation keys tagged for removal. + */ +public interface SparseAnnotations extends Annotations { + + /** + * {@inheritDoc} + * <p> + * Note that this set includes keys for any attributes tagged for removal. + * </p> + */ + @Override + Set<String> keys(); + + /** + * Indicates whether the specified key has been tagged as removed. This is + * used for merging sparse annotation sets. + * + * @param key annotation key + * @return true if the previous annotation has been tagged for removal + */ + boolean isRemoved(String key); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java new file mode 100644 index 00000000..7f157e95 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java @@ -0,0 +1,87 @@ +/* + * 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.behaviour; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.onosproject.net.PortNumber; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * Behaviour for handling various drivers for bridge configurations. + */ +public interface BridgeConfig extends HandlerBehaviour { + + /** + * Add a bridge. + * + * @param bridgeName bridge name + */ + void addBridge(BridgeName bridgeName); + + /** + * Remove a bridge. + * + * @param bridgeName bridge name + */ + void deleteBridge(BridgeName bridgeName); + + /** + * Remove a bridge. + * + * @return bridge collection + */ + Collection<BridgeDescription> getBridges(); + + /** + * Add a logical/virtual port. + * + * @param port port number + */ + void addPort(PortDescription port); + + /** + * Delete a logical/virtual port. + * + * @param port port number + */ + void deletePort(PortDescription port); + + /** + * Delete a logical/virtual port. + * + * @return collection of port + */ + Collection<PortDescription> getPorts(); + + /** + * Get a collection of port. + * + * @return portNumbers set of PortNumber + */ + Set<PortNumber> getPortNumbers(); + + /** + * Get logical/virtual ports by ifaceIds. + * + * @param ifaceIds the ifaceid that needed + * @return list of PortNumber + */ + List<PortNumber> getLocalPorts(Iterable<String> ifaceIds); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeDescription.java new file mode 100644 index 00000000..3c1d5542 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeDescription.java @@ -0,0 +1,46 @@ +/* + * Copyright 2014-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.behaviour; + +import org.onosproject.net.Description; +import org.onosproject.net.DeviceId; + +/** + * The abstraction of bridge in OVSDB protocol. + */ +public interface BridgeDescription extends Description { + + /** + * Returns bridge name. + * + * @return bridge name + */ + BridgeName bridgeName(); + + /** + * Returns controller identifier that this bridge belongs to. + * + * @return controller identifier + */ + DeviceId cotrollerDeviceId(); + + /** + * Returns bridge identifier . + * + * @return bridge identifier + */ + DeviceId deviceId(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java new file mode 100644 index 00000000..3f782954 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-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.behaviour; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +/** + * Represents for a bridge name. + */ +public final class BridgeName { + + private final String name; + + // Public construction is prohibited + private BridgeName(String name) { + this.name = name; + } + + /** + * Creates a bridge name using the supplied string. + * + * @param name bridge name + * @return BridgeName + */ + public static BridgeName bridgeName(String name) { + return new BridgeName(name); + } + + /** + * Returns the bridge name string. + * + * @return name string + */ + public String name() { + return name; + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof BridgeName) { + final BridgeName that = (BridgeName) obj; + return this.getClass() == that.getClass() && + Objects.equals(this.name, that.name); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("name", name) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerConfig.java new file mode 100644 index 00000000..bb8a788b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerConfig.java @@ -0,0 +1,39 @@ +/* + * 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.behaviour; + +import java.util.List; + +/** + * Device behaviour to obtain and set controllers at the device. + */ +public interface ControllerConfig { + + //TODO: add other controller parameters as needed. + + /** + * Obtain the list of controller which are currently configured. + * @return a list for controller descriptions + */ + List<ControllerInfo> getControllers(); + + /** + * Set a list of controllers on a device. + * @param controllers a list of controller descriptions + */ + void setControllers(List<ControllerInfo> controllers); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerInfo.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerInfo.java new file mode 100644 index 00000000..9ff808a9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ControllerInfo.java @@ -0,0 +1,38 @@ +/* + * 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.behaviour; + +import org.onlab.packet.IpAddress; + +/** + * Represents information for a device to connect to a controller. + */ +public class ControllerInfo { + + public final IpAddress ip; + public final int tcpPort; + + /** + * Information for contacting the controller. + * + * @param ip the ip address + * @param tcpPort the tcp port + */ + public ControllerInfo(IpAddress ip, int tcpPort) { + this.ip = ip; + this.tcpPort = tcpPort; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java new file mode 100644 index 00000000..6a6f670f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java @@ -0,0 +1,87 @@ +/* + * Copyright 2014-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.behaviour; + +import java.util.Objects; + +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.DeviceId; +import org.onosproject.net.SparseAnnotations; + +import com.google.common.base.MoreObjects; + +/** + * The default implementation of bridge. + */ +public final class DefaultBridgeDescription extends AbstractDescription + implements BridgeDescription { + + private final BridgeName name; + private final DeviceId deviceId; + private final DeviceId controllerId; + + public DefaultBridgeDescription(BridgeName name, DeviceId controllerId, + DeviceId deviceId, + SparseAnnotations... annotations) { + super(annotations); + this.name = name; + this.deviceId = deviceId; + this.controllerId = controllerId; + } + + @Override + public BridgeName bridgeName() { + return name; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public DeviceId cotrollerDeviceId() { + return controllerId; + } + + @Override + public int hashCode() { + return Objects.hash(name, deviceId, controllerId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultBridgeDescription) { + final DefaultBridgeDescription that = (DefaultBridgeDescription) obj; + return this.getClass() == that.getClass() + && Objects.equals(this.name, that.name) + && Objects.equals(this.deviceId, that.deviceId) + && Objects.equals(this.controllerId, that.controllerId); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("name", name) + .add("deviceId", deviceId).add("controllerId", controllerId) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultNextGroup.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultNextGroup.java new file mode 100644 index 00000000..ef1f9de7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultNextGroup.java @@ -0,0 +1,33 @@ +/* + * 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.behaviour; + +/** + * Default implementation of a next group. + */ +public class DefaultNextGroup implements NextGroup { + + private final byte[] data; + + public DefaultNextGroup(byte[] data) { + this.data = data; + } + + @Override + public byte[] data() { + return data; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultTunnelDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultTunnelDescription.java new file mode 100644 index 00000000..7554a3cb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/DefaultTunnelDescription.java @@ -0,0 +1,87 @@ +/* + * 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.behaviour; + +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; + +/** + * Default implementation of immutable tunnel description entity. + */ +@Beta +public class DefaultTunnelDescription extends AbstractDescription + implements TunnelDescription { + + private final TunnelEndPoint src; + private final TunnelEndPoint dst; + private final Type type; + // which a tunnel match up + // tunnel producer + private final TunnelName tunnelName; // name of a tunnel + + /** + * Creates a tunnel description using the supplied information. + * + * @param src TunnelPoint source + * @param dst TunnelPoint destination + * @param type tunnel type + * @param tunnelName tunnel name + * @param annotations optional key/value annotations + */ + public DefaultTunnelDescription(TunnelEndPoint src, + TunnelEndPoint dst, Type type, + TunnelName tunnelName, + SparseAnnotations... annotations) { + super(annotations); + this.src = src; + this.dst = dst; + this.type = type; + this.tunnelName = tunnelName; + } + + @Override + public TunnelEndPoint src() { + return src; + } + + @Override + public TunnelEndPoint dst() { + return dst; + } + + @Override + public Type type() { + return type; + } + + @Override + public TunnelName tunnelName() { + return tunnelName; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("src", src()) + .add("dst", dst()) + .add("type", type()) + .add("tunnelName", tunnelName()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/IpTunnelEndPoint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/IpTunnelEndPoint.java new file mode 100644 index 00000000..83ad4756 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/IpTunnelEndPoint.java @@ -0,0 +1,80 @@ +/* + * 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.behaviour; + +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onlab.packet.IpAddress; + +import com.google.common.base.MoreObjects; + +/** + * Represent for a tunnel point using ip address. + */ +@Beta +public final class IpTunnelEndPoint implements TunnelEndPoint { + + private final IpAddress ip; + + /** + * Public construction is prohibited. + * @param ip ip address + */ + private IpTunnelEndPoint(IpAddress ip) { + this.ip = ip; + } + + /** + * Create a IP tunnel end point. + * @param ip IP address + * @return IpTunnelEndPoint + */ + public static IpTunnelEndPoint ipTunnelPoint(IpAddress ip) { + return new IpTunnelEndPoint(ip); + } + + /** + * Returns IP address. + * @return IP address + */ + public IpAddress ip() { + return ip; + } + + @Override + public int hashCode() { + return Objects.hash(ip); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IpTunnelEndPoint) { + final IpTunnelEndPoint other = (IpTunnelEndPoint) obj; + return Objects.equals(this.ip, other.ip); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()).add("ip", ip).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/MplsQuery.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/MplsQuery.java new file mode 100644 index 00000000..0e9f466d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/MplsQuery.java @@ -0,0 +1,35 @@ +/* + * 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.behaviour; + +import com.google.common.annotations.Beta; +import org.onosproject.net.PortNumber; +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * A HandlerBehaviour to check the capability of MPLS. + */ +@Beta +public interface MplsQuery extends HandlerBehaviour { + + /** + * Indicates if MPLS can be used at the port. + + * @param port port to be checked for the capability + * @return true if MPLS can be used at the port, false otherwise. + */ + boolean isEnabled(PortNumber port); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/NextGroup.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/NextGroup.java new file mode 100644 index 00000000..b5a3891c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/NextGroup.java @@ -0,0 +1,30 @@ +/* + * 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.behaviour; + +/** + * Opaque data type for carrying group-like information. + * Only relevant to a pipeliner driver. + */ +public interface NextGroup { + + /** + * Serialized form of the next group. + * @return a byte array. + */ + byte[] data(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java new file mode 100644 index 00000000..dcfc5883 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java @@ -0,0 +1,57 @@ +/* + * 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.behaviour; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.HandlerBehaviour; +import org.onosproject.net.flowobjective.FilteringObjective; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.NextObjective; + +/** + * Behaviour for handling various pipelines. + */ +public interface Pipeliner extends HandlerBehaviour { + + /** + * Initializes the driver with context required for its operation. + * + * @param deviceId the deviceId + * @param context processing context + */ + void init(DeviceId deviceId, PipelinerContext context); + + /** + * Installs the filtering rules onto the device. + * + * @param filterObjective a filtering objective + */ + void filter(FilteringObjective filterObjective); + + /** + * Installs the forwarding rules onto the device. + * + * @param forwardObjective a forwarding objective + */ + void forward(ForwardingObjective forwardObjective); + + /** + * Installs the next hop elements into the device. + * + * @param nextObjective a next objectives + */ + void next(NextObjective nextObjective); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PipelinerContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PipelinerContext.java new file mode 100644 index 00000000..d0ca42b1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PipelinerContext.java @@ -0,0 +1,41 @@ +/* + * 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.behaviour; + +import org.onlab.osgi.ServiceDirectory; +import org.onosproject.net.flowobjective.FlowObjectiveStore; + +/** + * Processing context and supporting services for the pipeline behaviour. + */ +public interface PipelinerContext { + + /** + * Returns the service directory which can be used to obtain references + * to various supporting services. + * + * @return service directory + */ + ServiceDirectory directory(); + + /** + * Returns the Objective Store where data can be stored and retrieved. + * @return the flow objective store + */ + FlowObjectiveStore store(); + + // TODO: add means to store and access shared state +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortAdmin.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortAdmin.java new file mode 100644 index 00000000..141e27dc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortAdmin.java @@ -0,0 +1,33 @@ +/* + * 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.behaviour; + +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * Means to administratively enable/disable a logical port at the device. + */ +public interface PortAdmin extends HandlerBehaviour { + + /** + * Enable/disable administratively a port. + * + * @param port a port description containing the desired port state + */ + void enable(PortDescription port); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortConfig.java new file mode 100644 index 00000000..83dd99d8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/PortConfig.java @@ -0,0 +1,40 @@ +/* + * 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.behaviour; + +import com.google.common.primitives.UnsignedInteger; +import org.onosproject.net.device.PortDescription; +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * Means to configure a logical port at the device. + */ +public interface PortConfig extends HandlerBehaviour { + + /** + * Apply QoS configuration on a device. + * @param port a port description + * @param queueId an unsigned integer + */ + void applyQoS(PortDescription port, UnsignedInteger queueId); + + /** + * Remove a QoS configuration. + * @param port a port description + */ + void removeQoS(PortDescription port); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueConfig.java new file mode 100644 index 00000000..22f3ecb7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueConfig.java @@ -0,0 +1,56 @@ +/* + * 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.behaviour; + +import com.google.common.primitives.UnsignedInteger; + +import java.util.Set; + +/** + * Means to alter a device's dataplane queues. + */ +public interface QueueConfig { + + /** + * Obtain all queues configured on a device. + * + * @return a list of queue descriptions + */ + Set<QueueInfo> getQueues(); + + /** + * Obtain a specific queue given a queue id. + * + * @param queueId an unsigned integer representing a queue id + * @return a queue description + */ + QueueInfo getQueue(UnsignedInteger queueId); + + /** + * Add a queue to a device. + * + * @param queue a queue description + */ + void addQueue(QueueInfo queue); + + /** + * Remove a queue from a device. + * + * @param queueId an unsigned integer + */ + void removeQueue(UnsignedInteger queueId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueInfo.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueInfo.java new file mode 100644 index 00000000..25852b36 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/QueueInfo.java @@ -0,0 +1,56 @@ +/* + * 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.behaviour; + +import com.google.common.primitives.UnsignedInteger; + +/** + * Represents a dataplane queue. + */ +public class QueueInfo { + + public enum Type { + /** + * Supports burst and priority as well as min and max rates. + */ + FULL, + + /** + * Only support min and max rates. + */ + MINMAX + } + + private final UnsignedInteger queueId; + private final Type type; + private final long minRate; + private final long maxRate; + private final long burst; + private final long priority; + + public QueueInfo(UnsignedInteger queueId, Type type, long minRate, + long maxRate, long burst, long priority) { + this.queueId = queueId; + this.type = type; + this.minRate = minRate; + this.maxRate = maxRate; + this.burst = burst; + this.priority = priority; + } + + //TODO builder + // public static QueueInfoBuilder builder() {} +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java new file mode 100644 index 00000000..7e79a57e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java @@ -0,0 +1,55 @@ +/* + * 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.behaviour; + +import java.util.Collection; + +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * Behaviour for handling various drivers for tunnel configuration. + */ +public interface TunnelConfig extends HandlerBehaviour { + + /** + * Creates a tunnel on this device. + * + * @param tunnel tunnel descriptor + */ + void createTunnel(TunnelDescription tunnel); + + /** + * Removes a tunnel on this device. + * + * @param tunnel tunnel descriptor + */ + void removeTunnel(TunnelDescription tunnel); + + /** + * Updates a tunnel on this device. + * + * @param tunnel tunnel descriptor + */ + void updateTunnel(TunnelDescription tunnel); + + /** + * Returns tunnels created on this device. + * + * @return collection of tunnels + */ + Collection<TunnelDescription> getTunnels(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelDescription.java new file mode 100755 index 00000000..b2fb6996 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelDescription.java @@ -0,0 +1,86 @@ +/* + * 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.behaviour; + +import org.onosproject.net.Annotated; +import org.onosproject.net.Description; + +import com.google.common.annotations.Beta; + +/** + * Describes a tunnel. + */ +@Beta +public interface TunnelDescription extends Description, Annotated { + + /** + * Tunnel technology type. + */ + enum Type { + /** + * Signifies that this is a MPLS tunnel. + */ + MPLS, + /** + * Signifies that this is a L2 tunnel. + */ + VLAN, + /** + * Signifies that this is a DC L2 extension tunnel. + */ + VXLAN, + /** + * Signifies that this is a L3 tunnel. + */ + GRE, + /** + * Signifies that this is a L1 OTN tunnel. + */ + ODUK, + /** + * Signifies that this is a L0 OCH tunnel. + */ + OCH + } + + /** + * Returns the connection point source. + * + * @return tunnel source ConnectionPoint + */ + TunnelEndPoint src(); + + /** + * Returns the connection point destination. + * + * @return tunnel destination + */ + TunnelEndPoint dst(); + + /** + * Returns the tunnel type. + * + * @return tunnel type + */ + Type type(); + + /** + * Return the name of a tunnel. + * + * @return Tunnel Name + */ + TunnelName tunnelName(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelEndPoint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelEndPoint.java new file mode 100644 index 00000000..c354c38d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelEndPoint.java @@ -0,0 +1,28 @@ +/* + * 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.behaviour; + +import com.google.common.annotations.Beta; + +/** + * Represents for source end point or destination end point of a tunnel. Maybe a tunnel + * based on ConnectPoint, IpAddress, MacAddress and so on is built. + */ +@Beta +public interface TunnelEndPoint { + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelName.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelName.java new file mode 100644 index 00000000..9be26549 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelName.java @@ -0,0 +1,79 @@ +/* + * 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.behaviour; + +import com.google.common.annotations.Beta; + +import java.util.Objects; + +/** + * Represents for a unique tunnel name. TunnelId is generated by ONOS while + * TunnelName is given by producer. The consumer can borrow tunnels with + * TunnelId or TunnelName. + */ +@Beta +public final class TunnelName { + private final String str; + + // Default constructor for serialization + private TunnelName(String tunnelName) { + this.str = tunnelName; + } + + + /** + * Creates a tunnel name using the supplied URI string. + * + * @param tunnelName tunnel name string + * @return tunnel name object + */ + public static TunnelName tunnelName(String tunnelName) { + return new TunnelName(tunnelName); + } + + /** + * The string of tunnel name. + * + * @return the string of tunnel name + */ + public String value() { + return str; + } + + @Override + public int hashCode() { + return Objects.hash(str); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TunnelName) { + final TunnelName that = (TunnelName) obj; + return this.getClass() == that.getClass() + && Objects.equals(this.str, that.str); + } + return false; + } + + @Override + public String toString() { + return str; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/VlanQuery.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/VlanQuery.java new file mode 100644 index 00000000..a1057c90 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/VlanQuery.java @@ -0,0 +1,35 @@ +/* + * 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.behaviour; + +import com.google.common.annotations.Beta; +import org.onosproject.net.PortNumber; +import org.onosproject.net.driver.HandlerBehaviour; + +/** + * A HandlerBehaviour to check the capability of VLAN. + */ +@Beta +public interface VlanQuery extends HandlerBehaviour { + + /** + * Indicates if VLAN can be used at the port. + * + * @param port port to be checked for the capability + * @return true if VLAN can be used at the port, false otherwise. + */ + boolean isEnabled(PortNumber port); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/package-info.java new file mode 100644 index 00000000..f0a9a5e5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Abstractions of various device configuration or device adaptation behaviours; + * counterpart to the device driver subsystem. + */ +package org.onosproject.net.behaviour;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java new file mode 100644 index 00000000..5cdc0c12 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java @@ -0,0 +1,312 @@ +/* + * 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.config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.annotations.Beta; +import com.google.common.collect.Lists; + +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Base abstraction of a configuration facade for a specific subject. Derived + * classes should keep all state in the specified JSON tree as that is the + * only state that will be distributed or persisted; this class is merely + * a facade for interacting with a particular facet of configuration on a + * given subject. + * + * @param <S> type of subject + */ +@Beta +public abstract class Config<S> { + + protected S subject; + protected String key; + + protected JsonNode node; + protected ObjectNode object; + protected ArrayNode array; + protected ObjectMapper mapper; + + protected ConfigApplyDelegate delegate; + + /** + * Initializes the configuration behaviour with necessary context. + * + * @param subject configuration subject + * @param key configuration key + * @param node JSON node where configuration data is stored + * @param mapper JSON object mapper + * @param delegate delegate context + */ + public void init(S subject, String key, JsonNode node, ObjectMapper mapper, + ConfigApplyDelegate delegate) { + this.subject = checkNotNull(subject); + this.key = key; + this.node = checkNotNull(node); + this.object = node instanceof ObjectNode ? (ObjectNode) node : null; + this.array = node instanceof ArrayNode ? (ArrayNode) node : null; + this.mapper = checkNotNull(mapper); + this.delegate = checkNotNull(delegate); + } + + /** + * Returns the specific subject to which this configuration pertains. + * + * @return configuration subject + */ + public S subject() { + return subject; + } + + /** + * Returns the configuration key. This is primarily aimed for use in + * composite JSON trees in external representations and has no bearing on + * the internal behaviours. + * + * @return configuration key + */ + public String key() { + return key; + } + + /** + * Returns the JSON node that contains the configuration data. + * + * @return JSON node backing the configuration + */ + public JsonNode node() { + return node; + } + + /** + * Applies any configuration changes made via this configuration. + */ + public void apply() { + delegate.onApply(this); + } + + + // Miscellaneous helpers for interacting with JSON + + /** + * Gets the specified property as a string. + * + * @param name property name + * @param defaultValue default value if property not set + * @return property value or default value + */ + protected String get(String name, String defaultValue) { + return object.path(name).asText(defaultValue); + } + + /** + * Sets the specified property as a string or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @return self + */ + protected Config<S> setOrClear(String name, String value) { + if (value != null) { + object.put(name, value); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified property as a boolean. + * + * @param name property name + * @param defaultValue default value if property not set + * @return property value or default value + */ + protected boolean get(String name, boolean defaultValue) { + return object.path(name).asBoolean(defaultValue); + } + + /** + * Sets the specified property as a boolean or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @return self + */ + protected Config<S> setOrClear(String name, Boolean value) { + if (value != null) { + object.put(name, value.booleanValue()); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified property as an integer. + * + * @param name property name + * @param defaultValue default value if property not set + * @return property value or default value + */ + protected int get(String name, int defaultValue) { + return object.path(name).asInt(defaultValue); + } + + /** + * Sets the specified property as an integer or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @return self + */ + protected Config<S> setOrClear(String name, Integer value) { + if (value != null) { + object.put(name, value.intValue()); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified property as a long. + * + * @param name property name + * @param defaultValue default value if property not set + * @return property value or default value + */ + protected long get(String name, long defaultValue) { + return object.path(name).asLong(defaultValue); + } + + /** + * Sets the specified property as a long or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @return self + */ + protected Config<S> setOrClear(String name, Long value) { + if (value != null) { + object.put(name, value.longValue()); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified property as a double. + * + * @param name property name + * @param defaultValue default value if property not set + * @return property value or default value + */ + protected double get(String name, double defaultValue) { + return object.path(name).asDouble(defaultValue); + } + + /** + * Sets the specified property as a double or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @return self + */ + protected Config<S> setOrClear(String name, Double value) { + if (value != null) { + object.put(name, value.doubleValue()); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified property as an enum. + * + * @param name property name + * @param defaultValue default value if property not set + * @param enumClass the enum class + * @param <E> type of enum + * @return property value or default value + */ + protected <E extends Enum<E>> E get(String name, E defaultValue, Class<E> enumClass) { + return Enum.valueOf(enumClass, object.path(name).asText(defaultValue.toString())); + } + + /** + * Sets the specified property as a double or clears it if null value given. + * + * @param name property name + * @param value new value or null to clear the property + * @param <E> type of enum + * @return self + */ + protected <E extends Enum> Config<S> setOrClear(String name, E value) { + if (value != null) { + object.put(name, value.toString()); + } else { + object.remove(name); + } + return this; + } + + /** + * Gets the specified array property as a list of items. + * + * @param name property name + * @param function mapper from string to item + * @param <T> type of item + * @return list of items + */ + protected <T> List<T> getList(String name, Function<String, T> function) { + List<T> list = Lists.newArrayList(); + ArrayNode arrayNode = (ArrayNode) object.path(name); + arrayNode.forEach(i -> list.add(function.apply(i.asText()))); + return list; + } + + /** + * Sets the specified property as an array of items in a given collection or + * clears it if null is given. + * + * @param name propertyName + * @param collection collection of items + * @param <T> type of items + * @return self + */ + protected <T> Config<S> setOrClear(String name, Collection<T> collection) { + if (collection == null) { + object.remove(name); + } else { + ArrayNode arrayNode = mapper.createArrayNode(); + collection.forEach(i -> arrayNode.add(i.toString())); + object.set(name, arrayNode); + } + return this; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigApplyDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigApplyDelegate.java new file mode 100644 index 00000000..1160a097 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigApplyDelegate.java @@ -0,0 +1,33 @@ +/* + * 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.config; + +import com.google.common.annotations.Beta; + +/** + * Delegate for notification when configuration changes have been applied. + */ +@Beta +public interface ConfigApplyDelegate { + + /** + * Processes changes applied to the specified configuration. + * + * @param config changed configuration + */ + void onApply(Config config); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigFactory.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigFactory.java new file mode 100644 index 00000000..25a34025 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigFactory.java @@ -0,0 +1,122 @@ +/* + * 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.config; + + +import com.google.common.annotations.Beta; + +/** + * Base abstract factory for creating configurations for the specified subject type. + * + * @param <S> type of subject + * @param <C> type of configuration + */ +@Beta +public abstract class ConfigFactory<S, C extends Config<S>> { + + private final SubjectFactory<S> subjectFactory; + private final Class<C> configClass; + private final String configKey; + private final boolean isList; + + /** + * Creates a new configuration factory for the specified class of subjects + * capable of generating the configurations of the specified class. The + * subject and configuration class keys are used merely as keys for use in + * composite JSON trees. + * + * @param subjectFactory subject factory + * @param configClass configuration class + * @param configKey configuration class key + */ + protected ConfigFactory(SubjectFactory<S> subjectFactory, + Class<C> configClass, String configKey) { + this(subjectFactory, configClass, configKey, false); + } + + /** + * Creates a new configuration factory for the specified class of subjects + * capable of generating the configurations of the specified class. The + * subject and configuration class keys are used merely as keys for use in + * composite JSON trees. + * <p> + * Note that configurations backed by JSON array are not easily extensible + * at the top-level as they are inherently limited to holding an ordered + * list of items. + * </p> + * + * @param subjectFactory subject factory + * @param configClass configuration class + * @param configKey configuration class key + * @param isList true to indicate backing by JSON array + */ + protected ConfigFactory(SubjectFactory<S> subjectFactory, + Class<C> configClass, String configKey, + boolean isList) { + this.subjectFactory = subjectFactory; + this.configClass = configClass; + this.configKey = configKey; + this.isList = isList; + } + + /** + * Returns the class of the subject to which this factory applies. + * + * @return subject type + */ + public SubjectFactory<S> subjectFactory() { + return subjectFactory; + } + + /** + * Returns the class of the configuration which this factory generates. + * + * @return configuration type + */ + public Class<C> configClass() { + return configClass; + } + + /** + * Returns the unique key (within subject class) of this configuration. + * This is primarily aimed for use in composite JSON trees in external + * representations and has no bearing on the internal behaviours. + * + * @return configuration key + */ + public String configKey() { + return configKey; + } + + /** + * Creates a new but uninitialized configuration. Framework will initialize + * the configuration via {@link Config#init} method. + * + * @return new uninitialized configuration + */ + public abstract C createConfig(); + + /** + * Indicates whether the configuration is a list and should be backed by + * a JSON array rather than JSON object. + * + * @return true if backed by JSON array + */ + public boolean isList() { + return isList; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigOperator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigOperator.java new file mode 100644 index 00000000..505e8b3b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/ConfigOperator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014-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.config; + +/** + * An interface signifying a class that implements network configuration + * information from multiple sources. There is a natural ordering to the + * precedence of information, depending on its source: + * <ol> + * <li>Intents (from applications), which override</li> + * <li>Configs (from the network configuration subsystem), which override</li> + * <li>Descriptions (from southbound)</li> + * </ol> + * i.e., for a field representing the same attribute, the value from a Config + * entity will be used over that from the Description. + */ +public interface ConfigOperator { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigEvent.java new file mode 100644 index 00000000..ee9ceadf --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigEvent.java @@ -0,0 +1,92 @@ +/* + * 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.config; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes network configuration event. + */ +public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, Object> { + + private final Class configClass; + + /** + * Type of network configuration events. + */ + public enum Type { + /** + * Signifies that a network configuration was registered. + */ + CONFIG_REGISTERED, + + /** + * Signifies that a network configuration was unregistered. + */ + CONFIG_UNREGISTERED, + + /** + * Signifies that network configuration was added. + */ + CONFIG_ADDED, + + /** + * Signifies that network configuration was updated. + */ + CONFIG_UPDATED, + + /** + * Signifies that network configuration was removed. + */ + CONFIG_REMOVED + } + + /** + * Creates an event of a given type and for the specified subject and the + * current time. + * + * @param type event type + * @param subject event subject + * @param configClass configuration class + */ + public NetworkConfigEvent(Type type, Object subject, Class configClass) { + super(type, subject); + this.configClass = configClass; + } + + /** + * Creates an event of a given type and for the specified subject and time. + * + * @param type device event type + * @param subject event subject + * @param configClass configuration class + * @param time occurrence time + */ + public NetworkConfigEvent(Type type, Object subject, Class configClass, long time) { + super(type, subject, time); + this.configClass = configClass; + } + + /** + * Returns the class of configuration that has been changed. + * + * @return configuration class + */ + public Class configClass() { + return configClass; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigListener.java new file mode 100644 index 00000000..73177755 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigListener.java @@ -0,0 +1,24 @@ +/* + * 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.config; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving network configuration related events. + */ +public interface NetworkConfigListener extends EventListener<NetworkConfigEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigRegistry.java new file mode 100644 index 00000000..b4937d74 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigRegistry.java @@ -0,0 +1,75 @@ +/* + * 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.config; + +import com.google.common.annotations.Beta; + +import java.util.Set; + +/** + * Service for tracking network configuration factories. It is the basis for + * extensibility to allow various core subsystems or apps to register their + * own configuration factories that permit use to inject additional meta + * information about how various parts of the network should be viewed and + * treated. + */ +@Beta +public interface NetworkConfigRegistry extends NetworkConfigService { + + /** + * Registers the specified configuration factory. + * + * @param configFactory configuration factory + */ + void registerConfigFactory(ConfigFactory configFactory); + + /** + * Unregisters the specified configuration factory. + * + * @param configFactory configuration factory + */ + void unregisterConfigFactory(ConfigFactory configFactory); + + /** + * Returns set of all registered configuration factories. + * + * @return set of config factories + */ + Set<ConfigFactory> getConfigFactories(); + + /** + * Returns set of all configuration factories registered for the specified + * class of subject. + * + * @param subjectClass subject class + * @param <S> type of subject + * @param <C> type of configuration + * @return set of config factories + */ + <S, C extends Config<S>> Set<ConfigFactory<S, C>> getConfigFactories(Class<S> subjectClass); + + /** + * Returns the configuration factory that produces the specified class of + * configurations. + * + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return config factory + */ + <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java new file mode 100644 index 00000000..c1eed980 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java @@ -0,0 +1,146 @@ +/* + * 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.config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.annotations.Beta; +import org.onosproject.event.ListenerService; + +import java.util.Set; + +/** + * Service for tracking network configurations which specify how the discovered + * network information should be interpreted and how the core or applications + * should act on or configure the network. + */ +@Beta +public interface NetworkConfigService + extends ListenerService<NetworkConfigEvent, NetworkConfigListener> { + + /** + * Returns the set of subject classes for which configuration may be + * available. + * + * @return set of subject classes + */ + Set<Class> getSubjectClasses(); + + /** + * Returns the subject factory with the specified key. + * + * @param subjectKey subject class key + * @return subject class + */ + SubjectFactory getSubjectFactory(String subjectKey); + + /** + * Returns the subject factory for the specified class. + * + * @param subjectClass subject class + * @return subject class key + */ + SubjectFactory getSubjectFactory(Class subjectClass); + + /** + * Returns the configuration class with the specified key. + * + * @param subjectKey subject class key + * @param configKey subject class name + * @return subject class + */ + Class<? extends Config> getConfigClass(String subjectKey, String configKey); + + /** + * Returns the set of subjects for which some configuration is available. + * + * @param subjectClass subject class + * @param <S> type of subject + * @return set of configured subjects + */ + <S> Set<S> getSubjects(Class<S> subjectClass); + + /** + * Returns the set of subjects for which the specified configuration is + * available. + * + * @param subjectClass subject class + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return set of configured subjects + */ + <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass); + + /** + * Returns all configurations for the specified subject. + * + * @param subject configuration subject + * @param <S> type of subject + * @return set of configurations + */ + <S> Set<? extends Config<S>> getConfigs(S subject); + + /** + * Returns the configuration for the specified subject and configuration + * class if one is available; null otherwise. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration or null if one is not available + */ + <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass); + + /** + * Creates a new configuration for the specified subject and configuration + * class. If one already exists, it is simply returned. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration or null if one is not available + */ + <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass); + + /** + * Applies configuration for the specified subject and configuration + * class using the raw JSON object. If configuration already exists, it + * will be updated. + * + * @param subject configuration subject + * @param configClass configuration class + * @param json raw JSON node containing the configuration data + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration or null if one is not available + */ + <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, + JsonNode json); + + /** + * Clears any configuration for the specified subject and configuration + * class. If one does not exist, this call has no effect. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + */ + <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java new file mode 100644 index 00000000..9dd66e8d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java @@ -0,0 +1,130 @@ +/* + * 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.config; + +import com.fasterxml.jackson.databind.JsonNode; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Mechanism for distributing and storing network configuration information. + */ +public interface NetworkConfigStore extends Store<NetworkConfigEvent, NetworkConfigStoreDelegate> { + + /** + * Adds a new configuration factory. + * + * @param configFactory configuration factory to add + */ + void addConfigFactory(ConfigFactory configFactory); + + /** + * Removes a configuration factory. + * + * @param configFactory configuration factory to remove + */ + void removeConfigFactory(ConfigFactory configFactory); + + /** + * Returns the configuration factory for the specified configuration class. + * + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration factory or null + */ + <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass); + + /** + * Returns set of subjects of the specified class, which have some + * network configuration associated with them. + * + * @param subjectClass subject class + * @param <S> type of subject + * @return set of subject + */ + <S> Set<S> getSubjects(Class<S> subjectClass); + + /** + * Returns set of subjects of the specified class, which have the + * specified class of network configuration associated with them. + * + * @param subjectClass subject class + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return set of subject + */ + <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass); + + /** + * Returns set of configuration classes available for the specified subject. + * + * @param subject configuration subject + * @param <S> type of subject + * @return set of configuration classes + */ + <S> Set<Class<? extends Config<S>>> getConfigClasses(S subject); + + /** + * Get the configuration of the given class and for the specified subject. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration object + */ + <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass); + + /** + * Creates a new configuration of the given class for the specified subject. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration object + */ + <S, C extends Config<S>> C createConfig(S subject, Class<C> configClass); + + /** + * Applies configuration for the specified subject and configuration + * class using the raw JSON object. If configuration already exists, it + * will be updated. + * + * @param subject configuration subject + * @param configClass configuration class + * @param json raw JSON node containing the configuration data + * @param <S> type of subject + * @param <C> type of configuration + * @return configuration object + */ + <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, + JsonNode json); + + /** + * Clears the configuration of the given class for the specified subject. + * + * @param subject configuration subject + * @param configClass configuration class + * @param <S> type of subject + * @param <C> type of configuration + */ + <S, C extends Config<S>> void clearConfig(S subject, Class<C> configClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStoreDelegate.java new file mode 100644 index 00000000..15d3d3e8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * 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.config; + +import org.onosproject.store.StoreDelegate; + +/** + * Network configuration store delegate abstraction. + */ +public interface NetworkConfigStoreDelegate extends StoreDelegate<NetworkConfigEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/SubjectFactory.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/SubjectFactory.java new file mode 100644 index 00000000..cd2db344 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/SubjectFactory.java @@ -0,0 +1,75 @@ +/* + * 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.config; + + +import com.google.common.annotations.Beta; + +/** + * Base abstract factory for creating configuration subjects from their + * string key image. + * + * @param <S> subject class + */ +@Beta +public abstract class SubjectFactory<S> { + + private final Class<S> subjectClass; + private final String subjectKey; + + /** + * Creates a new configuration factory for the specified class of subjects + * capable of generating the configurations of the specified class. The + * subject and configuration class keys are used merely as keys for use in + * composite JSON trees. + * + * @param subjectClass subject class + * @param subjectKey subject class key + */ + protected SubjectFactory(Class<S> subjectClass, String subjectKey) { + this.subjectClass = subjectClass; + this.subjectKey = subjectKey; + } + + /** + * Returns the class of the subject to which this factory applies. + * + * @return subject type + */ + public Class<S> subjectClass() { + return subjectClass; + } + + /** + * Returns the unique key of this configuration subject class. + * This is primarily aimed for use in composite JSON trees in external + * representations and has no bearing on the internal behaviours. + * + * @return configuration key + */ + public String subjectKey() { + return subjectKey; + } + + /** + * Creates a configuration subject from its key image. + * + * @param subjectKey subject class key + * @return configuration subject + */ + public abstract S createSubject(String subjectKey); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/AllowedEntityConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/AllowedEntityConfig.java new file mode 100644 index 00000000..6e6663c4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/AllowedEntityConfig.java @@ -0,0 +1,49 @@ +/* + * 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.config.basics; + +import org.onosproject.net.config.Config; + +/** + * Base abstraction for network entities for which admission into control + * domain can be selectively configured, e.g. devices, end-stations, links + */ +public abstract class AllowedEntityConfig<S> extends Config<S> { + + private static final String ALLOWED = "allowed"; + + /** + * Indicates whether the element is allowed for admission into the control + * domain. + * + * @return true if element is allowed + */ + public boolean isAllowed() { + return get(ALLOWED, true); + } + + /** + * Specifies whether the element is to be allowed for admission into the + * control domain. + * + * @param isAllowed true to allow; false to forbid; null to clear + * @return self + */ + public AllowedEntityConfig isAllowed(Boolean isAllowed) { + return (AllowedEntityConfig) setOrClear(ALLOWED, isAllowed); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java new file mode 100644 index 00000000..fd8bfa3e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicDeviceConfig.java @@ -0,0 +1,70 @@ +/* + * 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.config.basics; + +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; + +/** + * Basic configuration for network infrastructure devices. + */ +public class BasicDeviceConfig extends BasicElementConfig<DeviceId> { + + public static final String TYPE = "type"; + public static final String DRIVER = "driver"; + + /** + * Returns the device type. + * + * @return device type override + */ + public Device.Type type() { + return get(TYPE, Device.Type.SWITCH, Device.Type.class); + } + + /** + * Sets the device type. + * + * @param type device type override + * @return self + */ + public BasicDeviceConfig type(Device.Type type) { + return (BasicDeviceConfig) setOrClear(TYPE, type); + } + + /** + * Returns the device driver name. + * + * @return driver name of null if not set + */ + public String driver() { + return get(DRIVER, subject.toString()); + } + + /** + * Sets the driver name. + * + * @param driverName new driver name; null to clear + * @return self + */ + public BasicElementConfig driver(String driverName) { + return (BasicElementConfig) setOrClear(DRIVER, driverName); + } + + // TODO: device port meta-data to be configured via BasicPortsConfig + // TODO: device credentials/keys + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java new file mode 100644 index 00000000..7b3248c9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicElementConfig.java @@ -0,0 +1,130 @@ +/* + * 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.config.basics; + +/** + * Basic configuration for network elements, e.g. devices, hosts. Such elements + * can have a friendly name, geo-coordinates, logical rack coordinates and + * an owner entity. + */ +public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { + + public static final String NAME = "name"; + + public static final String LATITUDE = "latitude"; + public static final String LONGITUDE = "longitude"; + + public static final String RACK_ADDRESS = "rackAddress"; + public static final String OWNER = "owner"; + + protected static final double DEFAULT_COORD = -1.0; + + /** + * Returns friendly label for the element. + * + * @return friendly label or element id itself if not set + */ + public String name() { + return get(NAME, subject.toString()); + } + + /** + * Sets friendly label for the element. + * + * @param name new friendly label; null to clear + * @return self + */ + public BasicElementConfig name(String name) { + return (BasicElementConfig) setOrClear(NAME, name); + } + + /** + * Returns element latitude. + * + * @return element latitude; -1 if not set + */ + public double latitude() { + return get(LATITUDE, DEFAULT_COORD); + } + + /** + * Sets the element latitude. + * + * @param latitude new latitude; null to clear + * @return self + */ + public BasicElementConfig latitude(Double latitude) { + return (BasicElementConfig) setOrClear(LATITUDE, latitude); + } + + /** + * Returns element latitude. + * + * @return element latitude; -1 if not set + */ + public double longitude() { + return get(LONGITUDE, DEFAULT_COORD); + } + + /** + * Sets the element longitude. + * + * @param longitude new longitude; null to clear + * @return self + */ + public BasicElementConfig longitude(Double longitude) { + return (BasicElementConfig) setOrClear(LONGITUDE, longitude); + } + + /** + * Returns the element rack address. + * + * @return rack address; null if not set + */ + public String rackAddress() { + return get(RACK_ADDRESS, null); + } + + /** + * Sets element rack address. + * + * @param address new rack address; null to clear + * @return self + */ + public BasicElementConfig rackAddress(String address) { + return (BasicElementConfig) setOrClear(RACK_ADDRESS, address); + } + + /** + * Returns owner of the element. + * + * @return owner or null if not set + */ + public String owner() { + return get(OWNER, null); + } + + /** + * Sets the owner of the element. + * + * @param owner new owner; null to clear + * @return self + */ + public BasicElementConfig owner(String owner) { + return (BasicElementConfig) setOrClear(OWNER, owner); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java new file mode 100644 index 00000000..2fe2b2c0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java @@ -0,0 +1,27 @@ +/* + * 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.config.basics; + +import org.onosproject.net.HostId; + +/** + * Basic configuration for network end-station hosts. + */ +public class BasicHostConfig extends BasicElementConfig<HostId> { + + // TODO: determine what aspects of configuration to add for hosts + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java new file mode 100644 index 00000000..b6068ee7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicLinkConfig.java @@ -0,0 +1,90 @@ +/* + * 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.config.basics; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +import java.time.Duration; + +/** + * Basic configuration for network infrastructure link. + */ +public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { + + public static final String TYPE = "type"; + public static final String LATENCY = "latency"; + public static final String BANDWIDTH = "bandwidth"; + + /** + * Returns the link type. + * + * @return link type override + */ + public Link.Type type() { + return get(TYPE, Link.Type.DIRECT, Link.Type.class); + } + + /** + * Sets the link type. + * + * @param type link type override + * @return self + */ + public BasicLinkConfig type(Link.Type type) { + return (BasicLinkConfig) setOrClear(TYPE, type); + } + + /** + * Returns link latency in terms of nanos. + * + * @return link latency; -1 if not set + */ + public Duration latency() { + return Duration.ofNanos(get(LATENCY, -1)); + } + + /** + * Sets the link latency. + * + * @param latency new latency; null to clear + * @return self + */ + public BasicLinkConfig latency(Duration latency) { + Long nanos = latency == null ? null : latency.toNanos(); + return (BasicLinkConfig) setOrClear(LATENCY, nanos); + } + + /** + * Returns link bandwidth in terms of Mbps. + * + * @return link bandwidth; -1 if not set + */ + public long bandwidth() { + return get(BANDWIDTH, -1); + } + + /** + * Sets the link bandwidth. + * + * @param bandwidth new bandwidth; null to clear + * @return self + */ + public BasicLinkConfig bandwidth(Long bandwidth) { + return (BasicLinkConfig) setOrClear(BANDWIDTH, bandwidth); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/OpticalPortConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/OpticalPortConfig.java new file mode 100644 index 00000000..b06c4228 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/OpticalPortConfig.java @@ -0,0 +1,175 @@ +package org.onosproject.net.config.basics; + +import java.util.Optional; + +import org.onosproject.net.config.Config; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Port; + +import com.fasterxml.jackson.databind.JsonNode; + + +/** + * Configurations for an optical port on a device. + */ +public class OpticalPortConfig extends Config<ConnectPoint> { + // optical type {OMS, OCH, ODUClt, fiber} + public static final String TYPE = "type"; + + // port name. "name" is the alphanumeric name of the port, but "port" refers + // to the port number used as a name string (i.e., for ports without + // alphanumeric names). + public static final String NAME = "name"; + public static final String PORT = "port"; + public static final String STATIC_PORT = "staticPort"; + public static final String STATIC_LAMBDA = "staticLambda"; + + // **Linc-OE : remove if it's not needed after all.** + public static final String SPEED = "speed"; + + /** + * Returns the Enum value representing the type of port. + * + * @return the port type, or null if invalid or unset + */ + public Port.Type type() { + JsonNode type = object.path(TYPE); + if (type.isMissingNode()) { + return null; + } + return Port.Type.valueOf(type.asText()); + } + + /** + * Returns the port name associated with this port configuration. The Name + * is an alphanumeric string. + * + * @return the name of this port, else, an empty string + */ + public String name() { + return getStringValue(NAME); + } + + /** + * Returns a stringified representation of the port number, configured in + * some port types without an alphanumeric name as the port name. + * + * @return A string representation of the port number + */ + public String numberName() { + return getStringValue(PORT); + } + + /** + * Returns the string-representation of name of the output port. This is + * usually an OMS port for an OCH input ports, or an OCH port for ODU input + * ports. + * + * @return the name of this port, else, an empty string + */ + public String staticPort() { + return getStringValue(STATIC_PORT); + } + + private String getStringValue(String field) { + JsonNode name = object.path(field); + return name.isMissingNode() ? "" : name.asText(); + } + + /** + * Returns the output lambda configured for this port. The lambda value is + * expressed as a frequency value. If the port type doesn't have a notion of + * lambdas, this returns an empty Optional. + * + * @return an Optional that may contain a frequency value. + */ + public Optional<Long> staticLambda() { + JsonNode sl = object.path(STATIC_LAMBDA); + if (sl.isMissingNode()) { + return Optional.empty(); + } + return Optional.of(sl.asLong()); + } + + /** + * Returns the port speed configured for this port. If the port doesn't have + * a notion of speed, this returns an empty Optional. + * + * @return a port speed value whose default is 0. + */ + public Optional<Integer> speed() { + JsonNode s = object.path(SPEED); + if (s.isMissingNode()) { + return Optional.empty(); + } + return Optional.of(s.asInt()); + } + + /** + * Sets the port type, or updates it if it's already set. A null argument removes + * this field. + * + * @param type the port type + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig portType(Port.Type type) { + // if unspecified, ideally fall back on FIBER or PACKET. + String pt = (type == null) ? null : type.toString(); + return (OpticalPortConfig) setOrClear(TYPE, pt); + } + + /** + * Sets the port name, or updates it if already set. A null argument removes + * this field. + * + * @param name the port's name + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig portName(String name) { + return (OpticalPortConfig) setOrClear(NAME, name); + } + + /** + * Sets the port name from port number, or updates it if already set. A null + * argument removes this field. + * + * @param name the port number, to be used as name + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig portNumberName(Long name) { + return (OpticalPortConfig) setOrClear(PORT, name); + } + + /** + * Sets the output port name, or updates it if already set. A null argument + * removes this field. + * + * @param name the output port's name + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig staticPort(String name) { + return (OpticalPortConfig) setOrClear(STATIC_PORT, name); + } + + /** + * Sets the output lambda index, or updates it if already set. A null argument + * removes this field. + * + * @param index the output lambda + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig staticLambda(Long index) { + return (OpticalPortConfig) setOrClear(STATIC_LAMBDA, index); + } + + /** + * Sets the port speed, or updates it if already set. A null argument + * removes this field. + * + * @param bw the port bandwidth + * @return this OpticalPortConfig instance + */ + public OpticalPortConfig speed(Integer bw) { + return (OpticalPortConfig) setOrClear(SPEED, bw); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/SubjectFactories.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/SubjectFactories.java new file mode 100644 index 00000000..884f2e20 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/SubjectFactories.java @@ -0,0 +1,93 @@ +/* + * 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.config.basics; + +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.HostId; +import org.onosproject.net.LinkKey; +import org.onosproject.net.config.SubjectFactory; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Set of subject factories for potential configuration subjects. + */ +public final class SubjectFactories { + + // Construction forbidden + private SubjectFactories() { + } + + // Required for resolving application identifiers + private static CoreService coreService; + + public static final SubjectFactory<ApplicationId> APP_SUBJECT_FACTORY = + new SubjectFactory<ApplicationId>(ApplicationId.class, "apps") { + @Override + public ApplicationId createSubject(String key) { + return coreService.registerApplication(key); + } + }; + + public static final SubjectFactory<DeviceId> DEVICE_SUBJECT_FACTORY = + new SubjectFactory<DeviceId>(DeviceId.class, "devices") { + @Override + public DeviceId createSubject(String key) { + return DeviceId.deviceId(key); + } + }; + + public static final SubjectFactory<ConnectPoint> CONNECT_POINT_SUBJECT_FACTORY = + new SubjectFactory<ConnectPoint>(ConnectPoint.class, "ports") { + @Override + public ConnectPoint createSubject(String key) { + return ConnectPoint.deviceConnectPoint(key); + } + }; + + public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY = + new SubjectFactory<HostId>(HostId.class, "hosts") { + @Override + public HostId createSubject(String key) { + return HostId.hostId(key); + } + }; + + public static final SubjectFactory<LinkKey> LINK_SUBJECT_FACTORY = + new SubjectFactory<LinkKey>(LinkKey.class, "links") { + @Override + public LinkKey createSubject(String key) { + String[] cps = key.split("-"); + checkArgument(cps.length == 2, "Incorrect link key format: %s", key); + return LinkKey.linkKey(ConnectPoint.deviceConnectPoint(cps[0]), + ConnectPoint.deviceConnectPoint(cps[1])); + } + }; + + /** + * Provides reference to the core service, which is required for + * application subject factory. + * + * @param service core service reference + */ + public static void setCoreService(CoreService service) { + coreService = service; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/package-info.java new file mode 100644 index 00000000..4d0f27e9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Various basic builtin network configurations. + */ +package org.onosproject.net.config.basics;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/package-info.java new file mode 100644 index 00000000..f300717a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/package-info.java @@ -0,0 +1,20 @@ +/* + * 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 tracking network environment configuration. + */ +package org.onosproject.net.config; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java new file mode 100644 index 00000000..3a8c8c1f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java @@ -0,0 +1,145 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; +import org.onlab.packet.ChassisId; + +import java.net.URI; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.net.Device.Type; + +/** + * Default implementation of immutable device description entity. + */ +public class DefaultDeviceDescription extends AbstractDescription + implements DeviceDescription { + private final URI uri; + private final Type type; + private final String manufacturer; + private final String hwVersion; + private final String swVersion; + private final String serialNumber; + private final ChassisId chassisId; + + /** + * Creates a device description using the supplied information. + * + * @param uri device URI + * @param type device type + * @param manufacturer device manufacturer + * @param hwVersion device HW version + * @param swVersion device SW version + * @param serialNumber device serial number + * @param chassis chassis id + * @param annotations optional key/value annotations map + */ + public DefaultDeviceDescription(URI uri, Type type, String manufacturer, + String hwVersion, String swVersion, + String serialNumber, ChassisId chassis, + SparseAnnotations... annotations) { + super(annotations); + this.uri = checkNotNull(uri, "Device URI cannot be null"); + this.type = checkNotNull(type, "Device type cannot be null"); + this.manufacturer = manufacturer; + this.hwVersion = hwVersion; + this.swVersion = swVersion; + this.serialNumber = serialNumber; + this.chassisId = chassis; + } + + /** + * Creates a device description using the supplied information. + * @param base DeviceDescription to basic information + * @param annotations Annotations to use. + */ + public DefaultDeviceDescription(DeviceDescription base, + SparseAnnotations... annotations) { + this(base.deviceURI(), base.type(), base.manufacturer(), + base.hwVersion(), base.swVersion(), base.serialNumber(), + base.chassisId(), annotations); + } + + /** + * Creates a device description using the supplied information. + * @param base DeviceDescription to basic information (except for type) + * @param type device type + * @param annotations Annotations to use. + */ + public DefaultDeviceDescription(DeviceDescription base, Type type, SparseAnnotations... annotations) { + this(base.deviceURI(), type, base.manufacturer(), + base.hwVersion(), base.swVersion(), base.serialNumber(), + base.chassisId(), annotations); + } + + @Override + public URI deviceURI() { + return uri; + } + + @Override + public Type type() { + return type; + } + + @Override + public String manufacturer() { + return manufacturer; + } + + @Override + public String hwVersion() { + return hwVersion; + } + + @Override + public String swVersion() { + return swVersion; + } + + @Override + public String serialNumber() { + return serialNumber; + } + + @Override + public ChassisId chassisId() { + return chassisId; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("uri", uri).add("type", type).add("mfr", manufacturer) + .add("hw", hwVersion).add("sw", swVersion) + .add("serial", serialNumber) + .toString(); + } + + // default constructor for serialization + private DefaultDeviceDescription() { + this.uri = null; + this.type = null; + this.manufacturer = null; + this.hwVersion = null; + this.swVersion = null; + this.serialNumber = null; + this.chassisId = null; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java new file mode 100644 index 00000000..572d201c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java @@ -0,0 +1,120 @@ +/* + * Copyright 2014 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.device; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; + +import static org.onosproject.net.Port.Type; + +/** + * Default implementation of immutable port description. + */ +public class DefaultPortDescription extends AbstractDescription + implements PortDescription { + + private static final long DEFAULT_SPEED = 1_000; + + private final PortNumber number; + private final boolean isEnabled; + private final Type type; + private final long portSpeed; + + /** + * Creates a port description using the supplied information. + * + * @param number port number + * @param isEnabled port enabled state + * @param annotations optional key/value annotations map + */ + public DefaultPortDescription(PortNumber number, boolean isEnabled, + SparseAnnotations... annotations) { + this(number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations); + } + + /** + * Creates a port description using the supplied information. + * + * @param number port number + * @param isEnabled port enabled state + * @param type port type + * @param portSpeed port speed in Mbps + * @param annotations optional key/value annotations map + */ + public DefaultPortDescription(PortNumber number, boolean isEnabled, + Type type, long portSpeed, + SparseAnnotations...annotations) { + super(annotations); + this.number = number; + this.isEnabled = isEnabled; + this.type = type; + this.portSpeed = portSpeed; + } + + // Default constructor for serialization + private DefaultPortDescription() { + this.number = null; + this.isEnabled = false; + this.portSpeed = DEFAULT_SPEED; + this.type = Type.COPPER; + } + + /** + * Creates a port description using the supplied information. + * + * @param base PortDescription to get basic information from + * @param annotations optional key/value annotations map + */ + public DefaultPortDescription(PortDescription base, + SparseAnnotations annotations) { + this(base.portNumber(), base.isEnabled(), base.type(), base.portSpeed(), + annotations); + } + + @Override + public PortNumber portNumber() { + return number; + } + + @Override + public boolean isEnabled() { + return isEnabled; + } + + @Override + public Type type() { + return type; + } + + @Override + public long portSpeed() { + return portSpeed; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("number", number) + .add("isEnabled", isEnabled) + .add("type", type) + .add("portSpeed", portSpeed) + .add("annotations", annotations()) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java new file mode 100644 index 00000000..540a945f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortStatistics.java @@ -0,0 +1,346 @@ +/* + * 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.device; + +import org.onosproject.net.DeviceId; + +/** + * Default implementation of immutable port statistics. + */ +public final class DefaultPortStatistics implements PortStatistics { + + private final DeviceId deviceId; + private final int port; + private final long packetsReceived; + private final long packetsSent; + private final long bytesReceived; + private final long bytesSent; + private final long packetsRxDropped; + private final long packetsTxDropped; + private final long packetsRxErrors; + private final long packetsTxErrors; + private final long durationSec; + private final long durationNano; + + private DefaultPortStatistics(DeviceId deviceId, + int port, + long packetsReceived, + long packetsSent, + long bytesReceived, + long bytesSent, + long packetsRxDropped, + long packetsTxDropped, + long packetsRxErrors, + long packetsTxErrors, + long durationSec, + long durationNano) { + this.deviceId = deviceId; + this.port = port; + this.packetsReceived = packetsReceived; + this.packetsSent = packetsSent; + this.bytesReceived = bytesReceived; + this.bytesSent = bytesSent; + this.packetsRxDropped = packetsRxDropped; + this.packetsTxDropped = packetsTxDropped; + this.packetsRxErrors = packetsRxErrors; + this.packetsTxErrors = packetsTxErrors; + this.durationSec = durationSec; + this.durationNano = durationNano; + } + + // Constructor for serializer + private DefaultPortStatistics() { + this.deviceId = null; + this.port = 0; + this.packetsReceived = 0; + this.packetsSent = 0; + this.bytesReceived = 0; + this.bytesSent = 0; + this.packetsRxDropped = 0; + this.packetsTxDropped = 0; + this.packetsRxErrors = 0; + this.packetsTxErrors = 0; + this.durationSec = 0; + this.durationNano = 0; + } + + /** + * Creates a builder for DefaultPortStatistics object. + * + * @return builder object for DefaultPortStatistics object + */ + public static DefaultPortStatistics.Builder builder() { + return new Builder(); + } + + @Override + public int port() { + return this.port; + } + + @Override + public long packetsReceived() { + return this.packetsReceived; + } + + @Override + public long packetsSent() { + return this.packetsSent; + } + + @Override + public long bytesReceived() { + return this.bytesReceived; + } + + @Override + public long bytesSent() { + return this.bytesSent; + } + + @Override + public long packetsRxDropped() { + return this.packetsRxDropped; + } + + @Override + public long packetsTxDropped() { + return this.packetsTxDropped; + } + + @Override + public long packetsRxErrors() { + return this.packetsRxErrors; + } + + @Override + public long packetsTxErrors() { + return this.packetsTxErrors; + } + + @Override + public long durationSec() { + return this.durationSec; + } + + @Override + public long durationNano() { + return this.durationNano; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("device: " + deviceId + ", "); + + sb.append("port: " + this.port + ", "); + sb.append("pktRx: " + this.packetsReceived + ", "); + sb.append("pktTx: " + this.packetsSent + ", "); + sb.append("byteRx: " + this.bytesReceived + ", "); + sb.append("byteTx: " + this.bytesSent + ", "); + sb.append("pktRxErr: " + this.packetsRxErrors + ", "); + sb.append("pktTxErr: " + this.packetsTxErrors + ", "); + sb.append("pktRxDrp: " + this.packetsRxDropped + ", "); + sb.append("pktTxDrp: " + this.packetsTxDropped); + + return sb.toString(); + } + + public static final class Builder { + + DeviceId deviceId; + int port; + long packetsReceived; + long packetsSent; + long bytesReceived; + long bytesSent; + long packetsRxDropped; + long packetsTxDropped; + long packetsRxErrors; + long packetsTxErrors; + long durationSec; + long durationNano; + + private Builder() { + + } + + /** + * Sets port number. + * + * @param port port number + * @return builder object + */ + public Builder setPort(int port) { + this.port = port; + + return this; + } + + /** + * Sets the device identifier. + * + * @param deviceId device identifier + * @return builder object + */ + public Builder setDeviceId(DeviceId deviceId) { + this.deviceId = deviceId; + + return this; + } + + /** + * Sets the number of packet received. + * + * @param packets number of packets received + * @return builder object + */ + public Builder setPacketsReceived(long packets) { + packetsReceived = packets; + + return this; + } + + /** + * Sets the number of packets sent. + * + * @param packets number of packets sent + * @return builder object + */ + public Builder setPacketsSent(long packets) { + packetsSent = packets; + + return this; + } + + /** + * Sets the number of received bytes. + * + * @param bytes number of received bytes. + * @return builder object + */ + public Builder setBytesReceived(long bytes) { + bytesReceived = bytes; + + return this; + } + + /** + * Sets the number of sent bytes. + * + * @param bytes number of sent bytes + * @return builder object + */ + public Builder setBytesSent(long bytes) { + bytesSent = bytes; + + return this; + } + + /** + * Sets the number of packets dropped by RX. + * + * @param packets number of packets dropped by RX + * @return builder object + */ + public Builder setPacketsRxDropped(long packets) { + packetsRxDropped = packets; + + return this; + } + + /** + * Sets the number of packets dropped by TX. + * + * @param packets number of packets + * @return builder object + */ + public Builder setPacketsTxDropped(long packets) { + packetsTxDropped = packets; + + return this; + } + + /** + * Sets the number of receive errors. + * + * @param packets number of receive errors + * @return builder object + */ + public Builder setPacketsRxErrors(long packets) { + packetsRxErrors = packets; + + return this; + } + + /** + * Sets the number of transmit errors. + * + * @param packets number of transmit errors + * @return builder object + */ + public Builder setPacketsTxErrors(long packets) { + packetsTxErrors = packets; + + return this; + } + + /** + * Sets the time port has been alive in seconds. + * + * @param sec time port has been alive in seconds + * @return builder object + */ + public Builder setDurationSec(long sec) { + durationSec = sec; + + return this; + } + + /** + * Sets the time port has been alive in nano seconds. + * + * @param nano time port has been alive in nano seconds + * @return builder object + */ + public Builder setDurationNano(long nano) { + durationNano = nano; + + return this; + } + + /** + * Creates a PortStatistics object. + * + * @return DefaultPortStatistics object + */ + public DefaultPortStatistics build() { + return new DefaultPortStatistics( + deviceId, + port, + packetsReceived, + packetsSent, + bytesReceived, + bytesSent, + packetsRxDropped, + packetsTxDropped, + packetsRxErrors, + packetsTxErrors, + durationSec, + durationNano); + } + + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java new file mode 100644 index 00000000..500b6359 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java @@ -0,0 +1,34 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.net.DeviceId; + +/** + * Service for administering the inventory of infrastructure devices. + */ +public interface DeviceAdminService extends DeviceService { + + /** + * Removes the device with the specified identifier. + * + * @param deviceId device identifier + */ + void removeDevice(DeviceId deviceId); + + // TODO: add ability to administratively suspend/resume device + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceClockService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceClockService.java new file mode 100644 index 00000000..5391999a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceClockService.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.net.DeviceId; +import org.onosproject.store.Timestamp; + +/** + * Interface for a logical clock service that vends per device timestamps. + */ +public interface DeviceClockService { + + /** + * Checks if this service can issue Timestamp for specified device. + * + * @param deviceId device identifier. + * @return true if timestamp can be issued for specified device + */ + boolean isTimestampAvailable(DeviceId deviceId); + + /** + * Returns a new timestamp for the specified deviceId. + * + * @param deviceId device identifier. + * @return timestamp. + */ + Timestamp getTimestamp(DeviceId deviceId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java new file mode 100644 index 00000000..64b84b5a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java @@ -0,0 +1,80 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.net.Description; +import org.onosproject.net.Device; +import org.onlab.packet.ChassisId; + +import java.net.URI; + +/** + * Carrier of immutable information about a device. + */ +public interface DeviceDescription extends Description { + + /** + * Protocol/provider specific URI that can be used to encode the identity + * information required to communicate with the device externally, e.g. + * datapath ID. + * + * @return provider specific URI for the device + */ + URI deviceURI(); + + /** + * Returns the type of the infrastructure device. + * + * @return type of the device + */ + Device.Type type(); + + /** + * Returns the device manufacturer name. + * + * @return manufacturer name + */ + String manufacturer(); + + /** + * Returns the device hardware version. + * + * @return hardware version + */ + String hwVersion(); + + /** + * Returns the device software version. + * + * @return software version + */ + String swVersion(); + + /** + * Returns the device serial number. + * + * @return serial number + */ + String serialNumber(); + + /** + * Returns a device chassis id. + * + * @return chassis id + */ + ChassisId chassisId(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceEvent.java new file mode 100644 index 00000000..18ab046f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceEvent.java @@ -0,0 +1,141 @@ +/* + * Copyright 2014-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.device; + +import org.joda.time.LocalDateTime; +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.Device; +import org.onosproject.net.Port; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Describes infrastructure device event. + */ +public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { + + private final Port port; + + /** + * Type of device events. + */ + public enum Type { + /** + * Signifies that a new device has been detected. + */ + DEVICE_ADDED, + + /** + * Signifies that some device attributes have changed; excludes + * availability changes. + */ + DEVICE_UPDATED, + + /** + * Signifies that a device has been removed. + */ + DEVICE_REMOVED, + + /** + * Signifies that a device has been administratively suspended. + */ + DEVICE_SUSPENDED, + + /** + * Signifies that a device has come online or has gone offline. + */ + DEVICE_AVAILABILITY_CHANGED, + + /** + * Signifies that a port has been added. + */ + PORT_ADDED, + + /** + * Signifies that a port has been updated. + */ + PORT_UPDATED, + + /** + * Signifies that a port has been removed. + */ + PORT_REMOVED, + + /** + * Signifies that port statistics has been updated. + */ + PORT_STATS_UPDATED + } + + /** + * Creates an event of a given type and for the specified device and the + * current time. + * + * @param type device event type + * @param device event device subject + */ + public DeviceEvent(Type type, Device device) { + this(type, device, null); + } + + /** + * Creates an event of a given type and for the specified device, port + * and the current time. + * + * @param type device event type + * @param device event device subject + * @param port optional port subject + */ + public DeviceEvent(Type type, Device device, Port port) { + super(type, device); + this.port = port; + } + + /** + * Creates an event of a given type and for the specified device and time. + * + * @param type device event type + * @param device event device subject + * @param port optional port subject + * @param time occurrence time + */ + public DeviceEvent(Type type, Device device, Port port, long time) { + super(type, device, time); + this.port = port; + } + + /** + * Returns the port subject. + * + * @return port subject or null if the event is not port specific. + */ + public Port port() { + return port; + } + + @Override + public String toString() { + if (port == null) { + return super.toString(); + } + return toStringHelper(this) + .add("time", new LocalDateTime(time())) + .add("type", type()) + .add("subject", subject()) + .add("port", port) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceListener.java new file mode 100644 index 00000000..c9809b81 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving infrastructure device related events. + */ +public interface DeviceListener extends EventListener<DeviceEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java new file mode 100644 index 00000000..d8adbb0e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of a device information provider. + */ +public interface DeviceProvider extends Provider { + + // TODO: consider how dirty the triggerProbe gets; if it costs too much, let's drop it + + /** + * Triggers an asynchronous probe of the specified device, intended to + * determine whether the device is present or not. An indirect result of this + * should be invocation of + * {@link org.onosproject.net.device.DeviceProviderService#deviceConnected} )} or + * {@link org.onosproject.net.device.DeviceProviderService#deviceDisconnected} + * at some later point in time. + * + * @param deviceId ID of device to be probed + */ + void triggerProbe(DeviceId deviceId); + + /** + * Notifies the provider of a mastership role change for the specified + * device as decided by the core. + * + * @param deviceId device identifier + * @param newRole newly determined mastership role + */ + void roleChanged(DeviceId deviceId, MastershipRole newRole); + + /** + * Checks the reachability (connectivity) of a device from this provider. + * + * @param deviceId device identifier + * @return true if reachable, false otherwise + */ + boolean isReachable(DeviceId deviceId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderRegistry.java new file mode 100644 index 00000000..a7ab7e36 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of a device provider registry. + */ +public interface DeviceProviderRegistry + extends ProviderRegistry<DeviceProvider, DeviceProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java new file mode 100644 index 00000000..e266df09 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java @@ -0,0 +1,82 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.provider.ProviderService; + +import java.util.Collection; +import java.util.List; + +/** + * Service through which device providers can inject device information into + * the core. + */ +public interface DeviceProviderService extends ProviderService<DeviceProvider> { + + // TODO: define suspend and remove actions on the mezzanine administrative API + + /** + * Signals the core that a device has connected or has been detected somehow. + * + * @param deviceId device identifier + * @param deviceDescription information about network device + */ + void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription); + + /** + * Signals the core that a device has disconnected or is no longer reachable. + * + * @param deviceId identity of the device to be removed + */ + void deviceDisconnected(DeviceId deviceId); + + /** + * Sends information about all ports of a device. It is up to the core to + * determine what has changed. + * + * @param deviceId identity of the device + * @param portDescriptions list of device ports + */ + void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions); + + /** + * Used to notify the core about port status change of a single port. + * + * @param deviceId identity of the device + * @param portDescription description of the port that changed + */ + void portStatusChanged(DeviceId deviceId, PortDescription portDescription); + + /** + * Notifies the core about the result of a RoleRequest sent to a device. + * + * @param deviceId identity of the device + * @param requested mastership role that was requested by the node + * @param response mastership role the switch accepted + */ + void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response); + + /** + * Sends statistics about all ports of a device. + * + * @param deviceId identity of the device + * @param portStatistics list of device port statistics + */ + void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceService.java new file mode 100644 index 00000000..f4671fb4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceService.java @@ -0,0 +1,132 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.event.ListenerService; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MastershipRole; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; + +import java.util.List; + +/** + * Service for interacting with the inventory of infrastructure devices. + */ +public interface DeviceService + extends ListenerService<DeviceEvent, DeviceListener> { + + /** + * Returns the number of infrastructure devices known to the system. + * + * @return number of infrastructure devices + */ + int getDeviceCount(); + + /** + * Returns a collection of the currently known infrastructure + * devices. + * + * @return collection of devices + */ + Iterable<Device> getDevices(); + + /** + * Returns a collection of the currently known infrastructure + * devices by device type. + * + * @param type device type + * @return collection of devices + */ + Iterable<Device> getDevices(Device.Type type); + + /** + * Returns an iterable collection of all devices + * currently available to the system. + * + * @return device collection + */ + Iterable<Device> getAvailableDevices(); + + /** + * Returns an iterable collection of all devices currently available to the system by device type. + * + * @param type device type + * @return device collection + */ + Iterable<Device> getAvailableDevices(Device.Type type); + + /** + * Returns the device with the specified identifier. + * + * @param deviceId device identifier + * @return device or null if one with the given identifier is not known + */ + Device getDevice(DeviceId deviceId); + + /** + * Returns the current mastership role for the specified device. + * + * @param deviceId device identifier + * @return designated mastership role + */ + //XXX do we want this method here when MastershipService already does? + MastershipRole getRole(DeviceId deviceId); + + + /** + * Returns the list of ports associated with the device. + * + * @param deviceId device identifier + * @return list of ports + */ + List<Port> getPorts(DeviceId deviceId); + + /** + * Returns the list of port statistics associated with the device. + * + * @param deviceId device identifier + * @return list of port statistics + */ + List<PortStatistics> getPortStatistics(DeviceId deviceId); + + /** + * Returns the list of port delta statistics associated with the device. + * + * @param deviceId device identifier + * @return list of port statistics + */ + List<PortStatistics> getPortDeltaStatistics(DeviceId deviceId); + + /** + * Returns the port with the specified number and hosted by the given device. + * + * @param deviceId device identifier + * @param portNumber port number + * @return device port + */ + Port getPort(DeviceId deviceId, PortNumber portNumber); + + /** + * Indicates whether or not the device is presently online and available. + * + * @param deviceId device identifier + * @return true if the device is available + */ + boolean isAvailable(DeviceId deviceId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java new file mode 100644 index 00000000..851b9709 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java @@ -0,0 +1,170 @@ +/* + * Copyright 2014-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.device; + +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.Collection; +import java.util.List; + +/** + * Manages inventory of infrastructure devices; not intended for direct use. + */ +public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> { + + /** + * Returns the number of devices known to the system. + * + * @return number of devices + */ + int getDeviceCount(); + + /** + * Returns an iterable collection of all devices known to the system. + * + * @return device collection + */ + Iterable<Device> getDevices(); + + /** + * Returns an iterable collection of all devices currently available to the system. + * + * @return device collection + */ + Iterable<Device> getAvailableDevices(); + + + + /** + * Returns the device with the specified identifier. + * + * @param deviceId device identifier + * @return device + */ + Device getDevice(DeviceId deviceId); + + /** + * Creates a new infrastructure device, or updates an existing one using + * the supplied device description. + * + * @param providerId provider identifier + * @param deviceId device identifier + * @param deviceDescription device description + * @return ready to send event describing what occurred; null if no change + */ + DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId, + DeviceDescription deviceDescription); + + // TODO: We may need to enforce that ancillary cannot interfere this state + /** + * Removes the specified infrastructure device. + * + * @param deviceId device identifier + * @return ready to send event describing what occurred; null if no change + */ + DeviceEvent markOffline(DeviceId deviceId); + + /** + * Updates the ports of the specified infrastructure device using the given + * list of port descriptions. The list is assumed to be comprehensive. + * + * @param providerId provider identifier + * @param deviceId device identifier + * @param portDescriptions list of port descriptions + * @return ready to send events describing what occurred; empty list if no change + */ + List<DeviceEvent> updatePorts(ProviderId providerId, DeviceId deviceId, + List<PortDescription> portDescriptions); + + /** + * Updates the port status of the specified infrastructure device using the + * given port description. + * + * @param providerId provider identifier + * @param deviceId device identifier + * @param portDescription port description + * @return ready to send event describing what occurred; null if no change + */ + DeviceEvent updatePortStatus(ProviderId providerId, DeviceId deviceId, + PortDescription portDescription); + + /** + * Returns the list of ports that belong to the specified device. + * + * @param deviceId device identifier + * @return list of device ports + */ + List<Port> getPorts(DeviceId deviceId); + + /** + * Updates the port statistics of the specified device using the give port + * statistics. + * + * @param providerId provider identifier + * @param deviceId device identifier + * @param portStats list of port statistics + * @return ready to send event describing what occurred; + */ + DeviceEvent updatePortStatistics(ProviderId providerId, DeviceId deviceId, + Collection<PortStatistics> portStats); + + /** + * Returns the list of port statistics of the specified device. + * + * @param deviceId device identifier + * @return list of port statistics of all ports of the device + */ + List<PortStatistics> getPortStatistics(DeviceId deviceId); + + /** + * Returns the list of delta port statistics of the specified device. + * + * @param deviceId device identifier + * @return list of delta port statistics of all ports of the device + */ + List<PortStatistics> getPortDeltaStatistics(DeviceId deviceId); + + /** + * Returns the specified device port. + * + * @param deviceId device identifier + * @param portNumber port number + * @return device port + */ + Port getPort(DeviceId deviceId, PortNumber portNumber); + + /** + * Indicates whether the specified device is available/online. + * + * @param deviceId device identifier + * @return true if device is available + */ + boolean isAvailable(DeviceId deviceId); + + /** + * Administratively removes the specified device from the store. + * + * @param deviceId device to be removed + * @return null if no such device, or was forwarded to remove master + */ + DeviceEvent removeDevice(DeviceId deviceId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStoreDelegate.java new file mode 100644 index 00000000..1a4fc67d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.store.StoreDelegate; + +/** + * Infrastructure device store delegate abstraction. + */ +public interface DeviceStoreDelegate extends StoreDelegate<DeviceEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OchPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OchPortDescription.java new file mode 100644 index 00000000..c3a7f415 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OchPortDescription.java @@ -0,0 +1,111 @@ +/* + * 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.device; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.OchSignal; +import org.onosproject.net.OduSignalType; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of immutable OCh port description. + */ +public class OchPortDescription extends DefaultPortDescription { + + private final OduSignalType signalType; + private final boolean isTunable; + private final OchSignal lambda; + + /** + * Creates OCH port description based on the supplied information. + * + * @param number port number + * @param isEnabled port enabled state + * @param signalType ODU signal type + * @param isTunable tunable wavelength capability + * @param lambda OCh signal + * @param annotations optional key/value annotations map + */ + public OchPortDescription(PortNumber number, boolean isEnabled, OduSignalType signalType, + boolean isTunable, OchSignal lambda, SparseAnnotations... annotations) { + super(number, isEnabled, Port.Type.OCH, 0, annotations); + this.signalType = signalType; + this.isTunable = isTunable; + this.lambda = checkNotNull(lambda); + } + + /** + * Creates OCH port description based on the supplied information. + * + * @param base PortDescription to get basic information from + * @param signalType ODU signal type + * @param isTunable tunable wavelength capability + * @param lambda OCh signal + * @param annotations optional key/value annotations map + */ + public OchPortDescription(PortDescription base, OduSignalType signalType, boolean isTunable, + OchSignal lambda, SparseAnnotations annotations) { + super(base, annotations); + this.signalType = signalType; + this.isTunable = isTunable; + this.lambda = checkNotNull(lambda); + } + + /** + * Returns ODU signal type. + * + * @return ODU signal type + */ + public OduSignalType signalType() { + return signalType; + } + + /** + * Returns true if port is wavelength tunable. + * + * @return tunable wavelength capability + */ + public boolean isTunable() { + return isTunable; + } + + /** + * Returns OCh signal. + * + * @return OCh signal + */ + public OchSignal lambda() { + return lambda; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("number", portNumber()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("signalType", signalType) + .add("isTunable", isTunable) + .add("lambda", lambda) + .add("annotations", annotations()) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OduCltPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OduCltPortDescription.java new file mode 100644 index 00000000..eee7de2d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OduCltPortDescription.java @@ -0,0 +1,77 @@ +/* + * 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.device; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.OduCltPort; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable ODU client port description. + */ +public class OduCltPortDescription extends DefaultPortDescription { + + private final OduCltPort.SignalType signalType; + + /** + * Creates ODU client port description based on the supplied information. + * + * @param number port number + * @param isEnabled port enabled state + * @param signalType ODU client signal type + * @param annotations optional key/value annotations map + */ + public OduCltPortDescription(PortNumber number, boolean isEnabled, OduCltPort.SignalType signalType, + SparseAnnotations... annotations) { + super(number, isEnabled, Port.Type.ODUCLT, 0, annotations); + this.signalType = signalType; + } + + /** + * Creates ODU client port description based on the supplied information. + * + * @param base PortDescription to get basic information from + * @param signalType ODU client signal type + * @param annotations optional key/value annotations map + */ + public OduCltPortDescription(PortDescription base, OduCltPort.SignalType signalType, + SparseAnnotations annotations) { + super(base, annotations); + this.signalType = signalType; + } + + /** + * Returns ODU client signal type. + * + * @return ODU client signal type + */ + public OduCltPort.SignalType signalType() { + return signalType; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("number", portNumber()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("signalType", signalType) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OmsPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OmsPortDescription.java new file mode 100644 index 00000000..131314a3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/OmsPortDescription.java @@ -0,0 +1,109 @@ +/* + * 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.device; + +import com.google.common.base.MoreObjects; +import org.onlab.util.Frequency; +import org.onosproject.net.Port; +import org.onosproject.net.PortNumber; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable OMS port description. + */ +public class OmsPortDescription extends DefaultPortDescription { + + private final Frequency minFrequency; + private final Frequency maxFrequency; + private final Frequency grid; + + /** + * Creates OMS port description based on the supplied information. + * + * @param number port number + * @param isEnabled port enabled state + * @param minFrequency minimum frequency + * @param maxFrequency maximum frequency + * @param grid grid spacing frequency + * @param annotations optional key/value annotations map + */ + public OmsPortDescription(PortNumber number, boolean isEnabled, Frequency minFrequency, Frequency maxFrequency, + Frequency grid, SparseAnnotations... annotations) { + super(number, isEnabled, Port.Type.OMS, 0, annotations); + this.minFrequency = minFrequency; + this.maxFrequency = maxFrequency; + this.grid = grid; + } + + /** + * Creates OMS port description based on the supplied information. + * + * @param base PortDescription to get basic information from + * @param minFrequency minimum frequency + * @param maxFrequency maximum frequency + * @param grid grid spacing frequency + * @param annotations optional key/value annotations map + */ + public OmsPortDescription(PortDescription base, Frequency minFrequency, Frequency maxFrequency, + Frequency grid, SparseAnnotations annotations) { + super(base, annotations); + this.minFrequency = minFrequency; + this.maxFrequency = maxFrequency; + this.grid = grid; + } + + /** + * Returns minimum frequency. + * + * @return minimum frequency + */ + public Frequency minFrequency() { + return minFrequency; + } + + /** + * Returns maximum frequency. + * + * @return maximum frequency + */ + public Frequency maxFrequency() { + return maxFrequency; + } + + /** + * Returns grid spacing frequency. + * + * @return grid spacing frequency + */ + public Frequency grid() { + return grid; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("number", portNumber()) + .add("isEnabled", isEnabled()) + .add("type", type()) + .add("minFrequency", minFrequency) + .add("maxFrequency", maxFrequency) + .add("grid", grid) + .add("annotations", annotations()) + .toString(); + } + +} + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortDescription.java new file mode 100644 index 00000000..3ed3efce --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortDescription.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014 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.device; + +import org.onosproject.net.Description; +import org.onosproject.net.PortNumber; + +import static org.onosproject.net.Port.Type; + +/** + * Information about a port. + */ +public interface PortDescription extends Description { + + /** + * Returns the port number. + * + * @return port number + */ + PortNumber portNumber(); + + /** + * Indicates whether or not the port is up and active. + * + * @return true if the port is active and has carrier signal + */ + boolean isEnabled(); + + /** + * Returns the port type. + * + * @return port type + */ + Type type(); + + /** + * Returns the current port speed in Mbps. + * + * @return current port speed + */ + long portSpeed(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java new file mode 100644 index 00000000..201bd7b6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/PortStatistics.java @@ -0,0 +1,100 @@ +/* + * 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.device; + +/** + * Statistics of a port. + */ +public interface PortStatistics { + + /** + * Returns the port number. + * + * @return port number + */ + int port(); + + /** + * Returns the number of packets received. + * + * @return the number of packets received + */ + long packetsReceived(); + + /** + * Returns the number of packets sent. + * + * @return the number of packets sent + */ + long packetsSent(); + + /** + * Returns the bytes received. + * + * @return the bytes received + */ + long bytesReceived(); + + /** + * Returns the bytes sent. + * + * @return the bytes sent + */ + long bytesSent(); + + /** + * Returns the number of packets dropped by RX. + * + * @return the number of packets dropped by RX + */ + long packetsRxDropped(); + + /** + * Returns the number of packets dropped by TX. + * + * @return the number of packets dropped by TX + */ + long packetsTxDropped(); + + /** + * Returns the number of transmit errors. + * + * @return the number of transmit errors + */ + long packetsRxErrors(); + + /** + * Returns the number of receive errors. + * + * @return the number of receive error + */ + long packetsTxErrors(); + + /** + * Returns the time port has been alive in seconds. + * + * @return the time port has been alive in seconds + */ + long durationSec(); + + /** + * Returns the time port has been alive in nano seconds. + * + * @return the time port has been alive in nano seconds + */ + long durationNano(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/package-info.java new file mode 100644 index 00000000..4ee64dcf --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Infrastructure device model & related services API definitions. + */ +package org.onosproject.net.device; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java new file mode 100644 index 00000000..784e6c55 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java @@ -0,0 +1,37 @@ +/* + * 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.driver; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Base implementation of device driver behaviour. + */ +public class AbstractBehaviour implements Behaviour { + + private DriverData data; + + @Override + public DriverData data() { + return data; + } + + @Override + public void setData(DriverData data) { + checkState(this.data == null, "Driver data already set"); + this.data = data; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java new file mode 100644 index 00000000..66b21ffe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java @@ -0,0 +1,38 @@ +/* + * 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.driver; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Base implementation of device driver handler behaviour. + */ +public class AbstractHandlerBehaviour + extends AbstractBehaviour implements HandlerBehaviour { + + private DriverHandler handler; + + @Override + public DriverHandler handler() { + return handler; + } + + @Override + public void setHandler(DriverHandler handler) { + checkState(this.handler == null, "Driver handler already set"); + this.handler = handler; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java new file mode 100644 index 00000000..6e28aa86 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java @@ -0,0 +1,39 @@ +/* + * 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.driver; + +/** + * Representation of a facet of device behaviour that can be used to talk about + * a device (in context of {@link DriverData}) or to a device (in context of + * {@link DriverHandler}). + */ +public interface Behaviour { + + /** + * Returns the driver data context. + * + * @return driver data + */ + DriverData data(); + + /** + * Sets the driver data context on this this behaviour should operate. + * + * @param data driver data + */ + void setData(DriverData data); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java new file mode 100644 index 00000000..b7a9f2b7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java @@ -0,0 +1,214 @@ +/* + * 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.driver; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableMap.copyOf; + +/** + * Default implementation of extensible driver. + */ +public class DefaultDriver implements Driver { + + private final String name; + private final Driver parent; + + private final String manufacturer; + private final String hwVersion; + private final String swVersion; + + private final Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours; + private final Map<String, String> properties; + + /** + * Creates a driver with the specified name. + * + * @param name driver name + * @param parent optional parent driver + * @param manufacturer device manufacturer + * @param hwVersion device hardware version + * @param swVersion device software version + * @param behaviours device behaviour classes + * @param properties properties for configuration of device behaviour classes + */ + public DefaultDriver(String name, Driver parent, String manufacturer, + String hwVersion, String swVersion, + Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours, + Map<String, String> properties) { + this.name = checkNotNull(name, "Name cannot be null"); + this.parent = parent; + this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null"); + this.hwVersion = checkNotNull(hwVersion, "HW version cannot be null"); + this.swVersion = checkNotNull(swVersion, "SW version cannot be null"); + this.behaviours = copyOf(checkNotNull(behaviours, "Behaviours cannot be null")); + this.properties = copyOf(checkNotNull(properties, "Properties cannot be null")); + } + + @Override + public Driver merge(Driver other) { + checkArgument(parent == null || Objects.equals(parent, other.parent()), + "Parent drivers are not the same"); + + // Merge the behaviours. + Map<Class<? extends Behaviour>, Class<? extends Behaviour>> + behaviours = Maps.newHashMap(); + behaviours.putAll(this.behaviours); + other.behaviours().forEach(b -> behaviours.put(b, other.implementation(b))); + + // Merge the properties. + ImmutableMap.Builder<String, String> properties = ImmutableMap.builder(); + properties.putAll(this.properties).putAll(other.properties()); + + return new DefaultDriver(name, other.parent(), manufacturer, hwVersion, swVersion, + ImmutableMap.copyOf(behaviours), properties.build()); + } + + @Override + public String name() { + return name; + } + + @Override + public String manufacturer() { + return manufacturer; + } + + @Override + public String hwVersion() { + return hwVersion; + } + + @Override + public String swVersion() { + return swVersion; + } + + @Override + public Driver parent() { + return parent; + } + + @Override + public Set<Class<? extends Behaviour>> behaviours() { + return behaviours.keySet(); + } + + @Override + public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) { + return behaviours.get(behaviour); + } + + @Override + public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) { + return behaviours.containsKey(behaviourClass) || + (parent != null && parent.hasBehaviour(behaviourClass)); + } + + @Override + public <T extends Behaviour> T createBehaviour(DriverData data, + Class<T> behaviourClass) { + T behaviour = createBehaviour(data, null, behaviourClass); + if (behaviour != null) { + return behaviour; + } else if (parent != null) { + return parent.createBehaviour(data, behaviourClass); + } + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); + } + + @Override + public <T extends Behaviour> T createBehaviour(DriverHandler handler, + Class<T> behaviourClass) { + T behaviour = createBehaviour(handler.data(), handler, behaviourClass); + if (behaviour != null) { + return behaviour; + } else if (parent != null) { + return parent.createBehaviour(handler, behaviourClass); + } + throw new IllegalArgumentException(behaviourClass.getName() + " not supported"); + } + + // Creates an instance of behaviour primed with the specified driver data. + private <T extends Behaviour> T createBehaviour(DriverData data, DriverHandler handler, + Class<T> behaviourClass) { + //checkArgument(handler != null || !HandlerBehaviour.class.isAssignableFrom(behaviourClass), + // "{} is applicable only to handler context", behaviourClass.getName()); + + // Locate the implementation of the requested behaviour. + Class<? extends Behaviour> implementation = behaviours.get(behaviourClass); + if (implementation != null) { + // Create an instance of the behaviour and apply data as its context. + T behaviour = createBehaviour(behaviourClass, implementation); + behaviour.setData(data); + + // If this is a handler behaviour, also apply handler as its context. + if (handler != null) { + ((HandlerBehaviour) behaviour).setHandler(handler); + } + return behaviour; + } + return null; + } + + @SuppressWarnings("unchecked") + private <T extends Behaviour> T createBehaviour(Class<T> behaviourClass, + Class<? extends Behaviour> implementation) { + try { + return (T) implementation.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + // TODO: add a specific unchecked exception + throw new IllegalArgumentException("Unable to create behaviour", e); + } + } + + @Override + public Set<String> keys() { + return properties.keySet(); + } + + @Override + public String value(String key) { + return properties.get(key); + } + + @Override + public Map<String, String> properties() { + return properties; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("name", name) + .add("parent", parent) + .add("manufacturer", manufacturer) + .add("hwVersion", hwVersion) + .add("swVersion", swVersion) + .add("behaviours", behaviours) + .add("properties", properties) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java new file mode 100644 index 00000000..76d7932d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java @@ -0,0 +1,100 @@ +/* + * 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.driver; + +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.DeviceId; +import org.onosproject.net.MutableAnnotations; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of driver data descriptor. + */ +public class DefaultDriverData implements DriverData { + + private final Driver driver; + private final DeviceId deviceId; + private final Map<String, String> properties; + + /** + * Creates new driver data. + * + * @param driver parent driver type + * @param deviceId device identifier + */ + public DefaultDriverData(Driver driver, DeviceId deviceId) { + this.driver = driver; + this.deviceId = deviceId; + this.properties = new HashMap<>(); + } + + @Override + public Driver driver() { + return driver; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public <T extends Behaviour> T behaviour(Class<T> behaviourClass) { + return driver.createBehaviour(this, behaviourClass); + } + + @Override + public MutableAnnotations set(String key, String value) { + properties.put(key, value); + return this; + } + + @Override + public MutableAnnotations clear(String... keys) { + if (keys.length == 0) { + properties.clear(); + } else { + for (String key : keys) { + properties.remove(key); + } + } + return this; + } + + @Override + public Set<String> keys() { + return ImmutableSet.copyOf(properties.keySet()); + } + + @Override + public String value(String key) { + return properties.get(key); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("type", driver) + .add("properties", properties) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverHandler.java new file mode 100644 index 00000000..28fdb2f3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverHandler.java @@ -0,0 +1,67 @@ +/* + * 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.driver; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of driver handler. + */ +public class DefaultDriverHandler implements DriverHandler { + + private final DefaultDriverData data; + + // Reference to service directory to provide run-time context. + protected static ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + + /** + * Creates new driver handler with the attached driver data. + * + * @param data driver data to attach + */ + public DefaultDriverHandler(DefaultDriverData data) { + this.data = data; + } + + @Override + public Driver driver() { + return data.driver(); + } + + @Override + public DriverData data() { + return data; + } + + @Override + public <T extends Behaviour> T behaviour(Class<T> behaviourClass) { + return data.driver().createBehaviour(this, behaviourClass); + } + + @Override + public <T> T get(Class<T> serviceClass) { + return serviceDirectory.get(serviceClass); + } + + @Override + public String toString() { + return toStringHelper(this).add("data", data).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java new file mode 100644 index 00000000..b2b5281c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProvider.java @@ -0,0 +1,86 @@ +/* + * 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.driver; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default driver provider implementation. + */ +public class DefaultDriverProvider implements DriverProvider { + + protected final Map<String, Driver> drivers = Maps.newConcurrentMap(); + + @Override + public Set<Driver> getDrivers() { + return ImmutableSet.copyOf(drivers.values()); + } + + /** + * Adds the specified drivers to the provider. + * + * @param drivers drivers to be added + */ + public void addDrivers(Set<Driver> drivers) { + drivers.forEach(this::addDriver); + } + + /** + * Adds the specified driver to the provider. + * + * @param driver driver to be provided + */ + public void addDriver(Driver driver) { + Driver ddc = drivers.get(driver.name()); + if (ddc == null) { + // If we don't have the driver yet, just use the new one. + drivers.put(driver.name(), driver); + } else { + // Otherwise merge the existing driver with the new one and rebind. + drivers.put(driver.name(), ddc.merge(driver)); + } + } + + /** + * Removes the specified drivers from the provider. + * + * @param drivers drivers to be removed + */ + public void removeDrivers(Set<Driver> drivers) { + drivers.forEach(this::removeDriver); + } + + /** + * Removes the specified driver from the provider. + * + * @param driver driver to be removed + */ + public void removeDriver(Driver driver) { + // TODO: make selective if possible + drivers.remove(driver.name()); + } + + @Override + public String toString() { + return toStringHelper(this).add("drivers", drivers).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProviderService.java new file mode 100644 index 00000000..153c7c56 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverProviderService.java @@ -0,0 +1,23 @@ +/* + * 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.driver; + +/** + * Service representing availability of default drivers. + */ +public interface DefaultDriverProviderService { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Driver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Driver.java new file mode 100644 index 00000000..50611b14 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/Driver.java @@ -0,0 +1,132 @@ +/* + * 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.driver; + +import org.onosproject.net.Annotations; + +import java.util.Map; +import java.util.Set; + +/** + * Representation of a specific family of device drivers. Behaviour configuration + * data is stored using {@link org.onosproject.net.Annotations}. + */ +public interface Driver extends Annotations { + + /** + * Returns the driver name. This is expected to be a reverse-DNS, + * Java package-like name. + * + * @return driver name + */ + String name(); + + /** + * Returns the parent driver from which this driver inherits behaviours + * and properties. + * + * @return parent driver; null if driver has no parent + */ + Driver parent(); + + /** + * Returns the device manufacturer name. + * + * @return manufacturer name + */ + String manufacturer(); + + /** + * Returns the device hardware version. + * + * @return hardware version + */ + String hwVersion(); + + /** + * Returns the device software version. + * + * @return software version + */ + String swVersion(); + + /** + * Returns the set of behaviours supported by this driver. + * It reflects behaviours of only this driver and not its parent. + * + * @return set of device driver behaviours + */ + Set<Class<? extends Behaviour>> behaviours(); + + /** + * Returns the implementation class for the specified behaviour. + * It reflects behaviours of only this driver and not its parent. + * + * @param behaviour behaviour interface + * @return implementation class + */ + Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour); + + /** + * Indicates whether or not the driver, or any of its parents, support + * the specified class of behaviour. It + * + * @param behaviourClass behaviour class + * @return true if behaviour is supported + */ + boolean hasBehaviour(Class<? extends Behaviour> behaviourClass); + + /** + * Creates an instance of behaviour primed with the specified driver data. + * If the current driver does not support the specified behaviour and the + * driver has parent, the request is delegated to the parent driver. + * + * @param data driver data context + * @param behaviourClass driver behaviour class + * @param <T> type of behaviour + * @return behaviour instance + */ + <T extends Behaviour> T createBehaviour(DriverData data, Class<T> behaviourClass); + + /** + * Creates an instance of behaviour primed with the specified driver data. + * If the current driver does not support the specified behaviour and the + * driver has parent, the request is delegated to the parent driver. + * + * @param handler driver handler context + * @param behaviourClass driver behaviour class + * @param <T> type of behaviour + * @return behaviour instance + */ + <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass); + + /** + * Returns the set of annotations as map of key/value properties. + * + * @return map of properties + */ + Map<String, String> properties(); + + /** + * Merges the specified driver behaviours and properties into this one, + * giving preference to the other driver when dealing with conflicts. + * + * @param other other driver + * @return merged driver + */ + Driver merge(Driver other); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverAdminService.java new file mode 100644 index 00000000..e7fa1385 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverAdminService.java @@ -0,0 +1,46 @@ +/* + * 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.driver; + +import java.util.Set; + +/** + * Service for managing drivers and driver behaviour implementations. + */ +public interface DriverAdminService extends DriverService { + + /** + * Returns the set of driver providers currently registered. + * + * @return registered driver providers + */ + Set<DriverProvider> getProviders(); + + /** + * Registers the specified driver provider. + * + * @param provider driver provider to register + */ + void registerProvider(DriverProvider provider); + + /** + * Unregisters the specified driver provider. + * + * @param provider driver provider to unregister + */ + void unregisterProvider(DriverProvider provider); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverConnect.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverConnect.java new file mode 100644 index 00000000..1d510913 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverConnect.java @@ -0,0 +1,36 @@ +/* + * 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.driver; + +/** + * Abstraction of handler behaviour used to set-up and tear-down driver + * connection with a device. + */ +public interface DriverConnect extends HandlerBehaviour { + + /** + * Connects to the device. + * + * @param credentials optional login credentials in string form + */ + void connect(String... credentials); + + /** + * Disconnects from the device. + */ + void disconnect(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverData.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverData.java new file mode 100644 index 00000000..1d66ea9a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverData.java @@ -0,0 +1,50 @@ +/* + * 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.driver; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.MutableAnnotations; + +/** + * Container for data about a device. Data is stored using + * {@link org.onosproject.net.MutableAnnotations}. + */ +public interface DriverData extends MutableAnnotations { + + /** + * Returns the parent device driver. + * + * @return device driver + */ + Driver driver(); + + /** + * Returns the device identifier. + * + * @return device identifier + */ + DeviceId deviceId(); + + /** + * Returns the specified facet of behaviour to access the device data. + * + * @param behaviourClass behaviour class + * @param <T> type of behaviour + * @return requested behaviour or null if not supported + */ + <T extends Behaviour> T behaviour(Class<T> behaviourClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverHandler.java new file mode 100644 index 00000000..202708ba --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverHandler.java @@ -0,0 +1,57 @@ +/* + * 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.driver; + +/** + * Representation of context for interacting with a device. + */ +public interface DriverHandler { + + /** + * Returns the parent device driver. + * + * @return device driver + */ + Driver driver(); + + /** + * Returns the device driver data. + * + * @return device driver data + */ + DriverData data(); + + /** + * Returns the specified facet of behaviour to interact with the device. + * + * @param behaviourClass behaviour class + * @param <T> type of behaviour + * @return behaviour + */ + <T extends Behaviour> T behaviour(Class<T> behaviourClass); + + /** + * Returns the reference to the implementation of the specified service. + * Provides access to run-time context. + * + * @param serviceClass service class + * @param <T> type of service + * @return service implementation + * @throws org.onlab.osgi.ServiceNotFoundException if service is unavailable + */ + <T> T get(Class<T> serviceClass); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverProvider.java new file mode 100644 index 00000000..354d93e9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverProvider.java @@ -0,0 +1,34 @@ +/* + * 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.driver; + +import java.util.Set; + +/** + * Represents entity capable of providing device drivers and their + * behaviours. + */ +public interface DriverProvider { + + /** + * Returns the set of driver types and behaviour implementations to be + * made available by this provider. + * + * @return set of driver types and their behaviours + */ + Set<Driver> getDrivers(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverResolver.java new file mode 100644 index 00000000..094c710f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverResolver.java @@ -0,0 +1,34 @@ +/* + * 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.driver; + +/** + * Entity capable of resolving a driver using its name. + */ +public interface DriverResolver { + + /** + * Returns the specified driver. + * + * @param driverName driver name + * @return driver + * @throws org.onlab.util.ItemNotFoundException if driver with the given + * name is not found + */ + Driver getDriver(String driverName); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverService.java new file mode 100644 index 00000000..1a74255b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/DriverService.java @@ -0,0 +1,83 @@ +/* + * 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.driver; + +import org.onosproject.net.DeviceId; + +import java.util.Set; + +/** + * Service for obtaining drivers and driver behaviour implementations. + */ +public interface DriverService extends DriverResolver { + + /** + * Returns the overall set of drivers being provided. + * + * @return provided drivers + */ + Set<Driver> getDrivers(); + + /** + * Returns the set of drivers which support the specified behaviour. + * + * @param withBehaviour behaviour class to query by + * @return provided drivers + */ + Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour); + + /** + * Returns the driver that matches the specified primordial device + * discovery information. + * + * @param mfr device manufacturer + * @param hw device hardware name/version + * @param sw device software version + * @return driver or null of no matching one is found + */ + Driver getDriver(String mfr, String hw, String sw); + + /** + * Returns the driver for the specified device. If the device carries + * {@code driver} annotation, its value is used to look-up the driver. + * Otherwise, the device manufacturer, hardware and software version + * attributes are used to look-up the driver. First using their literal + * values and if no driver is found, using ERE matching against the + * driver manufacturer, hardware and software version fields. + * + * @param deviceId device identifier + * @return driver or null of no matching one is found + * @throws org.onlab.util.ItemNotFoundException if device or driver for it + * are not found + */ + Driver getDriver(DeviceId deviceId); + + /** + * Creates a new driver handler for interacting with the specified device. + * The driver is looked-up using the same semantics as + * {@link #getDriver(DeviceId)} method. + * + * @param deviceId device identifier + * @param credentials optional login credentials in string form + * @return driver handler + * @throws org.onlab.util.ItemNotFoundException if device or driver for it + * are not found + */ + DriverHandler createHandler(DeviceId deviceId, String... credentials); + + // TODO: Devise a mechanism for retaining DriverData for devices + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java new file mode 100644 index 00000000..b5771ac1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java @@ -0,0 +1,38 @@ +/* + * 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.driver; + +/** + * Representation of a facet of device behaviour that can be used to interact + * with a device (in context of {@link org.onosproject.net.driver.DriverHandler}). + */ +public interface HandlerBehaviour extends Behaviour { + + /** + * Returns the driver handler context on which this behaviour operates. + * + * @return driver handler context + */ + DriverHandler handler(); + + /** + * Sets the driver handler context for this behaviour. + * + * @param handler driver handler + */ + void setHandler(DriverHandler handler); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/XmlDriverLoader.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/XmlDriverLoader.java new file mode 100644 index 00000000..fc5e04a1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/XmlDriverLoader.java @@ -0,0 +1,176 @@ +/* + * 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.driver; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.HierarchicalConfiguration; +import org.apache.commons.configuration.XMLConfiguration; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * Utility capable of reading driver configuration XML resources and producing + * a device driver provider as a result. + * <p> + * The drivers stream structure is as follows: + * </p> + * <pre> + * <drivers> + * <driver name=“...” [manufacturer="..." hwVersion="..." swVersion="..."]> + * <behaviour api="..." impl="..."/> + * ... + * [<property name=“key”>value</key>] + * ... + * </driver> + * ... + * </drivers> + * </pre> + */ +public class XmlDriverLoader { + + private static final String DRIVERS = "drivers"; + private static final String DRIVER = "driver"; + + private static final String BEHAVIOUR = "behaviour"; + private static final String PROPERTY = "property"; + + private static final String NAME = "[@name]"; + private static final String EXTENDS = "[@extends]"; + private static final String MFG = "[@manufacturer]"; + private static final String HW = "[@hwVersion]"; + private static final String SW = "[@swVersion]"; + private static final String API = "[@api]"; + private static final String IMPL = "[@impl]"; + + private final ClassLoader classLoader; + + private Map<String, Driver> drivers = Maps.newHashMap(); + + /** + * Creates a new driver loader capable of loading drivers from the supplied + * class loader. + * + * @param classLoader class loader to use + */ + public XmlDriverLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + /** + * Loads the specified drivers resource as an XML stream and parses it to + * produce a ready-to-register driver provider. + * + * @param driversStream stream containing the drivers definitions + * @param resolver driver resolver + * @return driver provider + * @throws java.io.IOException if issues are encountered reading the stream + * or parsing the driver definitions within + */ + public DefaultDriverProvider loadDrivers(InputStream driversStream, + DriverResolver resolver) throws IOException { + try { + XMLConfiguration cfg = new XMLConfiguration(); + cfg.setRootElementName(DRIVERS); + cfg.setAttributeSplittingDisabled(true); + + cfg.load(driversStream); + return loadDrivers(cfg, resolver); + } catch (ConfigurationException e) { + throw new IOException("Unable to load drivers", e); + } + } + + /** + * Loads a driver provider from the supplied hierarchical configuration. + * + * @param driversCfg hierarchical configuration containing the drivers definitions + * @param resolver driver resolver + * @return driver provider + */ + public DefaultDriverProvider loadDrivers(HierarchicalConfiguration driversCfg, + DriverResolver resolver) { + DefaultDriverProvider provider = new DefaultDriverProvider(); + for (HierarchicalConfiguration cfg : driversCfg.configurationsAt(DRIVER)) { + DefaultDriver driver = loadDriver(cfg, resolver); + drivers.put(driver.name(), driver); + provider.addDriver(driver); + } + drivers.clear(); + return provider; + } + + /** + * Loads a driver from the supplied hierarchical configuration. + * + * @param driverCfg hierarchical configuration containing the driver definition + * @param resolver driver resolver + * @return driver + */ + public DefaultDriver loadDriver(HierarchicalConfiguration driverCfg, + DriverResolver resolver) { + String name = driverCfg.getString(NAME); + String parentName = driverCfg.getString(EXTENDS); + String manufacturer = driverCfg.getString(MFG, ""); + String hwVersion = driverCfg.getString(HW, ""); + String swVersion = driverCfg.getString(SW, ""); + + Driver parent = parentName != null ? resolve(parentName, resolver) : null; + return new DefaultDriver(name, parent, manufacturer, hwVersion, swVersion, + parseBehaviours(driverCfg), + parseProperties(driverCfg)); + } + + // Resolves the driver by name locally at first and then using the specified resolver. + private Driver resolve(String parentName, DriverResolver resolver) { + Driver driver = drivers.get(parentName); + return driver != null ? driver : + (resolver != null ? resolver.getDriver(parentName) : null); + } + + // Parses the behaviours section. + private Map<Class<? extends Behaviour>, Class<? extends Behaviour>> + parseBehaviours(HierarchicalConfiguration driverCfg) { + ImmutableMap.Builder<Class<? extends Behaviour>, + Class<? extends Behaviour>> behaviours = ImmutableMap.builder(); + for (HierarchicalConfiguration b : driverCfg.configurationsAt(BEHAVIOUR)) { + behaviours.put(getClass(b.getString(API)), getClass(b.getString(IMPL))); + } + return behaviours.build(); + } + + // Parses the properties section. + private Map<String, String> parseProperties(HierarchicalConfiguration driverCfg) { + ImmutableMap.Builder<String, String> properties = ImmutableMap.builder(); + for (HierarchicalConfiguration b : driverCfg.configurationsAt(PROPERTY)) { + properties.put(b.getString(NAME), (String) b.getRootNode().getValue()); + } + return properties.build(); + } + + @SuppressWarnings("unchecked") + private Class<? extends Behaviour> getClass(String className) { + try { + return (Class<? extends Behaviour>) classLoader.loadClass(className); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Unable to load class " + className, e); + } + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/package-info.java new file mode 100644 index 00000000..fbc39a89 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/driver/package-info.java @@ -0,0 +1,68 @@ +/* + * 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. + */ + +/** + * Set of facilities to allow the platform to be extended with + * device specific behaviours and to allow modeling device behaviours while + * hiding details of specific device driver implementations. + * <p> + * {@link org.onosproject.net.driver.Driver} is a representation of a + * specific family of devices supports set of + * {@link org.onosproject.net.driver.Behaviour behaviour classes}. Default + * implementation is provided by the platform and allows DriverProviders to + * add different behaviour implementations via DriverService. + * </p> + * <p> + * {@link org.onosproject.net.driver.DriverData} is a container for data + * learned about a device. It is associated with a specific + * {@link org.onosproject.net.driver.Driver} + * and provides set of {@link org.onosproject.net.driver.Behaviour behaviours} + * for talking about a device. A default + * implementation provided by platform and has mutable key/value store for use by + * implementations of {@link org.onosproject.net.driver.Behaviour behaviours}. + * </p> + * <p> + * {@link org.onosproject.net.driver.DriverHandler} is an entity used as a + * context to interact with a device. It has a peer + * {@link org.onosproject.net.driver.DriverData} instance, which is used to + * store information learned about a device. It also + * provides set of {@link org.onosproject.net.driver.Behaviour behaviours} + * for talking to a device. + * </p> + * <p> + * {@link org.onosproject.net.driver.DriverService} can be used to query the + * inventory of device drivers and their behaviours, while the + * {@link org.onosproject.net.driver.DriverAdminService} allows adding/removing + * drivers and managing behaviour implementations. + * {@link org.onosproject.net.driver.DriverProvider} is an entity capable + * of add/removing drivers and supplying and managing behaviour + * implementations. A default implementation is provided by the framework along + * with a {@link org.onosproject.net.driver.XmlDriverLoader loader utility} to + * create a driver provider from an XML file structured as follows: + * <pre> + * <drivers> + * <driver name=“...” [manufacturer="..." hwVersion="..." swVersion="..."]> + * <behaviour api="..." impl="..."/> + * ... + * [<property name=“key”>value</key>] + * ... + * </driver> + * ... + * </drivers> + * </pre> + * + */ +package org.onosproject.net.driver;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortEvent.java new file mode 100644 index 00000000..85e6a1b5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortEvent.java @@ -0,0 +1,59 @@ +/* + * 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.edge; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.ConnectPoint; + +/** + * Describes an event pertaining to edge-port inventory. + */ +public class EdgePortEvent extends AbstractEvent<EdgePortEvent.Type, ConnectPoint> { + + public enum Type { + /** + * Signifies that a new edge port was detected. + */ + EDGE_PORT_ADDED, + + /** + * Signifies that a new edge port vanished. + */ + EDGE_PORT_REMOVED + } + + /** + * Creates a new edge port event. + * + * @param type event type + * @param subject connection point subject + */ + public EdgePortEvent(Type type, ConnectPoint subject) { + super(type, subject); + } + + /** + * Creates a new edge port event. + * + * @param type event type + * @param subject connection point subject + * @param time occurrence time + */ + public EdgePortEvent(Type type, ConnectPoint subject, long time) { + super(type, subject, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortListener.java new file mode 100644 index 00000000..dae03beb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortListener.java @@ -0,0 +1,24 @@ +/* + * 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.edge; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving edge port events. + */ +public interface EdgePortListener extends EventListener<EdgePortEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortService.java new file mode 100644 index 00000000..89a2c171 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/EdgePortService.java @@ -0,0 +1,75 @@ +/* + * 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.edge; + +import org.onosproject.event.ListenerService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.TrafficTreatment; + +import java.nio.ByteBuffer; +import java.util.Optional; + +/** + * Service for interacting with an inventory of network edge ports. A port + * is considered an edge port if it is an active port and does not have an + * infrastructure link associated with it. + */ +public interface EdgePortService + extends ListenerService<EdgePortEvent, EdgePortListener> { + + /** + * Indicates whether or not the specified connection point is an edge point. + * + * @param point connection point + * @return true if edge point + */ + boolean isEdgePoint(ConnectPoint point); + + /** + * Returns a collection of all edge point within the current topology. + * + * @return iterable collection of all edge points + */ + Iterable<ConnectPoint> getEdgePoints(); + + /** + * Returns a collection of all edge point for the specified device. + * + * @param deviceId device identifier + * @return iterable collection of all edge points for the device + */ + Iterable<ConnectPoint> getEdgePoints(DeviceId deviceId); + + /** + * Emits the specified packet, with optional treatment to all edge ports. + * + * @param data packet data + * @param treatment optional traffic treatment to apply to the packet + */ + void emitPacket(ByteBuffer data, Optional<TrafficTreatment> treatment); + + /** + * Emits the specified packet, with optional treatment to all edge ports. + * + * @param deviceId device where to send the packet out + * @param data packet data + * @param treatment optional traffic treatment to apply to the packet + */ + void emitPacket(DeviceId deviceId, ByteBuffer data, + Optional<TrafficTreatment> treatment); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/package-info.java new file mode 100644 index 00000000..d637f195 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/edge/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Service for interacting with network edge. + */ +package org.onosproject.net.edge;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperation.java new file mode 100644 index 00000000..09e34d88 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperation.java @@ -0,0 +1,128 @@ +/* + * Copyright 2014 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.flow; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A list of BatchOperationEntry. + * + * @param <T> the enum of operators <br> + * This enum must be defined in each sub-classes. + */ +public abstract class BatchOperation<T extends BatchOperationEntry<?, ?>> { + + private final List<T> ops; + + /** + * Creates new {@link BatchOperation} object. + */ + public BatchOperation() { + ops = new LinkedList<>(); + } + + /** + * Creates {@link BatchOperation} object from a list of batch operation + * entries. + * + * @param batchOperations the list of batch operation entries. + */ + public BatchOperation(Collection<T> batchOperations) { + ops = new LinkedList<>(checkNotNull(batchOperations)); + } + + /** + * Removes all operations maintained in this object. + */ + public void clear() { + ops.clear(); + } + + /** + * Returns the number of operations in this object. + * + * @return the number of operations in this object + */ + public int size() { + return ops.size(); + } + + /** + * Returns the operations in this object. + * + * @return the operations in this object + */ + public List<T> getOperations() { + return Collections.unmodifiableList(ops); + } + + /** + * Adds an operation. + * FIXME: Brian promises that the Intent Framework + * will not modify the batch operation after it has submitted it. + * Ali would prefer immutablity, but trusts brian for better or + * for worse. + * + * @param entry the operation to be added + * @return this object if succeeded, null otherwise + */ + public BatchOperation<T> addOperation(T entry) { + return ops.add(entry) ? this : null; + } + + /** + * Add all operations from another batch to this batch. + * + * @param another another batch + * @return true if success + */ + public boolean addAll(BatchOperation<T> another) { + return ops.addAll(another.getOperations()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null) { + return false; + } + + if (getClass() != o.getClass()) { + return false; + } + BatchOperation<?> other = (BatchOperation<?>) o; + + return this.ops.equals(other.ops); + } + + @Override + public int hashCode() { + return ops.hashCode(); + } + + @Override + public String toString() { + return ops.toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationEntry.java new file mode 100644 index 00000000..cc054286 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationEntry.java @@ -0,0 +1,90 @@ +/* + * Copyright 2014-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.flow; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A super class for batch operation entry classes. + * <p> + * This is the interface to classes which are maintained by BatchOperation as + * its entries. + */ +public class BatchOperationEntry<T extends Enum<?>, U> { + + private final T operator; + private final U target; + + /** + * Constructs new instance for the entry of the BatchOperation. + * + * @param operator the operator of this operation + * @param target the target object of this operation + */ + public BatchOperationEntry(T operator, U target) { + this.operator = checkNotNull(operator); + this.target = checkNotNull(target); + } + + /** + * Gets the target object of this operation. + * + * @return the target object of this operation + */ + public U target() { + return target; + } + + /** + * Gets the operator of this operation. + * + * @return the operator of this operation + */ + public T operator() { + return operator; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BatchOperationEntry<?, ?> other = (BatchOperationEntry<?, ?>) o; + return (this.operator == other.operator) && + Objects.equals(this.target, other.target); + } + + @Override + public int hashCode() { + return Objects.hash(operator, target); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("operator", operator) + .add("target", target) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationResult.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationResult.java new file mode 100644 index 00000000..684a8698 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/BatchOperationResult.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014 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.flow; + +import java.util.Set; + +/** + * Interface capturing the result of a batch operation. + * + */ +public interface BatchOperationResult<T> { + + /** + * Returns whether the operation was successful. + * @return true if successful, false otherwise + */ + boolean isSuccess(); + + /** + * Obtains a set of items which failed. + * @return a set of failures + */ + Set<T> failedItems(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/CompletedBatchOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/CompletedBatchOperation.java new file mode 100644 index 00000000..3afae5ef --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/CompletedBatchOperation.java @@ -0,0 +1,96 @@ +/* + * Copyright 2014-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.flow; + + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.DeviceId; + +import java.util.Collections; +import java.util.Set; + +/** + * Representation of a completed flow rule batch operation. + */ +public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { + + private final boolean success; + private final Set<FlowRule> failures; + private final Set<Long> failedIds; + private final DeviceId deviceId; + + /** + * Creates a new batch completion result. + * + * @param success indicates whether the completion is successful + * @param failures set of any failures encountered + * @param failedIds (optional) set of failed operation ids + * @param deviceId the device this operation completed for + */ + public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures, + Set<Long> failedIds, DeviceId deviceId) { + this.success = success; + this.failures = ImmutableSet.copyOf(failures); + this.failedIds = ImmutableSet.copyOf(failedIds); + this.deviceId = deviceId; + } + + /** + * Creates a new batch completion result. + * + * @param success indicates whether the completion is successful. + * @param failures set of any failures encountered + * @param deviceId the device this operation completed for + */ + public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures, + DeviceId deviceId) { + this.success = success; + this.failures = ImmutableSet.copyOf(failures); + this.failedIds = Collections.emptySet(); + this.deviceId = deviceId; + } + + + + @Override + public boolean isSuccess() { + return success; + } + + @Override + public Set<FlowRule> failedItems() { + return failures; + } + + public Set<Long> failedIds() { + return failedIds; + } + + public DeviceId deviceId() { + return this.deviceId; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("success?", success) + .add("failedItems", failures) + .add("failedIds", failedIds) + .add("deviceId", deviceId) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java new file mode 100644 index 00000000..f7e7708e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java @@ -0,0 +1,137 @@ +/* + * Copyright 2014-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.flow; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static org.slf4j.LoggerFactory.getLogger; + +import org.slf4j.Logger; + +public class DefaultFlowEntry extends DefaultFlowRule + implements StoredFlowEntry { + + private static final Logger log = getLogger(DefaultFlowEntry.class); + + private long life; + private long packets; + private long bytes; + private FlowEntryState state; + + private long lastSeen = -1; + + private final int errType; + + private final int errCode; + + public DefaultFlowEntry(FlowRule rule, FlowEntryState state, + long life, long packets, long bytes) { + super(rule); + this.state = state; + this.life = life; + this.packets = packets; + this.bytes = bytes; + this.errCode = -1; + this.errType = -1; + this.lastSeen = System.currentTimeMillis(); + } + + public DefaultFlowEntry(FlowRule rule) { + super(rule); + this.state = FlowEntryState.PENDING_ADD; + this.life = 0; + this.packets = 0; + this.bytes = 0; + this.errCode = -1; + this.errType = -1; + this.lastSeen = System.currentTimeMillis(); + } + + public DefaultFlowEntry(FlowRule rule, int errType, int errCode) { + super(rule); + this.state = FlowEntryState.FAILED; + this.errType = errType; + this.errCode = errCode; + this.lastSeen = System.currentTimeMillis(); + } + + @Override + public long life() { + return life; + } + + @Override + public long packets() { + return packets; + } + + @Override + public long bytes() { + return bytes; + } + + @Override + public FlowEntryState state() { + return this.state; + } + + @Override + public long lastSeen() { + return lastSeen; + } + + @Override + public void setLastSeen() { + this.lastSeen = System.currentTimeMillis(); + } + + @Override + public void setState(FlowEntryState newState) { + this.state = newState; + } + + @Override + public void setLife(long life) { + this.life = life; + } + + @Override + public void setPackets(long packets) { + this.packets = packets; + } + + @Override + public void setBytes(long bytes) { + this.bytes = bytes; + } + + @Override + public int errType() { + return this.errType; + } + + @Override + public int errCode() { + return this.errCode; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("rule", super.toString()) + .add("state", state) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java new file mode 100644 index 00000000..44a4d364 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java @@ -0,0 +1,390 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.core.ApplicationId; +import org.onosproject.core.DefaultGroupId; +import org.onosproject.core.GroupId; +import org.onosproject.net.DeviceId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class DefaultFlowRule implements FlowRule { + + private final DeviceId deviceId; + private final int priority; + private final TrafficSelector selector; + private final TrafficTreatment treatment; + private final long created; + + private final FlowId id; + + private final Short appId; + + private final int timeout; + private final boolean permanent; + private final GroupId groupId; + + private final Integer tableId; + private final FlowRuleExtPayLoad payLoad; + + public DefaultFlowRule(FlowRule rule) { + this.deviceId = rule.deviceId(); + this.priority = rule.priority(); + this.selector = rule.selector(); + this.treatment = rule.treatment(); + this.appId = rule.appId(); + this.groupId = rule.groupId(); + this.id = rule.id(); + this.timeout = rule.timeout(); + this.permanent = rule.isPermanent(); + this.created = System.currentTimeMillis(); + this.tableId = rule.tableId(); + this.payLoad = rule.payLoad(); + } + + private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, + TrafficTreatment treatment, Integer priority, + FlowId flowId, Boolean permanent, Integer timeout, + Integer tableId) { + + this.deviceId = deviceId; + this.selector = selector; + this.treatment = treatment; + this.priority = priority; + this.appId = (short) (flowId.value() >>> 48); + this.id = flowId; + this.permanent = permanent; + this.timeout = timeout; + this.tableId = tableId; + this.created = System.currentTimeMillis(); + + + //FIXME: fields below will be removed. + this.groupId = new DefaultGroupId(0); + this.payLoad = null; + } + + /** + * Support for the third party flow rule. Creates a flow rule of flow table. + * + * @param deviceId the identity of the device where this rule applies + * @param selector the traffic selector that identifies what traffic this + * rule + * @param treatment the traffic treatment that applies to selected traffic + * @param priority the flow rule priority given in natural order + * @param appId the application id of this flow + * @param timeout the timeout for this flow requested by an application + * @param permanent whether the flow is permanent i.e. does not time out + * @param payLoad 3rd-party origin private flow + */ + public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, + TrafficTreatment treatment, int priority, + ApplicationId appId, int timeout, boolean permanent, + FlowRuleExtPayLoad payLoad) { + + if (priority < FlowRule.MIN_PRIORITY) { + throw new IllegalArgumentException("Priority cannot be less than " + + MIN_PRIORITY); + } + + this.deviceId = deviceId; + this.priority = priority; + this.selector = selector; + this.treatment = treatment; + this.appId = appId.id(); + this.groupId = new DefaultGroupId(0); + this.timeout = timeout; + this.permanent = permanent; + this.tableId = 0; + this.created = System.currentTimeMillis(); + this.payLoad = payLoad; + + /* + * id consists of the following. | appId (16 bits) | groupId (16 bits) | + * flowId (32 bits) | + */ + this.id = FlowId.valueOf((((long) this.appId) << 48) + | (((long) this.groupId.id()) << 32) + | (this.hash() & 0xffffffffL)); + } + + /** + * Support for the third party flow rule. Creates a flow rule of group + * table. + * + * @param deviceId the identity of the device where this rule applies + * @param selector the traffic selector that identifies what traffic this + * rule + * @param treatment the traffic treatment that applies to selected traffic + * @param priority the flow rule priority given in natural order + * @param appId the application id of this flow + * @param groupId the group id of this flow + * @param timeout the timeout for this flow requested by an application + * @param permanent whether the flow is permanent i.e. does not time out + * @param payLoad 3rd-party origin private flow + * + */ + public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, + TrafficTreatment treatment, int priority, + ApplicationId appId, GroupId groupId, int timeout, + boolean permanent, FlowRuleExtPayLoad payLoad) { + + if (priority < FlowRule.MIN_PRIORITY) { + throw new IllegalArgumentException("Priority cannot be less than " + + MIN_PRIORITY); + } + + this.deviceId = deviceId; + this.priority = priority; + this.selector = selector; + this.treatment = treatment; + this.appId = appId.id(); + this.groupId = groupId; + this.timeout = timeout; + this.permanent = permanent; + this.created = System.currentTimeMillis(); + this.tableId = 0; + this.payLoad = payLoad; + + /* + * id consists of the following. | appId (16 bits) | groupId (16 bits) | + * flowId (32 bits) | + */ + this.id = FlowId.valueOf((((long) this.appId) << 48) + | (((long) this.groupId.id()) << 32) + | (this.hash() & 0xffffffffL)); + } + + @Override + public FlowId id() { + return id; + } + + @Override + public short appId() { + return appId; + } + + @Override + public GroupId groupId() { + return groupId; + } + + @Override + public int priority() { + return priority; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public TrafficSelector selector() { + return selector; + } + + @Override + public TrafficTreatment treatment() { + return treatment; + } + + @Override + /* + * The priority and statistics can change on a given treatment and selector + * + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public int hashCode() { + return Objects.hash(deviceId, selector, tableId, payLoad); + } + + //FIXME do we need this method in addition to hashCode()? + private int hash() { + return Objects.hash(deviceId, selector, tableId, payLoad); + } + + @Override + /* + * The priority and statistics can change on a given treatment and selector + * + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultFlowRule) { + DefaultFlowRule that = (DefaultFlowRule) obj; + return Objects.equals(deviceId, that.deviceId) && + Objects.equals(priority, that.priority) && + Objects.equals(selector, that.selector) && + Objects.equals(tableId, that.tableId) + && Objects.equals(payLoad, that.payLoad); + } + return false; + } + + @Override + public boolean exactMatch(FlowRule rule) { + return this.equals(rule) && + Objects.equals(this.id, rule.id()) && + Objects.equals(this.treatment, rule.treatment()); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", Long.toHexString(id.value())) + .add("deviceId", deviceId) + .add("priority", priority) + .add("selector", selector.criteria()) + .add("treatment", treatment == null ? "N/A" : treatment.allInstructions()) + .add("tableId", tableId) + .add("created", created) + .add("payLoad", payLoad) + .toString(); + } + + @Override + public int timeout() { + return timeout; + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public int tableId() { + return tableId; + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder implements FlowRule.Builder { + + private FlowId flowId; + private Integer priority; + private DeviceId deviceId; + private Integer tableId = 0; + private TrafficSelector selector; + private TrafficTreatment treatment; + private Integer timeout; + private Boolean permanent; + + @Override + public FlowRule.Builder withCookie(long cookie) { + this.flowId = FlowId.valueOf(cookie); + return this; + } + + @Override + public FlowRule.Builder fromApp(ApplicationId appId) { + this.flowId = computeFlowId(appId); + return this; + } + + @Override + public FlowRule.Builder withPriority(int priority) { + this.priority = priority; + return this; + } + + @Override + public FlowRule.Builder forDevice(DeviceId deviceId) { + this.deviceId = deviceId; + return this; + } + + @Override + public FlowRule.Builder forTable(int tableId) { + this.tableId = tableId; + return this; + } + + @Override + public FlowRule.Builder withSelector(TrafficSelector selector) { + this.selector = selector; + return this; + } + + @Override + public FlowRule.Builder withTreatment(TrafficTreatment treatment) { + this.treatment = treatment; + return this; + } + + @Override + public FlowRule.Builder makePermanent() { + this.timeout = 0; + this.permanent = true; + return this; + } + + @Override + public FlowRule.Builder makeTemporary(int timeout) { + this.permanent = false; + this.timeout = timeout; + return this; + } + + @Override + public FlowRule build() { + checkNotNull(flowId != null, "Either an application" + + " id or a cookie must be supplied"); + checkNotNull(selector != null, "Traffic selector cannot be null"); + checkNotNull(timeout != null || permanent != null, "Must either have " + + "a timeout or be permanent"); + checkNotNull(deviceId != null, "Must refer to a device"); + checkNotNull(priority != null, "Priority cannot be null"); + checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " + + MIN_PRIORITY); + + return new DefaultFlowRule(deviceId, selector, treatment, priority, + flowId, permanent, timeout, tableId); + } + + private FlowId computeFlowId(ApplicationId appId) { + return FlowId.valueOf((((long) appId.id()) << 48) + | (hash() & 0xffffffffL)); + } + + private int hash() { + return Objects.hash(deviceId, priority, selector, tableId); + } + + } + + @Override + public FlowRuleExtPayLoad payLoad() { + return payLoad; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java new file mode 100644 index 00000000..f88c6bc3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java @@ -0,0 +1,365 @@ +/* + * Copyright 2014-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.flow; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; +import org.onlab.packet.Ip6Address; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.net.IndexedLambda; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.criteria.Criteria; +import org.onosproject.net.flow.criteria.Criterion; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Default traffic selector implementation. + */ +public final class DefaultTrafficSelector implements TrafficSelector { + + private final Set<Criterion> criteria; + + private static final TrafficSelector EMPTY + = new DefaultTrafficSelector(Collections.emptySet()); + + /** + * Creates a new traffic selector with the specified criteria. + * + * @param criteria criteria + */ + private DefaultTrafficSelector(Set<Criterion> criteria) { + this.criteria = ImmutableSet.copyOf(criteria); + } + + @Override + public Set<Criterion> criteria() { + return criteria; + } + + @Override + public Criterion getCriterion(Criterion.Type type) { + for (Criterion c : criteria) { + if (c.type() == type) { + return c; + } + } + return null; + } + + @Override + public int hashCode() { + return criteria.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTrafficSelector) { + DefaultTrafficSelector that = (DefaultTrafficSelector) obj; + return Objects.equals(criteria, that.criteria); + + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("criteria", criteria) + .toString(); + } + + /** + * Returns a new traffic selector builder. + * + * @return traffic selector builder + */ + public static TrafficSelector.Builder builder() { + return new Builder(); + } + + /** + * Returns an empty traffic selector. + * + * @return empty traffic selector + */ + public static TrafficSelector emptySelector() { + return EMPTY; + } + + /** + * Returns a new traffic selector builder primed to produce entities + * patterned after the supplied selector. + * + * @param selector base selector + * @return traffic selector builder + */ + public static TrafficSelector.Builder builder(TrafficSelector selector) { + return new Builder(selector); + } + + /** + * Builder of traffic selector entities. + */ + public static final class Builder implements TrafficSelector.Builder { + + private final Map<Criterion.Type, Criterion> selector = new HashMap<>(); + + private Builder() { + } + + private Builder(TrafficSelector selector) { + for (Criterion c : selector.criteria()) { + add(c); + } + } + + @Override + public Builder add(Criterion criterion) { + selector.put(criterion.type(), criterion); + return this; + } + + @Override + public Builder matchInPort(PortNumber port) { + return add(Criteria.matchInPort(port)); + } + + @Override + public Builder matchInPhyPort(PortNumber port) { + return add(Criteria.matchInPhyPort(port)); + } + + @Override + public Builder matchMetadata(long metadata) { + return add(Criteria.matchMetadata(metadata)); + } + + @Override + public Builder matchEthDst(MacAddress addr) { + return add(Criteria.matchEthDst(addr)); + } + + @Override + public Builder matchEthSrc(MacAddress addr) { + return add(Criteria.matchEthSrc(addr)); + } + + @Override + public Builder matchEthType(short ethType) { + return add(Criteria.matchEthType(ethType)); + } + + @Override + public Builder matchVlanId(VlanId vlanId) { + return add(Criteria.matchVlanId(vlanId)); + } + + @Override + public Builder matchVlanPcp(byte vlanPcp) { + return add(Criteria.matchVlanPcp(vlanPcp)); + } + + @Override + public Builder matchIPDscp(byte ipDscp) { + return add(Criteria.matchIPDscp(ipDscp)); + } + + @Override + public Builder matchIPEcn(byte ipEcn) { + return add(Criteria.matchIPEcn(ipEcn)); + } + + @Override + public Builder matchIPProtocol(byte proto) { + return add(Criteria.matchIPProtocol(proto)); + } + + @Override + public Builder matchIPSrc(IpPrefix ip) { + return add(Criteria.matchIPSrc(ip)); + } + + @Override + public Builder matchIPDst(IpPrefix ip) { + return add(Criteria.matchIPDst(ip)); + } + + @Deprecated + @Override + public Builder matchTcpSrc(short tcpPort) { + return matchTcpSrc(TpPort.tpPort(tcpPort)); + } + + @Override + public Builder matchTcpSrc(TpPort tcpPort) { + return add(Criteria.matchTcpSrc(tcpPort)); + } + + @Deprecated + @Override + public Builder matchTcpDst(short tcpPort) { + return matchTcpDst(TpPort.tpPort(tcpPort)); + } + + @Override + public Builder matchTcpDst(TpPort tcpPort) { + return add(Criteria.matchTcpDst(tcpPort)); + } + + @Deprecated + @Override + public Builder matchUdpSrc(short udpPort) { + return matchUdpSrc(TpPort.tpPort(udpPort)); + } + + @Override + public Builder matchUdpSrc(TpPort udpPort) { + return add(Criteria.matchUdpSrc(udpPort)); + } + + @Deprecated + @Override + public Builder matchUdpDst(short udpPort) { + return matchUdpDst(TpPort.tpPort(udpPort)); + } + + @Override + public Builder matchUdpDst(TpPort udpPort) { + return add(Criteria.matchUdpDst(udpPort)); + } + + @Deprecated + @Override + public Builder matchSctpSrc(short sctpPort) { + return matchSctpSrc(TpPort.tpPort(sctpPort)); + } + + @Override + public Builder matchSctpSrc(TpPort sctpPort) { + return add(Criteria.matchSctpSrc(sctpPort)); + } + + @Deprecated + @Override + public Builder matchSctpDst(short sctpPort) { + return matchSctpDst(TpPort.tpPort(sctpPort)); + } + + @Override + public Builder matchSctpDst(TpPort sctpPort) { + return add(Criteria.matchSctpDst(sctpPort)); + } + + @Override + public Builder matchIcmpType(byte icmpType) { + return add(Criteria.matchIcmpType(icmpType)); + } + + @Override + public Builder matchIcmpCode(byte icmpCode) { + return add(Criteria.matchIcmpCode(icmpCode)); + } + + @Override + public Builder matchIPv6Src(IpPrefix ip) { + return add(Criteria.matchIPv6Src(ip)); + } + + @Override + public Builder matchIPv6Dst(IpPrefix ip) { + return add(Criteria.matchIPv6Dst(ip)); + } + + @Override + public Builder matchIPv6FlowLabel(int flowLabel) { + return add(Criteria.matchIPv6FlowLabel(flowLabel)); + } + + @Override + public Builder matchIcmpv6Type(byte icmpv6Type) { + return add(Criteria.matchIcmpv6Type(icmpv6Type)); + } + + @Override + public Builder matchIcmpv6Code(byte icmpv6Code) { + return add(Criteria.matchIcmpv6Code(icmpv6Code)); + } + + @Override + public Builder matchIPv6NDTargetAddress(Ip6Address targetAddress) { + return add(Criteria.matchIPv6NDTargetAddress(targetAddress)); + } + + @Override + public Builder matchIPv6NDSourceLinkLayerAddress(MacAddress mac) { + return add(Criteria.matchIPv6NDSourceLinkLayerAddress(mac)); + } + + @Override + public Builder matchIPv6NDTargetLinkLayerAddress(MacAddress mac) { + return add(Criteria.matchIPv6NDTargetLinkLayerAddress(mac)); + } + + @Override + public Builder matchMplsLabel(MplsLabel mplsLabel) { + return add(Criteria.matchMplsLabel(mplsLabel)); + } + + @Override + public Builder matchMplsBos(boolean mplsBos) { + return add(Criteria.matchMplsLabel(mplsBos)); + } + + @Override + public TrafficSelector.Builder matchTunnelId(long tunnelId) { + return add(Criteria.matchTunnelId(tunnelId)); + } + + @Override + public Builder matchIPv6ExthdrFlags(short exthdrFlags) { + return add(Criteria.matchIPv6ExthdrFlags(exthdrFlags)); + } + + @Deprecated + @Override + public Builder matchLambda(short lambda) { + return add(Criteria.matchLambda(new IndexedLambda(lambda))); + } + + @Deprecated + @Override + public Builder matchOpticalSignalType(short signalType) { + return add(Criteria.matchOpticalSignalType(signalType)); + } + + @Override + public TrafficSelector build() { + return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values())); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java new file mode 100644 index 00000000..5d18a9ad --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java @@ -0,0 +1,479 @@ +/* + * Copyright 2014-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.flow; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.onlab.packet.EthType; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.core.GroupId; +import org.onosproject.net.IndexedLambda; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.instructions.Instruction; +import org.onosproject.net.flow.instructions.Instructions; +import org.onosproject.net.meter.MeterId; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default traffic treatment implementation. + */ +public final class DefaultTrafficTreatment implements TrafficTreatment { + + private final List<Instruction> immediate; + private final List<Instruction> deferred; + private final List<Instruction> all; + private final Instructions.TableTypeTransition table; + private final Instructions.MetadataInstruction meta; + + private final boolean hasClear; + + private static final DefaultTrafficTreatment EMPTY + = new DefaultTrafficTreatment(Collections.emptyList()); + private final Instructions.MeterInstruction meter; + + /** + * Creates a new traffic treatment from the specified list of instructions. + * + * @param immediate immediate instructions + */ + private DefaultTrafficTreatment(List<Instruction> immediate) { + this.immediate = ImmutableList.copyOf(checkNotNull(immediate)); + this.deferred = ImmutableList.of(); + this.all = this.immediate; + this.hasClear = false; + this.table = null; + this.meta = null; + this.meter = null; + } + + /** + * Creates a new traffic treatment from the specified list of instructions. + * + * @param deferred deferred instructions + * @param immediate immediate instructions + * @param table table transition instruction + * @param clear instruction to clear the deferred actions list + */ + private DefaultTrafficTreatment(List<Instruction> deferred, + List<Instruction> immediate, + Instructions.TableTypeTransition table, + boolean clear, + Instructions.MetadataInstruction meta, + Instructions.MeterInstruction meter) { + this.immediate = ImmutableList.copyOf(checkNotNull(immediate)); + this.deferred = ImmutableList.copyOf(checkNotNull(deferred)); + this.all = new ImmutableList.Builder<Instruction>() + .addAll(immediate) + .addAll(deferred) + .build(); + this.table = table; + this.meta = meta; + this.hasClear = clear; + this.meter = meter; + } + + @Override + public List<Instruction> deferred() { + return deferred; + } + + @Override + public List<Instruction> immediate() { + return immediate; + } + + @Override + public List<Instruction> allInstructions() { + return all; + } + + @Override + public Instructions.TableTypeTransition tableTransition() { + return table; + } + + @Override + public boolean clearedDeferred() { + return hasClear; + } + + @Override + public Instructions.MetadataInstruction writeMetadata() { + return meta; + } + + @Override + public Instructions.MeterInstruction metered() { + return meter; + } + + /** + * Returns a new traffic treatment builder. + * + * @return traffic treatment builder + */ + public static TrafficTreatment.Builder builder() { + return new Builder(); + } + + /** + * Returns an empty traffic treatment. + * + * @return empty traffic treatment + */ + public static TrafficTreatment emptyTreatment() { + return EMPTY; + } + + /** + * Returns a new traffic treatment builder primed to produce entities + * patterned after the supplied treatment. + * + * @param treatment base treatment + * @return traffic treatment builder + */ + public static TrafficTreatment.Builder builder(TrafficTreatment treatment) { + return new Builder(treatment); + } + + //FIXME: Order of instructions may affect hashcode + @Override + public int hashCode() { + return Objects.hash(immediate, deferred, table, meta); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTrafficTreatment) { + DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj; + return Objects.equals(immediate, that.immediate) && + Objects.equals(deferred, that.deferred) && + Objects.equals(table, that.table) && + Objects.equals(meta, that.meta); + + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("immediate", immediate) + .add("deferred", deferred) + .add("transition", table == null ? "None" : table.toString()) + .add("cleared", hasClear) + .add("metadata", meta) + .toString(); + } + + /** + * Builds a list of treatments following the following order. + * Modifications -> Group -> Output (including drop) + */ + public static final class Builder implements TrafficTreatment.Builder { + + boolean clear = false; + + Instructions.TableTypeTransition table; + + Instructions.MetadataInstruction meta; + + Instructions.MeterInstruction meter; + + List<Instruction> deferred = Lists.newLinkedList(); + + List<Instruction> immediate = Lists.newLinkedList(); + + List<Instruction> current = immediate; + + + + // Creates a new builder + private Builder() { + } + + // Creates a new builder based off an existing treatment + private Builder(TrafficTreatment treatment) { + deferred(); + treatment.deferred().forEach(i -> add(i)); + + immediate(); + treatment.immediate().forEach(i -> add(i)); + + clear = treatment.clearedDeferred(); + } + + @Override + public Builder add(Instruction instruction) { + + switch (instruction.type()) { + case DROP: + case OUTPUT: + case GROUP: + case L0MODIFICATION: + case L2MODIFICATION: + case L3MODIFICATION: + case L4MODIFICATION: + current.add(instruction); + break; + case TABLE: + table = (Instructions.TableTypeTransition) instruction; + break; + case METADATA: + meta = (Instructions.MetadataInstruction) instruction; + break; + case METER: + meter = (Instructions.MeterInstruction) instruction; + default: + throw new IllegalArgumentException("Unknown instruction type: " + + instruction.type()); + } + + return this; + } + + @Override + public Builder drop() { + return add(Instructions.createDrop()); + } + + @Override + public Builder punt() { + return add(Instructions.createOutput(PortNumber.CONTROLLER)); + } + + @Override + public Builder setOutput(PortNumber number) { + return add(Instructions.createOutput(number)); + } + + @Override + public Builder setEthSrc(MacAddress addr) { + return add(Instructions.modL2Src(addr)); + } + + @Override + public Builder setEthDst(MacAddress addr) { + return add(Instructions.modL2Dst(addr)); + } + + @Override + public Builder setVlanId(VlanId id) { + return add(Instructions.modVlanId(id)); + } + + @Override + public Builder setVlanPcp(Byte pcp) { + return add(Instructions.modVlanPcp(pcp)); + } + + @Override + public Builder setIpSrc(IpAddress addr) { + return add(Instructions.modL3Src(addr)); + } + + @Override + public Builder setIpDst(IpAddress addr) { + return add(Instructions.modL3Dst(addr)); + } + + @Override + public Builder decNwTtl() { + return add(Instructions.decNwTtl()); + } + + @Override + public Builder copyTtlIn() { + return add(Instructions.copyTtlIn()); + } + + @Override + public Builder copyTtlOut() { + return add(Instructions.copyTtlOut()); + } + + @Override + public Builder pushMpls() { + return add(Instructions.pushMpls()); + } + + @Override + public Builder popMpls() { + return add(Instructions.popMpls()); + } + + @Override + public Builder popMpls(int etherType) { + return add(Instructions.popMpls(new EthType(etherType))); + } + + @Override + public Builder popMpls(EthType etherType) { + return add(Instructions.popMpls(etherType)); + } + + @Override + public Builder setMpls(MplsLabel mplsLabel) { + return add(Instructions.modMplsLabel(mplsLabel)); + } + + @Override + public Builder setMplsBos(boolean mplsBos) { + return add(Instructions.modMplsBos(mplsBos)); + } + + @Override + public Builder decMplsTtl() { + return add(Instructions.decMplsTtl()); + } + + @Deprecated + @Override + public Builder setLambda(short lambda) { + return add(Instructions.modL0Lambda(new IndexedLambda(lambda))); + } + + @Override + public Builder group(GroupId groupId) { + return add(Instructions.createGroup(groupId)); + } + + @Override + public TrafficTreatment.Builder meter(MeterId meterId) { + return add(Instructions.meterTraffic(meterId)); + } + + @Override + public Builder popVlan() { + return add(Instructions.popVlan()); + } + + @Override + public Builder pushVlan() { + return add(Instructions.pushVlan()); + } + + @Override + public Builder transition(FlowRule.Type type) { + return add(Instructions.transition(type.ordinal())); + } + + @Override + public Builder transition(Integer tableId) { + return add(Instructions.transition(tableId)); + } + + @Override + public Builder immediate() { + current = immediate; + return this; + } + + @Override + public Builder deferred() { + current = deferred; + return this; + } + + @Override + public Builder wipeDeferred() { + clear = true; + return this; + } + + @Override + public Builder writeMetadata(long metadata, long metadataMask) { + return add(Instructions.writeMetadata(metadata, metadataMask)); + } + + @Override + public Builder setTunnelId(long tunnelId) { + return add(Instructions.modTunnelId(tunnelId)); + } + + @Deprecated + @Override + public TrafficTreatment.Builder setTcpSrc(short port) { + return setTcpSrc(TpPort.tpPort(port)); + } + + @Override + public TrafficTreatment.Builder setTcpSrc(TpPort port) { + return add(Instructions.modTcpSrc(port)); + } + + @Deprecated + @Override + public TrafficTreatment.Builder setTcpDst(short port) { + return setTcpDst(TpPort.tpPort(port)); + } + + @Override + public TrafficTreatment.Builder setTcpDst(TpPort port) { + return add(Instructions.modTcpDst(port)); + } + + @Deprecated + @Override + public TrafficTreatment.Builder setUdpSrc(short port) { + return setUdpSrc(TpPort.tpPort(port)); + } + + @Override + public TrafficTreatment.Builder setUdpSrc(TpPort port) { + return add(Instructions.modUdpSrc(port)); + } + + @Deprecated + @Override + public TrafficTreatment.Builder setUdpDst(short port) { + return setUdpDst(TpPort.tpPort(port)); + } + + @Override + public TrafficTreatment.Builder setUdpDst(TpPort port) { + return add(Instructions.modUdpDst(port)); + } + + @Override + public TrafficTreatment build() { + //Don't add DROP instruction by default when instruction + //set is empty. This will be handled in DefaultSingleTablePipeline + //driver. + + //if (deferred.size() == 0 && immediate.size() == 0 + // && table == null && !clear) { + // drop(); + //} + return new DefaultTrafficTreatment(deferred, immediate, table, clear, meta, meter); + } + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java new file mode 100644 index 00000000..389b2142 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java @@ -0,0 +1,102 @@ +/* + * Copyright 2014 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.flow; + + +/** + * Represents a generalized match & action pair to be applied to + * an infrastucture device. + */ +public interface FlowEntry extends FlowRule { + + + enum FlowEntryState { + + /** + * Indicates that this rule has been submitted for addition. + * Not necessarily in the flow table. + */ + PENDING_ADD, + + /** + * Rule has been added which means it is in the flow table. + */ + ADDED, + + /** + * Flow has been marked for removal, might still be in flow table. + */ + PENDING_REMOVE, + + /** + * Flow has been removed from flow table and can be purged. + */ + REMOVED, + + /** + * Indicates that the installation of this flow has failed. + */ + FAILED + } + + /** + * Returns the flow entry state. + * + * @return flow entry state + */ + FlowEntryState state(); + + /** + * Returns the number of milliseconds this flow rule has been applied. + * + * @return number of millis + */ + long life(); + + /** + * Returns the number of packets this flow rule has matched. + * + * @return number of packets + */ + long packets(); + + /** + * Returns the number of bytes this flow rule has matched. + * + * @return number of bytes + */ + long bytes(); + + // TODO: consider removing this attribute + /** + * When this flow entry was last deemed active. + * @return epoch time of last activity + */ + long lastSeen(); + + /** + * Indicates the error type. + * @return an integer value of the error + */ + int errType(); + + /** + * Indicates the error code. + * @return an integer value of the error + */ + int errCode(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowId.java new file mode 100644 index 00000000..52500f59 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowId.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014 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.flow; + +import com.google.common.base.Objects; + +/** + * Representation of a Flow ID. + */ +public final class FlowId { + + private final long flowid; + + private FlowId(long id) { + this.flowid = id; + } + + public static FlowId valueOf(long id) { + return new FlowId(id); + } + + public long value() { + return flowid; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (obj.getClass() == this.getClass()) { + FlowId that = (FlowId) obj; + return Objects.equal(this.flowid, that.flowid); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.flowid); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java new file mode 100644 index 00000000..e446a9fe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java @@ -0,0 +1,265 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.core.ApplicationId; +import org.onosproject.core.GroupId; +import org.onosproject.net.DeviceId; + +/** + * Represents a generalized match & action pair to be applied to an + * infrastructure device. + */ +public interface FlowRule { + + static final int MAX_TIMEOUT = 60; + static final int MIN_PRIORITY = 0; + + /** + * The FlowRule type is used to determine in which table the flow rule needs + * to be put for multi-table support switch. For single table switch, + * Default is used. + * + * @deprecated in Cardinal Release + */ + @Deprecated + static enum Type { + /* + * Default type - used in flow rule for single table switch NOTE: this + * setting should not be used as Table 0 in a multi-table pipeline + */ + DEFAULT, + /* Used in flow entry for IP table */ + IP, + /* Used in flow entry for MPLS table */ + MPLS, + /* Used in flow entry for ACL table */ + ACL, + + /* VLAN-to-MPLS table */ + VLAN_MPLS, + + /* VLAN table */ + VLAN, + + /* Ethtype table */ + ETHER, + + /* Class of Service table */ + COS, + + /* Table 0 in a multi-table pipeline */ + FIRST, + } + + /** + * Returns the ID of this flow. + * + * @return the flow ID + */ + FlowId id(); + + /** + * Returns the application id of this flow. + * + * @return an applicationId + */ + short appId(); + + /** + * Returns the group id of this flow. + * + * @return an groupId + */ + GroupId groupId(); + + /** + * Returns the flow rule priority given in natural order; higher numbers + * mean higher priorities. + * + * @return flow rule priority + */ + int priority(); + + /** + * Returns the identity of the device where this rule applies. + * + * @return device identifier + */ + DeviceId deviceId(); + + /** + * Returns the traffic selector that identifies what traffic this rule + * should apply to. + * + * @return traffic selector + */ + TrafficSelector selector(); + + /** + * Returns the traffic treatment that applies to selected traffic. + * + * @return traffic treatment + */ + TrafficTreatment treatment(); + + /** + * Returns the timeout for this flow requested by an application. + * + * @return integer value of the timeout + */ + int timeout(); + + /** + * Returns whether the flow is permanent i.e. does not time out. + * + * @return true if the flow is permanent, otherwise false + */ + boolean isPermanent(); + + /** + * Returns the table id for this rule. + * + * @return an integer. + */ + int tableId(); + + /** + * {@inheritDoc} + * + * Equality for flow rules only considers 'match equality'. This means that + * two flow rules with the same match conditions will be equal, regardless + * of the treatment or other characteristics of the flow. + * + * @param obj the reference object with which to compare. + * @return {@code true} if this object is the same as the obj + * argument; {@code false} otherwise. + */ + boolean equals(Object obj); + + /** + * Returns whether this flow rule is an exact match to the flow rule given + * in the argument. + * <p> + * Exact match means that deviceId, priority, selector, + * tableId, flowId and treatment are equal. Note that this differs from + * the notion of object equality for flow rules, which does not consider the + * flowId or treatment when testing equality. + * </p> + * + * @param rule other rule to match against + * @return true if the rules are an exact match, otherwise false + */ + boolean exactMatch(FlowRule rule); + + /** + * A flowrule builder. + */ + interface Builder { + + /** + * Assigns a cookie value to this flowrule. Mutually exclusive with the + * fromApp method. This method is intended to take a cookie value from + * the dataplane and not from the application. + * + * @param cookie a long value + * @return this + */ + Builder withCookie(long cookie); + + /** + * Assigns the application that built this flow rule to this object. + * The short value of the appId will be used as a basis for the + * cookie value computation. It is expected that application use this + * call to set their application id. + * + * @param appId an application id + * @return this + */ + Builder fromApp(ApplicationId appId); + + /** + * Sets the priority for this flow rule. + * + * @param priority an integer + * @return this + */ + Builder withPriority(int priority); + + /** + * Sets the deviceId for this flow rule. + * + * @param deviceId a device id + * @return this + */ + Builder forDevice(DeviceId deviceId); + + /** + * Sets the table id for this flow rule. Default value is 0. + * + * @param tableId an integer + * @return this + */ + Builder forTable(int tableId); + + /** + * Sets the selector (or match field) for this flow rule. + * + * @param selector a traffic selector + * @return this + */ + Builder withSelector(TrafficSelector selector); + + /** + * Sets the traffic treatment for this flow rule. + * + * @param treatment a traffic treatment + * @return this + */ + Builder withTreatment(TrafficTreatment treatment); + + /** + * Makes this rule permanent on the dataplane. + * + * @return this + */ + Builder makePermanent(); + + /** + * Makes this rule temporary and timeout after the specified amount + * of time. + * + * @param timeout an integer + * @return this + */ + Builder makeTemporary(int timeout); + + /** + * Builds a flow rule object. + * + * @return a flow rule. + */ + FlowRule build(); + + } + + /** + * Returns the third party original flow rule. + * + * @return FlowRuleExtPayLoad + */ + FlowRuleExtPayLoad payLoad(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEntry.java new file mode 100644 index 00000000..455c6bd8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEntry.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation; + +@Deprecated +/** + * @deprecated in Drake release - no longer a public API + */ +public class FlowRuleBatchEntry + extends BatchOperationEntry<FlowRuleOperation, FlowRule> { + + private final Long id; // FIXME: consider using Optional<Long> + + public FlowRuleBatchEntry(FlowRuleOperation operator, FlowRule target) { + super(operator, target); + this.id = null; + } + + public FlowRuleBatchEntry(FlowRuleOperation operator, FlowRule target, Long id) { + super(operator, target); + this.id = id; + } + + public Long id() { + return id; + } + + public enum FlowRuleOperation { + ADD, + REMOVE, + MODIFY + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEvent.java new file mode 100644 index 00000000..2e823c23 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchEvent.java @@ -0,0 +1,116 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.DeviceId; + +@Deprecated +/** + * Describes flow rule batch event. + * + * @deprecated in Drake release - no longer a public API + */ +public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.Type, FlowRuleBatchRequest> { + + + /** + * Type of flow rule events. + */ + public enum Type { + + // Request has been forwarded to MASTER Node + /** + * Signifies that a batch operation has been initiated. + */ + BATCH_OPERATION_REQUESTED, + + // MASTER Node has pushed the batch down to the Device + // (e.g., Received barrier reply) + /** + * Signifies that a batch operation has completed. + */ + BATCH_OPERATION_COMPLETED, + } + + private final CompletedBatchOperation result; + private final DeviceId deviceId; + + /** + * Constructs a new FlowRuleBatchEvent. + * + * @param request batch operation request + * @param deviceId the device this batch will be processed on + * @return event. + */ + public static FlowRuleBatchEvent requested(FlowRuleBatchRequest request, DeviceId deviceId) { + FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_REQUESTED, request, deviceId); + return event; + } + + /** + * Constructs a new FlowRuleBatchEvent. + * @param request batch operation request. + * @param result completed batch operation result. + * @return event. + */ + public static FlowRuleBatchEvent completed(FlowRuleBatchRequest request, CompletedBatchOperation result) { + FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_COMPLETED, request, result); + return event; + } + + /** + * Returns the result of this batch operation. + * @return batch operation result. + */ + public CompletedBatchOperation result() { + return result; + } + + /** + * Returns the deviceId for this batch. + * @return device id + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Creates an event of a given type and for the specified flow rule batch. + * + * @param type flow rule batch event type + * @param request event flow rule batch subject + * @param result the result of the batch operation + */ + private FlowRuleBatchEvent(Type type, FlowRuleBatchRequest request, CompletedBatchOperation result) { + super(type, request); + this.result = result; + this.deviceId = result.deviceId(); + } + + /** + * Creates an event of a given type and for the specified flow rule batch. + * + * @param type flow rule batch event type + * @param request event flow rule batch subject + * @param deviceId the device id for this batch + */ + private FlowRuleBatchEvent(Type type, FlowRuleBatchRequest request, DeviceId deviceId) { + super(type, request); + this.result = null; + this.deviceId = deviceId; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchOperation.java new file mode 100644 index 00000000..35428f46 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchOperation.java @@ -0,0 +1,54 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.net.DeviceId; + +import java.util.Collection; + +@Deprecated +/** + * Class used with the flow subsystem to process per device + * batches. + * + * @deprecated in Drake release - no longer a public API + */ +public class FlowRuleBatchOperation + extends BatchOperation<FlowRuleBatchEntry> { + + /** + * This id is used to cary to id of the original + * FlowOperations and track where this batch operation + * came from. The id is unique cluster wide. + */ + private final long id; + private final DeviceId deviceId; + + public FlowRuleBatchOperation(Collection<FlowRuleBatchEntry> operations, + DeviceId deviceId, long flowOperationId) { + super(operations); + this.id = flowOperationId; + this.deviceId = deviceId; + } + + public DeviceId deviceId() { + return this.deviceId; + } + + public long id() { + return id; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java new file mode 100644 index 00000000..0b0585b9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.flow; + +import com.google.common.collect.Lists; +import org.onosproject.net.DeviceId; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +@Deprecated +/** + * @deprecated in Drake release - no longer a public API + */ +public class FlowRuleBatchRequest { + + /** + * This id is used to carry to id of the original + * FlowOperations and track where this batch operation + * came from. The id is unique cluster wide. + */ + private final long batchId; + + private final Set<FlowRuleBatchEntry> ops; + + + public FlowRuleBatchRequest(long batchId, Set<FlowRuleBatchEntry> ops) { + this.batchId = batchId; + this.ops = Collections.unmodifiableSet(ops); + } + + public Set<FlowRuleBatchEntry> ops() { + return ops; + } + + public FlowRuleBatchOperation asBatchOperation(DeviceId deviceId) { + List<FlowRuleBatchEntry> entries = Lists.newArrayList(); + entries.addAll(ops); + return new FlowRuleBatchOperation(entries, deviceId, batchId); + } + + public long batchId() { + return batchId; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleEvent.java new file mode 100644 index 00000000..41ef1c8a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleEvent.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes flow rule event. + */ +public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> { + + /** + * Type of flow rule events. + */ + public enum Type { + /** + * Signifies that a new flow rule has been detected. + */ + RULE_ADDED, + + /** + * Signifies that a flow rule has been removed. + */ + RULE_REMOVED, + + /** + * Signifies that a rule has been updated. + */ + RULE_UPDATED, + + // internal event between Manager <-> Store + + /* + * Signifies that a request to add flow rule has been added to the store. + */ + RULE_ADD_REQUESTED, + /* + * Signifies that a request to remove flow rule has been added to the store. + */ + RULE_REMOVE_REQUESTED, + } + + /** + * Creates an event of a given type and for the specified flow rule and the + * current time. + * + * @param type flow rule event type + * @param flowRule event flow rule subject + */ + public FlowRuleEvent(Type type, FlowRule flowRule) { + super(type, flowRule); + } + + /** + * Creates an event of a given type and for the specified flow rule and time. + * + * @param type flow rule event type + * @param flowRule event flow rule subject + * @param time occurrence time + */ + public FlowRuleEvent(Type type, FlowRule flowRule, long time) { + super(type, flowRule, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleExtPayLoad.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleExtPayLoad.java new file mode 100644 index 00000000..8d36be49 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleExtPayLoad.java @@ -0,0 +1,67 @@ +package org.onosproject.net.flow; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Arrays; + +/** + * Represents for 3rd-party private original flow. + */ +public final class FlowRuleExtPayLoad { + private final byte[] payLoad; + + /** + * private constructor. + * + * @param payLoad private flow + */ + private FlowRuleExtPayLoad(byte[] payLoad) { + this.payLoad = payLoad; + } + + /** + * Creates a FlowRuleExtPayLoad. + * + * @param payLoad payload byte data + * @return FlowRuleExtPayLoad payLoad + */ + public static FlowRuleExtPayLoad flowRuleExtPayLoad(byte[] payLoad) { + return new FlowRuleExtPayLoad(payLoad); + } + + /** + * Returns private flow. + * + * @return payLoad private flow + */ + public byte[] payLoad() { + return payLoad; + } + + @Override + public int hashCode() { + return Arrays.hashCode(payLoad); + } + + public int hash() { + return Arrays.hashCode(payLoad); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof FlowRuleExtPayLoad) { + FlowRuleExtPayLoad that = (FlowRuleExtPayLoad) obj; + return Arrays.equals(payLoad, that.payLoad); + + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("payLoad", payLoad).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleListener.java new file mode 100644 index 00000000..1a6ef7d9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving flow rule related events. + */ +public interface FlowRuleListener extends EventListener<FlowRuleEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperation.java new file mode 100644 index 00000000..82d43be8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperation.java @@ -0,0 +1,67 @@ +/* + * 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.flow; + +import com.google.common.base.MoreObjects; + +/** + * Representation of an operation on a flow rule table. + */ +public class FlowRuleOperation { + + /** + * Type of flow table operations. + */ + public enum Type { + ADD, + MODIFY, + REMOVE + } + + private final FlowRule rule; + private final Type type; + + public FlowRuleOperation(FlowRule rule, Type type) { + this.rule = rule; + this.type = type; + } + + /** + * Returns the type of operation. + * + * @return type + */ + public Type type() { + return type; + } + + /** + * Returns the flow rule. + * + * @return flow rule + */ + public FlowRule rule() { + return rule; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("rule", rule) + .add("type", type) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperations.java new file mode 100644 index 00000000..84e0b8be --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperations.java @@ -0,0 +1,181 @@ +/* + * 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.flow; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Set; + +import static org.onosproject.net.flow.FlowRuleOperation.Type.*; + +/** + * A batch of flow rule operations that are broken into stages. + * TODO move this up to parent's package + */ +public class FlowRuleOperations { + + private final List<Set<FlowRuleOperation>> stages; + private final FlowRuleOperationsContext callback; // TODO consider Optional + + private FlowRuleOperations(List<Set<FlowRuleOperation>> stages, + FlowRuleOperationsContext cb) { + this.stages = stages; + this.callback = cb; + } + + // kryo-constructor + protected FlowRuleOperations() { + this.stages = Lists.newArrayList(); + this.callback = null; + } + + /** + * Returns the flow rule operations as sets of stages that should be + * executed sequentially. + * + * @return flow rule stages + */ + public List<Set<FlowRuleOperation>> stages() { + return stages; + } + + /** + * Returns the callback for this batch of operations. + * + * @return callback + */ + public FlowRuleOperationsContext callback() { + return callback; + } + + /** + * Returns a new builder. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("stages", stages) + .toString(); + } + + /** + * A builder for constructing flow rule operations. + */ + public static final class Builder { + + private final ImmutableList.Builder<Set<FlowRuleOperation>> listBuilder = ImmutableList.builder(); + private ImmutableSet.Builder<FlowRuleOperation> currentStage = ImmutableSet.builder(); + + // prevent use of the default constructor outside of this file; use the above method + private Builder() {} + + /** + * Appends a flow rule add to the current stage. + * + * @param flowRule flow rule + * @return this + */ + public Builder add(FlowRule flowRule) { + currentStage.add(new FlowRuleOperation(flowRule, ADD)); + return this; + } + + /** + * Appends an existing flow rule to the current stage. + * + * @param flowRuleOperation flow rule operation + * @return this + */ + public Builder operation(FlowRuleOperation flowRuleOperation) { + currentStage.add(flowRuleOperation); + return this; + } + + /** + * Appends a flow rule modify to the current stage. + * + * @param flowRule flow rule + * @return this + */ + public Builder modify(FlowRule flowRule) { + currentStage.add(new FlowRuleOperation(flowRule, MODIFY)); + return this; + } + + /** + * Appends a flow rule remove to the current stage. + * + * @param flowRule flow rule + * @return this + */ + // FIXME this is confusing, consider renaming + public Builder remove(FlowRule flowRule) { + currentStage.add(new FlowRuleOperation(flowRule, REMOVE)); + return this; + } + + /** + * Closes the current stage. + */ + private void closeStage() { + ImmutableSet<FlowRuleOperation> stage = currentStage.build(); + if (!stage.isEmpty()) { + listBuilder.add(stage); + } + } + + /** + * Closes the current stage and starts a new one. + * + * @return this + */ + public Builder newStage() { + closeStage(); + currentStage = ImmutableSet.builder(); + return this; + } + + /** + * Builds the immutable flow rule operations. + * + * @return flow rule operations + */ + public FlowRuleOperations build() { + return build(null); + } + + /** + * Builds the immutable flow rule operations. + * + * @param cb the callback to call when this operation completes + * @return flow rule operations + */ + public FlowRuleOperations build(FlowRuleOperationsContext cb) { + closeStage(); + return new FlowRuleOperations(listBuilder.build(), cb); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperationsContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperationsContext.java new file mode 100644 index 00000000..c405b129 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleOperationsContext.java @@ -0,0 +1,28 @@ +/* + * 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.flow; + +/** + * The context of a flow rule operations that will become the subject of + * the notification. + * + * Implementations of this class must be serializable. + */ +public interface FlowRuleOperationsContext { + // TODO we might also want to execute a method on behalf of the app + default void onSuccess(FlowRuleOperations ops){} + default void onError(FlowRuleOperations ops){} +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProvider.java new file mode 100644 index 00000000..ac2895eb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProvider.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of a flow rule provider. + */ +public interface FlowRuleProvider extends Provider { + + /** + * Instructs the provider to apply the specified flow rules to their + * respective devices. + * @param flowRules one or more flow rules + * throws SomeKindOfException that indicates which ones were applied and + * which ones failed + */ + void applyFlowRule(FlowRule... flowRules); + + /** + * Instructs the provider to remove the specified flow rules to their + * respective devices. + * @param flowRules one or more flow rules + * throws SomeKindOfException that indicates which ones were applied and + * which ones failed + */ + void removeFlowRule(FlowRule... flowRules); + + /** + * Removes rules by their id. + * @param id the id to remove + * @param flowRules one or more flow rules + */ + void removeRulesById(ApplicationId id, FlowRule... flowRules); + + /** + * Installs a batch of flow rules. Each flowrule is associated to an + * operation which results in either addition, removal or modification. + * @param batch a batch of flow rules + */ + void executeBatch(FlowRuleBatchOperation batch); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderRegistry.java new file mode 100644 index 00000000..7e317c01 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction for a flow rule provider registry. + */ +public interface FlowRuleProviderRegistry + extends ProviderRegistry<FlowRuleProvider, FlowRuleProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java new file mode 100644 index 00000000..8a36a921 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +/** + * Service through which flow rule providers can inject information into + * the core. + */ +public interface FlowRuleProviderService extends ProviderService<FlowRuleProvider> { + + /** + * Signals that a flow rule that was previously installed has been removed. + * + * @param flowEntry removed flow entry + */ + void flowRemoved(FlowEntry flowEntry); + + /** + * Pushes the collection of flow entries currently applied on the given + * device. + * + * @param deviceId device identifier + * @param flowEntries collection of flow rules + */ + void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries); + + /** + * Indicates to the core that the requested batch operation has + * been completed. + * + * @param batchId the batch which was processed + * @param operation the resulting outcome of the operation + */ + void batchOperationCompleted(long batchId, CompletedBatchOperation operation); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java new file mode 100644 index 00000000..e2971158 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.core.ApplicationId; +import org.onosproject.event.ListenerService; +import org.onosproject.net.DeviceId; + +/** + * Service for injecting flow rules into the environment and for obtaining + * information about flow rules already in the environment. This implements + * semantics of a distributed authoritative flow table where the master copy + * of the flow rules lies with the controller and the devices hold only the + * 'cached' copy. + */ +public interface FlowRuleService + extends ListenerService<FlowRuleEvent, FlowRuleListener> { + + /** + * The topic used for obtaining globally unique ids. + */ + static String FLOW_OP_TOPIC = "flow-ops-ids"; + + /** + * Returns the number of flow rules in the system. + * + * @return flow rule count + */ + int getFlowRuleCount(); + + /** + * Returns the collection of flow entries applied on the specified device. + * This will include flow rules which may not yet have been applied to + * the device. + * + * @param deviceId device identifier + * @return collection of flow rules + */ + Iterable<FlowEntry> getFlowEntries(DeviceId deviceId); + + // TODO: add createFlowRule factory method and execute operations method + + /** + * Applies the specified flow rules onto their respective devices. These + * flow rules will be retained by the system and re-applied anytime the + * device reconnects to the controller. + * + * @param flowRules one or more flow rules + */ + void applyFlowRules(FlowRule... flowRules); + + /** + * Removes the specified flow rules from their respective devices. If the + * device is not presently connected to the controller, these flow will + * be removed once the device reconnects. + * + * @param flowRules one or more flow rules + * throws SomeKindOfException that indicates which ones were removed and + * which ones failed + */ + void removeFlowRules(FlowRule... flowRules); + + /** + * Removes all rules by id. + * + * @param appId id to remove + */ + void removeFlowRulesById(ApplicationId appId); + + /** + * Returns a list of rules with this application id. + * + * @param id the id to look up + * @return collection of flow rules + */ + Iterable<FlowRule> getFlowRulesById(ApplicationId id); + + /** + * Returns a list of rules filterd by application and group id. + * + * @param appId the application id to lookup + * @param groupId the groupid to lookup + * @return collection of flow rules + */ + Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId, short groupId); + + /** + * Applies a batch operation of FlowRules. + * + * @param ops batch operation to apply + */ + void apply(FlowRuleOperations ops); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStore.java new file mode 100644 index 00000000..cece9893 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStore.java @@ -0,0 +1,96 @@ +/* + * Copyright 2014-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.flow; + +import org.onosproject.net.DeviceId; +import org.onosproject.store.Store; + +/** + * Manages inventory of flow rules; not intended for direct use. + */ +public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDelegate> { + + /** + * Returns the number of flow rule in the store. + * + * @return number of flow rules + */ + int getFlowRuleCount(); + + /** + * Returns the stored flow. + * + * @param rule the rule to look for + * @return a flow rule + */ + FlowEntry getFlowEntry(FlowRule rule); + + /** + * Returns the flow entries associated with a device. + * + * @param deviceId the device ID + * @return the flow entries + */ + Iterable<FlowEntry> getFlowEntries(DeviceId deviceId); + + /** + * // TODO: Better description of method behavior. + * Stores a new flow rule without generating events. + * + * @param rule the flow rule to add + * @deprecated in Cardinal Release + */ + @Deprecated + void storeFlowRule(FlowRule rule); + + /** + * Stores a batch of flow rules. + * + * @param batchOperation batch of flow rules. + * A batch can contain flow rules for a single device only. + * + */ + void storeBatch(FlowRuleBatchOperation batchOperation); + + /** + * Invoked on the completion of a storeBatch operation. + * + * @param event flow rule batch event + */ + void batchOperationComplete(FlowRuleBatchEvent event); + + /** + * Marks a flow rule for deletion. Actual deletion will occur + * when the provider indicates that the flow has been removed. + * + * @param rule the flow rule to delete + */ + void deleteFlowRule(FlowRule rule); + + /** + * Stores a new flow rule, or updates an existing entry. + * + * @param rule the flow rule to add or update + * @return flow_added event, or null if just an update + */ + FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule); + + /** + * @param rule the flow entry to remove + * @return flow_removed event, or null if nothing removed + */ + FlowRuleEvent removeFlowRule(FlowEntry rule); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStoreDelegate.java new file mode 100644 index 00000000..c4ddb129 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/FlowRuleStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.store.StoreDelegate; + +/** + * Flow rule store delegate abstraction. + */ +public interface FlowRuleStoreDelegate extends StoreDelegate<FlowRuleBatchEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java new file mode 100644 index 00000000..dc0c3395 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java @@ -0,0 +1,50 @@ +/* + * Copyright 2014 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.flow; + + +public interface StoredFlowEntry extends FlowEntry { + + /** + * Sets the last active epoch time. + */ + void setLastSeen(); + + /** + * Sets the new state for this entry. + * @param newState new flow entry state. + */ + void setState(FlowEntryState newState); + + /** + * Sets how long this entry has been entered in the system. + * @param life epoch time + */ + void setLife(long life); + + /** + * Number of packets seen by this entry. + * @param packets a long value + */ + void setPackets(long packets); + + /** + * Number of bytes seen by this rule. + * @param bytes a long value + */ + void setBytes(long bytes); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java new file mode 100644 index 00000000..f2de9a0f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java @@ -0,0 +1,420 @@ +/* + * Copyright 2014-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.flow; + +import java.util.Set; + +import org.onlab.packet.Ip6Address; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.DefaultTrafficSelector.Builder; +import org.onosproject.net.flow.criteria.Criterion; + +/** + * Abstraction of a slice of network traffic. + */ +public interface TrafficSelector { + + /** + * Returns selection criteria as an ordered list. + * + * @return list of criteria + */ + Set<Criterion> criteria(); + + /** + * Returns the selection criterion for a particular type, if it exists in + * this traffic selector. + * + * @param type criterion type to look up + * @return the criterion of the specified type if one exists, otherwise null + */ + Criterion getCriterion(Criterion.Type type); + + /** + * Builder of traffic selector entities. + */ + interface Builder { + + /** + * Adds a traffic selection criterion. If a same type criterion has + * already been added, it will be replaced by this one. + * + * @param criterion new criterion + * @return self + */ + Builder add(Criterion criterion); + + /** + * Matches an inport. + * + * @param port the inport + * @return a selection builder + */ + Builder matchInPort(PortNumber port); + + /** + * Matches a physical inport. + * + * @param port the physical inport + * @return a selection builder + */ + Builder matchInPhyPort(PortNumber port); + + /** + * Matches a metadata. + * + * @param metadata the metadata + * @return a selection builder + */ + Builder matchMetadata(long metadata); + + /** + * Matches a l2 dst address. + * + * @param addr a l2 address + * @return a selection builder + */ + Builder matchEthDst(MacAddress addr); + + /** + * Matches a l2 src address. + * + * @param addr a l2 address + * @return a selection builder + */ + Builder matchEthSrc(MacAddress addr); + + /** + * Matches the ethernet type. + * + * @param ethType an ethernet type + * @return a selection builder + */ + Builder matchEthType(short ethType); + + /** + * Matches the vlan id. + * + * @param vlanId a vlan id + * @return a selection builder + */ + Builder matchVlanId(VlanId vlanId); + + /** + * Matches a vlan priority. + * + * @param vlanPcp a vlan priority + * @return a selection builder + */ + Builder matchVlanPcp(byte vlanPcp); + + /** + * Matches an IP DSCP (6 bits in ToS field). + * + * @param ipDscp an IP DSCP value + * @return a selection builder + */ + Builder matchIPDscp(byte ipDscp); + + /** + * Matches an IP ECN (2 bits in ToS field). + * + * @param ipEcn an IP ECN value + * @return a selection builder + */ + Builder matchIPEcn(byte ipEcn); + + /** + * Matches the l3 protocol. + * + * @param proto a l3 protocol + * @return a selection builder + */ + Builder matchIPProtocol(byte proto); + + /** + * Matches a l3 IPv4 address. + * + * @param ip a l3 address + * @return a selection builder + */ + Builder matchIPSrc(IpPrefix ip); + + /** + * Matches a l3 IPv4 address. + * + * @param ip a l3 address + * @return a selection builder + */ + Builder matchIPDst(IpPrefix ip); + + /** + * Matches a TCP source port number. + * + * @param tcpPort a TCP source port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchTcpSrc(short tcpPort); + + /** + * Matches a TCP source port number. + * + * @param tcpPort a TCP source port number + * @return a selection builder + */ + Builder matchTcpSrc(TpPort tcpPort); + + /** + * Matches a TCP destination port number. + * + * @param tcpPort a TCP destination port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchTcpDst(short tcpPort); + + /** + * Matches a TCP destination port number. + * + * @param tcpPort a TCP destination port number + * @return a selection builder + */ + Builder matchTcpDst(TpPort tcpPort); + + /** + * Matches an UDP source port number. + * + * @param udpPort an UDP source port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchUdpSrc(short udpPort); + + /** + * Matches an UDP source port number. + * + * @param udpPort an UDP source port number + * @return a selection builder + */ + Builder matchUdpSrc(TpPort udpPort); + + /** + * Matches an UDP destination port number. + * + * @param udpPort an UDP destination port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchUdpDst(short udpPort); + + /** + * Matches an UDP destination port number. + * + * @param udpPort an UDP destination port number + * @return a selection builder + */ + Builder matchUdpDst(TpPort udpPort); + + /** + * Matches a SCTP source port number. + * + * @param sctpPort a SCTP source port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchSctpSrc(short sctpPort); + + /** + * Matches a SCTP source port number. + * + * @param sctpPort a SCTP source port number + * @return a selection builder + */ + Builder matchSctpSrc(TpPort sctpPort); + + /** + * Matches a SCTP destination port number. + * + * @param sctpPort a SCTP destination port number + * @return a selection builder + * @deprecated in Drake release + */ + @Deprecated + Builder matchSctpDst(short sctpPort); + + /** + * Matches a SCTP destination port number. + * + * @param sctpPort a SCTP destination port number + * @return a selection builder + */ + Builder matchSctpDst(TpPort sctpPort); + + /** + * Matches an ICMP type. + * + * @param icmpType an ICMP type + * @return a selection builder + */ + Builder matchIcmpType(byte icmpType); + + /** + * Matches an ICMP code. + * + * @param icmpCode an ICMP code + * @return a selection builder + */ + Builder matchIcmpCode(byte icmpCode); + + /** + * Matches a l3 IPv6 address. + * + * @param ip a l3 IPv6 address + * @return a selection builder + */ + Builder matchIPv6Src(IpPrefix ip); + + /** + * Matches a l3 IPv6 address. + * + * @param ip a l3 IPv6 address + * @return a selection builder + */ + Builder matchIPv6Dst(IpPrefix ip); + + /** + * Matches an IPv6 flow label. + * + * @param flowLabel an IPv6 flow label + * @return a selection builder + */ + Builder matchIPv6FlowLabel(int flowLabel); + + /** + * Matches an ICMPv6 type. + * + * @param icmpv6Type an ICMPv6 type + * @return a selection builder + */ + Builder matchIcmpv6Type(byte icmpv6Type); + + /** + * Matches an ICMPv6 code. + * + * @param icmpv6Code an ICMPv6 code + * @return a selection builder + */ + Builder matchIcmpv6Code(byte icmpv6Code); + + /** + * Matches an IPv6 Neighbor Discovery target address. + * + * @param targetAddress an IPv6 Neighbor Discovery target address + * @return a selection builder + */ + Builder matchIPv6NDTargetAddress(Ip6Address targetAddress); + + /** + * Matches an IPv6 Neighbor Discovery source link-layer address. + * + * @param mac an IPv6 Neighbor Discovery source link-layer address + * @return a selection builder + */ + Builder matchIPv6NDSourceLinkLayerAddress(MacAddress mac); + + /** + * Matches an IPv6 Neighbor Discovery target link-layer address. + * + * @param mac an IPv6 Neighbor Discovery target link-layer address + * @return a selection builder + */ + Builder matchIPv6NDTargetLinkLayerAddress(MacAddress mac); + + /** + * Matches on a MPLS label. + * + * @param mplsLabel a MPLS label. + * @return a selection builder + */ + Builder matchMplsLabel(MplsLabel mplsLabel); + + /** + * Matches on a MPLS Bottom-of-Stack indicator bit. + * + * @param mplsBos boolean value indicating BOS=1 (true) or BOS=0 (false). + * @return a selection builder + */ + Builder matchMplsBos(boolean mplsBos); + + /** + * Matches a tunnel id. + * + * @param tunnelId a tunnel id + * @return a selection builder + */ + Builder matchTunnelId(long tunnelId); + + /** + * Matches on IPv6 Extension Header pseudo-field flags. + * + * @param exthdrFlags the IPv6 Extension Header pseudo-field flags + * @return a selection builder + */ + Builder matchIPv6ExthdrFlags(short exthdrFlags); + + /** + * Matches an optical signal ID or lambda. + * + * @param lambda lambda + * @return a selection builder + * @deprecated in Cardinal Release. + * Use {@link #add(Criterion)} with an instance created + * by {@link org.onosproject.net.flow.criteria.Criteria#matchLambda(org.onosproject.net.Lambda)}. + */ + @Deprecated + Builder matchLambda(short lambda); + + /** + * Matches an optical Signal Type. + * + * @param signalType signalType + * @return a selection builder + * @deprecated in Cardinal Release. + * Use {@link #add(Criterion)}} with an instance created + * by {@link org.onosproject.net.flow.criteria.Criteria#matchOchSignalType(org.onosproject.net.OchSignalType)}. + */ + @Deprecated + Builder matchOpticalSignalType(short signalType); + + /** + * Builds an immutable traffic selector. + * + * @return traffic selector + */ + TrafficSelector build(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java new file mode 100644 index 00000000..1ce669c2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java @@ -0,0 +1,431 @@ +/* + * Copyright 2014-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.flow; + +import org.onlab.packet.EthType; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.core.GroupId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.instructions.Instruction; +import org.onosproject.net.flow.instructions.Instructions; +import org.onosproject.net.meter.MeterId; + +import java.util.List; + +/** + * Abstraction of network traffic treatment. + */ +public interface TrafficTreatment { + + /** + * Returns the list of treatment instructions that will be applied + * further down the pipeline. + * @return list of treatment instructions + */ + List<Instruction> deferred(); + + /** + * Returns the list of treatment instructions that will be applied + * immediately. + * @return list of treatment instructions + */ + List<Instruction> immediate(); + + /** + * Returns the list of all instructions in the treatment, both immediate and + * deferred. + * + * @return list of treatment instructions + */ + List<Instruction> allInstructions(); + + /** + * Returns the next table in the pipeline. + * @return a table transition; may be null. + */ + Instructions.TableTypeTransition tableTransition(); + + /** + * Whether the deferred treatment instructions will be cleared + * by the device. + * @return a boolean + */ + boolean clearedDeferred(); + + /** + * Returns the metadata instruction if there is one. + * + * @return a metadata instruction that may be null + */ + Instructions.MetadataInstruction writeMetadata(); + + /** + * Returns the meter instruction if there is one. + * + * @return a meter instruction that may be null + */ + Instructions.MeterInstruction metered(); + + /** + * Builder of traffic treatment entities. + */ + interface Builder { + + /** + * Adds an instruction to the builder. + * + * @param instruction an instruction + * @return a treatment builder + */ + Builder add(Instruction instruction); + + /** + * Adds a drop instruction. + * + * @return a treatment builder + */ + Builder drop(); + + /** + * Adds a punt-to-controller instruction. + * + * @return a treatment builder + */ + Builder punt(); + + /** + * Set the output port. + * + * @param number the out port + * @return a treatment builder + */ + Builder setOutput(PortNumber number); + + /** + * Sets the src l2 address. + * + * @param addr a macaddress + * @return a treatment builder + */ + Builder setEthSrc(MacAddress addr); + + /** + * Sets the dst l2 address. + * + * @param addr a macaddress + * @return a treatment builder + */ + Builder setEthDst(MacAddress addr); + + /** + * Sets the vlan id. + * + * @param id a vlanid + * @return a treatment builder + */ + Builder setVlanId(VlanId id); + + /** + * Sets the vlan priority. + * + * @param pcp a vlan priority + * @return a treatment builder + */ + Builder setVlanPcp(Byte pcp); + + /** + * Sets the src l3 address. + * + * @param addr an ip + * @return a treatment builder + */ + Builder setIpSrc(IpAddress addr); + + /** + * Sets the dst l3 address. + * + * @param addr an ip + * @return a treatment builder + */ + Builder setIpDst(IpAddress addr); + + /** + * Decrement the TTL in IP header by one. + * + * @return a treatment builder + */ + Builder decNwTtl(); + + /** + * Copy the TTL to outer protocol layer. + * + * @return a treatment builder + */ + Builder copyTtlOut(); + + /** + * Copy the TTL to inner protocol layer. + * + * @return a treatment builder + */ + Builder copyTtlIn(); + + /** + * Push MPLS ether type. + * + * @return a treatment builder. + */ + Builder pushMpls(); + + /** + * Pops MPLS ether type. + * + * @return a treatment builder. + */ + Builder popMpls(); + + /** + * Pops MPLS ether type and set the new ethertype. + * + * @param etherType an ether type + * @return a treatment builder. + * @deprecated in Drake Release + */ + @Deprecated + Builder popMpls(int etherType); + + /** + * Pops MPLS ether type and set the new ethertype. + * + * @param etherType an ether type + * @return a treatment builder. + */ + Builder popMpls(EthType etherType); + + /** + * Sets the mpls label. + * + * @param mplsLabel MPLS label. + * @return a treatment builder. + */ + Builder setMpls(MplsLabel mplsLabel); + + /** + * Sets the mpls bottom-of-stack indicator bit. + * + * @param mplsBos boolean to set BOS=1 (true) or BOS=0 (false). + * @return a treatment builder. + */ + Builder setMplsBos(boolean mplsBos); + + /** + * Decrement MPLS TTL. + * + * @return a treatment builder + */ + Builder decMplsTtl(); + + /** + * Sets the optical channel ID or lambda. + * + * @param lambda optical channel ID + * @return a treatment builder + * @deprecated in Drake Release + */ + @Deprecated + Builder setLambda(short lambda); + + /** + * Sets the group ID. + * + * @param groupId group ID + * @return a treatment builder + */ + Builder group(GroupId groupId); + + /** + * Sets a meter to be used by this flow. + * + * @param meterId a meter id + * @return a treatment builder + */ + Builder meter(MeterId meterId); + + /** + * Sets the next table type to transition to. + * + * @param type the table type + * @return a treatement builder + * @deprecated in Cardinal Release + */ + @Deprecated + Builder transition(FlowRule.Type type); + + /** + * Sets the next table id to transition to. + * + * @param tableId the table table + * @return a treatement builder + */ + Builder transition(Integer tableId); + + + /** + * Pops outermost VLAN tag. + * + * @return a treatment builder. + */ + Builder popVlan(); + + /** + * Pushes a new VLAN tag. + * + * @return a treatment builder. + */ + Builder pushVlan(); + + /** + * Any instructions preceded by this method call will be deferred. + * @return a treatment builder + */ + Builder deferred(); + + /** + * Any instructions preceded by this method call will be immediate. + * @return a treatment builder + */ + Builder immediate(); + + + /** + * Instructs the device to clear the deferred instructions set. + * @return a treatment builder + */ + Builder wipeDeferred(); + + /** + * Writes metadata to associate with a packet. + * <pre> + * {@code + * new_metadata = (old_metadata & ̃mask) | (value & mask) + * } + * </pre> + * + * @param value the metadata to write + * @param mask the masked bits for the value + * @return a treatment builder + */ + Builder writeMetadata(long value, long mask); + + /** + * Sets the tunnel id. + * + * @param tunnelId a tunnel id. + * @return a treatment builder. + */ + Builder setTunnelId(long tunnelId); + + /** + * Sets the src TCP port. + * + * @param port a port number + * @return a treatment builder + * @deprecated in Drake release + */ + @Deprecated + Builder setTcpSrc(short port); + + /** + * Sets the src TCP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setTcpSrc(TpPort port); + + /** + * Sets the dst TCP port. + * + * @param port a port number + * @return a treatment builder + * @deprecated in Drake release + */ + @Deprecated + Builder setTcpDst(short port); + + /** + * Sets the dst TCP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setTcpDst(TpPort port); + + /** + * Sets the src UDP port. + * + * @param port a port number + * @return a treatment builder + * @deprecated in Drake release + */ + @Deprecated + Builder setUdpSrc(short port); + + /** + * Sets the src UDP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setUdpSrc(TpPort port); + + /** + * Sets the dst UDP port. + * + * @param port a port number + * @return a treatment builder + * @deprecated in Drake release + */ + @Deprecated + Builder setUdpDst(short port); + + /** + * Sets the dst UDP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setUdpDst(TpPort port); + + /** + * Builds an immutable traffic treatment descriptor. + * <p> + * If the treatment is empty when build() is called, it will add a default + * drop rule automatically. For a treatment that is actually empty, use + * {@link org.onosproject.net.flow.DefaultTrafficTreatment#emptyTreatment}. + * </p> + * + * @return traffic treatment + */ + TrafficTreatment build(); + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Treatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Treatment.java new file mode 100644 index 00000000..a77079ce --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/Treatment.java @@ -0,0 +1,36 @@ +/* + * Copyright 2014 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.flow; + +import org.onosproject.net.PortNumber; + +/** + * Abstraction of different kinds of treatment that can be applied to an + * outbound packet. + */ +public interface Treatment { + + // TODO: implement these later: modifications, group + // TODO: elsewhere provide factory methods for some default treatments + + /** + * Returns the port number where the packet should be emitted. + * + * @return output port number + */ + PortNumber output(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java new file mode 100644 index 00000000..0252cfbc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java @@ -0,0 +1,527 @@ +/* + * Copyright 2014-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.flow.criteria; + +import org.onlab.packet.EthType; +import org.onlab.packet.Ip6Address; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.net.IndexedLambda; +import org.onosproject.net.Lambda; +import org.onosproject.net.OchSignal; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.criteria.Criterion.Type; +import org.onosproject.net.OchSignalType; + +/** + * Factory class to create various traffic selection criteria. + */ +public final class Criteria { + + //TODO: incomplete type implementation. Need to implement complete list from Criterion + + // Ban construction + private Criteria() { + } + + /** + * Creates a match on IN_PORT field using the specified value. + * + * @param port inport value + * @return match criterion + */ + public static Criterion matchInPort(PortNumber port) { + return new PortCriterion(port, Type.IN_PORT); + } + + /** + * Creates a match on IN_PHY_PORT field using the specified value. + * + * @param port inport value + * @return match criterion + */ + public static Criterion matchInPhyPort(PortNumber port) { + return new PortCriterion(port, Type.IN_PHY_PORT); + } + + /** + * Creates a match on METADATA field using the specified value. + * + * @param metadata metadata value (64 bits data) + * @return match criterion + */ + public static Criterion matchMetadata(long metadata) { + return new MetadataCriterion(metadata); + } + + /** + * Creates a match on ETH_DST field using the specified value. This value + * may be a wildcard mask. + * + * @param mac MAC address value or wildcard mask + * @return match criterion + */ + public static Criterion matchEthDst(MacAddress mac) { + return new EthCriterion(mac, Type.ETH_DST); + } + + /** + * Creates a match on ETH_SRC field using the specified value. This value + * may be a wildcard mask. + * + * @param mac MAC address value or wildcard mask + * @return match criterion + */ + public static Criterion matchEthSrc(MacAddress mac) { + return new EthCriterion(mac, Type.ETH_SRC); + } + + /** + * Creates a match on ETH_TYPE field using the specified value. + * + * @param ethType eth type value (16 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchEthType(int ethType) { + return new EthTypeCriterion(ethType); + } + + /** + * Creates a match on ETH_TYPE field using the specified value. + * + * @param ethType eth type value + * @return match criterion + */ + public static Criterion matchEthType(EthType ethType) { + return new EthTypeCriterion(ethType); + } + + /** + * Creates a match on VLAN ID field using the specified value. + * + * @param vlanId vlan id value + * @return match criterion + */ + public static Criterion matchVlanId(VlanId vlanId) { + return new VlanIdCriterion(vlanId); + } + + /** + * Creates a match on VLAN PCP field using the specified value. + * + * @param vlanPcp vlan pcp value (3 bits) + * @return match criterion + */ + public static Criterion matchVlanPcp(byte vlanPcp) { + return new VlanPcpCriterion(vlanPcp); + } + + /** + * Creates a match on IP DSCP field using the specified value. + * + * @param ipDscp ip dscp value (6 bits) + * @return match criterion + */ + public static Criterion matchIPDscp(byte ipDscp) { + return new IPDscpCriterion(ipDscp); + } + + /** + * Creates a match on IP ECN field using the specified value. + * + * @param ipEcn ip ecn value (2 bits) + * @return match criterion + */ + public static Criterion matchIPEcn(byte ipEcn) { + return new IPEcnCriterion(ipEcn); + } + + /** + * Creates a match on IP proto field using the specified value. + * + * @param proto ip protocol value (8 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchIPProtocol(short proto) { + return new IPProtocolCriterion(proto); + } + + /** + * Creates a match on IPv4 source field using the specified value. + * + * @param ip ipv4 source value + * @return match criterion + */ + public static Criterion matchIPSrc(IpPrefix ip) { + return new IPCriterion(ip, Type.IPV4_SRC); + } + + /** + * Creates a match on IPv4 destination field using the specified value. + * + * @param ip ipv4 source value + * @return match criterion + */ + public static Criterion matchIPDst(IpPrefix ip) { + return new IPCriterion(ip, Type.IPV4_DST); + } + + /** + * Creates a match on TCP source port field using the specified value. + * + * @param tcpPort TCP source port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchTcpSrc(short tcpPort) { + return new TcpPortCriterion(TpPort.tpPort(tcpPort), Type.TCP_SRC); + } + + /** + * Creates a match on TCP source port field using the specified value. + * + * @param tcpPort TCP source port + * @return match criterion + */ + public static Criterion matchTcpSrc(TpPort tcpPort) { + return new TcpPortCriterion(tcpPort, Type.TCP_SRC); + } + + /** + * Creates a match on TCP destination port field using the specified value. + * + * @param tcpPort TCP destination port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchTcpDst(short tcpPort) { + return new TcpPortCriterion(TpPort.tpPort(tcpPort), Type.TCP_DST); + } + + /** + * Creates a match on TCP destination port field using the specified value. + * + * @param tcpPort TCP destination port + * @return match criterion + */ + public static Criterion matchTcpDst(TpPort tcpPort) { + return new TcpPortCriterion(tcpPort, Type.TCP_DST); + } + + /** + * Creates a match on UDP source port field using the specified value. + * + * @param udpPort UDP source port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchUdpSrc(short udpPort) { + return new UdpPortCriterion(TpPort.tpPort(udpPort), Type.UDP_SRC); + } + + /** + * Creates a match on UDP source port field using the specified value. + * + * @param udpPort UDP source port + * @return match criterion + */ + public static Criterion matchUdpSrc(TpPort udpPort) { + return new UdpPortCriterion(udpPort, Type.UDP_SRC); + } + + /** + * Creates a match on UDP destination port field using the specified value. + * + * @param udpPort UDP destination port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchUdpDst(short udpPort) { + return new UdpPortCriterion(TpPort.tpPort(udpPort), Type.UDP_DST); + } + + /** + * Creates a match on UDP destination port field using the specified value. + * + * @param udpPort UDP destination port + * @return match criterion + */ + public static Criterion matchUdpDst(TpPort udpPort) { + return new UdpPortCriterion(udpPort, Type.UDP_DST); + } + + /** + * Creates a match on SCTP source port field using the specified value. + * + * @param sctpPort SCTP source port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchSctpSrc(short sctpPort) { + return new SctpPortCriterion(TpPort.tpPort(sctpPort), Type.SCTP_SRC); + } + + /** + * Creates a match on SCTP source port field using the specified value. + * + * @param sctpPort SCTP source port + * @return match criterion + */ + public static Criterion matchSctpSrc(TpPort sctpPort) { + return new SctpPortCriterion(sctpPort, Type.SCTP_SRC); + } + + /** + * Creates a match on SCTP destination port field using the specified + * value. + * + * @param sctpPort SCTP destination port + * @return match criterion + * @deprecated in Drake release + */ + @Deprecated + public static Criterion matchSctpDst(short sctpPort) { + return new SctpPortCriterion(TpPort.tpPort(sctpPort), Type.SCTP_DST); + } + + /** + * Creates a match on SCTP destination port field using the specified + * value. + * + * @param sctpPort SCTP destination port + * @return match criterion + */ + public static Criterion matchSctpDst(TpPort sctpPort) { + return new SctpPortCriterion(sctpPort, Type.SCTP_DST); + } + + /** + * Creates a match on ICMP type field using the specified value. + * + * @param icmpType ICMP type (8 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchIcmpType(short icmpType) { + return new IcmpTypeCriterion(icmpType); + } + + /** + * Creates a match on ICMP code field using the specified value. + * + * @param icmpCode ICMP code (8 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchIcmpCode(short icmpCode) { + return new IcmpCodeCriterion(icmpCode); + } + + /** + * Creates a match on IPv6 source field using the specified value. + * + * @param ip ipv6 source value + * @return match criterion + */ + public static Criterion matchIPv6Src(IpPrefix ip) { + return new IPCriterion(ip, Type.IPV6_SRC); + } + + /** + * Creates a match on IPv6 destination field using the specified value. + * + * @param ip ipv6 destination value + * @return match criterion + */ + public static Criterion matchIPv6Dst(IpPrefix ip) { + return new IPCriterion(ip, Type.IPV6_DST); + } + + /** + * Creates a match on IPv6 flow label field using the specified value. + * + * @param flowLabel IPv6 flow label (20 bits) + * @return match criterion + */ + public static Criterion matchIPv6FlowLabel(int flowLabel) { + return new IPv6FlowLabelCriterion(flowLabel); + } + + /** + * Creates a match on ICMPv6 type field using the specified value. + * + * @param icmpv6Type ICMPv6 type (8 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchIcmpv6Type(short icmpv6Type) { + return new Icmpv6TypeCriterion(icmpv6Type); + } + + /** + * Creates a match on ICMPv6 code field using the specified value. + * + * @param icmpv6Code ICMPv6 code (8 bits unsigned integer) + * @return match criterion + */ + public static Criterion matchIcmpv6Code(short icmpv6Code) { + return new Icmpv6CodeCriterion(icmpv6Code); + } + + /** + * Creates a match on IPv6 Neighbor Discovery target address using the + * specified value. + * + * @param targetAddress IPv6 Neighbor Discovery target address + * @return match criterion + */ + public static Criterion matchIPv6NDTargetAddress(Ip6Address targetAddress) { + return new IPv6NDTargetAddressCriterion(targetAddress); + } + + /** + * Creates a match on IPv6 Neighbor Discovery source link-layer address + * using the specified value. + * + * @param mac IPv6 Neighbor Discovery source link-layer address + * @return match criterion + */ + public static Criterion matchIPv6NDSourceLinkLayerAddress(MacAddress mac) { + return new IPv6NDLinkLayerAddressCriterion(mac, Type.IPV6_ND_SLL); + } + + /** + * Creates a match on IPv6 Neighbor Discovery target link-layer address + * using the specified value. + * + * @param mac IPv6 Neighbor Discovery target link-layer address + * @return match criterion + */ + public static Criterion matchIPv6NDTargetLinkLayerAddress(MacAddress mac) { + return new IPv6NDLinkLayerAddressCriterion(mac, Type.IPV6_ND_TLL); + } + + /** + * Creates a match on MPLS label. + * + * @param mplsLabel MPLS label (20 bits) + * @return match criterion + */ + public static Criterion matchMplsLabel(MplsLabel mplsLabel) { + return new MplsCriterion(mplsLabel); + } + + /** + * Creates a match on MPLS Bottom-of-Stack indicator bit. + * + * @param mplsBos boolean value indicating true (BOS=1) or false (BOS=0) + * @return match criterion + */ + public static Criterion matchMplsLabel(boolean mplsBos) { + return new MplsBosCriterion(mplsBos); + } + + /** + * Creates a match on Tunnel ID. + * + * @param tunnelId Tunnel ID (64 bits) + * @return match criterion + */ + public static Criterion matchTunnelId(long tunnelId) { + return new TunnelIdCriterion(tunnelId); + } + + /** + * Creates a match on IPv6 Extension Header pseudo-field fiags. + * Those are defined in Criterion.IPv6ExthdrFlags. + * + * @param exthdrFlags IPv6 Extension Header pseudo-field flags (16 bits) + * @return match criterion + */ + public static Criterion matchIPv6ExthdrFlags(int exthdrFlags) { + return new IPv6ExthdrFlagsCriterion(exthdrFlags); + } + + /** + * Creates a match on lambda field using the specified value. + * + * @param lambda lambda to match on (16 bits unsigned integer) + * @return match criterion + * @deprecated in Cardinal Release. Use {@link #matchLambda(Lambda)} instead. + */ + @Deprecated + public static Criterion matchLambda(int lambda) { + return new LambdaCriterion(lambda, Type.OCH_SIGID); + } + + /** + * Creates a match on lambda using the specified value. + * + * @param lambda lambda + * @return match criterion + */ + public static Criterion matchLambda(Lambda lambda) { + if (lambda instanceof IndexedLambda) { + return new IndexedLambdaCriterion((IndexedLambda) lambda); + } else if (lambda instanceof OchSignal) { + return new OchSignalCriterion((OchSignal) lambda); + } else { + throw new UnsupportedOperationException(String.format("Unsupported type of Lambda: %s", lambda)); + } + } + + /** + * Creates a match on optical signal type using the specified value. + * + * @param sigType optical signal type (8 bits unsigned integer) + * @return match criterion + * @deprecated in Cardinal Release + */ + @Deprecated + public static Criterion matchOpticalSignalType(short sigType) { + return new OpticalSignalTypeCriterion(sigType, Type.OCH_SIGTYPE); + } + + /** + * Create a match on OCh (Optical Channel) signal type. + * + * @param signalType OCh signal type + * @return match criterion + */ + public static Criterion matchOchSignalType(OchSignalType signalType) { + return new OchSignalTypeCriterion(signalType); + } + + public static Criterion dummy() { + return new DummyCriterion(); + } + + /** + * Dummy Criterion used with @see{FilteringObjective}. + */ + private static class DummyCriterion implements Criterion { + + @Override + public Type type() { + return Type.DUMMY; + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java new file mode 100644 index 00000000..12ab57de --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java @@ -0,0 +1,181 @@ +/* + * Copyright 2014-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.flow.criteria; + + +/** + * Representation of a single header field selection. + */ +public interface Criterion { + + /** + * Types of fields to which the selection criterion may apply. + */ + // From page 75 of OpenFlow 1.5.0 spec + enum Type { + /** Switch input port. */ + IN_PORT, + /** Switch physical input port. */ + IN_PHY_PORT, + /** Metadata passed between tables. */ + METADATA, + /** Ethernet destination address. */ + ETH_DST, + /** Ethernet source address. */ + ETH_SRC, + /** Ethernet frame type. */ + ETH_TYPE, + /** VLAN id. */ + VLAN_VID, + /** VLAN priority. */ + VLAN_PCP, + /** IP DSCP (6 bits in ToS field). */ + IP_DSCP, + /** IP ECN (2 bits in ToS field). */ + IP_ECN, + /** IP protocol. */ + IP_PROTO, + /** IPv4 source address. */ + IPV4_SRC, + /** IPv4 destination address. */ + IPV4_DST, + /** TCP source port. */ + TCP_SRC, + /** TCP destination port. */ + TCP_DST, + /** UDP source port. */ + UDP_SRC, + /** UDP destination port. */ + UDP_DST, + /** SCTP source port. */ + SCTP_SRC, + /** SCTP destination port. */ + SCTP_DST, + /** ICMP type. */ + ICMPV4_TYPE, + /** ICMP code. */ + ICMPV4_CODE, + /** ARP opcode. */ + ARP_OP, + /** ARP source IPv4 address. */ + ARP_SPA, + /** ARP target IPv4 address. */ + ARP_TPA, + /** ARP source hardware address. */ + ARP_SHA, + /** ARP target hardware address. */ + ARP_THA, + /** IPv6 source address. */ + IPV6_SRC, + /** IPv6 destination address. */ + IPV6_DST, + /** IPv6 Flow Label. */ + IPV6_FLABEL, + /** ICMPv6 type. */ + ICMPV6_TYPE, + /** ICMPv6 code. */ + ICMPV6_CODE, + /** Target address for ND. */ + IPV6_ND_TARGET, + /** Source link-layer for ND. */ + IPV6_ND_SLL, + /** Target link-layer for ND. */ + IPV6_ND_TLL, + /** MPLS label. */ + MPLS_LABEL, + /** MPLS TC. */ + MPLS_TC, + /** MPLS BoS bit. */ + MPLS_BOS, + /** PBB I-SID. */ + PBB_ISID, + /** Logical Port Metadata. */ + TUNNEL_ID, + /** IPv6 Extension Header pseudo-field. */ + IPV6_EXTHDR, + /** Unassigned value: 40. */ + UNASSIGNED_40, + /** PBB UCA header field. */ + PBB_UCA, + /** TCP flags. */ + TCP_FLAGS, + /** Output port from action set metadata. */ + ACTSET_OUTPUT, + /** Packet type value. */ + PACKET_TYPE, + + // + // NOTE: Everything below is defined elsewhere: ONOS-specific, + // extensions, etc. + // + /** Optical channel signal ID (lambda). */ + OCH_SIGID, + /** Optical channel signal type (fixed or flexible). */ + OCH_SIGTYPE, + + /** + * An empty criterion. + */ + DUMMY + } + + /** + * Returns the type of criterion. + * + * @return type of criterion + */ + Type type(); + + /** + * Bit definitions for IPv6 Extension Header pseudo-field. + * From page 79 of OpenFlow 1.5.0 spec. + */ + enum IPv6ExthdrFlags { + /** "No next header" encountered. */ + NONEXT((short) (1 << 0)), + /** Encrypted Sec Payload header present. */ + ESP((short) (1 << 1)), + /** Authentication header present. */ + AUTH((short) (1 << 2)), + /** 1 or 2 dest headers present. */ + DEST((short) (1 << 3)), + /** Fragment header present. */ + FRAG((short) (1 << 4)), + /** Router header present. */ + ROUTER((short) (1 << 5)), + /** Hop-by-hop header present. */ + HOP((short) (1 << 6)), + /** Unexpected repeats encountered. */ + UNREP((short) (1 << 7)), + /** Unexpected sequencing encountered. */ + UNSEQ((short) (1 << 8)); + + private short value; + + IPv6ExthdrFlags(short value) { + this.value = value; + } + + /** + * Gets the value as an integer. + * + * @return the value as an integer + */ + public short getValue() { + return this.value; + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java new file mode 100644 index 00000000..6020974d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.MacAddress; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of MAC address criterion. + */ +public final class EthCriterion implements Criterion { + private final MacAddress mac; + private final Type type; + + /** + * Constructor. + * + * @param mac the source or destination MAC address to match + * @param type the match type. Should be either Type.ETH_DST or + * Type.ETH_SRC + */ + EthCriterion(MacAddress mac, Type type) { + this.mac = mac; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the MAC address to match. + * + * @return the MAC address to match + */ + public MacAddress mac() { + return this.mac; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("mac", mac).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type.ordinal(), mac); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof EthCriterion) { + EthCriterion that = (EthCriterion) obj; + return Objects.equals(mac, that.mac) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java new file mode 100644 index 00000000..b2666d4d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java @@ -0,0 +1,89 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.EthType; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of Ethernet type criterion (16 bits unsigned integer). + */ +public final class EthTypeCriterion implements Criterion { + + + private final EthType ethType; + + /** + * Constructor. + * + * @param ethType the Ethernet frame type to match (16 bits unsigned + * integer) + */ + EthTypeCriterion(int ethType) { + this.ethType = new EthType(ethType); + } + + /** + * Constructor. + * + * @param ethType the Ethernet frame type to match + */ + EthTypeCriterion(EthType ethType) { + this.ethType = ethType; + } + + @Override + public Type type() { + return Type.ETH_TYPE; + } + + /** + * Gets the Ethernet frame type to match. + * + * @return the Ethernet frame type to match (16 bits unsigned integer) + */ + public EthType ethType() { + return ethType; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("ethType", ethType.toString()) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), ethType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof EthTypeCriterion) { + EthTypeCriterion that = (EthTypeCriterion) obj; + return Objects.equals(ethType, that.ethType) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java new file mode 100644 index 00000000..018afe80 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.IpPrefix; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IP address criterion. + */ +public final class IPCriterion implements Criterion { + private final IpPrefix ip; + private final Type type; + + /** + * Constructor. + * + * @param ip the IP prefix to match. Could be either IPv4 or IPv6 + * @param type the match type. Should be one of the following: + * Type.IPV4_SRC, Type.IPV4_DST, Type.IPV6_SRC, Type.IPV6_DST + */ + IPCriterion(IpPrefix ip, Type type) { + this.ip = ip; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the IP prefix to match. + * + * @return the IP prefix to match + */ + public IpPrefix ip() { + return this.ip; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("ip", ip).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), ip); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPCriterion) { + IPCriterion that = (IPCriterion) obj; + return Objects.equals(ip, that.ip) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java new file mode 100644 index 00000000..8634aa66 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java @@ -0,0 +1,76 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IP DSCP (Differentiated Services Code Point) + * criterion (6 bits). + */ +public final class IPDscpCriterion implements Criterion { + private static final byte MASK = 0x3f; + private final byte ipDscp; // IP DSCP value: 6 bits + + /** + * Constructor. + * + * @param ipDscp the IP DSCP value to match + */ + IPDscpCriterion(byte ipDscp) { + this.ipDscp = (byte) (ipDscp & MASK); + } + + @Override + public Type type() { + return Type.IP_DSCP; + } + + /** + * Gets the IP DSCP value to match. + * + * @return the IP DSCP value to match + */ + public byte ipDscp() { + return ipDscp; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("ipDscp", Long.toHexString(ipDscp)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), ipDscp); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPDscpCriterion) { + IPDscpCriterion that = (IPDscpCriterion) obj; + return Objects.equals(ipDscp, that.ipDscp) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java new file mode 100644 index 00000000..48b3fbf6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java @@ -0,0 +1,76 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IP ECN (Explicit Congestion Notification) criterion + * (2 bits). + */ +public final class IPEcnCriterion implements Criterion { + private static final byte MASK = 0x3; + private final byte ipEcn; // IP ECN value: 2 bits + + /** + * Constructor. + * + * @param ipEcn the IP ECN value to match (2 bits) + */ + IPEcnCriterion(byte ipEcn) { + this.ipEcn = (byte) (ipEcn & MASK); + } + + @Override + public Type type() { + return Type.IP_ECN; + } + + /** + * Gets the IP ECN value to match. + * + * @return the IP ECN value to match (2 bits) + */ + public byte ipEcn() { + return ipEcn; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("ipEcn", Long.toHexString(ipEcn)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), ipEcn); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPEcnCriterion) { + IPEcnCriterion that = (IPEcnCriterion) obj; + return Objects.equals(ipEcn, that.ipEcn) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java new file mode 100644 index 00000000..6879f802 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java @@ -0,0 +1,76 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of Internet Protocol Number criterion (8 bits unsigned) + * integer. + */ +public final class IPProtocolCriterion implements Criterion { + private static final short MASK = 0xff; + private final short proto; // IP protocol number: 8 bits + + /** + * Constructor. + * + * @param protocol the IP protocol (e.g., TCP=6, UDP=17) to match + * (8 bits unsigned integer) + */ + IPProtocolCriterion(short protocol) { + this.proto = (short) (protocol & MASK); + } + + @Override + public Type type() { + return Type.IP_PROTO; + } + + /** + * Gets the IP protocol to match. + * + * @return the IP protocol to match (8 bits unsigned integer) + */ + public short protocol() { + return proto; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("protocol", proto).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), proto); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPProtocolCriterion) { + IPProtocolCriterion that = (IPProtocolCriterion) obj; + return Objects.equals(proto, that.proto); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java new file mode 100644 index 00000000..2463bf64 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java @@ -0,0 +1,78 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IPv6 Extension Header pseudo-field criterion + * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags. + */ +public final class IPv6ExthdrFlagsCriterion implements Criterion { + private static final int MASK = 0xffff; + private final int exthdrFlags; // IPv6 Exthdr flags: 16 bits + + /** + * Constructor. + * + * @param exthdrFlags the IPv6 Extension Header pseudo-field flags + * to match (16 bits). Those are defined in Criterion.IPv6ExthdrFlags + */ + IPv6ExthdrFlagsCriterion(int exthdrFlags) { + this.exthdrFlags = exthdrFlags & MASK; + } + + @Override + public Type type() { + return Type.IPV6_EXTHDR; + } + + /** + * Gets the IPv6 Extension Header pseudo-field flags to match. + * + * @return the IPv6 Extension Header pseudo-field flags to match + * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags + */ + public int exthdrFlags() { + return exthdrFlags; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("exthdrFlags", Long.toHexString(exthdrFlags)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), exthdrFlags); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPv6ExthdrFlagsCriterion) { + IPv6ExthdrFlagsCriterion that = (IPv6ExthdrFlagsCriterion) obj; + return Objects.equals(exthdrFlags, that.exthdrFlags) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java new file mode 100644 index 00000000..6e1021d9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java @@ -0,0 +1,76 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IPv6 Flow Label (RFC 6437) criterion (20 bits unsigned + * integer). + */ +public final class IPv6FlowLabelCriterion implements Criterion { + private static final int MASK = 0xfffff; + private final int flowLabel; // IPv6 flow label: 20 bits + + /** + * Constructor. + * + * @param flowLabel the IPv6 flow label to match (20 bits) + */ + IPv6FlowLabelCriterion(int flowLabel) { + this.flowLabel = flowLabel & MASK; + } + + @Override + public Type type() { + return Type.IPV6_FLABEL; + } + + /** + * Gets the IPv6 flow label to match. + * + * @return the IPv6 flow label to match (20 bits) + */ + public int flowLabel() { + return flowLabel; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("flowLabel", Long.toHexString(flowLabel)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), flowLabel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPv6FlowLabelCriterion) { + IPv6FlowLabelCriterion that = (IPv6FlowLabelCriterion) obj; + return Objects.equals(flowLabel, that.flowLabel) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java new file mode 100644 index 00000000..9f310d4a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java @@ -0,0 +1,81 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.MacAddress; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IPv6 Neighbor Discovery link-layer address criterion. + */ +public final class IPv6NDLinkLayerAddressCriterion implements Criterion { + private final MacAddress mac; + private final Type type; + + /** + * Constructor. + * + * @param mac the source or destination link-layer address to match + * @param type the match type. Should be either Type.IPV6_ND_SLL or + * Type.IPV6_ND_TLL + */ + IPv6NDLinkLayerAddressCriterion(MacAddress mac, Type type) { + this.mac = mac; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the MAC link-layer address to match. + * + * @return the MAC link-layer address to match + */ + public MacAddress mac() { + return this.mac; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("mac", mac).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), mac); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPv6NDLinkLayerAddressCriterion) { + IPv6NDLinkLayerAddressCriterion that = + (IPv6NDLinkLayerAddressCriterion) obj; + return Objects.equals(mac, that.mac) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java new file mode 100644 index 00000000..ffef044a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java @@ -0,0 +1,77 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.Ip6Address; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of IPv6 Neighbor Discovery target address criterion. + */ +public final class IPv6NDTargetAddressCriterion implements Criterion { + private final Ip6Address targetAddress; + + /** + * Constructor. + * + * @param targetAddress the IPv6 target address to match + */ + IPv6NDTargetAddressCriterion(Ip6Address targetAddress) { + this.targetAddress = targetAddress; + } + + @Override + public Type type() { + return Type.IPV6_ND_TARGET; + } + + /** + * Gets the IPv6 target address to match. + * + * @return the IPv6 target address to match + */ + public Ip6Address targetAddress() { + return this.targetAddress; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("targetAddress", targetAddress).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), targetAddress); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IPv6NDTargetAddressCriterion) { + IPv6NDTargetAddressCriterion that = + (IPv6NDTargetAddressCriterion) obj; + return Objects.equals(targetAddress, that.targetAddress) && + Objects.equals(type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java new file mode 100644 index 00000000..516f61b3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of ICMP code criterion (8 bits unsigned integer). + */ +public final class IcmpCodeCriterion implements Criterion { + private static final short MASK = 0xff; + private final short icmpCode; // The ICMP code: 8 bits + + /** + * Constructor. + * + * @param icmpCode the ICMP code to match (8 bits unsigned integer) + */ + IcmpCodeCriterion(short icmpCode) { + this.icmpCode = (short) (icmpCode & MASK); + } + + @Override + public Type type() { + return Type.ICMPV4_CODE; + } + + /** + * Gets the ICMP code to match. + * + * @return the ICMP code to match (8 bits unsigned integer) + */ + public short icmpCode() { + return icmpCode; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("icmpCode", icmpCode).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), icmpCode); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IcmpCodeCriterion) { + IcmpCodeCriterion that = (IcmpCodeCriterion) obj; + return Objects.equals(icmpCode, that.icmpCode) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java new file mode 100644 index 00000000..63251425 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of ICMP type criterion (8 bits unsigned integer). + */ +public final class IcmpTypeCriterion implements Criterion { + private static final short MASK = 0xff; + private final short icmpType; // The ICMP type: 8 bits + + /** + * Constructor. + * + * @param icmpType the ICMP type to match (8 bits unsigned integer) + */ + IcmpTypeCriterion(short icmpType) { + this.icmpType = (short) (icmpType & MASK); + } + + @Override + public Type type() { + return Type.ICMPV4_TYPE; + } + + /** + * Gets the ICMP type to match. + * + * @return the ICMP type to match (8 bits unsigned integer) + */ + public short icmpType() { + return icmpType; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("icmpType", icmpType).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), icmpType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof IcmpTypeCriterion) { + IcmpTypeCriterion that = (IcmpTypeCriterion) obj; + return Objects.equals(icmpType, that.icmpType) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java new file mode 100644 index 00000000..a41b6fef --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of ICMPv6 code criterion (8 bits unsigned integer). + */ +public final class Icmpv6CodeCriterion implements Criterion { + private static final short MASK = 0xff; + private final short icmpv6Code; // ICMPv6 code: 8 bits + + /** + * Constructor. + * + * @param icmpv6Code the ICMPv6 code to match (8 bits unsigned integer) + */ + Icmpv6CodeCriterion(short icmpv6Code) { + this.icmpv6Code = (short) (icmpv6Code & MASK); + } + + @Override + public Type type() { + return Type.ICMPV6_CODE; + } + + /** + * Gets the ICMPv6 code to match. + * + * @return the ICMPv6 code to match (8 bits unsigned integer) + */ + public short icmpv6Code() { + return icmpv6Code; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("icmpv6Code", icmpv6Code).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), icmpv6Code); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Icmpv6CodeCriterion) { + Icmpv6CodeCriterion that = (Icmpv6CodeCriterion) obj; + return Objects.equals(icmpv6Code, that.icmpv6Code) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java new file mode 100644 index 00000000..7410ba17 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of ICMPv6 type criterion (8 bits unsigned integer). + */ +public final class Icmpv6TypeCriterion implements Criterion { + private static final short MASK = 0xff; + private final short icmpv6Type; // ICMPv6 type: 8 bits + + /** + * Constructor. + * + * @param icmpv6Type the ICMPv6 type to match (8 bits unsigned integer) + */ + Icmpv6TypeCriterion(short icmpv6Type) { + this.icmpv6Type = (short) (icmpv6Type & MASK); + } + + @Override + public Type type() { + return Type.ICMPV6_TYPE; + } + + /** + * Gets the ICMPv6 type to match. + * + * @return the ICMPv6 type to match (8 bits unsigned integer) + */ + public short icmpv6Type() { + return icmpv6Type; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("icmpv6Type", icmpv6Type).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), icmpv6Type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Icmpv6TypeCriterion) { + Icmpv6TypeCriterion that = (Icmpv6TypeCriterion) obj; + return Objects.equals(icmpv6Type, that.icmpv6Type) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IndexedLambdaCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IndexedLambdaCriterion.java new file mode 100644 index 00000000..88a6fe10 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/IndexedLambdaCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.IndexedLambda; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of indexed lambda criterion. + */ +public class IndexedLambdaCriterion implements Criterion { + + private final IndexedLambda lambda; + + /** + * Creates a criterion with the specified value. + * + * @param lambda lambda index number + */ + IndexedLambdaCriterion(IndexedLambda lambda) { + this.lambda = checkNotNull(lambda); + } + + @Override + public Type type() { + // TODO: consider defining a new specific type + // Now OCH_SIGID is used due to compatibility concerns + return Type.OCH_SIGID; + } + + /** + * Returns the indexed lambda to match. + * + * @return the indexed lambda to match + */ + public IndexedLambda lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof IndexedLambdaCriterion)) { + return false; + } + final IndexedLambdaCriterion that = (IndexedLambdaCriterion) obj; + return Objects.equals(this.lambda, that.lambda); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("lambda", lambda) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java new file mode 100644 index 00000000..656800b1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of lambda (wavelength) criterion (16 bits unsigned + * integer). + */ +public final class LambdaCriterion implements Criterion { + private static final int MASK = 0xffff; + private final int lambda; // Lambda value: 16 bits + private final Type type; + + /** + * Constructor. + * + * @param lambda the lambda (wavelength) to match (16 bits unsigned + * integer) + * @param type the match type. Should be Type.OCH_SIGID + */ + LambdaCriterion(int lambda, Type type) { + this.lambda = lambda & MASK; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the lambda (wavelength) to match. + * + * @return the lambda (wavelength) to match (16 bits unsigned integer) + */ + public int lambda() { + return lambda; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("lambda", lambda).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof LambdaCriterion) { + LambdaCriterion that = (LambdaCriterion) obj; + return Objects.equals(lambda, that.lambda) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java new file mode 100644 index 00000000..8177b483 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of Metadata criterion. + */ +public final class MetadataCriterion implements Criterion { + private final long metadata; + + /** + * Constructor. + * + * @param metadata the metadata to match (64 bits data) + */ + MetadataCriterion(long metadata) { + this.metadata = metadata; + } + + @Override + public Type type() { + return Type.METADATA; + } + + /** + * Gets the metadata to match. + * + * @return the metadata to match (64 bits data) + */ + public long metadata() { + return metadata; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("metadata", Long.toHexString(metadata)) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), metadata); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MetadataCriterion) { + MetadataCriterion that = (MetadataCriterion) obj; + return Objects.equals(metadata, that.metadata) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsBosCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsBosCriterion.java new file mode 100644 index 00000000..1ace8931 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsBosCriterion.java @@ -0,0 +1,48 @@ +package org.onosproject.net.flow.criteria; + +import static com.google.common.base.MoreObjects.toStringHelper; +import java.util.Objects; + +/** + * Implementation of MPLS BOS criterion (1 bit). + */ +public class MplsBosCriterion implements Criterion { + private boolean mplsBos; + + MplsBosCriterion(boolean mplsBos) { + this.mplsBos = mplsBos; + } + + @Override + public Type type() { + return Type.MPLS_BOS; + } + + public boolean mplsBos() { + return mplsBos; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("bos", mplsBos).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), mplsBos); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MplsBosCriterion) { + MplsBosCriterion that = (MplsBosCriterion) obj; + return Objects.equals(mplsBos, that.mplsBos()) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java new file mode 100644 index 00000000..34d384f1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java @@ -0,0 +1,67 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.MplsLabel; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of MPLS tag criterion (20 bits). + */ +public final class MplsCriterion implements Criterion { + private static final int MASK = 0xfffff; + private final MplsLabel mplsLabel; + + MplsCriterion(MplsLabel mplsLabel) { + this.mplsLabel = mplsLabel; + } + + @Override + public Type type() { + return Type.MPLS_LABEL; + } + + public MplsLabel label() { + return mplsLabel; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("mpls", mplsLabel).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), mplsLabel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MplsCriterion) { + MplsCriterion that = (MplsCriterion) obj; + return Objects.equals(mplsLabel, that.mplsLabel) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalCriterion.java new file mode 100644 index 00000000..3a51a6bd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalCriterion.java @@ -0,0 +1,81 @@ +/* + * 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.flow.criteria; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.OchSignal; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of OCh (Optical Channel) signal criterion. + * This criterion is based on the specification of "OFPXMT_EXP_OCH_SIGID" in + * Open Networking Foundation "Optical Transport Protocol Extension Version 1.0", but + * defined in protocol agnostic way. + */ +public final class OchSignalCriterion implements Criterion { + + private final OchSignal lambda; + + /** + * Create an instance with the specified OCh signal. + * + * @param lambda OCh signal + */ + OchSignalCriterion(OchSignal lambda) { + this.lambda = checkNotNull(lambda); + } + + @Override + public Type type() { + return Type.OCH_SIGID; + } + + /** + * Returns the OCh signal to match. + * + * @return the OCh signal to match + */ + public OchSignal lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof OchSignalCriterion)) { + return false; + } + final OchSignalCriterion that = (OchSignalCriterion) obj; + return Objects.equals(this.lambda, that.lambda); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("lambda", lambda) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalTypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalTypeCriterion.java new file mode 100644 index 00000000..cf838bf3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OchSignalTypeCriterion.java @@ -0,0 +1,78 @@ +/* + * 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.flow.criteria; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.OchSignalType; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Implementation of OCh (Optical Channel) signal type criterion. + */ +public class OchSignalTypeCriterion implements Criterion { + + private final OchSignalType signalType; + + /** + * Creates a criterion with the specified value. + * + * @param signalType OCh signal type + */ + OchSignalTypeCriterion(OchSignalType signalType) { + this.signalType = checkNotNull(signalType); + } + + @Override + public Type type() { + return Type.OCH_SIGTYPE; + } + + /** + * Returns the OCh signal type to match. + * + * @return the OCh signal type to match + */ + public OchSignalType signalType() { + return signalType; + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), signalType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof OchSignalTypeCriterion)) { + return false; + } + final OchSignalTypeCriterion that = (OchSignalTypeCriterion) obj; + return Objects.equals(this.signalType, that.signalType); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("signalType", signalType) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java new file mode 100644 index 00000000..b712675b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java @@ -0,0 +1,83 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of optical signal type criterion (8 bits unsigned + * integer). + * + * @deprecated in Cardinal Release + */ +@Deprecated +public final class OpticalSignalTypeCriterion implements Criterion { + private static final short MASK = 0xff; + private final short signalType; // Signal type value: 8 bits + private final Type type; + + /** + * Constructor. + * + * @param signalType the optical signal type to match (8 bits unsigned + * integer) + * @param type the match type. Should be Type.OCH_SIGTYPE + */ + OpticalSignalTypeCriterion(short signalType, Type type) { + this.signalType = (short) (signalType & MASK); + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the optical signal type to match. + * + * @return the optical signal type to match (8 bits unsigned integer) + */ + public short signalType() { + return signalType; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("signalType", signalType).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), signalType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OpticalSignalTypeCriterion) { + OpticalSignalTypeCriterion that = (OpticalSignalTypeCriterion) obj; + return Objects.equals(signalType, that.signalType) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java new file mode 100644 index 00000000..f07cd500 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onosproject.net.PortNumber; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of input port criterion. + */ +public final class PortCriterion implements Criterion { + private final PortNumber port; + private final Type type; + + /** + * Constructor. + * + * @param port the input port number to match + * @param type the match type. Should be either Type.IN_PORT or + * Type.IN_PHY_PORT + */ + PortCriterion(PortNumber port, Type type) { + this.port = port; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the input port number to match. + * + * @return the input port number to match + */ + public PortNumber port() { + return this.port; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("port", port).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), port); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PortCriterion) { + PortCriterion that = (PortCriterion) obj; + return Objects.equals(port, that.port) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java new file mode 100644 index 00000000..2d4cf15a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.TpPort; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of SCTP port criterion (16 bits unsigned integer). + */ +public final class SctpPortCriterion implements Criterion { + private final TpPort sctpPort; + private final Type type; + + /** + * Constructor. + * + * @param sctpPort the SCTP port to match + * @param type the match type. Should be either Type.SCTP_SRC or + * Type.SCTP_DST + */ + SctpPortCriterion(TpPort sctpPort, Type type) { + this.sctpPort = sctpPort; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the SCTP port to match. + * + * @return the SCTP port to match + */ + public TpPort sctpPort() { + return this.sctpPort; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("sctpPort", sctpPort).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), sctpPort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof SctpPortCriterion) { + SctpPortCriterion that = (SctpPortCriterion) obj; + return Objects.equals(sctpPort, that.sctpPort) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java new file mode 100644 index 00000000..e682b238 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.TpPort; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of TCP port criterion (16 bits unsigned integer). + */ +public final class TcpPortCriterion implements Criterion { + private final TpPort tcpPort; + private final Type type; + + /** + * Constructor. + * + * @param tcpPort the TCP port to match + * @param type the match type. Should be either Type.TCP_SRC or + * Type.TCP_DST + */ + TcpPortCriterion(TpPort tcpPort, Type type) { + this.tcpPort = tcpPort; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the TCP port to match. + * + * @return the TCP port to match + */ + public TpPort tcpPort() { + return this.tcpPort; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("tcpPort", tcpPort).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), tcpPort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TcpPortCriterion) { + TcpPortCriterion that = (TcpPortCriterion) obj; + return Objects.equals(tcpPort, that.tcpPort) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java new file mode 100644 index 00000000..3362c73f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java @@ -0,0 +1,74 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +/** + * Implementation of Tunnel ID criterion. + */ +public class TunnelIdCriterion implements Criterion { + private final long tunnelId; + + /** + * Constructor. + * + * @param tunnelId a Tunnel ID to match(64 bits) + */ + TunnelIdCriterion(long tunnelId) { + this.tunnelId = tunnelId; + } + + @Override + public Type type() { + return Type.TUNNEL_ID; + } + + /** + * Gets the Tunnel ID to match. + * + * @return the Tunnel ID to match (64 bits) + */ + public long tunnelId() { + return tunnelId; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("tunnelId", Long.toHexString(tunnelId)) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), tunnelId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TunnelIdCriterion) { + TunnelIdCriterion that = (TunnelIdCriterion) obj; + return Objects.equals(tunnelId, that.tunnelId) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java new file mode 100644 index 00000000..8a29f471 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java @@ -0,0 +1,80 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.TpPort; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of UDP port criterion (16 bits unsigned integer). + */ +public final class UdpPortCriterion implements Criterion { + private final TpPort udpPort; + private final Type type; + + /** + * Constructor. + * + * @param udpPort the UDP port to match + * @param type the match type. Should be either Type.UDP_SRC or + * Type.UDP_DST + */ + UdpPortCriterion(TpPort udpPort, Type type) { + this.udpPort = udpPort; + this.type = type; + } + + @Override + public Type type() { + return this.type; + } + + /** + * Gets the UDP port to match. + * + * @return the UDP port to match + */ + public TpPort udpPort() { + return this.udpPort; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("udpPort", udpPort).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), udpPort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof UdpPortCriterion) { + UdpPortCriterion that = (UdpPortCriterion) obj; + return Objects.equals(udpPort, that.udpPort) && + Objects.equals(type, that.type); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java new file mode 100644 index 00000000..c73edb12 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java @@ -0,0 +1,76 @@ +/* + * 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.flow.criteria; + +import org.onlab.packet.VlanId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of VLAN ID criterion. + */ +public final class VlanIdCriterion implements Criterion { + private final VlanId vlanId; + + /** + * Constructor. + * + * @param vlanId the VLAN ID to match + */ + VlanIdCriterion(VlanId vlanId) { + this.vlanId = vlanId; + } + + @Override + public Type type() { + return Type.VLAN_VID; + } + + /** + * Gets the VLAN ID to match. + * + * @return the VLAN ID to match + */ + public VlanId vlanId() { + return vlanId; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("vlanId", vlanId).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), vlanId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof VlanIdCriterion) { + VlanIdCriterion that = (VlanIdCriterion) obj; + return Objects.equals(vlanId, that.vlanId) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java new file mode 100644 index 00000000..0c83e141 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java @@ -0,0 +1,75 @@ +/* + * 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.flow.criteria; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of VLAN priority criterion (3 bits). + */ +public final class VlanPcpCriterion implements Criterion { + private static final byte MASK = 0x7; + private final byte vlanPcp; // VLAN pcp value: 3 bits + + /** + * Constructor. + * + * @param vlanPcp the VLAN priority to match (3 bits) + */ + VlanPcpCriterion(byte vlanPcp) { + this.vlanPcp = (byte) (vlanPcp & MASK); + } + + @Override + public Type type() { + return Type.VLAN_PCP; + } + + /** + * Gets the VLAN priority to match. + * + * @return the VLAN priority to match (3 bits) + */ + public byte priority() { + return vlanPcp; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("priority", Long.toHexString(vlanPcp)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), vlanPcp); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof VlanPcpCriterion) { + VlanPcpCriterion that = (VlanPcpCriterion) obj; + return Objects.equals(vlanPcp, that.vlanPcp) && + Objects.equals(this.type(), that.type()); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/package-info.java new file mode 100644 index 00000000..1f091928 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Traffic selection criteria model. + */ +package org.onosproject.net.flow.criteria; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java new file mode 100644 index 00000000..6f2cac6b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java @@ -0,0 +1,84 @@ +/* + * Copyright 2014-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.flow.instructions; + +/** + * Abstraction of a single traffic treatment step. + */ +public interface Instruction { + + /** + * Represents the type of traffic treatment. + */ + enum Type { + /** + * Signifies that the traffic should be dropped. + */ + DROP, + + /** + * Signifies that the traffic should be output to a port. + */ + OUTPUT, + + /** + * Signifies that traffic should be sent out of a group. + */ + GROUP, + + /** + * Signifies that traffic should be metered according to a meter. + */ + METER, + + /** + * Signifies that the traffic should be modified in L0 way. + */ + L0MODIFICATION, + + /** + * Signifies that the traffic should be modified in L2 way. + */ + L2MODIFICATION, + + /** + * Signifies that the traffic should be passed to another table. + */ + TABLE, + + /** + * Signifies that the traffic should be modified in L3 way. + */ + L3MODIFICATION, + + /** + * Signifies that metadata be attached to traffic. + */ + METADATA, + + /** + * Signifies that the traffic should be modified in L4 way. + */ + L4MODIFICATION + } + + /** + * Returns the type of instruction. + * @return type of instruction + */ + Type type(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java new file mode 100644 index 00000000..c5358a29 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java @@ -0,0 +1,742 @@ +/* + * Copyright 2014-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.flow.instructions; + +import org.onlab.packet.EthType; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.TpPort; +import org.onlab.packet.VlanId; +import org.onosproject.core.GroupId; +import org.onosproject.net.IndexedLambda; +import org.onosproject.net.Lambda; +import org.onosproject.net.OchSignal; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType; +import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; +import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction; +import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType; +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction; +import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType; +import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; +import org.onosproject.net.meter.MeterId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Factory class for creating various traffic treatment instructions. + */ +public final class Instructions { + + + // Ban construction + private Instructions() {} + + /** + * Creates an output instruction using the specified port number. This can + * include logical ports such as CONTROLLER, FLOOD, etc. + * + * @param number port number + * @return output instruction + */ + public static OutputInstruction createOutput(final PortNumber number) { + checkNotNull(number, "PortNumber cannot be null"); + return new OutputInstruction(number); + } + + /** + * Creates a drop instruction. + * + * @return drop instruction + */ + public static DropInstruction createDrop() { + return new DropInstruction(); + } + + /** + * Creates a group instruction. + * + * @param groupId Group Id + * @return group instruction + */ + public static GroupInstruction createGroup(final GroupId groupId) { + checkNotNull(groupId, "GroupId cannot be null"); + return new GroupInstruction(groupId); + } + + public static MeterInstruction meterTraffic(final MeterId meterId) { + checkNotNull(meterId, "meter id cannot be null"); + return new MeterInstruction(meterId); + } + + /** + * Creates a l0 modification. + * + * @param lambda the lambda to modify to + * @return a l0 modification + * @deprecated in Cardinal Release. Use {@link #modL0Lambda(Lambda)} instead. + */ + @Deprecated + public static L0ModificationInstruction modL0Lambda(short lambda) { + checkNotNull(lambda, "L0 lambda cannot be null"); + return new ModLambdaInstruction(L0SubType.LAMBDA, lambda); + } + + /** + * Creates an L0 modification with the specified OCh signal. + * + * @param lambda OCh signal + * @return an L0 modification + */ + public static L0ModificationInstruction modL0Lambda(Lambda lambda) { + checkNotNull(lambda, "L0 OCh signal cannot be null"); + + if (lambda instanceof IndexedLambda) { + return new ModLambdaInstruction(L0SubType.LAMBDA, (short) ((IndexedLambda) lambda).index()); + } else if (lambda instanceof OchSignal) { + return new ModOchSignalInstruction((OchSignal) lambda); + } else { + throw new UnsupportedOperationException(String.format("Unsupported type: %s", lambda)); + } + } + + /** + * Creates a l2 src modification. + * + * @param addr the mac address to modify to + * @return a l2 modification + */ + public static L2ModificationInstruction modL2Src(MacAddress addr) { + checkNotNull(addr, "Src l2 address cannot be null"); + return new L2ModificationInstruction.ModEtherInstruction( + L2ModificationInstruction.L2SubType.ETH_SRC, addr); + } + + /** + * Creates a L2 dst modification. + * + * @param addr the mac address to modify to + * @return a L2 modification + */ + public static L2ModificationInstruction modL2Dst(MacAddress addr) { + checkNotNull(addr, "Dst l2 address cannot be null"); + return new L2ModificationInstruction.ModEtherInstruction( + L2ModificationInstruction.L2SubType.ETH_DST, addr); + } + + /** + * Creates a VLAN ID modification. + * + * @param vlanId the VLAN ID to modify to + * @return a L2 modification + */ + public static L2ModificationInstruction modVlanId(VlanId vlanId) { + checkNotNull(vlanId, "VLAN id cannot be null"); + return new L2ModificationInstruction.ModVlanIdInstruction(vlanId); + } + + /** + * Creates a VLAN PCP modification. + * + * @param vlanPcp the PCP to modify to + * @return a L2 modification + */ + public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) { + checkNotNull(vlanPcp, "VLAN Pcp cannot be null"); + return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp); + } + + /** + * Creates a MPLS label modification. + * + * @param mplsLabel MPLS label to set + * @return a L2 Modification + */ + public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) { + checkNotNull(mplsLabel, "MPLS label cannot be null"); + return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel); + } + + /** + * Creates a MPLS BOS bit modification. + * + * @param mplsBos MPLS BOS bit to set (true) or unset (false) + * @return a L2 Modification + */ + public static L2ModificationInstruction modMplsBos(boolean mplsBos) { + return new L2ModificationInstruction.ModMplsBosInstruction(mplsBos); + } + + /** + * Creates a MPLS decrement TTL modification. + * + * @return a L2 Modification + */ + public static L2ModificationInstruction decMplsTtl() { + return new L2ModificationInstruction.ModMplsTtlInstruction(); + } + + /** + * Creates a L3 IPv4 src modification. + * + * @param addr the IPv4 address to modify to + * @return a L3 modification + */ + public static L3ModificationInstruction modL3Src(IpAddress addr) { + checkNotNull(addr, "Src l3 IPv4 address cannot be null"); + return new ModIPInstruction(L3SubType.IPV4_SRC, addr); + } + + /** + * Creates a L3 IPv4 dst modification. + * + * @param addr the IPv4 address to modify to + * @return a L3 modification + */ + public static L3ModificationInstruction modL3Dst(IpAddress addr) { + checkNotNull(addr, "Dst l3 IPv4 address cannot be null"); + return new ModIPInstruction(L3SubType.IPV4_DST, addr); + } + + /** + * Creates a L3 IPv6 src modification. + * + * @param addr the IPv6 address to modify to + * @return a L3 modification + */ + public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) { + checkNotNull(addr, "Src l3 IPv6 address cannot be null"); + return new ModIPInstruction(L3SubType.IPV6_SRC, addr); + } + + /** + * Creates a L3 IPv6 dst modification. + * + * @param addr the IPv6 address to modify to + * @return a L3 modification + */ + public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) { + checkNotNull(addr, "Dst l3 IPv6 address cannot be null"); + return new ModIPInstruction(L3SubType.IPV6_DST, addr); + } + + /** + * Creates a L3 IPv6 Flow Label modification. + * + * @param flowLabel the IPv6 flow label to modify to (20 bits) + * @return a L3 modification + */ + public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) { + return new ModIPv6FlowLabelInstruction(flowLabel); + } + + /** + * Creates a L3 decrement TTL modification. + * + * @return a L3 modification + */ + public static L3ModificationInstruction decNwTtl() { + return new ModTtlInstruction(L3SubType.DEC_TTL); + } + + /** + * Creates a L3 copy TTL to outer header modification. + * + * @return a L3 modification + */ + public static L3ModificationInstruction copyTtlOut() { + return new ModTtlInstruction(L3SubType.TTL_OUT); + } + + /** + * Creates a L3 copy TTL to inner header modification. + * + * @return a L3 modification + */ + public static L3ModificationInstruction copyTtlIn() { + return new ModTtlInstruction(L3SubType.TTL_IN); + } + + /** + * Creates a push MPLS header instruction. + * + * @return a L2 modification. + */ + public static Instruction pushMpls() { + return new L2ModificationInstruction.PushHeaderInstructions( + L2ModificationInstruction.L2SubType.MPLS_PUSH, + EthType.EtherType.MPLS_UNICAST.ethType()); + } + + /** + * Creates a pop MPLS header instruction. + * + * @return a L2 modification. + */ + public static Instruction popMpls() { + return new L2ModificationInstruction.PushHeaderInstructions( + L2ModificationInstruction.L2SubType.MPLS_POP, + EthType.EtherType.MPLS_UNICAST.ethType()); + } + + /** + * Creates a pop MPLS header instruction with a particular ethertype. + * + * @param etherType Ethernet type to set + * @return a L2 modification. + * @deprecated in Cardinal Release + */ + @Deprecated + public static Instruction popMpls(int etherType) { + checkNotNull(etherType, "Ethernet type cannot be null"); + return new L2ModificationInstruction.PushHeaderInstructions( + L2ModificationInstruction.L2SubType.MPLS_POP, new EthType(etherType)); + } + + + /** + * Creates a pop MPLS header instruction with a particular ethertype. + * + * @param etherType Ethernet type to set + * @return a L2 modification. + */ + public static Instruction popMpls(EthType etherType) { + checkNotNull(etherType, "Ethernet type cannot be null"); + return new L2ModificationInstruction.PushHeaderInstructions( + L2ModificationInstruction.L2SubType.MPLS_POP, etherType); + } + + /** + * Creates a pop VLAN header instruction. + * + * @return a L2 modification + */ + public static Instruction popVlan() { + return new L2ModificationInstruction.PopVlanInstruction( + L2ModificationInstruction.L2SubType.VLAN_POP); + } + + /** + * Creates a push VLAN header instruction. + * + * @return a L2 modification + */ + public static Instruction pushVlan() { + return new L2ModificationInstruction.PushHeaderInstructions( + L2ModificationInstruction.L2SubType.VLAN_PUSH, + EthType.EtherType.VLAN.ethType()); + } + + /** + * Sends the packet to the table id. + * + * @param tableId flow rule table id + * @return table type transition instruction + */ + public static Instruction transition(Integer tableId) { + checkNotNull(tableId, "Table id cannot be null"); + return new TableTypeTransition(tableId); + } + + /** + * Writes metadata to associate with a packet. + * + * @param metadata the metadata value to write + * @param metadataMask the bits to mask for the metadata value + * @return metadata instruction + */ + public static Instruction writeMetadata(long metadata, long metadataMask) { + return new MetadataInstruction(metadata, metadataMask); + } + + /** + * Creates a Tunnel ID modification. + * + * @param tunnelId the Tunnel ID to modify to + * @return a L2 modification + */ + public static L2ModificationInstruction modTunnelId(long tunnelId) { + checkNotNull(tunnelId, "Tunnel id cannot be null"); + return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId); + } + + /** + * Creates a TCP src modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + * @deprecated in Drake release + */ + @Deprecated + public static L4ModificationInstruction modTcpSrc(short port) { + checkNotNull(port, "Src TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_SRC, TpPort.tpPort(port)); + } + + /** + * Creates a TCP src modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modTcpSrc(TpPort port) { + checkNotNull(port, "Src TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_SRC, port); + } + + /** + * Creates a TCP dst modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + * @deprecated in Drake release + */ + @Deprecated + public static L4ModificationInstruction modTcpDst(short port) { + checkNotNull(port, "Dst TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_DST, TpPort.tpPort(port)); + } + + /** + * Creates a TCP dst modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modTcpDst(TpPort port) { + checkNotNull(port, "Dst TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_DST, port); + } + + /** + * Creates a UDP src modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + * @deprecated in Drake release + */ + @Deprecated + public static L4ModificationInstruction modUdpSrc(short port) { + checkNotNull(port, "Src UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_SRC, TpPort.tpPort(port)); + } + + /** + * Creates a UDP src modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modUdpSrc(TpPort port) { + checkNotNull(port, "Src UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_SRC, port); + } + + /** + * Creates a UDP dst modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + * @deprecated in Drake release + */ + @Deprecated + public static L4ModificationInstruction modUdpDst(short port) { + checkNotNull(port, "Dst UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_DST, TpPort.tpPort(port)); + } + + /** + * Creates a UDP dst modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modUdpDst(TpPort port) { + checkNotNull(port, "Dst UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_DST, port); + } + + /** + * Drop instruction. + */ + public static final class DropInstruction implements Instruction { + + private DropInstruction() {} + + @Override + public Type type() { + return Type.DROP; + } + + @Override + public String toString() { + return toStringHelper(type().toString()).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DropInstruction) { + return true; + } + return false; + } + } + + /** + * Output Instruction. + */ + public static final class OutputInstruction implements Instruction { + private final PortNumber port; + + private OutputInstruction(PortNumber port) { + this.port = port; + } + + public PortNumber port() { + return port; + } + + @Override + public Type type() { + return Type.OUTPUT; + } + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("port", port).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), port); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OutputInstruction) { + OutputInstruction that = (OutputInstruction) obj; + return Objects.equals(port, that.port); + + } + return false; + } + } + + /** + * Group Instruction. + */ + public static final class GroupInstruction implements Instruction { + private final GroupId groupId; + + private GroupInstruction(GroupId groupId) { + this.groupId = groupId; + } + + public GroupId groupId() { + return groupId; + } + + @Override + public Type type() { + return Type.GROUP; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("group ID", groupId.id()).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), groupId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof GroupInstruction) { + GroupInstruction that = (GroupInstruction) obj; + return Objects.equals(groupId, that.groupId); + + } + return false; + } + } + + /** + * A meter instruction. + */ + public static final class MeterInstruction implements Instruction { + private final MeterId meterId; + + private MeterInstruction(MeterId meterId) { + this.meterId = meterId; + } + + public MeterId meterId() { + return meterId; + } + + @Override + public Type type() { + return Type.METER; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("meter ID", meterId.id()).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), meterId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MeterInstruction) { + MeterInstruction that = (MeterInstruction) obj; + return Objects.equals(meterId, that.meterId); + + } + return false; + } + } + + /** + * Transition instruction. + */ + public static class TableTypeTransition implements Instruction { + private final Integer tableId; + + TableTypeTransition(Integer tableId) { + this.tableId = tableId; + } + + @Override + public Type type() { + return Type.TABLE; + } + + public Integer tableId() { + return this.tableId; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("tableId", this.tableId).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), tableId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof TableTypeTransition) { + TableTypeTransition that = (TableTypeTransition) obj; + return Objects.equals(tableId, that.tableId); + + } + return false; + } + } + + /** + * Metadata instruction. + */ + public static class MetadataInstruction implements Instruction { + private final long metadata; + private final long metadataMask; + + MetadataInstruction(long metadata, long metadataMask) { + this.metadata = metadata; + this.metadataMask = metadataMask; + } + + @Override + public Type type() { + return Type.METADATA; + } + + public long metadata() { + return this.metadata; + } + + public long metadataMask() { + return this.metadataMask; + } + + @Override + public String toString() { + return toStringHelper(type().toString()) + .add("metadata", Long.toHexString(this.metadata)) + .add("metadata mask", Long.toHexString(this.metadataMask)) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type().ordinal(), metadata, metadataMask); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof MetadataInstruction) { + MetadataInstruction that = (MetadataInstruction) obj; + return Objects.equals(metadata, that.metadata) && + Objects.equals(metadataMask, that.metadataMask); + + } + return false; + } + } + +} + + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java new file mode 100644 index 00000000..a6e5903c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java @@ -0,0 +1,139 @@ +/* + * Copyright 2014-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.flow.instructions; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.OchSignal; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +public abstract class L0ModificationInstruction implements Instruction { + + /** + * Represents the type of traffic treatment. + */ + public enum L0SubType { + /** + * Lambda modification. + */ + LAMBDA, + /** + * OCh (Optical Channel) modification. + */ + OCH, + } + + public abstract L0SubType subtype(); + + @Override + public final Type type() { + return Type.L0MODIFICATION; + } + + /** + * Represents a L0 lambda modification instruction. + */ + public static final class ModLambdaInstruction extends L0ModificationInstruction { + + private final L0SubType subtype; + private final short lambda; + + ModLambdaInstruction(L0SubType subType, short lambda) { + this.subtype = subType; + this.lambda = lambda; + } + + @Override + public L0SubType subtype() { + return this.subtype; + } + + public short lambda() { + return this.lambda; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("lambda", lambda).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype, lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModLambdaInstruction) { + ModLambdaInstruction that = (ModLambdaInstruction) obj; + return Objects.equals(lambda, that.lambda) && + Objects.equals(subtype, that.subtype); + } + return false; + } + } + + /** + * Represents an L0 OCh (Optical Channel) modification instruction. + */ + public static final class ModOchSignalInstruction extends L0ModificationInstruction { + + private final OchSignal lambda; + + ModOchSignalInstruction(OchSignal lambda) { + this.lambda = lambda; + } + + @Override + public L0SubType subtype() { + return L0SubType.OCH; + } + + public OchSignal lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ModOchSignalInstruction)) { + return false; + } + final ModOchSignalInstruction that = (ModOchSignalInstruction) obj; + return Objects.equals(this.lambda, that.lambda); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("lambda", lambda) + .toString(); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java new file mode 100644 index 00000000..0dbbb451 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java @@ -0,0 +1,517 @@ +/* + * Copyright 2014-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.flow.instructions; + +import org.onlab.packet.EthType; +import org.onlab.packet.MacAddress; +import org.onlab.packet.MplsLabel; +import org.onlab.packet.VlanId; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Abstraction of a single traffic treatment step. + */ +public abstract class L2ModificationInstruction implements Instruction { + + /** + * Represents the type of traffic treatment. + */ + public enum L2SubType { + /** + * Ether src modification. + */ + ETH_SRC, + + /** + * Ether dst modification. + */ + ETH_DST, + + /** + * VLAN id modification. + */ + VLAN_ID, + + /** + * VLAN priority modification. + */ + VLAN_PCP, + + /** + * MPLS Label modification. + */ + MPLS_LABEL, + + /** + * MPLS Push modification. + */ + MPLS_PUSH, + + /** + * MPLS Pop modification. + */ + MPLS_POP, + + /** + * MPLS TTL modification. + */ + DEC_MPLS_TTL, + + /** + * VLAN Pop modification. + */ + VLAN_POP, + + /** + * VLAN Push modification. + */ + VLAN_PUSH, + + /** + * Tunnel id modification. + */ + TUNNEL_ID, + + /** + * MPLS BOS instruction. + */ + MPLS_BOS + } + + // TODO: Create factory class 'Instructions' that will have various factory + // to create specific instructions. + + public abstract L2SubType subtype(); + + @Override + public final Type type() { + return Type.L2MODIFICATION; + } + + /** + * Represents a L2 src/dst modification instruction. + */ + public static final class ModEtherInstruction extends L2ModificationInstruction { + + private final L2SubType subtype; + private final MacAddress mac; + + ModEtherInstruction(L2SubType subType, MacAddress addr) { + + this.subtype = subType; + this.mac = addr; + } + + @Override + public L2SubType subtype() { + return this.subtype; + } + + public MacAddress mac() { + return this.mac; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("mac", mac).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype, mac); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModEtherInstruction) { + ModEtherInstruction that = (ModEtherInstruction) obj; + return Objects.equals(mac, that.mac) && + Objects.equals(subtype, that.subtype); + } + return false; + } + } + + // TODO This instruction is reused for Pop-Mpls. Consider renaming. + public static final class PushHeaderInstructions extends + L2ModificationInstruction { + + + private final L2SubType subtype; + private final EthType ethernetType; // Ethernet type value: 16 bits + + PushHeaderInstructions(L2SubType subType, EthType ethernetType) { + this.subtype = subType; + this.ethernetType = ethernetType; + } + + public EthType ethernetType() { + return ethernetType; + } + + @Override + public L2SubType subtype() { + return this.subtype; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("ethernetType", ethernetType()) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype, ethernetType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PushHeaderInstructions) { + PushHeaderInstructions that = (PushHeaderInstructions) obj; + return Objects.equals(subtype, that.subtype) && + Objects.equals(this.ethernetType, that.ethernetType); + } + return false; + } + } + + + + /** + * Represents a VLAN id modification instruction. + */ + public static final class ModVlanIdInstruction extends L2ModificationInstruction { + + private final VlanId vlanId; + + ModVlanIdInstruction(VlanId vlanId) { + this.vlanId = vlanId; + } + + @Override + public L2SubType subtype() { + return L2SubType.VLAN_ID; + } + + public VlanId vlanId() { + return this.vlanId; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("id", vlanId).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), vlanId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModVlanIdInstruction) { + ModVlanIdInstruction that = (ModVlanIdInstruction) obj; + return Objects.equals(vlanId, that.vlanId); + } + return false; + } + } + + /** + * Represents a VLAN PCP modification instruction. + */ + public static final class ModVlanPcpInstruction extends L2ModificationInstruction { + + private static final byte MASK = 0x7; + private final byte vlanPcp; + + ModVlanPcpInstruction(byte vlanPcp) { + this.vlanPcp = (byte) (vlanPcp & MASK); + } + + @Override + public L2SubType subtype() { + return L2SubType.VLAN_PCP; + } + + public byte vlanPcp() { + return this.vlanPcp; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("pcp", Long.toHexString(vlanPcp)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), vlanPcp); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModVlanPcpInstruction) { + ModVlanPcpInstruction that = (ModVlanPcpInstruction) obj; + return Objects.equals(vlanPcp, that.vlanPcp); + } + return false; + } + } + + /** + * Represents a VLAN POP modification instruction. + */ + public static final class PopVlanInstruction extends L2ModificationInstruction { + private final L2SubType subtype; + + PopVlanInstruction(L2SubType subType) { + this.subtype = subType; + } + + @Override + public L2SubType subtype() { + return subtype; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PopVlanInstruction) { + PopVlanInstruction that = (PopVlanInstruction) obj; + return Objects.equals(subtype, that.subtype); + } + return false; + } + } + + /** + * Represents a MPLS label modification. + */ + public static final class ModMplsLabelInstruction + extends L2ModificationInstruction { + + private final MplsLabel mplsLabel; + + ModMplsLabelInstruction(MplsLabel mplsLabel) { + this.mplsLabel = mplsLabel; + } + + /** + * @deprecated in Drake Release. + * @return integer value of label + */ + // Consider changing return value to MplsLabel + // after deprecation process so that it'll be symmetric to + // MplsCriterion#label() + @Deprecated + public Integer label() { + return mplsLabel.toInt(); + } + + public MplsLabel mplsLabel() { + return mplsLabel; + } + + @Override + public L2SubType subtype() { + return L2SubType.MPLS_LABEL; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("mpls", mplsLabel).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), mplsLabel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModMplsLabelInstruction) { + ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj; + return Objects.equals(mplsLabel, that.mplsLabel); + } + return false; + } + } + + /** + * Represents a MPLS BOS modification. + */ + public static final class ModMplsBosInstruction + extends L2ModificationInstruction { + + private final boolean mplsBos; + + ModMplsBosInstruction(boolean mplsBos) { + this.mplsBos = mplsBos; + } + + public boolean mplsBos() { + return mplsBos; + } + + @Override + public L2SubType subtype() { + return L2SubType.MPLS_BOS; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()).add("bos", mplsBos) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), mplsBos); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModMplsBosInstruction) { + ModMplsBosInstruction that = (ModMplsBosInstruction) obj; + return Objects.equals(mplsBos, that.mplsBos()); + } + return false; + } + } + + /** + * Represents a MPLS TTL modification. + */ + public static final class ModMplsTtlInstruction + extends L2ModificationInstruction { + + ModMplsTtlInstruction() { + } + + @Override + public L2SubType subtype() { + return L2SubType.DEC_MPLS_TTL; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModMplsTtlInstruction) { + return true; + } + return false; + } + } + + /** + * Represents a Tunnel id modification. + */ + public static final class ModTunnelIdInstruction + extends L2ModificationInstruction { + + private final long tunnelId; + + ModTunnelIdInstruction(long tunnelId) { + this.tunnelId = tunnelId; + } + + public long tunnelId() { + return this.tunnelId; + } + + @Override + public L2SubType subtype() { + return L2SubType.TUNNEL_ID; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("id", Long.toHexString(tunnelId)) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), tunnelId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModTunnelIdInstruction) { + ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj; + return Objects.equals(tunnelId, that.tunnelId); + } + return false; + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java new file mode 100644 index 00000000..41819504 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L3ModificationInstruction.java @@ -0,0 +1,231 @@ +/* + * Copyright 2014-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.flow.instructions; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import org.onlab.packet.IpAddress; + +/** + * Abstraction of a single traffic treatment step. + */ +public abstract class L3ModificationInstruction implements Instruction { + + /** + * Represents the type of traffic treatment. + */ + public enum L3SubType { + /** + * IPv4 src modification. + */ + IPV4_SRC, + + /** + * IPv4 dst modification. + */ + IPV4_DST, + + /** + * IPv6 src modification. + */ + IPV6_SRC, + + /** + * IPv6 dst modification. + */ + IPV6_DST, + + /** + * IPv6 flow label modification. + */ + IPV6_FLABEL, + + /** + * Decrement TTL. + */ + DEC_TTL, + + /** + * Copy TTL out. + */ + TTL_OUT, + + /** + * Copy TTL in. + */ + TTL_IN + + //TODO: remaining types + } + + /** + * Returns the subtype of the modification instruction. + * @return type of instruction + */ + public abstract L3SubType subtype(); + + @Override + public final Type type() { + return Type.L3MODIFICATION; + } + + /** + * Represents a L3 src/dst modification instruction. + */ + public static final class ModIPInstruction extends L3ModificationInstruction { + + private final L3SubType subtype; + private final IpAddress ip; + + ModIPInstruction(L3SubType subType, IpAddress addr) { + + this.subtype = subType; + this.ip = addr; + } + + @Override + public L3SubType subtype() { + return this.subtype; + } + + public IpAddress ip() { + return this.ip; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("ip", ip).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), ip); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModIPInstruction) { + ModIPInstruction that = (ModIPInstruction) obj; + return Objects.equals(ip, that.ip) && + Objects.equals(this.subtype(), that.subtype()); + } + return false; + } + } + + /** + * Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction + * (20 bits unsigned integer). + */ + public static final class ModIPv6FlowLabelInstruction + extends L3ModificationInstruction { + private static final int MASK = 0xfffff; + private final int flowLabel; // IPv6 flow label: 20 bits + + /** + * Creates a new flow mod instruction. + * + * @param flowLabel the IPv6 flow label to set in the treatment (20 bits) + */ + ModIPv6FlowLabelInstruction(int flowLabel) { + this.flowLabel = flowLabel & MASK; + } + + @Override + public L3SubType subtype() { + return L3SubType.IPV6_FLABEL; + } + + /** + * Gets the IPv6 flow label to set in the treatment. + * + * @return the IPv6 flow label to set in the treatment (20 bits) + */ + public int flowLabel() { + return this.flowLabel; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("flowLabel", Long.toHexString(flowLabel)).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), flowLabel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModIPv6FlowLabelInstruction) { + ModIPv6FlowLabelInstruction that = + (ModIPv6FlowLabelInstruction) obj; + return Objects.equals(flowLabel, that.flowLabel); + } + return false; + } + } + + /** + * Represents a L3 TTL modification instruction. + */ + public static final class ModTtlInstruction extends L3ModificationInstruction { + + private final L3SubType subtype; + + ModTtlInstruction(L3SubType subtype) { + this.subtype = subtype; + } + + @Override + public L3SubType subtype() { + return this.subtype; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModTtlInstruction) { + ModTtlInstruction that = (ModTtlInstruction) obj; + return Objects.equals(this.subtype(), that.subtype()); + } + return false; + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java new file mode 100644 index 00000000..441a2c5f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java @@ -0,0 +1,114 @@ +/* + * Copyright 2014-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.flow.instructions; + +import org.onlab.packet.TpPort; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Abstraction of a single traffic treatment step. + */ +public abstract class L4ModificationInstruction implements Instruction { + + /** + * Represents the type of traffic treatment. + */ + public enum L4SubType { + /** + * TCP src modification. + */ + TCP_SRC, + + /** + * TCP dst modification. + */ + TCP_DST, + + /** + * UDP src modification. + */ + UDP_SRC, + + /** + * UDP dst modification. + */ + UDP_DST + + //TODO: remaining types + } + + /** + * Returns the subtype of the modification instruction. + * + * @return type of instruction + */ + public abstract L4SubType subtype(); + + @Override + public Type type() { + return Type.L4MODIFICATION; + } + + /** + * Represents a L4 src/dst modification instruction. + */ + public static final class ModTransportPortInstruction extends L4ModificationInstruction { + + private final L4SubType subtype; + private final TpPort port; + + public ModTransportPortInstruction(L4SubType subtype, TpPort port) { + this.subtype = subtype; + this.port = port; + } + + @Override + public L4SubType subtype() { + return this.subtype; + } + + public TpPort port() { + return this.port; + } + + @Override + public String toString() { + return toStringHelper(subtype().toString()) + .add("port", port).toString(); + } + + @Override + public int hashCode() { + return Objects.hash(type(), subtype(), port); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ModTransportPortInstruction) { + ModTransportPortInstruction that = (ModTransportPortInstruction) obj; + return Objects.equals(port, that.port) && + Objects.equals(this.subtype(), that.subtype()); + } + return false; + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/package-info.java new file mode 100644 index 00000000..65f58a40 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Traffic treatment model. + */ +package org.onosproject.net.flow.instructions; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/package-info.java new file mode 100644 index 00000000..6068b6f2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/package-info.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014-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. + */ + +/** + * Flow rule model & related services API definitions. + * + * <p> + * The figure below depicts the general interactions between different + * components of the intent subsystem.<br> + * <img src="doc-files/flow-design.png" alt="ONOS flow rule subsystem design"> + * </p> + */ +package org.onosproject.net.flow; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java new file mode 100644 index 00000000..7b5924fb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java @@ -0,0 +1,239 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.criteria.Criteria; +import org.onosproject.net.flow.criteria.Criterion; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of a filtering objective. + */ +@Beta +public final class DefaultFilteringObjective implements FilteringObjective { + + + private final Type type; + private final boolean permanent; + private final int timeout; + private final ApplicationId appId; + private final int priority; + private final Criterion key; + private final List<Criterion> conditions; + private final int id; + private final Operation op; + private final Optional<ObjectiveContext> context; + + private DefaultFilteringObjective(Builder builder) { + this.key = builder.key; + this.type = builder.type; + this.permanent = builder.permanent; + this.timeout = builder.timeout; + this.appId = builder.appId; + this.priority = builder.priority; + this.conditions = builder.conditions; + this.op = builder.op; + this.context = Optional.ofNullable(builder.context); + + this.id = Objects.hash(type, key, conditions, permanent, + timeout, appId, priority); + } + + @Override + public Criterion key() { + return key; + } + + @Override + public Type type() { + return this.type; + } + + @Override + public Collection<Criterion> conditions() { + return conditions; + } + + @Override + public int id() { + return id; + } + + @Override + public int priority() { + return priority; + } + + @Override + public ApplicationId appId() { + return appId; + } + + @Override + public int timeout() { + return timeout; + } + + @Override + public boolean permanent() { + return permanent; + } + + @Override + public Operation op() { + return op; + } + + @Override + public Optional<ObjectiveContext> context() { + return context; + } + + /** + * Returns a new builder. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + + public static final class Builder implements FilteringObjective.Builder { + private final ImmutableList.Builder<Criterion> listBuilder + = ImmutableList.builder(); + + private Type type; + private boolean permanent = DEFAULT_PERMANENT; + private int timeout = DEFAULT_TIMEOUT; + private ApplicationId appId; + private int priority = DEFAULT_PRIORITY; + private Criterion key = Criteria.dummy(); + private List<Criterion> conditions; + private Operation op; + private ObjectiveContext context; + + @Override + public Builder withKey(Criterion key) { + this.key = key; + return this; + } + + @Override + public Builder addCondition(Criterion criterion) { + listBuilder.add(criterion); + return this; + } + + @Override + public Builder permit() { + this.type = Type.PERMIT; + return this; + } + + @Override + public Builder deny() { + this.type = Type.DENY; + return this; + } + + @Override + public Builder makeTemporary(int timeout) { + this.timeout = timeout; + permanent = false; + return this; + } + + @Override + public Builder makePermanent() { + permanent = true; + return this; + } + + @Override + public Builder fromApp(ApplicationId appId) { + this.appId = appId; + return this; + } + + @Override + public Builder withPriority(int priority) { + this.priority = priority; + return this; + } + + @Override + public FilteringObjective add() { + conditions = listBuilder.build(); + op = Operation.ADD; + checkNotNull(type, "Must have a type."); + checkArgument(!conditions.isEmpty(), "Must have at least one condition."); + checkNotNull(appId, "Must supply an application id"); + + return new DefaultFilteringObjective(this); + + } + + @Override + public FilteringObjective remove() { + conditions = listBuilder.build(); + checkNotNull(type, "Must have a type."); + checkArgument(!conditions.isEmpty(), "Must have at least one condition."); + checkNotNull(appId, "Must supply an application id"); + op = Operation.REMOVE; + + return new DefaultFilteringObjective(this); + + } + + @Override + public FilteringObjective add(ObjectiveContext context) { + conditions = listBuilder.build(); + checkNotNull(type, "Must have a type."); + checkArgument(!conditions.isEmpty(), "Must have at least one condition."); + checkNotNull(appId, "Must supply an application id"); + op = Operation.ADD; + this.context = context; + + return new DefaultFilteringObjective(this); + } + + @Override + public FilteringObjective remove(ObjectiveContext context) { + conditions = listBuilder.build(); + checkNotNull(type, "Must have a type."); + checkArgument(!conditions.isEmpty(), "Must have at least one condition."); + checkNotNull(appId, "Must supply an application id"); + op = Operation.REMOVE; + this.context = context; + + return new DefaultFilteringObjective(this); + } + + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java new file mode 100644 index 00000000..0abf5abe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java @@ -0,0 +1,241 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Objects; +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of a forwarding objective. + */ +@Beta +public final class DefaultForwardingObjective implements ForwardingObjective { + + private final TrafficSelector selector; + private final Flag flag; + private final boolean permanent; + private final int timeout; + private final ApplicationId appId; + private final int priority; + private final Integer nextId; + private final TrafficTreatment treatment; + private final Operation op; + private final Optional<ObjectiveContext> context; + + private final int id; + + private DefaultForwardingObjective(Builder builder) { + this.selector = builder.selector; + this.flag = builder.flag; + this.permanent = builder.permanent; + this.timeout = builder.timeout; + this.appId = builder.appId; + this.priority = builder.priority; + this.nextId = builder.nextId; + this.treatment = builder.treatment; + this.op = builder.op; + this.context = Optional.ofNullable(builder.context); + + this.id = Objects.hash(selector, flag, permanent, + timeout, appId, priority, nextId, + treatment, op); + } + + + @Override + public TrafficSelector selector() { + return selector; + } + + @Override + public Integer nextId() { + return nextId; + } + + @Override + public TrafficTreatment treatment() { + return treatment; + } + + + @Override + public Flag flag() { + return flag; + } + + @Override + public int id() { + return id; + } + + @Override + public int priority() { + return priority; + } + + @Override + public ApplicationId appId() { + return appId; + } + + @Override + public int timeout() { + return timeout; + } + + @Override + public boolean permanent() { + return permanent; + } + + @Override + public Operation op() { + return op; + } + + @Override + public Optional<ObjectiveContext> context() { + return context; + } + + /** + * Returns a new builder. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + public static final class Builder implements ForwardingObjective.Builder { + + private TrafficSelector selector; + private Flag flag; + private boolean permanent = DEFAULT_PERMANENT; + private int timeout = DEFAULT_TIMEOUT; + private int priority = DEFAULT_PRIORITY; + private ApplicationId appId; + private Integer nextId; + private TrafficTreatment treatment; + private Operation op; + private ObjectiveContext context; + + @Override + public Builder withSelector(TrafficSelector selector) { + this.selector = selector; + return this; + } + + @Override + public Builder nextStep(int nextId) { + this.nextId = nextId; + return this; + } + + @Override + public Builder withTreatment(TrafficTreatment treatment) { + this.treatment = treatment; + return this; + } + + @Override + public Builder withFlag(Flag flag) { + this.flag = flag; + return this; + } + + @Override + public Builder makeTemporary(int timeout) { + this.timeout = timeout; + this.permanent = false; + return this; + } + + @Override + public Builder makePermanent() { + this.permanent = true; + return this; + } + + @Override + public Builder fromApp(ApplicationId appId) { + this.appId = appId; + return this; + } + + @Override + public Builder withPriority(int priority) { + this.priority = priority; + return this; + } + + @Override + public ForwardingObjective add() { + checkNotNull(selector, "Must have a selector"); + checkNotNull(flag, "A flag must be set"); + checkArgument(nextId != null || treatment != null, "Must supply at " + + "least a treatment and/or a nextId"); + checkNotNull(appId, "Must supply an application id"); + op = Operation.ADD; + return new DefaultForwardingObjective(this); + } + + @Override + public ForwardingObjective remove() { + checkNotNull(selector, "Must have a selector"); + checkNotNull(flag, "A flag must be set"); + checkArgument(nextId != null || treatment != null, "Must supply at " + + "least a treatment and/or a nextId"); + checkNotNull(appId, "Must supply an application id"); + op = Operation.REMOVE; + return new DefaultForwardingObjective(this); + } + + @Override + public ForwardingObjective add(ObjectiveContext context) { + checkNotNull(selector, "Must have a selector"); + checkNotNull(flag, "A flag must be set"); + checkArgument(nextId != null || treatment != null, "Must supply at " + + "least a treatment and/or a nextId"); + checkNotNull(appId, "Must supply an application id"); + op = Operation.ADD; + this.context = context; + + return new DefaultForwardingObjective(this); + } + + @Override + public ForwardingObjective remove(ObjectiveContext context) { + checkNotNull(selector, "Must have a selector"); + checkNotNull(flag, "A flag must be set"); + checkArgument(nextId != null || treatment != null, "Must supply at " + + "least a treatment and/or a nextId"); + checkNotNull(appId, "Must supply an application id"); + op = Operation.REMOVE; + this.context = context; + + return new DefaultForwardingObjective(this); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java new file mode 100644 index 00000000..20e89295 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java @@ -0,0 +1,222 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Default implementation of a next objective. + */ +@Beta +public final class DefaultNextObjective implements NextObjective { + + private final List<TrafficTreatment> treatments; + private final ApplicationId appId; + private final Type type; + private final Integer id; + private final Operation op; + private final Optional<ObjectiveContext> context; + + private DefaultNextObjective(Builder builder) { + this.treatments = builder.treatments; + this.appId = builder.appId; + this.type = builder.type; + this.id = builder.id; + this.op = builder.op; + this.context = Optional.ofNullable(builder.context); + } + + @Override + public Collection<TrafficTreatment> next() { + return treatments; + } + + @Override + public Type type() { + return type; + } + + @Override + public int id() { + return id; + } + + @Override + public int priority() { + return 0; + } + + @Override + public ApplicationId appId() { + return appId; + } + + @Override + public int timeout() { + return 0; + } + + @Override + public boolean permanent() { + return false; + } + + @Override + public Operation op() { + return op; + } + + @Override + public Optional<ObjectiveContext> context() { + return context; + } + + /** + * Returns a new builder. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + public static final class Builder implements NextObjective.Builder { + + private ApplicationId appId; + private Type type; + private Integer id; + private List<TrafficTreatment> treatments; + private Operation op; + private ObjectiveContext context; + + private final ImmutableList.Builder<TrafficTreatment> listBuilder + = ImmutableList.builder(); + + @Override + public Builder withId(int nextId) { + this.id = nextId; + return this; + } + + @Override + public Builder withType(Type type) { + this.type = type; + return this; + } + + @Override + public Builder addTreatment(TrafficTreatment treatment) { + listBuilder.add(treatment); + return this; + } + + /** + * Noop. This method has no effect. + * + * @param timeout a timeout + * @return a next objective builder + */ + @Override + public Builder makeTemporary(int timeout) { + return this; + } + + /** + * Noop. This method has no effect. + * + * @return a next objective builder + */ + @Override + public Builder makePermanent() { + return this; + } + + @Override + public Builder fromApp(ApplicationId appId) { + this.appId = appId; + return this; + } + + /** + * Noop. This method has no effect. + * + * @param priority an integer + * @return a next objective builder + */ + @Override + public Builder withPriority(int priority) { + return this; + } + + @Override + public NextObjective add() { + treatments = listBuilder.build(); + op = Operation.ADD; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + checkArgument(!treatments.isEmpty(), "Must have at least one treatment"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective remove() { + treatments = listBuilder.build(); + op = Operation.REMOVE; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective add(ObjectiveContext context) { + treatments = listBuilder.build(); + op = Operation.ADD; + this.context = context; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + checkArgument(!treatments.isEmpty(), "Must have at least one treatment"); + + return new DefaultNextObjective(this); + } + + @Override + public NextObjective remove(ObjectiveContext context) { + treatments = listBuilder.build(); + op = Operation.REMOVE; + this.context = context; + checkNotNull(appId, "Must supply an application id"); + checkNotNull(id, "id cannot be null"); + checkNotNull(type, "The type cannot be null"); + + return new DefaultNextObjective(this); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java new file mode 100644 index 00000000..58304571 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java @@ -0,0 +1,158 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.criteria.Criterion; + +import java.util.Collection; + +/** + * Represents a filtering flow objective. Each filtering flow objective + * is made up of a key (criterion) to a set of criteria. Using this information + * a pipeline aware driver will decide how this objective should be mapped + * to the specific device pipeline. For example, consider the following + * filtering objective: + * + * portX -> {MAC1, IP1, MAC2} + * + * The driver could decide to pass L3 packet to the L3 table and L2 packets to + * the L2 table for packets arriving on portX. + * + * Filtering objectives do not only represent what should be permitted into the + * pipeline but can also be used to deny or drop unwanted packets by specifying + * the appropriate type of filtering objective. It is also important to note + * that submitting a filtering objective does not necessarily result in rules + * programmed at the switch, the driver is free to decide when these rules are + * programmed. For example, a filtering rule may only be programmed once a + * corresponding forwarding objective has been received. + */ +@Beta +public interface FilteringObjective extends Objective { + + enum Type { + /** + * Enables the filtering condition. + */ + PERMIT, + + /** + * Disables the filtering condition. + */ + DENY + } + + /** + * Obtain the key for this filter. + * + * @return a criterion + */ + Criterion key(); + + /** + * Obtain this filtering type. + * + * @return the type + */ + Type type(); + + /** + * The set of conditions the filter must provision at the device. + * + * @return a collection of criteria + */ + Collection<Criterion> conditions(); + + /** + * Builder of Filtering objective entities. + */ + interface Builder extends Objective.Builder { + + /** + * Specify the key for the filter. + * + * @param key a criterion + * @return a filter objective builder + */ + Builder withKey(Criterion key); + + /** + * Add a filtering condition. + * + * @param criterion new criterion + * @return a filtering builder + */ + Builder addCondition(Criterion criterion); + + /** + * Permit this filtering condition set. + * + * @return a filtering builder + */ + Builder permit(); + + /** + * Deny this filtering condition set. + * + * @return a filtering builder + */ + Builder deny(); + + /** + * Assigns an application id. + * + * @param appId an application id + * @return a filtering builder + */ + Builder fromApp(ApplicationId appId); + + /** + * Builds the filtering objective that will be added. + * + * @return a filtering objective + */ + FilteringObjective add(); + + /** + * Builds the filtering objective that will be removed. + * + * @return a filtering objective. + */ + FilteringObjective remove(); + + /** + * Builds the filtering objective that will be added. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a filtering objective + */ + FilteringObjective add(ObjectiveContext context); + + /** + * Builds the filtering objective that will be removed. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a filtering objective + */ + FilteringObjective remove(ObjectiveContext context); + + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java new file mode 100644 index 00000000..d3254151 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java @@ -0,0 +1,65 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.net.DeviceId; + +/** + * Service for programming data plane flow rules in manner independent of + * specific device table pipeline configuration. + */ +@Beta +public interface FlowObjectiveService { + + /** + * Installs the filtering rules onto the specified device. + * + * @param deviceId device identifier + * @param filteringObjective the filtering objective + */ + void filter(DeviceId deviceId, FilteringObjective filteringObjective); + + /** + * Installs the forwarding rules onto the specified device. + * + * @param deviceId device identifier + * @param forwardingObjective the forwarding objective + */ + void forward(DeviceId deviceId, ForwardingObjective forwardingObjective); + + /** + * Installs the next hop elements into the specified device. + * + * @param deviceId device identifier + * @param nextObjective a next objective + */ + void next(DeviceId deviceId, NextObjective nextObjective); + + /** + * Obtains a globally unique next objective. + * + * @return an integer + */ + int allocateNextId(); + + /** + * Installs the filtering rules onto the specified device. + * + * @param policy policy expression + */ + void initPolicy(String policy); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java new file mode 100644 index 00000000..ecf5d733 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java @@ -0,0 +1,50 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.net.behaviour.NextGroup; +import org.onosproject.store.Store; + +/** + * The flow objective store. + */ +@Beta +public interface FlowObjectiveStore + extends Store<ObjectiveEvent, FlowObjectiveStoreDelegate> { + + /** + * Adds a NextGroup to the store. + * + * @param nextId an integer + * @param group a next group opaque object + */ + void putNextGroup(Integer nextId, NextGroup group); + + /** + * Fetch a next group from the store. + * @param nextId an integer + * @return a next group + */ + NextGroup getNextGroup(Integer nextId); + + /** + * Allocates a next objective id. This id is globally unique + * + * @return an integer + */ + int allocateNextId(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStoreDelegate.java new file mode 100644 index 00000000..2189af1b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStoreDelegate.java @@ -0,0 +1,26 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.store.StoreDelegate; + +/** + * Flow Objective store delegate abstraction. + */ +@Beta +public interface FlowObjectiveStoreDelegate extends StoreDelegate<ObjectiveEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjective.java new file mode 100644 index 00000000..9857a710 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjective.java @@ -0,0 +1,158 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +/** + * Represents a description of which types of traffic need to + * be forwarded through the device. A forwarding objective may + * result in multiple rules at the device. There are two main types + * of forwarding objectives: + * + * - Versatile + * - Specific + * + * A versatile forwarding objective represents a composite rule that matches + * two or more header fields. The use of versatile usually indicates that this + * rule should be inserted in its entirety into the ACL table. Although, + * drivers for some devices are free to implement this differently. + * + * A specific forwarding objective represents a specific rule matching one or + * more header fields. The installation of this rule may result in several rules + * at the device. For example, one per table type. + */ +@Beta +public interface ForwardingObjective extends Objective { + + /** + * Represents whether this objective is monolithic or + * may be broken down into parts. + */ + enum Flag { + /** + * A decomposable objective. + */ + SPECIFIC, + + /** + * A monolithic objective. + */ + VERSATILE + } + + /** + * Obtain the selector for this objective. + * + * @return a traffic selector + */ + TrafficSelector selector(); + + /** + * Obtain the traffic treatment for this objective. Mutually exclusive with + * 'treatment'. + * + * @return an integer + */ + Integer nextId(); + + /** + * A traffic treatment for this forwarding objective. Mutually exclusive + * with a nextId. + * + * @return a traffic treatment + */ + TrafficTreatment treatment(); + + /** + * Obtain the type of this objective. + * + * @return a flag type + */ + Flag flag(); + + /** + * A forwarding objective builder. + */ + interface Builder extends Objective.Builder { + + /** + * Assigns a selector to the forwarding objective. + * + * @param selector a traffic selector + * @return a forwarding objective builder + */ + Builder withSelector(TrafficSelector selector); + + /** + * Assigns a next step to the forwarding objective. + * + * @param nextId a next objective id. + * @return a forwarding objective builder + */ + Builder nextStep(int nextId); + + /** + * Assigns the treatment for this forwarding objective. + * + * @param treatment a traffic treatment + * @return a forwarding objective + */ + Builder withTreatment(TrafficTreatment treatment); + + /** + * Assigns the flag to the forwarding objective. + * + * @param flag a flag + * @return a forwarding objective builder + */ + Builder withFlag(Flag flag); + + /** + * Builds the forwarding objective that will be added. + * + * @return a forwarding objective + */ + ForwardingObjective add(); + + /** + * Builds the forwarding objective that will be removed. + * + * @return a forwarding objective. + */ + ForwardingObjective remove(); + + /** + * Builds the forwarding objective that will be added. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a forwarding objective + */ + ForwardingObjective add(ObjectiveContext context); + + /** + * Builds the forwarding objective that will be removed. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a forwarding objective + */ + ForwardingObjective remove(ObjectiveContext context); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java new file mode 100644 index 00000000..1350d7a1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java @@ -0,0 +1,167 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Collection; + +/** + * Represents a nexthop which will be translated by a driver + * into the appropriate group or actions needed to implement + * the egress function. + * + * A next objective is made up of a collection of traffic treatments + * associated with a type. These types are: + * + * - Hashed + * - Broadcast + * - Failover + * - Simple + * + * These types will indicate to the driver what the intended behaviour is. + * For example, a broadcast next objective with a collection of output + * treatments will indicate to a driver that all output actions are expected + * to be executed simultaneously. The driver is then free to implement this + * as a group or a simple action list. + */ +@Beta +public interface NextObjective extends Objective { + + /** + * Represents the type of next phase to build. + */ + enum Type { + /** + * A hashed packet processing. + */ + HASHED, + + /** + * Broadcast packet process. + */ + BROADCAST, + + /** + * Failover handling. + */ + FAILOVER, + + /** + * Simple processing. Could be a group or a treatment. + */ + SIMPLE + } + + /** + * The collection of treatments that need to be applied to a set of traffic. + * + * @return a collection of traffic treatments + */ + Collection<TrafficTreatment> next(); + + /** + * The type of operation that will be applied to the traffic using the collection + * of treatments. + * + * @return a type + */ + Type type(); + + /** + * A next step builder. + */ + interface Builder extends Objective.Builder { + + /** + * Specifies the id for this next objective. + * + * @param nextId an integer + * @return a next objective builder + */ + Builder withId(int nextId); + + /** + * Sets the type of next step. + * + * @param type a type + * @return a next step builder + */ + Builder withType(Type type); + + /** + * Adds a treatment to this next step. + * + * @param treatment a traffic treatment + * @return a next step builder + */ + Builder addTreatment(TrafficTreatment treatment); + + /** + * Specifies the application which applied the filter. + * + * @param appId an application id + * @return an objective builder + */ + @Override + Builder fromApp(ApplicationId appId); + + /** + * Sets the priority for this objective. + * + * @param priority an integer + * @return an objective builder + */ + @Override + Builder withPriority(int priority); + + /** + * Builds the next objective that will be added. + * + * @return a next objective + */ + NextObjective add(); + + /** + * Builds the next objective that will be removed. + * + * @return a next objective. + */ + NextObjective remove(); + + /** + * Builds the next objective that will be added. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a next objective + */ + NextObjective add(ObjectiveContext context); + + /** + * Builds the next objective that will be removed. + * The context will be used to notify the calling application. + * + * @param context an objective context + * @return a next objective + */ + NextObjective remove(ObjectiveContext context); + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java new file mode 100644 index 00000000..090c298c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java @@ -0,0 +1,134 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; + +import java.util.Optional; + +/** + * Base representation of an flow description. + */ +@Beta +public interface Objective { + + static final boolean DEFAULT_PERMANENT = true; + static final int DEFAULT_TIMEOUT = 0; + static final int DEFAULT_PRIORITY = 32768; + + /** + * Type of operation. + */ + enum Operation { + /** + * Adds the objective. + */ + ADD, + + /** + * Removes the objective. + */ + REMOVE + } + + /** + * An identifier for this objective. + * + * @return an integer + */ + int id(); + + /** + * The priority for this objective. + * + * @return an integer + */ + int priority(); + + /** + * The application which applied this objective. + * + * @return an application id + */ + ApplicationId appId(); + + /** + * The timeout for this objective. + * + * @return an integer + */ + int timeout(); + + /** + * Whether this objective is permanent. + * + * @return a boolean + */ + boolean permanent(); + + /** + * The type of operation for this objective. + * + * @return an operation + */ + Operation op(); + + /** + * Obtains an optional context. + * + * @return optional; which will be empty if there is no context. + * Otherwise it will return the context. + */ + Optional<ObjectiveContext> context(); + + /** + * An objective builder. + */ + interface Builder { + /** + * Makes the filtering objective temporary. + * + * @param timeout a timeout + * @return an objective builder + */ + Builder makeTemporary(int timeout); + + /** + * Makes the filtering objective permanent. + * + * @return an objective builder + */ + Builder makePermanent(); + + /** + * Specifies the application which applied the filter. + * + * @param appId an application id + * @return an objective builder + */ + Builder fromApp(ApplicationId appId); + + /** + * Sets the priority for this objective. + * + * @param priority an integer + * @return an objective builder + */ + Builder withPriority(int priority); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveContext.java new file mode 100644 index 00000000..f3d23e4a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveContext.java @@ -0,0 +1,47 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; + +/** + * The context of a objective that will become the subject of + * the notification. + * <p> + * Implementations of this class must be serializable. + * </p> + */ +@Beta +public interface ObjectiveContext { + + /** + * Invoked on successful execution of the flow objective. + * + * @param objective objective to execute + */ + default void onSuccess(Objective objective) { + } + + /** + * Invoked when error is encountered while executing the flow objective. + * + * @param objective objective to execute + * @param error error encountered + */ + default void onError(Objective objective, ObjectiveError error) { + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveError.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveError.java new file mode 100644 index 00000000..fd159d7e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveError.java @@ -0,0 +1,60 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; + +/** + * Represents the set of errors possible when processing an objective. + */ +@Beta +public enum ObjectiveError { + + /** + * The driver processing this objective does not know how to process it. + */ + UNSUPPORTED, + + /** + * The flow installation for this objective failed. + */ + FLOWINSTALLATIONFAILED, + + /** + * THe group installation for this objective failed. + */ + GROUPINSTALLATIONFAILED, + + /** + * The group was reported as installed but is missing. + */ + GROUPMISSING, + + /** + * The device was not available to install objectives to. + */ + DEVICEMISSING, + + /** + * Incorrect Objective parameters passed in by the caller. + */ + BADPARAMS, + + /** + * An unknown error occurred. + */ + UNKNOWN +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveEvent.java new file mode 100644 index 00000000..c6937e31 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/ObjectiveEvent.java @@ -0,0 +1,64 @@ +/* + * 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.flowobjective; + +import com.google.common.annotations.Beta; +import org.onosproject.event.AbstractEvent; + +/** + * Describes a objective event. + */ +@Beta +public class ObjectiveEvent extends AbstractEvent<ObjectiveEvent.Type, Integer> { + + /** + * Type of objective events. + */ + public enum Type { + /** + * Signifies that the objective has been added to the store. + */ + ADD, + + /** + * Signifies that the objective has been removed. + */ + REMOVE + } + + /** + * Creates an event of the given type for the specified objective id. + * + * @param type the type of the event + * @param objective the objective id the event is about + */ + public ObjectiveEvent(Type type, Integer objective) { + super(type, objective); + } + + /** + * Creates an event of the given type for the specified objective id at the given + * time. + * + * @param type the type of the event + * @param objective the objective id the event is about + * @param time the time of the event + */ + public ObjectiveEvent(Type type, Integer objective, long time) { + super(type, objective, time); + } +} + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/package-info.java new file mode 100644 index 00000000..105f7b59 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * Abstractions for objective-based flow programming of data plane without + * requiring device pipeline structure awareness. This subsystem is + * experimental and its interfaces will change in the upcoming release. + */ +package org.onosproject.net.flowobjective;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java new file mode 100644 index 00000000..546a4513 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java @@ -0,0 +1,229 @@ +/* + * 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.group; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import org.onosproject.core.GroupId; +import org.onosproject.net.DeviceId; + +/** + * ONOS implementation of default group that is stored in the system. + */ +public class DefaultGroup extends DefaultGroupDescription + implements Group, StoredGroupEntry { + + private GroupState state; + private boolean isGroupStateAddedFirstTime; + private long life; + private long packets; + private long bytes; + private long referenceCount; + private GroupId id; + + /** + * Initializes default values. + * + * @param newId group id for new group + */ + private void initialize(GroupId newId) { + id = newId; + state = GroupState.PENDING_ADD; + life = 0; + packets = 0; + bytes = 0; + referenceCount = 0; + } + + /** + * Default group object constructor with the parameters. + * + * @param id group identifier + * @param groupDesc group description parameters + */ + public DefaultGroup(GroupId id, GroupDescription groupDesc) { + super(groupDesc); + initialize(id); + } + + /** + * Default group object constructor with the available information + * from data plane. + * + * @param id group identifier + * @param deviceId device identifier + * @param type type of the group + * @param buckets immutable list of group bucket + */ + public DefaultGroup(GroupId id, + DeviceId deviceId, + GroupDescription.Type type, + GroupBuckets buckets) { + super(deviceId, type, buckets); + initialize(id); + } + + /** + * Returns group identifier associated with a group object. + * + * @return GroupId Group Identifier + */ + @Override + public GroupId id() { + return this.id; + } + + /** + * Returns current state of a group object. + * + * @return GroupState Group State + */ + @Override + public GroupState state() { + return this.state; + } + + /** + * Returns the number of milliseconds this group has been alive. + * + * @return number of millis + */ + @Override + public long life() { + return this.life; + } + + /** + * Returns the number of packets processed by this group. + * + * @return number of packets + */ + @Override + public long packets() { + return this.packets; + } + + /** + * Returns the number of bytes processed by this group. + * + * @return number of bytes + */ + @Override + public long bytes() { + return this.bytes; + } + + /** + * Sets the new state for this entry. + * + * @param newState new group entry state. + */ + @Override + public void setState(Group.GroupState newState) { + this.state = newState; + } + + /** + * Sets how long this entry has been entered in the system. + * + * @param life epoch time + */ + @Override + public void setLife(long life) { + this.life = life; + } + + /** + * Sets number of packets processed by this group entry. + * + * @param packets a long value + */ + @Override + public void setPackets(long packets) { + this.packets = packets; + } + + /** + * Sets number of bytes processed by this group entry. + * + * @param bytes a long value + */ + @Override + public void setBytes(long bytes) { + this.bytes = bytes; + } + + @Override + public void setReferenceCount(long referenceCount) { + this.referenceCount = referenceCount; + } + + @Override + public long referenceCount() { + return referenceCount; + } + + /* + * The deviceId, type and buckets are used for hash. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public int hashCode() { + return super.hashCode() + Objects.hash(id); + } + + /* + * The deviceId, groupId, type and buckets should be same. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultGroup) { + DefaultGroup that = (DefaultGroup) obj; + return super.equals(obj) && + Objects.equals(id, that.id); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("description", super.toString()) + .add("groupid", id) + .add("state", state) + .toString(); + } + + @Override + public void setIsGroupStateAddedFirstTime(boolean isGroupStateAddedFirstTime) { + this.isGroupStateAddedFirstTime = isGroupStateAddedFirstTime; + } + + @Override + public boolean isGroupStateAddedFirstTime() { + return isGroupStateAddedFirstTime; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java new file mode 100644 index 00000000..6efd3e79 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java @@ -0,0 +1,252 @@ +/* + * 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.group; + +import org.onosproject.core.GroupId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.Instruction; + +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Group bucket implementation. A group bucket is collection of + * instructions that can be performed on a traffic flow. A select + * Group can have one or more Buckets where traffic will be + * processed by a single bucket in the group, based on device + * specific selection algorithm (e.g. hash on some fields of the + * incoming traffic flows or round robin) and hence can contains + * optional weight field to define the weights among the buckets + * in the group. A failover group bucket is associated with a + * specific port or group that controls its liveness. + */ +public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketEntry { + private final GroupDescription.Type type; + private final TrafficTreatment treatment; + private final short weight; + private final PortNumber watchPort; + private final GroupId watchGroup; + private long packets; + private long bytes; + + /** + * Group bucket constructor with the parameters. + * + * @param type group bucket type + * @param treatment traffic treatment associated with group bucket + * @param weight optional weight associated with group bucket + * @param watchPort port that determines the liveness of group bucket + * @param watchGroup group that determines the liveness of group bucket + */ + private DefaultGroupBucket(GroupDescription.Type type, + TrafficTreatment treatment, + short weight, + PortNumber watchPort, + GroupId watchGroup) { + this.type = type; + this.treatment = checkNotNull(treatment); + this.weight = weight; + this.watchPort = watchPort; + this.watchGroup = watchGroup; + } + + /** + * Creates indirect group bucket. + * + * @param treatment traffic treatment associated with group bucket + * @return indirect group bucket object + */ + public static GroupBucket createIndirectGroupBucket( + TrafficTreatment treatment) { + return new DefaultGroupBucket(GroupDescription.Type.INDIRECT, + treatment, + (short) -1, + null, + null); + } + + /** + * Creates select group bucket with weight as 1. + * + * @param treatment traffic treatment associated with group bucket + * @return select group bucket object + */ + public static GroupBucket createSelectGroupBucket( + TrafficTreatment treatment) { + return new DefaultGroupBucket(GroupDescription.Type.SELECT, + treatment, + (short) 1, + null, + null); + } + + /** + * Creates select group bucket with specified weight. + * + * @param treatment traffic treatment associated with group bucket + * @param weight weight associated with group bucket + * @return select group bucket object + */ + public static GroupBucket createSelectGroupBucket( + TrafficTreatment treatment, + short weight) { + if (weight == 0) { + return null; + } + + return new DefaultGroupBucket(GroupDescription.Type.SELECT, + treatment, + weight, + null, + null); + } + + /** + * Creates failover group bucket with watchport or watchgroup. + * + * @param treatment traffic treatment associated with group bucket + * @param watchPort port that determines the liveness of group bucket + * @param watchGroup group that determines the liveness of group bucket + * @return failover group bucket object + */ + public static GroupBucket createFailoverGroupBucket( + TrafficTreatment treatment, + PortNumber watchPort, + GroupId watchGroup) { + checkArgument(((watchPort != null) || (watchGroup != null))); + return new DefaultGroupBucket(GroupDescription.Type.FAILOVER, + treatment, + (short) -1, + watchPort, + watchGroup); + } + + @Override + public GroupDescription.Type type() { + return this.type; + } + + /** + * Returns list of Traffic instructions that are part of the bucket. + * + * @return TrafficTreatment Traffic instruction list + */ + @Override + public TrafficTreatment treatment() { + return treatment; + } + + /** + * Returns weight of select group bucket. + * + * @return short weight associated with a bucket + */ + @Override + public short weight() { + return weight; + } + + /** + * Returns port number used for liveness detection for a + * failover bucket. + * + * @return PortNumber port number used for liveness detection + */ + @Override + public PortNumber watchPort() { + return watchPort; + } + + /** + * Returns group identifier used for liveness detection for a + * failover bucket. + * + * @return GroupId group identifier to be used for liveness detection + */ + @Override + public GroupId watchGroup() { + return watchGroup; + } + + /* + * The type and treatment can change on a given bucket + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public int hashCode() { + return Objects.hash(type, treatment); + } + + /* + * The priority and statistics can change on a given treatment and selector + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultGroupBucket) { + DefaultGroupBucket that = (DefaultGroupBucket) obj; + List<Instruction> myInstructions = this.treatment.allInstructions(); + List<Instruction> theirInstructions = that.treatment.allInstructions(); + + return Objects.equals(type, that.type) && + myInstructions.containsAll(theirInstructions) && + theirInstructions.containsAll(myInstructions); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("type", type) + .add("treatment", treatment) + .add("packets", packets) + .add("bytes", bytes) + .toString(); + } + + @Override + public long packets() { + return packets; + } + + @Override + public long bytes() { + return bytes; + } + + @Override + public void setPackets(long packets) { + this.packets = packets; + } + + @Override + public void setBytes(long bytes) { + this.bytes = bytes; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java new file mode 100644 index 00000000..1580d835 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java @@ -0,0 +1,204 @@ +/* + * 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.group; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +/** + * Default implementation of group description interface. + */ +public class DefaultGroupDescription implements GroupDescription { + private final GroupDescription.Type type; + private final GroupBuckets buckets; + private final GroupKey appCookie; + private final ApplicationId appId; + private final DeviceId deviceId; + private final Integer givenGroupId; + + /** + * Constructor to be used by north bound applications. + * NOTE: The caller of this subsystem MUST ensure the appCookie + * provided in this API is immutable. + * NOTE: The caller may choose to pass in 'null' for the groupId. This is + * the typical case, where the caller allows the group subsystem to choose + * the groupId in a globally unique way. If the caller passes in the groupId, + * the caller MUST ensure that the id is globally unique (not just unique + * per device). + * + * @param deviceId device identifier + * @param type type of the group + * @param buckets immutable list of group bucket + * @param appCookie immutable application cookie of type DefaultGroupKey + * to be associated with the group + * @param groupId group identifier + * @param appId application id + */ + public DefaultGroupDescription(DeviceId deviceId, + GroupDescription.Type type, + GroupBuckets buckets, + GroupKey appCookie, + Integer groupId, + ApplicationId appId) { + this.type = checkNotNull(type); + this.deviceId = checkNotNull(deviceId); + this.buckets = checkNotNull(buckets); + this.appCookie = appCookie; + this.givenGroupId = groupId; + this.appId = appId; + } + + /** + * Constructor to be used by group subsystem internal components. + * Creates group description object from another object of same type. + * + * @param groupDesc group description object + * + */ + public DefaultGroupDescription(GroupDescription groupDesc) { + this.type = groupDesc.type(); + this.deviceId = groupDesc.deviceId(); + this.buckets = groupDesc.buckets(); + this.appCookie = groupDesc.appCookie(); + this.appId = groupDesc.appId(); + this.givenGroupId = groupDesc.givenGroupId(); + } + + /** + * Constructor to be used by group subsystem internal components. + * Creates group description object from the information retrieved + * from data plane. + * + * @param deviceId device identifier + * @param type type of the group + * @param buckets immutable list of group bucket + * + */ + public DefaultGroupDescription(DeviceId deviceId, + GroupDescription.Type type, + GroupBuckets buckets) { + this(deviceId, type, buckets, null, null, null); + } + + /** + * Returns type of a group object. + * + * @return GroupType group type + */ + @Override + public GroupDescription.Type type() { + return this.type; + } + + /** + * Returns device identifier on which this group object is created. + * + * @return DeviceId device identifier + */ + @Override + public DeviceId deviceId() { + return this.deviceId; + } + + /** + * Returns application identifier that has created this group object. + * + * @return ApplicationId application identifier + */ + @Override + public ApplicationId appId() { + return this.appId; + } + + /** + * Returns application cookie associated with a group object. + * + * @return GroupKey application cookie + */ + @Override + public GroupKey appCookie() { + return this.appCookie; + } + + /** + * Returns group buckets of a group. + * + * @return GroupBuckets immutable list of group bucket + */ + @Override + public GroupBuckets buckets() { + return this.buckets; + } + + /** + * Returns groupId passed in by application. + * + * @return Integer group Id passed in by caller. May be null if caller passed + * in null during GroupDescription creation. + */ + @Override + public Integer givenGroupId() { + return this.givenGroupId; + } + + @Override + /* + * The deviceId, type and buckets are used for hash. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public int hashCode() { + return Objects.hash(deviceId, type, buckets); + } + + @Override + /* + * The deviceId, type and buckets should be same. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultGroupDescription) { + DefaultGroupDescription that = (DefaultGroupDescription) obj; + return Objects.equals(deviceId, that.deviceId) && + Objects.equals(type, that.type) && + Objects.equals(buckets, that.buckets); + + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("deviceId", deviceId) + .add("type", type) + .add("buckets", buckets) + .add("appId", appId) + .add("givenGroupId", givenGroupId) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java new file mode 100644 index 00000000..7f00ae70 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java @@ -0,0 +1,55 @@ +/* + * 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.group; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Arrays; + +/** + * Default implementation of group key interface. + */ +public class DefaultGroupKey implements GroupKey { + + private final byte[] key; + + public DefaultGroupKey(byte[] key) { + this.key = checkNotNull(key); + } + + @Override + public byte[] key() { + return key; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DefaultGroupKey)) { + return false; + } + DefaultGroupKey that = (DefaultGroupKey) o; + return (Arrays.equals(this.key, that.key)); + } + + @Override + public int hashCode() { + return Arrays.hashCode(this.key); + } + +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/Group.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/Group.java new file mode 100644 index 00000000..54407752 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/Group.java @@ -0,0 +1,99 @@ +/* + * 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.group; + +import org.onosproject.core.GroupId; + +/** + * ONOS representation of group that is stored in the system. + */ +public interface Group extends GroupDescription { + /** + * State of the group object in ONOS. + */ + enum GroupState { + /** + * Group create request is queued as group AUDIT is in progress. + */ + WAITING_AUDIT_COMPLETE, + /** + * Group create request is processed by ONOS and not yet + * received the confirmation from data plane. + */ + PENDING_ADD, + /** + * Group is missing in data plane and retrying GROUP ADD request. + */ + PENDING_ADD_RETRY, + /** + * Group is created in the data plane. + */ + ADDED, + /** + * Group update request is processed by ONOS and not + * received the confirmation from data plane post which + * state moves to ADDED state. + */ + PENDING_UPDATE, + /** + * Group delete request is processed by ONOS and not + * received the confirmation from data plane. + */ + PENDING_DELETE + } + + /** + * Returns group identifier associated with a group object. + * + * @return GroupId Group Identifier + */ + GroupId id(); + + /** + * Returns current state of a group object. + * + * @return GroupState Group State + */ + GroupState state(); + + /** + * Returns the number of milliseconds this group has been alive. + * + * @return number of millis + */ + long life(); + + /** + * Returns the number of packets processed by this group. + * + * @return number of packets + */ + long packets(); + + /** + * Returns the number of bytes processed by this group. + * + * @return number of bytes + */ + long bytes(); + + /** + * Returns the number of flow rules or other groups reference this group. + * + * @return number of flow rules or other groups pointing to this group + */ + long referenceCount(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java new file mode 100644 index 00000000..a503c154 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java @@ -0,0 +1,80 @@ +/* + * 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.group; + +import org.onosproject.core.GroupId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.TrafficTreatment; + +/** + * Group Bucket definition. A default group Bucket is collection of + * Instructions that can be performed on a traffic flow. A failover + * group bucket is associated with a specific port or group that + * controls its liveness. A select group bucket contains optional + * weight field to define the weights among the buckets in the group. + */ +public interface GroupBucket { + /** + * Returns group type of the bucket. + * + * @return GroupType group type + */ + GroupDescription.Type type(); + + /** + * Returns list of Traffic instructions that are part of the bucket. + * + * @return TrafficTreatment traffic instruction list + */ + TrafficTreatment treatment(); + + /** + * Returns weight of select group bucket. + * + * @return short weight associated with a bucket + */ + short weight(); + + /** + * Returns port number used for liveness detection for a + * failover bucket. + * + * @return PortNumber port number used for liveness detection + */ + PortNumber watchPort(); + + /** + * Returns group identifier used for liveness detection for a + * failover bucket. + * + * @return GroupId group identifier to be used for liveness detection + */ + GroupId watchGroup(); + + /** + * Returns the number of packets processed by this group bucket. + * + * @return number of packets + */ + long packets(); + + /** + * Returns the number of bytes processed by this group bucket. + * + * @return number of bytes + */ + long bytes(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java new file mode 100644 index 00000000..c0b5e5c6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java @@ -0,0 +1,76 @@ +/* + * 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.group; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; + +import com.google.common.collect.ImmutableList; + +/** + * Immutable collection of group bucket. + */ +public final class GroupBuckets { + private final List<GroupBucket> buckets; + + /** + * Creates a immutable list of group bucket. + * + * @param buckets list of group bucket + */ + public GroupBuckets(List<GroupBucket> buckets) { + this.buckets = ImmutableList.copyOf(checkNotNull(buckets)); + } + + /** + * Returns immutable list of group buckets. + * + * @return list of group bucket + */ + public List<GroupBucket> buckets() { + return buckets; + } + + @Override + public int hashCode() { + int result = 17; + int combinedHash = 0; + for (GroupBucket bucket:buckets) { + combinedHash = combinedHash + bucket.hashCode(); + } + result = 31 * result + combinedHash; + + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof GroupBuckets) { + return (this.buckets.containsAll(((GroupBuckets) obj).buckets) && + ((GroupBuckets) obj).buckets.containsAll(this.buckets)); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("buckets", buckets.toString()) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java new file mode 100644 index 00000000..671b9a54 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java @@ -0,0 +1,91 @@ +/* + * 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.group; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +/** + * ONOS representation of group description that is used to create + * a group. It contains immutable properties of a ONOS group construct + * such as "type", "DeviceId", "appCookie", "appId" and "buckets" + */ +public interface GroupDescription { + /** + * Types of the group supported by ONOS. + */ + enum Type { + /** + * Load-balancing among different buckets in a group. + */ + SELECT, + /** + * Single Bucket Group. + */ + INDIRECT, + /** + * Multicast to all buckets in a group. + */ + ALL, + /** + * Uses the first live bucket in a group. + */ + FAILOVER + } + + /** + * Returns type of a group object. + * + * @return GroupType group type + */ + Type type(); + + /** + * Returns device identifier on which this group object is created. + * + * @return DeviceId device identifier + */ + DeviceId deviceId(); + + /** + * Returns application identifier that has created this group object. + * + * @return ApplicationId application identifier + */ + ApplicationId appId(); + + /** + * Returns application cookie associated with a group object. + * + * @return GroupKey application cookie + */ + GroupKey appCookie(); + + /** + * Returns groupId passed in by caller. + * + * @return Integer group id passed in by caller. May be null if caller + * passed in null to let groupService determin the group id. + */ + Integer givenGroupId(); + + /** + * Returns group buckets of a group. + * + * @return GroupBuckets immutable list of group bucket + */ + GroupBuckets buckets(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java new file mode 100644 index 00000000..45fbb3ed --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java @@ -0,0 +1,99 @@ +/* + * 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.group; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes group events. + */ +public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { + + /** + * Type of flow rule events. + */ + public enum Type { + /** + * Signifies that a new Group has been detected. + */ + GROUP_ADDED, + + /** + * Signifies that a Group has been removed. + */ + GROUP_REMOVED, + + /** + * Signifies that a Group has been updated. + */ + GROUP_UPDATED, + + /** + * Signifies that a request to create Group has failed. + */ + GROUP_ADD_FAILED, + + /** + * Signifies that a request to remove Group has failed. + */ + GROUP_REMOVE_FAILED, + + /** + * Signifies that a request to update Group has failed. + */ + GROUP_UPDATE_FAILED, + + // internal event between Manager <-> Store + + /* + * Signifies that a request to create Group has been added to the store. + */ + GROUP_ADD_REQUESTED, + /* + * Signifies that a request to update Group has been added to the store. + */ + GROUP_UPDATE_REQUESTED, + /* + * Signifies that a request to delete Group has been added to the store. + */ + GROUP_REMOVE_REQUESTED, + + + } + + /** + * Creates an event of a given type and for the specified Group and the + * current time. + * + * @param type Group event type + * @param group event subject + */ + public GroupEvent(Type type, Group group) { + super(type, group); + } + + /** + * Creates an event of a given type and for the specified Group and time. + * + * @param type Group event type + * @param group event subject + * @param time occurrence time + */ + public GroupEvent(Type type, Group group, long time) { + super(type, group, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupKey.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupKey.java new file mode 100644 index 00000000..a63bee27 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupKey.java @@ -0,0 +1,31 @@ +/* + * 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.group; + +/** + * Representation of generalized Key that would be used to store + * groups in < Key, Value > store. This key uses a generic + * byte array so that applications can associate their groups with + * any of their data by translating it into a byte array. + */ +public interface GroupKey { + /** + * Returns the byte representation of key. + * + * @return byte array + */ + byte[] key(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupListener.java new file mode 100644 index 00000000..349ce6a7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupListener.java @@ -0,0 +1,24 @@ +/* + * 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.group; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving Group related events. + */ +public interface GroupListener extends EventListener<GroupEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java new file mode 100644 index 00000000..e4173b30 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java @@ -0,0 +1,181 @@ +/* + * 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.group; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import org.onosproject.core.GroupId; + +/** + * Group operation definition to be used between core and provider + * layers of group subsystem. + * + */ +public final class GroupOperation { + private final Type opType; + private final GroupId groupId; + private final GroupDescription.Type groupType; + private final GroupBuckets buckets; + + public enum Type { + /** + * Create a group in a device with the specified parameters. + */ + ADD, + /** + * Modify a group in a device with the specified parameters. + */ + MODIFY, + /** + * Delete a specified group. + */ + DELETE + } + + /** + * Group operation constructor with the parameters. + * + * @param opType group operation type + * @param groupId group Identifier + * @param groupType type of the group + * @param buckets immutable list of group buckets to be part of group + */ + private GroupOperation(Type opType, + GroupId groupId, + GroupDescription.Type groupType, + GroupBuckets buckets) { + this.opType = checkNotNull(opType); + this.groupId = checkNotNull(groupId); + this.groupType = checkNotNull(groupType); + this.buckets = buckets; + } + + /** + * Creates ADD group operation object. + * + * @param groupId group Identifier + * @param groupType type of the group + * @param buckets immutable list of group buckets to be part of group + * @return add group operation object + */ + public static GroupOperation createAddGroupOperation(GroupId groupId, + GroupDescription.Type groupType, + GroupBuckets buckets) { + checkNotNull(buckets); + return new GroupOperation(Type.ADD, groupId, groupType, buckets); + } + + /** + * Creates MODIFY group operation object. + * + * @param groupId group Identifier + * @param groupType type of the group + * @param buckets immutable list of group buckets to be part of group + * @return modify group operation object + */ + public static GroupOperation createModifyGroupOperation(GroupId groupId, + GroupDescription.Type groupType, + GroupBuckets buckets) { + checkNotNull(buckets); + return new GroupOperation(Type.MODIFY, groupId, groupType, buckets); + + } + + /** + * Creates DELETE group operation object. + * + * @param groupId group Identifier + * @param groupType type of the group + * @return delete group operation object + */ + public static GroupOperation createDeleteGroupOperation(GroupId groupId, + GroupDescription.Type groupType) { + return new GroupOperation(Type.DELETE, groupId, groupType, null); + + } + + /** + * Returns group operation type. + * + * @return GroupOpType group operation type + */ + public Type opType() { + return this.opType; + } + + /** + * Returns group identifier attribute of the operation. + * + * @return GroupId group identifier + */ + public GroupId groupId() { + return this.groupId; + } + + /** + * Returns group type attribute of the operation. + * + * @return GroupType group type + */ + public GroupDescription.Type groupType() { + return this.groupType; + } + + /** + * Returns group buckets associated with the operation. + * + * @return GroupBuckets group buckets + */ + public GroupBuckets buckets() { + return this.buckets; + } + + @Override + /* + * The deviceId, type and buckets are used for hash. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public int hashCode() { + return (buckets != null) ? Objects.hash(groupId, opType, buckets) : + Objects.hash(groupId, opType); + } + + @Override + /* + * The deviceId, type and buckets should be same. + * + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof GroupOperation) { + GroupOperation that = (GroupOperation) obj; + return Objects.equals(groupId, that.groupId) && + Objects.equals(groupType, that.groupType) && + Objects.equals(opType, that.opType) && + Objects.equals(buckets, that.buckets); + + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java new file mode 100644 index 00000000..bc03628d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java @@ -0,0 +1,50 @@ +/* + * 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.group; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; + +import com.google.common.collect.ImmutableList; + +/** + * Immutable collection of group operation to be used between + * core and provider layers of group subsystem. + * + */ +public final class GroupOperations { + private final List<GroupOperation> operations; + + /** + * Creates a immutable list of group operation. + * + * @param operations list of group operation + */ + public GroupOperations(List<GroupOperation> operations) { + this.operations = ImmutableList.copyOf(checkNotNull(operations)); + } + + /** + * Returns immutable list of group operation. + * + * @return list of group operation + */ + public List<GroupOperation> operations() { + return operations; + } + +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java new file mode 100644 index 00000000..6757e669 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java @@ -0,0 +1,37 @@ +/* + * 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.group; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of group provider. + */ +public interface GroupProvider extends Provider { + + /** + * Performs a batch of group operation in the specified device with the + * specified parameters. + * + * @param deviceId device identifier on which the batch of group + * operations to be executed + * @param groupOps immutable list of group operation + */ + void performGroupOperation(DeviceId deviceId, + GroupOperations groupOps); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderRegistry.java new file mode 100644 index 00000000..d45789db --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * 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.group; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction for a group provider registry. + */ +public interface GroupProviderRegistry + extends ProviderRegistry<GroupProvider, GroupProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java new file mode 100644 index 00000000..076de498 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java @@ -0,0 +1,47 @@ +/* + * 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.group; + +import java.util.Collection; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +/** + * Service through which Group providers can inject information into + * the core. + */ +public interface GroupProviderService extends ProviderService<GroupProvider> { + + /** + * Notifies core if any failure from data plane during group operations. + * + * @param deviceId the device ID + * @param operation offended group operation + */ + void groupOperationFailed(DeviceId deviceId, GroupOperation operation); + + /** + * Pushes the collection of group detected in the data plane along + * with statistics. + * + * @param deviceId device identifier + * @param groupEntries collection of group entries as seen in data plane + */ + void pushGroupMetrics(DeviceId deviceId, + Collection<Group> groupEntries); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupService.java new file mode 100644 index 00000000..4163248f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupService.java @@ -0,0 +1,139 @@ +/* + * 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.group; + +import org.onosproject.core.ApplicationId; +import org.onosproject.event.ListenerService; +import org.onosproject.net.DeviceId; + +/** + * Service for create/update/delete "group" in the devices. + * Flow entries can point to a "group" defined in the devices that enables + * to represent additional methods of forwarding like load-balancing or + * failover among different group of ports or multicast to all ports + * specified in a group. + * "group" can also be used for grouping common actions of different flows, + * so that in some scenarios only one group entry required to be modified + * for all the referencing flow entries instead of modifying all of them. + * + * This implements semantics of a distributed authoritative group store + * where the master copy of the groups lies with the controller and + * the devices hold only the 'cached' copy. + */ +public interface GroupService + extends ListenerService<GroupEvent, GroupListener> { + + /** + * Creates a group in the specified device with the provided buckets. + * This API provides an option for application to associate a cookie + * while creating a group, so that applications can look-up the + * groups based on the cookies. These Groups will be retained by + * the core system and re-applied if any groups found missing in the + * device when it reconnects. This API would immediately return after + * submitting the request locally or to a remote Master controller + * instance. As a response to this API invocation, GROUP_ADDED or + * GROUP_ADD_FAILED notifications would be provided along with cookie + * depending on the result of the operation on the device in the + * data plane. The caller may also use "getGroup" API to get the + * Group object created as part of this request. + * + * @param groupDesc group creation parameters + * + */ + void addGroup(GroupDescription groupDesc); + + /** + * Returns a group object associated to an application cookie. + * + * NOTE1: The presence of group object in the system does not + * guarantee that the "group" is actually created in device. + * GROUP_ADDED notification would confirm the creation of + * this group in data plane. + * + * @param deviceId device identifier + * @param appCookie application cookie to be used for lookup + * @return group associated with the application cookie or + * NULL if Group is not found for the provided cookie + */ + Group getGroup(DeviceId deviceId, GroupKey appCookie); + + /** + * Appends buckets to existing group. The caller can optionally + * associate a new cookie during this updation. GROUP_UPDATED or + * GROUP_UPDATE_FAILED notifications would be provided along with + * cookie depending on the result of the operation on the device. + * + * @param deviceId device identifier + * @param oldCookie cookie to be used to retrieve the existing group + * @param buckets immutable list of group bucket to be added + * @param newCookie immutable cookie to be used post update operation + * @param appId Application Id + */ + void addBucketsToGroup(DeviceId deviceId, + GroupKey oldCookie, + GroupBuckets buckets, + GroupKey newCookie, + ApplicationId appId); + + /** + * Removes buckets from existing group. The caller can optionally + * associate a new cookie during this updation. GROUP_UPDATED or + * GROUP_UPDATE_FAILED notifications would be provided along with + * cookie depending on the result of the operation on the device. + * + * @param deviceId device identifier + * @param oldCookie cookie to be used to retrieve the existing group + * @param buckets immutable list of group bucket to be removed + * @param newCookie immutable cookie to be used post update operation + * @param appId Application Id + */ + void removeBucketsFromGroup(DeviceId deviceId, + GroupKey oldCookie, + GroupBuckets buckets, + GroupKey newCookie, + ApplicationId appId); + + /** + * Deletes a group associated to an application cookie. + * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be + * provided along with cookie depending on the result of the + * operation on the device. + * + * @param deviceId device identifier + * @param appCookie application cookie to be used for lookup + * @param appId Application Id + */ + void removeGroup(DeviceId deviceId, GroupKey appCookie, ApplicationId appId); + + /** + * Retrieves all groups created by an application in the specified device + * as seen by current controller instance. + * + * @param deviceId device identifier + * @param appId application id + * @return collection of immutable group objects created by the application + */ + Iterable<Group> getGroups(DeviceId deviceId, ApplicationId appId); + + /** + * Returns all groups associated with the given device. + * + * @param deviceId device ID to get groups for + * @return iterable of device's groups + */ + Iterable<Group> getGroups(DeviceId deviceId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStore.java new file mode 100644 index 00000000..8b6df5d9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStore.java @@ -0,0 +1,175 @@ +/* + * 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.group; + +import java.util.Collection; + +import org.onosproject.core.GroupId; +import org.onosproject.net.DeviceId; +import org.onosproject.store.Store; + +/** + * Manages inventory of groups per device; not intended for direct use. + */ +public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { + + enum UpdateType { + /** + * Modify existing group entry by adding provided information. + */ + ADD, + /** + * Modify existing group by removing provided information from it. + */ + REMOVE + } + + /** + * Returns the number of groups for the specified device in the store. + * + * @param deviceId the device ID + * @return number of groups for the specified device + */ + int getGroupCount(DeviceId deviceId); + + /** + * Returns the groups associated with a device. + * + * @param deviceId the device ID + * @return the group entries + */ + Iterable<Group> getGroups(DeviceId deviceId); + + /** + * Returns the stored group entry. + * + * @param deviceId the device ID + * @param appCookie the group key + * @return a group associated with the key + */ + Group getGroup(DeviceId deviceId, GroupKey appCookie); + + /** + * Returns the stored group entry for an id. + * + * @param deviceId the device ID + * @param groupId the group identifier + * @return a group associated with the key + */ + Group getGroup(DeviceId deviceId, GroupId groupId); + + /** + * Stores a new group entry using the information from group description. + * + * @param groupDesc group description to be used to store group entry + */ + void storeGroupDescription(GroupDescription groupDesc); + + /** + * Updates the existing group entry with the information + * from group description. + * + * @param deviceId the device ID + * @param oldAppCookie the current group key + * @param type update type + * @param newBuckets group buckets for updates + * @param newAppCookie optional new group key + */ + void updateGroupDescription(DeviceId deviceId, + GroupKey oldAppCookie, + UpdateType type, + GroupBuckets newBuckets, + GroupKey newAppCookie); + + /** + * Triggers deleting the existing group entry. + * + * @param deviceId the device ID + * @param appCookie the group key + */ + void deleteGroupDescription(DeviceId deviceId, + GroupKey appCookie); + + /** + * Stores a new group entry, or updates an existing entry. + * + * @param group group entry + */ + void addOrUpdateGroupEntry(Group group); + + /** + * Removes the group entry from store. + * + * @param group group entry + */ + void removeGroupEntry(Group group); + + /** + * A group entry that is present in switch but not in the store. + * + * @param group group entry + */ + void addOrUpdateExtraneousGroupEntry(Group group); + + /** + * Remove the group entry from extraneous database. + * + * @param group group entry + */ + void removeExtraneousGroupEntry(Group group); + + /** + * Returns the extraneous groups associated with a device. + * + * @param deviceId the device ID + * + * @return the extraneous group entries + */ + Iterable<Group> getExtraneousGroups(DeviceId deviceId); + + /** + * Indicates the first group audit is completed. + * + * @param deviceId the device ID + * @param completed initial audit status + */ + void deviceInitialAuditCompleted(DeviceId deviceId, boolean completed); + + /** + * Retrieves the initial group audit status for a device. + * + * @param deviceId the device ID + * + * @return initial group audit status + */ + boolean deviceInitialAuditStatus(DeviceId deviceId); + + /** + * Indicates the group operations failed. + * + * @param deviceId the device ID + * @param operation the group operation failed + */ + void groupOperationFailed(DeviceId deviceId, GroupOperation operation); + + /** + * Submits the group metrics to store for a given device ID. + * + * @param deviceId the device ID + * @param groupEntries the group entries as received from southbound + */ + void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStoreDelegate.java new file mode 100644 index 00000000..308ebb1c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/GroupStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * 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.group; + +import org.onosproject.store.StoreDelegate; + +/** + * Group store delegate abstraction. + */ +public interface GroupStoreDelegate extends StoreDelegate<GroupEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java new file mode 100644 index 00000000..131875b3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupBucketEntry.java @@ -0,0 +1,37 @@ +/* + * 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.group; + +/** + * Generic group bucket entry representation that is stored in a + * group object. A group bucket entry provides additional info of + * group bucket like statistics...etc + */ +public interface StoredGroupBucketEntry extends GroupBucket { + /** + * Sets number of packets processed by this group bucket entry. + * + * @param packets a long value + */ + void setPackets(long packets); + + /** + * Sets number of bytes processed by this group bucket entry. + * + * @param bytes a long value + */ + void setBytes(long bytes); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupEntry.java new file mode 100644 index 00000000..47d36122 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/StoredGroupEntry.java @@ -0,0 +1,75 @@ +/* + * 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.group; + +/** + * Interface that defines set methods for a group entry + * that is stored in the system. + */ +public interface StoredGroupEntry extends Group { + + /** + * Sets the new state for this entry. + * + * @param newState new group entry state. + */ + void setState(Group.GroupState newState); + + /** + * Sets if group has transitioned to ADDED state for the first time. + * This is to differentiate state transitions "from PENDING_ADD to ADDED" + * and "from PENDING_UPDATE to ADDED". For internal use only. + * + * @param isGroupAddedFirstTime true if group moves to ADDED state + * for the first time. + */ + void setIsGroupStateAddedFirstTime(boolean isGroupAddedFirstTime); + + /** + * Returns the isGroupStateAddedFirstTime value. For internal use only. + * + * @return isGroupStateAddedFirstTime value + */ + boolean isGroupStateAddedFirstTime(); + + /** + * Sets how long this entry has been entered in the system. + * + * @param life epoch time + */ + void setLife(long life); + + /** + * Sets number of packets processed by this group entry. + * + * @param packets a long value + */ + void setPackets(long packets); + + /** + * Sets number of bytes processed by this group entry. + * + * @param bytes a long value + */ + void setBytes(long bytes); + + /** + * Sets number of flow rules or groups referencing this group entry. + * + * @param referenceCount reference count + */ + void setReferenceCount(long referenceCount); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/package-info.java new file mode 100644 index 00000000..26528c48 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Abstractions for interacting with device port groups. + */ +package org.onosproject.net.group;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java new file mode 100644 index 00000000..1f05197a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java @@ -0,0 +1,122 @@ +/* + * Copyright 2014 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.host; + +import java.util.Collections; +import java.util.Set; + +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.HostLocation; +import org.onosproject.net.SparseAnnotations; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; + +import com.google.common.collect.ImmutableSet; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of an immutable host description. + */ +public class DefaultHostDescription extends AbstractDescription + implements HostDescription { + + private final MacAddress mac; + private final VlanId vlan; + private final HostLocation location; + private final Set<IpAddress> ip; + + /** + * Creates a host description using the supplied information. + * + * @param mac host MAC address + * @param vlan host VLAN identifier + * @param location host location + * @param annotations optional key/value annotations map + */ + public DefaultHostDescription(MacAddress mac, VlanId vlan, + HostLocation location, + SparseAnnotations... annotations) { + this(mac, vlan, location, Collections.<IpAddress>emptySet(), + annotations); + } + + /** + * Creates a host description using the supplied information. + * + * @param mac host MAC address + * @param vlan host VLAN identifier + * @param location host location + * @param ip host IP address + * @param annotations optional key/value annotations map + */ + public DefaultHostDescription(MacAddress mac, VlanId vlan, + HostLocation location, IpAddress ip, + SparseAnnotations... annotations) { + this(mac, vlan, location, ImmutableSet.of(ip), annotations); + } + + /** + * Creates a host description using the supplied information. + * + * @param mac host MAC address + * @param vlan host VLAN identifier + * @param location host location + * @param ip host IP addresses + * @param annotations optional key/value annotations map + */ + public DefaultHostDescription(MacAddress mac, VlanId vlan, + HostLocation location, Set<IpAddress> ip, + SparseAnnotations... annotations) { + super(annotations); + this.mac = mac; + this.vlan = vlan; + this.location = location; + this.ip = ImmutableSet.copyOf(ip); + } + + @Override + public MacAddress hwAddress() { + return mac; + } + + @Override + public VlanId vlan() { + return vlan; + } + + @Override + public HostLocation location() { + return location; + } + + @Override + public Set<IpAddress> ipAddress() { + return ip; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("mac", mac) + .add("vlan", vlan) + .add("location", location) + .add("ipAddress", ip) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostAdminService.java new file mode 100644 index 00000000..d620fedb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostAdminService.java @@ -0,0 +1,66 @@ +/* + * Copyright 2014-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.host; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.HostId; + +/** + * Service for administering the inventory of end-station hosts. + */ +public interface HostAdminService extends HostService { + + /** + * Removes the end-station host with the specified identifier. + * + * @param hostId host identifier + */ + void removeHost(HostId hostId); + + /** + * Binds IP and MAC addresses to the given connection point. + * <p> + * The addresses are added to the set of addresses already bound to the + * connection point. + * + * @param addresses address object containing addresses to add and the port + * to add them to + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void bindAddressesToPort(PortAddresses addresses); + + /** + * Removes the addresses contained in the given PortAddresses object from + * the set of addresses bound to the port. + * + * @param portAddresses set of addresses to remove and port to remove them + * from + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void unbindAddressesFromPort(PortAddresses portAddresses); + + /** + * Removes all address information for the given connection point. + * + * @param connectPoint the connection point to remove address information + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void clearAddresses(ConnectPoint connectPoint); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostDescription.java new file mode 100644 index 00000000..14c6f7ad --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostDescription.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014 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.host; + +import java.util.Set; + +import org.onosproject.net.Description; +import org.onosproject.net.HostLocation; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; + +/** + * Information describing host and its location. + */ +public interface HostDescription extends Description { + + /** + * Returns the MAC address associated with this host (NIC). + * + * @return the MAC address of this host + */ + MacAddress hwAddress(); + + /** + * Returns the VLAN associated with this host. + * + * @return the VLAN ID value + */ + VlanId vlan(); + + /** + * Returns the location of the host on the network edge. + * + * @return the network location + */ + HostLocation location(); + + /** + * Returns the IP address associated with this host's MAC. + * + * @return host IP address + */ + Set<IpAddress> ipAddress(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java new file mode 100644 index 00000000..98329df0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.Host; + +/** + * Describes end-station host event. + */ +public class HostEvent extends AbstractEvent<HostEvent.Type, Host> { + + /** + * Type of host events. + */ + public enum Type { + /** + * Signifies that a new host has been detected. + */ + HOST_ADDED, + + /** + * Signifies that a host has been removed. + */ + HOST_REMOVED, + + /** + * Signifies that host data changed, e.g. IP address + */ + HOST_UPDATED, + + /** + * Signifies that a host location has changed. + */ + HOST_MOVED + } + + /** + * Creates an event of a given type and for the specified host and the + * current time. + * + * @param type host event type + * @param host event host subject + */ + public HostEvent(Type type, Host host) { + super(type, host); + } + + /** + * Creates an event of a given type and for the specified host and time. + * + * @param type host event type + * @param host event host subject + * @param time occurrence time + */ + public HostEvent(Type type, Host host, long time) { + super(type, host, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostListener.java new file mode 100644 index 00000000..2eef7592 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving end-station host related events. + */ +public interface HostListener extends EventListener<HostEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProvider.java new file mode 100644 index 00000000..0270996b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.net.Host; +import org.onosproject.net.provider.Provider; + +/** + * Provider of information about hosts and their location on the network. + */ +public interface HostProvider extends Provider { + + /** + * Triggers an asynchronous probe of the specified host, intended to + * determine whether the host is present or not. An indirect result of this + * should be invocation of {@link org.onosproject.net.host.HostProviderService#hostDetected} + * or {@link org.onosproject.net.host.HostProviderService#hostVanished} + * at some later point in time. + * + * @param host host to probe + */ + void triggerProbe(Host host); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderRegistry.java new file mode 100644 index 00000000..8ab600c2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of a host provider registry. + */ +public interface HostProviderRegistry + extends ProviderRegistry<HostProvider, HostProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java new file mode 100644 index 00000000..8678a297 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostProviderService.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.net.HostId; +import org.onosproject.net.provider.ProviderService; + +/** + * Means of conveying host information to the core. + */ +public interface HostProviderService extends ProviderService<HostProvider> { + + /** + * Notifies the core when a host has been detected on a network along with + * information that identifies the host location. + * + * @param hostId id of the host that been detected + * @param hostDescription description of host and its location + */ + void hostDetected(HostId hostId, HostDescription hostDescription); + + /** + * Notifies the core when a host is no longer detected on a network. + * + * @param hostId id of the host that vanished + */ + void hostVanished(HostId hostId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostService.java new file mode 100644 index 00000000..be114f05 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostService.java @@ -0,0 +1,146 @@ +/* + * Copyright 2014 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.host; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.event.ListenerService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; + +import java.util.Set; + +/** + * Service for interacting with the inventory of end-station hosts. + */ +public interface HostService + extends ListenerService<HostEvent, HostListener> { + + /** + * Returns the number of end-station hosts known to the system. + * + * @return number of end-station hosts + */ + int getHostCount(); + + /** + * Returns a collection of all end-station hosts. + * + * @return collection of hosts + */ + Iterable<Host> getHosts(); + + /** + * Returns the host with the specified identifier. + * + * @param hostId host identifier + * @return host or null if one with the given identifier is not known + */ + Host getHost(HostId hostId); + + /** + * Returns the set of hosts that belong to the specified VLAN. + * + * @param vlanId vlan identifier + * @return set of hosts in the given vlan id + */ + Set<Host> getHostsByVlan(VlanId vlanId); + + /** + * Returns the set of hosts that have the specified MAC address. + * + * @param mac mac address + * @return set of hosts with the given mac + */ + Set<Host> getHostsByMac(MacAddress mac); + + /** + * Returns the set of hosts that have the specified IP address. + * + * @param ip ip address + * @return set of hosts with the given IP + */ + Set<Host> getHostsByIp(IpAddress ip); + + // TODO: consider adding Host getHostByIp(IpAddress ip, VlanId vlan); + + /** + * Returns the set of hosts whose most recent location is the specified + * connection point. + * + * @param connectPoint connection point + * @return set of hosts connected to the connection point + */ + Set<Host> getConnectedHosts(ConnectPoint connectPoint); + + /** + * Returns the set of hosts whose most recent location is the specified + * infrastructure device. + * + * @param deviceId device identifier + * @return set of hosts connected to the device + */ + Set<Host> getConnectedHosts(DeviceId deviceId); + + /** + * Requests the host service to monitor hosts with the given IP address and + * notify listeners of changes. + * + * @param ip IP address of the host to monitor + */ + void startMonitoringIp(IpAddress ip); + + /** + * Stops the host service from monitoring an IP address. + * + * @param ip IP address to stop monitoring + */ + // TODO clients can cancel other client's requests + void stopMonitoringIp(IpAddress ip); + + /** + * Requests the host service to resolve the MAC address for the given IP + * address. This will trigger a notification to the host listeners if the MAC + * address is found. + * + * @param ip IP address to find the MAC address for + */ + void requestMac(IpAddress ip); + + /** + * Returns the addresses information for all connection points. + * + * @return the set of address bindings for all connection points + * @deprecated in Drake release: use InterfaceService instead + */ + @Deprecated + Set<PortAddresses> getAddressBindings(); + + /** + * Retrieves the addresses that have been bound to the given connection + * point. + * + * @param connectPoint the connection point to retrieve address bindings for + * @return addresses bound to the port + * @deprecated in Drake release: use InterfaceService instead + */ + @Deprecated + Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStore.java new file mode 100644 index 00000000..ca11a942 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStore.java @@ -0,0 +1,167 @@ +/* + * Copyright 2014 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.host; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Manages inventory of end-station hosts; not intended for direct use. + */ +public interface HostStore extends Store<HostEvent, HostStoreDelegate> { + + /** + * Creates a new host or updates the existing one based on the specified + * description. + * + * @param providerId provider identification + * @param hostId host identification + * @param hostDescription host description data + * @return appropriate event or null if no change resulted + */ + HostEvent createOrUpdateHost(ProviderId providerId, HostId hostId, + HostDescription hostDescription); + + // FIXME: API to remove only IpAddress is missing + /** + * Removes the specified host from the inventory. + * + * @param hostId host identification + * @return remove event or null if host was not found + */ + HostEvent removeHost(HostId hostId); + + /** + * Returns the number of hosts in the store. + * + * @return host count + */ + int getHostCount(); + + /** + * Returns a collection of all hosts in the store. + * + * @return iterable collection of all hosts + */ + Iterable<Host> getHosts(); + + /** + * Returns the host with the specified identifer. + * + * @param hostId host identification + * @return host or null if not found + */ + Host getHost(HostId hostId); + + /** + * Returns the set of all hosts within the specified VLAN. + * + * @param vlanId vlan id + * @return set of hosts in the vlan + */ + Set<Host> getHosts(VlanId vlanId); + + /** + * Returns the set of hosts with the specified MAC address. + * + * @param mac mac address + * @return set of hosts with the given mac + */ + Set<Host> getHosts(MacAddress mac); + + /** + * Returns the set of hosts with the specified IP address. + * + * @param ip ip address + * @return set of hosts with the given IP + */ + Set<Host> getHosts(IpAddress ip); + + /** + * Returns the set of hosts whose location falls on the given connection point. + * + * @param connectPoint connection point + * @return set of hosts + */ + Set<Host> getConnectedHosts(ConnectPoint connectPoint); + + /** + * Returns the set of hosts whose location falls on the given device. + * + * @param deviceId infrastructure device identifier + * @return set of hosts + */ + Set<Host> getConnectedHosts(DeviceId deviceId); + + /** + * Updates the address information for a given port. The given address + * information is added to any previously held information for the port. + * + * @param addresses the port and address information + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void updateAddressBindings(PortAddresses addresses); + + /** + * Removes the given addresses from the set of address information held for + * a port. + * + * @param addresses the port and address information + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void removeAddressBindings(PortAddresses addresses); + + /** + * Removes any previously stored address information for a given connection + * point. + * + * @param connectPoint the connection point + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + void clearAddressBindings(ConnectPoint connectPoint); + + /** + * Returns the address bindings stored for all connection points. + * + * @return the set of address bindings + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + Set<PortAddresses> getAddressBindings(); + + /** + * Returns the address bindings for a particular connection point. + * + * @param connectPoint the connection point to return address information + * for + * @return address information for the connection point + * @deprecated in Drake release: address info now stored in InterfaceService + */ + @Deprecated + Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStoreDelegate.java new file mode 100644 index 00000000..efc84232 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.host; + +import org.onosproject.store.StoreDelegate; + +/** + * Infrastructure link store delegate abstraction. + */ +public interface HostStoreDelegate extends StoreDelegate<HostEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java new file mode 100644 index 00000000..2f53df50 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java @@ -0,0 +1,192 @@ +/* + * Copyright 2014 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.host; + +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a single IP address information on an interface. + * + * TODO: + * - Add computation for the default broadcast address if it is not + * specified + * - Add explicit checks that each IP address or prefix belong to the + * same IP version: IPv4/IPv6. + * - Inside the copy constructor we should use copy constructors for each + * field + */ +public class InterfaceIpAddress { + private final IpAddress ipAddress; + private final IpPrefix subnetAddress; + private final IpAddress broadcastAddress; + private final IpAddress peerAddress; + + /** + * Copy constructor. + * + * @param other the object to copy from + */ + public InterfaceIpAddress(InterfaceIpAddress other) { + // TODO: we should use copy constructors for each field + this.ipAddress = other.ipAddress; + this.subnetAddress = other.subnetAddress; + this.broadcastAddress = other.broadcastAddress; + this.peerAddress = other.peerAddress; + } + + /** + * Constructor for a given IP address and a subnet address. + * + * @param ipAddress the IP address + * @param subnetAddress the IP subnet address + */ + public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress) { + this.ipAddress = checkNotNull(ipAddress); + this.subnetAddress = checkNotNull(subnetAddress); + // TODO: Recompute the default broadcast address from the subnet + // address + this.broadcastAddress = null; + this.peerAddress = null; + } + + /** + * Constructor for a given IP address and a subnet address. + * + * @param ipAddress the IP address + * @param subnetAddress the IP subnet address + * @param broadcastAddress the IP broadcast address. It can be used + * to specify non-default broadcast address + */ + public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress, + IpAddress broadcastAddress) { + this.ipAddress = checkNotNull(ipAddress); + this.subnetAddress = checkNotNull(subnetAddress); + this.broadcastAddress = broadcastAddress; + this.peerAddress = null; + } + + /** + * Constructor for a given IP address and a subnet address. + * + * @param ipAddress the IP address + * @param subnetAddress the IP subnet address + * @param broadcastAddress the IP broadcast address. It can be used + * to specify non-default broadcast address. It should be null for + * point-to-point interfaces with a peer address + * @param peerAddress the peer IP address for point-to-point interfaces + */ + public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress, + IpAddress broadcastAddress, + IpAddress peerAddress) { + this.ipAddress = checkNotNull(ipAddress); + this.subnetAddress = checkNotNull(subnetAddress); + this.broadcastAddress = broadcastAddress; + this.peerAddress = peerAddress; + } + + /** + * Gets the IP address. + * + * @return the IP address + */ + public IpAddress ipAddress() { + return ipAddress; + } + + /** + * Gets the IP subnet address. + * + * @return the IP subnet address + */ + public IpPrefix subnetAddress() { + return subnetAddress; + } + + /** + * Gets the subnet IP broadcast address. + * + * @return the subnet IP broadcast address + */ + public IpAddress broadcastAddress() { + return broadcastAddress; + } + + /** + * Gets the IP point-to-point interface peer address. + * + * @return the IP point-to-point interface peer address + */ + public IpAddress peerAddress() { + return peerAddress; + } + + /** + * Converts a CIDR string literal to an interface IP address. + * E.g. 10.0.0.1/24 + * + * @param value an IP address value in string form + * @return an interface IP address + * @throws IllegalArgumentException if the argument is invalid + */ + public static InterfaceIpAddress valueOf(String value) { + String[] splits = value.split("/"); + checkArgument(splits.length == 2, "Invalid IP address and prefix length format"); + + // NOTE: IpPrefix will mask-out the bits after the prefix length. + IpPrefix subnet = IpPrefix.valueOf(value); + IpAddress addr = IpAddress.valueOf(splits[0]); + return new InterfaceIpAddress(addr, subnet); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (!(other instanceof InterfaceIpAddress)) { + return false; + } + InterfaceIpAddress otherAddr = (InterfaceIpAddress) other; + + return Objects.equals(this.ipAddress, otherAddr.ipAddress) + && Objects.equals(this.subnetAddress, otherAddr.subnetAddress) + && Objects.equals(this.broadcastAddress, + otherAddr.broadcastAddress) + && Objects.equals(this.peerAddress, otherAddr.peerAddress); + } + + @Override + public int hashCode() { + return Objects.hash(ipAddress, subnetAddress, broadcastAddress, + peerAddress); + } + + @Override + public String toString() { + /*return toStringHelper(this).add("ipAddress", ipAddress) + .add("subnetAddress", subnetAddress) + .add("broadcastAddress", broadcastAddress) + .add("peerAddress", peerAddress) + .omitNullValues().toString();*/ + return ipAddress.toString() + "/" + subnetAddress.prefixLength(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/PortAddresses.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/PortAddresses.java new file mode 100644 index 00000000..74f22ae9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/PortAddresses.java @@ -0,0 +1,127 @@ +/* + * Copyright 2014-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.host; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.net.ConnectPoint; + +import com.google.common.base.MoreObjects; + +/** + * Represents address information bound to a port. + */ +public final class PortAddresses { + + private final ConnectPoint connectPoint; + private final Set<InterfaceIpAddress> ipAddresses; + private final MacAddress macAddress; + private final VlanId vlan; + + /** + * Constructs a PortAddresses object for the given connection point, with a + * set of IP addresses and a MAC address. Both address parameters are + * optional and can be set to null. + * + * @param connectPoint the connection point these addresses are for + * @param ipAddresses a set of interface IP addresses + * @param mac a MAC address + * @param vlan a VLAN ID + */ + public PortAddresses(ConnectPoint connectPoint, + Set<InterfaceIpAddress> ipAddresses, MacAddress mac, VlanId vlan) { + this.connectPoint = connectPoint; + this.ipAddresses = (ipAddresses == null) ? + Collections.<InterfaceIpAddress>emptySet() + : new HashSet<>(ipAddresses); + this.macAddress = mac; + this.vlan = vlan; + } + + /** + * Returns the connection point this address information is bound to. + * + * @return the connection point + */ + public ConnectPoint connectPoint() { + return connectPoint; + } + + /** + * Returns the set of interface IP addresses. + * + * @return the interface IP addresses + */ + public Set<InterfaceIpAddress> ipAddresses() { + return ipAddresses; + } + + /** + * Returns the MAC address. + * + * @return the MAC address + */ + public MacAddress mac() { + return macAddress; + } + + /** + * Returns the VLAN ID. + * + * @return the VLAN ID + */ + public VlanId vlan() { + return vlan; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof PortAddresses)) { + return false; + } + + PortAddresses otherPa = (PortAddresses) other; + + return Objects.equals(this.connectPoint, otherPa.connectPoint) + && Objects.equals(this.ipAddresses, otherPa.ipAddresses) + && Objects.equals(this.macAddress, otherPa.macAddress) + && Objects.equals(this.vlan, otherPa.vlan); + } + + @Override + public int hashCode() { + return Objects.hash(connectPoint, ipAddresses, macAddress, vlan); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("connect-point", connectPoint) + .add("ip-addresses", ipAddresses) + .add("mac-address", macAddress) + .add("vlan", vlan) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/package-info.java new file mode 100644 index 00000000..4f2bc7c4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * End-station host model & related services API definitions. + */ +package org.onosproject.net.host; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java new file mode 100644 index 00000000..7caee3e8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java @@ -0,0 +1,187 @@ +/* + * Copyright 2014-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.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.Link; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of connectivity intent for traffic matching some criteria. + */ +@Beta +public abstract class ConnectivityIntent extends Intent { + + // TODO: other forms of intents should be considered for this family: + // point-to-point with constraints (waypoints/obstacles) + // multi-to-single point with constraints (waypoints/obstacles) + // single-to-multi point with constraints (waypoints/obstacles) + // concrete path (with alternate) + // ... + + private final TrafficSelector selector; + private final TrafficTreatment treatment; + private final List<Constraint> constraints; + + /** + * Creates a connectivity intent that matches on the specified selector + * and applies the specified treatment. + * <p> + * Path will be optimized based on the first constraint if one is given. + * </p> + * + * @param appId application identifier + * @param key explicit key to use for intent + * @param resources required network resources (optional) + * @param selector traffic selector + * @param treatment treatment + * @param constraints optional prioritized list of constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if the selector or treatment is null + */ + protected ConnectivityIntent(ApplicationId appId, + Key key, + Collection<NetworkResource> resources, + TrafficSelector selector, + TrafficTreatment treatment, + List<Constraint> constraints, + int priority) { + super(appId, key, resources, priority); + this.selector = checkNotNull(selector); + this.treatment = checkNotNull(treatment); + this.constraints = checkNotNull(constraints); + } + + /** + * Constructor for serializer. + */ + protected ConnectivityIntent() { + super(); + this.selector = null; + this.treatment = null; + this.constraints = Collections.emptyList(); + } + + /** + * Abstract builder for connectivity intents. + */ + public abstract static class Builder extends Intent.Builder { + protected TrafficSelector selector = DefaultTrafficSelector.emptySelector(); + protected TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); + protected List<Constraint> constraints = ImmutableList.of(); + + @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 priority(int priority) { + return (Builder) super.priority(priority); + } + + + /** + * Sets the traffic selector for the intent that will be built. + * + * @param selector selector to use for built intent + * @return this builder + */ + public Builder selector(TrafficSelector selector) { + this.selector = selector; + return this; + } + + /** + * Sets the traffic treatment for the intent that will be built. + * + * @param treatment treatment to use for built intent + * @return this builder + */ + public Builder treatment(TrafficTreatment treatment) { + this.treatment = treatment; + return this; + } + + /** + * Sets the constraints for the intent that will be built. + * + * @param constraints constraints to use for built intent + * @return this builder + */ + public Builder constraints(List<Constraint> constraints) { + this.constraints = ImmutableList.copyOf(constraints); + return this; + } + } + + + /** + * Returns the match specifying the type of traffic. + * + * @return traffic match + */ + public TrafficSelector selector() { + return selector; + } + + /** + * Returns the action applied to the traffic. + * + * @return applied action + */ + public TrafficTreatment treatment() { + return treatment; + } + + /** + * Returns the set of connectivity constraints. + * + * @return list of intent constraints + */ + public List<Constraint> constraints() { + return constraints; + } + + /** + * Produces a collection of network resources from the given links. + * + * @param links collection of links + * @return collection of link resources + */ + protected static Collection<NetworkResource> resources(Collection<Link> links) { + return ImmutableSet.copyOf(links); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Constraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Constraint.java new file mode 100644 index 00000000..03acf17c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Constraint.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014 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.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.resource.link.LinkResourceService; + +/** + * Representation of a connectivity constraint capable of evaluating a link + * and determining the cost of traversing that link in the context of this + * constraint. + */ +@Beta +public interface Constraint { + + // TODO: Consider separating cost vs viability. + + /** + * Evaluates the specified link and provides the cost for its traversal. + * + * @param link link to be evaluated + * @param resourceService resource service for validating availability of + * link resources + * @return cost of link traversal + */ + double cost(Link link, LinkResourceService resourceService); + + /** + * Validates that the specified path satisfies the constraint. + * + * @param path path to be validated + * @param resourceService resource service for validating availability of + * link resources + * @return cost of link traversal + */ + boolean validate(Path path, LinkResourceService resourceService); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java new file mode 100644 index 00000000..0646a003 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java @@ -0,0 +1,110 @@ +/* + * 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.core.ApplicationId; +import org.onosproject.net.NetworkResource; +import org.onosproject.net.flow.FlowRule; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An intent that enables to tell flow level operation. + * This instance holds a collection of flow rules that may be executed in parallel. + */ +@Beta +public class FlowRuleIntent extends Intent { + + private final Collection<FlowRule> flowRules; + + /** + * Creates an flow rule intent with the specified flow rules to be set. + * + * @param appId application id + * @param flowRules flow rules to be set. + * @deprecated in Cardinal Release + */ + @Deprecated + public FlowRuleIntent(ApplicationId appId, List<FlowRule> flowRules) { + this(appId, null, flowRules, Collections.emptyList()); + } + + /** + * Creates a flow rule intent with the specified flow rules and resources. + * + * @param appId application id + * @param flowRules flow rules to be set + * @param resources network resource to be set + */ + public FlowRuleIntent(ApplicationId appId, List<FlowRule> flowRules, Collection<NetworkResource> resources) { + this(appId, null, flowRules, resources); + } + + /** + * Creates an flow rule intent with the specified key, flow rules to be set, and + * required network resources. + * + * @param appId application id + * @param key key + * @param flowRules flow rules + * @param resources network resources + */ + public FlowRuleIntent(ApplicationId appId, Key key, Collection<FlowRule> flowRules, + Collection<NetworkResource> resources) { + super(appId, key, resources, DEFAULT_INTENT_PRIORITY); + this.flowRules = ImmutableList.copyOf(checkNotNull(flowRules)); + } + + /** + * Constructor for serializer. + */ + protected FlowRuleIntent() { + super(); + this.flowRules = null; + } + + /** + * Returns a collection of flow rules to be set. + * + * @return a collection of flow rules + */ + public Collection<FlowRule> flowRules() { + return flowRules; + } + + @Override + public boolean isInstallable() { + return true; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id()) + .add("key", key()) + .add("appId", appId()) + .add("resources", resources()) + .add("flowRule", flowRules) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java new file mode 100644 index 00000000..bd4219ad --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java @@ -0,0 +1,194 @@ +/* + * Copyright 2014-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.ImmutableSet; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.HostId; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of end-station to end-station bidirectional connectivity. + */ +@Beta +public final class HostToHostIntent extends ConnectivityIntent { + + private final HostId one; + private final HostId two; + + /** + * Returns a new host to host intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder of a host to host intent. + */ + public static final class Builder extends ConnectivityIntent.Builder { + HostId one; + HostId two; + + 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); + } + + /** + * Sets the first host of the intent that will be built. + * + * @param one first host + * @return this builder + */ + public Builder one(HostId one) { + this.one = one; + return this; + } + + /** + * Sets the second host of the intent that will be built. + * + * @param two second host + * @return this builder + */ + public Builder two(HostId two) { + this.two = two; + return this; + } + + /** + * Builds a host to host intent from the accumulated parameters. + * + * @return point to point intent + */ + public HostToHostIntent build() { + + return new HostToHostIntent( + appId, + key, + one, + two, + selector, + treatment, + constraints, + priority + ); + } + } + + + /** + * Creates a new host-to-host intent with the supplied host pair. + * + * @param appId application identifier + * @param key intent key + * @param one first host + * @param two second host + * @param selector action + * @param treatment ingress port + * @param constraints optional prioritized list of path selection constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code one} or {@code two} is null. + */ + private HostToHostIntent(ApplicationId appId, Key key, + HostId one, HostId two, + TrafficSelector selector, + TrafficTreatment treatment, + List<Constraint> constraints, + int priority) { + super(appId, key, ImmutableSet.of(one, two), selector, treatment, + constraints, priority); + + // TODO: consider whether the case one and two are same is allowed + this.one = checkNotNull(one); + this.two = checkNotNull(two); + + } + + /** + * Returns identifier of the first host. + * + * @return first host identifier + */ + public HostId one() { + return one; + } + + /** + * Returns identifier of the second host. + * + * @return second host identifier + */ + public HostId two() { + return two; + } + + @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("constraints", constraints()) + .add("one", one) + .add("two", two) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Intent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Intent.java new file mode 100644 index 00000000..077fd895 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Intent.java @@ -0,0 +1,218 @@ +/* + * Copyright 2014-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 java.util.Collection; +import java.util.Objects; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.IdGenerator; +import org.onosproject.net.NetworkResource; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +/** + * 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 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; + } + + /** + * Creates a new intent. + * + * @param appId application identifier + * @param key optional key + * @param resources required network resources (optional) + * @param priority flow rule priority + */ + 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); + } + + /** + * Abstract builder for intents. + */ + public abstract static class Builder { + protected ApplicationId appId; + protected Key key; + protected int priority = Intent.DEFAULT_INTENT_PRIORITY; + + /** + * 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; + } + + } + + /** + * Returns the intent 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; + } + + /** + * 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 (Objects.equals(idGenerator, oldIdGenerator)) { + idGenerator = null; + } + } + + public Key key() { + return key; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentBatchDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentBatchDelegate.java new file mode 100644 index 00000000..e4babfb1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentBatchDelegate.java @@ -0,0 +1,35 @@ +/* + * Copyright 2014-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 java.util.Collection; + +/** + * Facade for receiving notifications from the intent batch service. + */ +@Beta +public interface IntentBatchDelegate { + + /** + * Submits the specified batch of intent operations for processing. + * + * @param operations batch of operations + */ + void execute(Collection<IntentData> operations); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentClockService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentClockService.java new file mode 100644 index 00000000..d0dbacf8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentClockService.java @@ -0,0 +1,34 @@ +/* + * 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 org.onosproject.store.Timestamp; + +/** + * Logical clock service that issues per-intent timestamps. + */ +@Beta +public interface IntentClockService { + + /** + * Returns a new timestamp for the specified intent. + * + * @param intentId identifier for the intent. + * @return timestamp + */ + Timestamp getTimestamp(IntentId intentId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java new file mode 100644 index 00000000..9a059be8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java @@ -0,0 +1,44 @@ +/* + * Copyright 2014 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.net.resource.link.LinkResourceAllocations; + +import java.util.List; +import java.util.Set; + +/** + * Abstraction of a compiler which is capable of taking an intent + * and translating it to other, potentially installable, intents. + * + * @param <T> the type of intent + */ +@Beta +public interface IntentCompiler<T extends Intent> { + /** + * Compiles the specified intent into other intents. + * + * @param intent intent to be compiled + * @param installable previously compilation result; optional + * @param resources previously allocated resources; optional + * @return list of resulting intents + * @throws IntentException if issues are encountered while compiling the intent + */ + List<Intent> compile(T intent, List<Intent> installable, + Set<LinkResourceAllocations> resources); + +} 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(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentEvent.java new file mode 100644 index 00000000..b27a5074 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentEvent.java @@ -0,0 +1,146 @@ +/* + * Copyright 2014-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 org.onosproject.event.AbstractEvent; + +/** + * A class to represent an intent related event. + */ +@Beta +public class IntentEvent extends AbstractEvent<IntentEvent.Type, Intent> { + + public enum Type { + /** + * Signifies that an intent is to be installed or reinstalled. + */ + INSTALL_REQ, + + /** + * Signifies that an intent has been successfully installed. + */ + INSTALLED, + + /** + * Signifies that an intent has failed compilation and that it cannot + * be satisfied by the network at this time. + */ + FAILED, + + /** + * Signifies that an intent will be withdrawn. + */ + WITHDRAW_REQ, + + /** + * Signifies that an intent has been withdrawn from the system. + */ + WITHDRAWN, + + /** + * Signifies that an intent has failed installation or withdrawal, but + * still hold some or all of its resources. + * (e.g. link reservations, flow rules on the data plane, etc.) + */ + CORRUPT, + + /** + * Signifies that an intent has been purged from the system. + */ + PURGED + } + + /** + * Creates an event of a given type and for the specified intent and the + * current time. + * + * @param type event type + * @param intent subject intent + * @param time time the event created in milliseconds since start of epoch + */ + public IntentEvent(Type type, Intent intent, long time) { + super(type, intent, time); + } + + /** + * Creates an event of a given type and for the specified intent and the + * current time. + * + * @param type event type + * @param intent subject intent + */ + public IntentEvent(Type type, Intent intent) { + super(type, intent); + } + + /** + * Creates an IntentEvent based on the state contained in the given intent + * data. Some states are not sent as external events, and these states will + * return null events. + * + * @param data the intent data to create an event for + * @return new intent event if the state is valid, otherwise null. + */ + public static IntentEvent getEvent(IntentData data) { + return getEvent(data.state(), data.intent()); + } + + /** + * Creates an IntentEvent based on the given state and intent. Some states + * are not sent as external events, and these states will return null events. + * + * @param state new state of the intent + * @param intent intent to put in event + * @return new intent event if the state is valid, otherwise null. + */ + public static IntentEvent getEvent(IntentState state, Intent intent) { + Type type; + switch (state) { + case INSTALL_REQ: + type = Type.INSTALL_REQ; + break; + case INSTALLED: + type = Type.INSTALLED; + break; + case WITHDRAW_REQ: + type = Type.WITHDRAW_REQ; + break; + case WITHDRAWN: + type = Type.WITHDRAWN; + break; + case FAILED: + type = Type.FAILED; + break; + case CORRUPT: + type = Type.CORRUPT; + break; + case PURGE_REQ: + type = Type.PURGED; + break; + + // fallthrough to default from here + case COMPILING: + case INSTALLING: + case RECOMPILING: + case WITHDRAWING: + default: + return null; + } + return new IntentEvent(type, intent); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentException.java new file mode 100644 index 00000000..3ac1df50 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentException.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014 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; + +/** + * Represents an intent related error. + */ +@Beta +public class IntentException extends RuntimeException { + + private static final long serialVersionUID = 1907263634145241319L; + + /** + * Constructs an exception with no message and no underlying cause. + */ + public IntentException() { + } + + /** + * Constructs an exception with the specified message. + * + * @param message the message describing the specific nature of the error + */ + public IntentException(String message) { + super(message); + } + + /** + * Constructs an exception with the specified message and the underlying cause. + * + * @param message the message describing the specific nature of the error + * @param cause the underlying cause of this error + */ + public IntentException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java new file mode 100644 index 00000000..d7c7c641 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-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 java.util.Map; + +/** + * Service for extending the capability of intent framework by + * adding additional compilers or/and installers. + */ +@Beta +public interface IntentExtensionService { + /** + * Registers the specified compiler for the given intent class. + * + * @param cls intent class + * @param compiler intent compiler + * @param <T> the type of intent + */ + <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler); + + /** + * Unregisters the compiler for the specified intent class. + * + * @param cls intent class + * @param <T> the type of intent + */ + <T extends Intent> void unregisterCompiler(Class<T> cls); + + /** + * Returns immutable set of bindings of currently registered intent compilers. + * + * @return the set of compiler bindings + */ + Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentId.java new file mode 100644 index 00000000..b9a30d2d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentId.java @@ -0,0 +1,87 @@ +/* + * Copyright 2014-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 org.onosproject.net.newresource.ResourceConsumer; + +/** + * Intent identifier suitable as an external key. + * <p>This class is immutable.</p> + */ +@Beta +public final class IntentId implements ResourceConsumer { + + private final long value; + + /** + * Creates an intent identifier from the specified long representation. + * + * @param value long value + * @return intent identifier + */ + public static IntentId valueOf(long value) { + return new IntentId(value); + } + + /** + * Constructor for serializer. + */ + IntentId() { + this.value = 0; + } + + /** + * Constructs the ID corresponding to a given long value. + * + * @param value the underlying value of this ID + */ + IntentId(long value) { + this.value = value; + } + + /** + * Returns the backing value. + * + * @return the value + */ + public long fingerprint() { + return value; + } + + @Override + public int hashCode() { + return Long.hashCode(value); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof IntentId)) { + return false; + } + IntentId that = (IntentId) obj; + return this.value == that.value; + } + + @Override + public String toString() { + return "0x" + Long.toHexString(value); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentListener.java new file mode 100644 index 00000000..4858c7ed --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentListener.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014 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.event.EventListener; + +/** + * Listener for {@link IntentEvent intent events}. + */ +@Beta +public interface IntentListener extends EventListener<IntentEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentOperation.java new file mode 100644 index 00000000..1b51b4f3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentOperation.java @@ -0,0 +1,124 @@ +/* + * Copyright 2014-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 java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of an intent-related operation, e.g. add, remove, replace. + */ +@Beta +public final class IntentOperation { + + private final Type type; + private final Intent intent; + + /** + * Operation type. + */ + public enum Type { + /** + * Indicates that an intent should be added. + */ + SUBMIT, + + /** + * Indicates that an intent should be removed. + */ + WITHDRAW, + } + + /** + * Creates an intent operation. + * + * @param type operation type + * @param intent intent subject + */ + public IntentOperation(Type type, Intent intent) { + this.type = checkNotNull(type); + this.intent = intent; + } + + /** + * Returns the type of the operation. + * + * @return operation type + */ + public Type type() { + return type; + } + + /** + * Returns the identifier of the intent to which this operation applies. + * + * @return intent identifier + */ + public IntentId intentId() { + return intent.id(); + } + + /** + * Returns the key for this intent. + * + * @return key value + */ + public Key key() { + return intent.key(); + } + + /** + * Returns the intent to which this operation applied. For remove, + * this can be null. + * + * @return intent that is the subject of the operation; null for remove + */ + public Intent intent() { + return intent; + } + + @Override + public int hashCode() { + return Objects.hash(type, intent); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final IntentOperation other = (IntentOperation) obj; + return Objects.equals(this.type, other.type) && + Objects.equals(this.intent, other.intent); + } + + + @Override + public String toString() { + return toStringHelper(this) + .add("type", type) + .add("intent", intent) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentService.java new file mode 100644 index 00000000..8533cebc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentService.java @@ -0,0 +1,123 @@ +/* + * Copyright 2014-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 org.onosproject.event.ListenerService; + +import java.util.List; + +/** + * Service for application submitting or withdrawing their intents. + */ +@Beta +public interface IntentService + extends ListenerService<IntentEvent, IntentListener> { + + /** + * Submits an intent into the system. + * <p> + * This is an asynchronous request meaning that any compiling or + * installation activities may be done at later time. + * </p> + * @param intent intent to be submitted + */ + void submit(Intent intent); + + /** + * Withdraws an intent from the system. + * <p> + * This is an asynchronous request meaning that the environment may be + * affected at later time. + * </p> + * @param intent intent to be withdrawn + */ + void withdraw(Intent intent); + + /** + * Purges a specific intent from the system if it is <b>FAILED</b> or + * <b>WITHDRAWN</b>. Otherwise, the intent remains in its current state. + * + * @param intent intent to purge + */ + void purge(Intent intent); + + /** + * Fetches an intent based on its key. + * + * @param key key of the intent + * @return intent object if the key is found, null otherwise + */ + Intent getIntent(Key key); + + /** + * Returns an iterable of intents currently in the system. + * + * @return set of intents + */ + Iterable<Intent> getIntents(); + + /** + * Returns an iterable of intent data objects currently in the system. + * + * @return set of intent data objects + */ + Iterable<IntentData> getIntentData(); + + /** + * Returns the number of intents currently in the system. + * + * @return number of intents + */ + long getIntentCount(); + + /** + * Retrieves the state of an intent by its identifier. + * + * @param intentKey intent identifier + * @return the intent state or null if one with the given identifier is not + * found + */ + IntentState getIntentState(Key intentKey); + + /** + * Returns the list of the installable events associated with the specified + * top-level intent. + * + * @param intentKey top-level intent identifier + * @return compiled installable intents + */ + List<Intent> getInstallableIntents(Key intentKey); + + /** + * Signifies whether the local node is responsible for processing the given + * intent key. + * + * @param intentKey intent key to check + * @return true if the local node is responsible for the intent key, + * otherwise false + */ + boolean isLocal(Key intentKey); + + /** + * Returns the list of intent requests pending processing. + * + * @return intents pending processing + */ + Iterable<Intent> getPending(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentState.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentState.java new file mode 100644 index 00000000..1e5fd054 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentState.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014-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; + +/** + * Representation of the phases an intent may attain during its lifecycle. + */ +@Beta +public enum IntentState { + + /** + * Signifies that the intent has been submitted and will start compiling + * shortly. However, this compilation may not necessarily occur on the + * local controller instance. + * <p> + * All intent in the runtime take this state first. + * </p><p> + * Intents will also pass through this state when they are updated. + * </p> + */ + INSTALL_REQ, // TODO submit_REQ? + + /** + * Signifies that the intent is being compiled into installable intents. + * This is a transitional state after which the intent will enter either + * {@link #FAILED} state or {@link #INSTALLING} state. + */ + COMPILING, //TODO do we really need this? + + /** + * Signifies that the resulting installable intents are being installed + * into the network environment. This is a transitional state after which + * the intent will enter either {@link #INSTALLED} state or + * {@link #RECOMPILING} state. + */ + INSTALLING, + + /** + * The intent has been successfully installed. This is a state where the + * intent may remain parked until it is withdrawn by the application or + * until the network environment changes in some way to make the original + * set of installable intents untenable. + */ + INSTALLED, + + /** + * Signifies that the intent is being recompiled into installable intents + * as an attempt to adapt to an anomaly in the network environment. + * This is a transitional state after which the intent will enter either + * {@link #FAILED} state or {@link #INSTALLING} state. + * <p> + * Exit to the {@link #FAILED} state may be caused by failure to compile + * or by compiling into the same set of installable intents which have + * previously failed to be installed. + * </p> + */ + RECOMPILING, // TODO perhaps repurpose as BROKEN. + + /** + * Indicates that an application has requested that an intent be withdrawn. + * It will start withdrawing shortly, but not necessarily on this instance. + * Intents can also be parked here if it is impossible to withdraw them. + */ + WITHDRAW_REQ, + + /** + * Indicates that the intent is being withdrawn. This is a transitional + * state, triggered by invocation of the + * {@link IntentService#withdraw(Intent)} but one with only one outcome, + * which is the the intent being placed in the {@link #WITHDRAWN} state. + */ + WITHDRAWING, + + /** + * Indicates that the intent has been successfully withdrawn. + */ + WITHDRAWN, + + /** + * Signifies that the intent has failed to be installed and cannot be + * satisfied given current network conditions. But, the framework will + * reattempt to install it when network conditions change until it is + * withdrawn by an application. + */ + FAILED, //TODO consider renaming to UNSATISFIABLE + + /** + * Signifies that an intent has failed either installation or withdrawal, + * and still hold some or all of its resources. + * (e.g. link reservations, flow rules on the data plane, etc.) + */ + CORRUPT, //TODO consider renaming to ERROR + + /** + * Indicates that the intent should be purged from the database. + * <p> + * Note: This operation will only be performed if the intent is already + * in WITHDRAWN or FAILED. + * </p> + */ + PURGE_REQ +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStore.java new file mode 100644 index 00000000..167ba152 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStore.java @@ -0,0 +1,143 @@ +/* + * Copyright 2014-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 org.onosproject.store.Store; + +import java.util.List; + +/** + * Manages inventory of end-station intents; not intended for direct use. + */ +@Beta +public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> { + + /** + * Returns the number of intents in the store. + * + * @return the number of intents in the store + */ + long getIntentCount(); + + /** + * Returns an iterable of all intents in the store. + * + * @return iterable of all intents + */ + Iterable<Intent> getIntents(); + + + /** + * Returns an iterable of all intent data objects in the store. + * + * @param localOnly should only intents for which this instance is master + * be returned + * @param olderThan specified duration in milliseconds (0 for "now") + * @return iterable of all intent data objects + */ + Iterable<IntentData> getIntentData(boolean localOnly, long olderThan); + + /** + * Returns the state of the specified intent. + * + * @param intentKey intent identification + * @return current intent state + */ + IntentState getIntentState(Key intentKey); + + /** + * Returns the list of the installable events associated with the specified + * original intent. + * + * @param intentKey original intent identifier + * @return compiled installable intents, or null if no installables exist + */ + List<Intent> getInstallableIntents(Key intentKey); + + /** + * Writes an IntentData object to the store. + * + * @param newData new intent data to write + */ + void write(IntentData newData); + + /** + * Writes a batch of IntentData objects to the store. A batch has no + * semantics, this is simply a convenience API. + * + * @param updates collection of intent data objects to write + */ + void batchWrite(Iterable<IntentData> updates); + + /** + * Returns the intent with the specified identifier. + * + * @param key key + * @return intent or null if not found + */ + Intent getIntent(Key key); + + /** + * Returns the intent data object associated with the specified key. + * + * @param key key to look up + * @return intent data object + */ + IntentData getIntentData(Key key); + + /** + * Adds a new operation, which should be persisted and delegated. + * + * @param intent operation + */ + void addPending(IntentData intent); + + /** + * Checks to see whether the calling instance is the master for processing + * this intent, or more specifically, the key contained in this intent. + * + * @param intentKey intentKey to check + * @return true if master; false, otherwise + */ + //TODO better name + boolean isMaster(Key intentKey); + + /** + * Returns the intent requests pending processing. + * + * @return pending intents + */ + Iterable<Intent> getPending(); + + /** + * Returns the intent data objects that are pending processing. + * + * @return pending intent data objects + */ + Iterable<IntentData> getPendingData(); + + /** + * Returns the intent data objects that are pending processing for longer + * than the specified duration. + * + * @param localOnly should only intents for which this instance is master + * be returned + * @param olderThan specified duration in milliseconds (0 for "now") + * @return pending intent data objects + */ + Iterable<IntentData> getPendingData(boolean localOnly, long olderThan); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStoreDelegate.java new file mode 100644 index 00000000..fd99881c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/IntentStoreDelegate.java @@ -0,0 +1,42 @@ +/* + * Copyright 2014-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 org.onosproject.store.StoreDelegate; + +/** + * Intent store delegate abstraction. + */ +@Beta +public interface IntentStoreDelegate extends StoreDelegate<IntentEvent> { + + /** + * Provides an intent data object that should be processed (compiled and + * installed) by this manager. + * + * @param intentData intent data object + */ + void process(IntentData intentData); + + /** + * Called when a new intent has been updated for which this node is the master. + * + * @param intentData intent data object + */ + default void onUpdate(IntentData intentData) { + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Key.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Key.java new file mode 100644 index 00000000..18baafc8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/Key.java @@ -0,0 +1,163 @@ +/* + * 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.hash.HashFunction; +import com.google.common.hash.Hashing; +import org.onosproject.core.ApplicationId; + +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +/** + * Key class for Intents. + */ +// TODO maybe pull this up to utils +@Beta +public abstract class Key { + + //TODO consider making this a HashCode object (worry about performance) + private final long hash; + private static final HashFunction HASH_FN = Hashing.md5(); + + protected Key(long hash) { + this.hash = hash; + } + + public long hash() { + return hash; + } + + @Override + public int hashCode() { + return Long.hashCode(hash); + } + + @Override + public abstract boolean equals(Object obj); + + /** + * Creates a key based on the provided string. + * <p> + * Note: Two keys with equal value, but different appId, are not equal. + * </p> + * + * @param key the provided string + * @param appId application id to associate with this key + * @return the key for the string + */ + public static Key of(String key, ApplicationId appId) { + return new StringKey(key, appId); + } + + /** + * Creates a key based on the provided long. + * <p> + * Note: Two keys with equal value, but different appId, are not equal. + * Also, "10" and 10L are different. + * </p> + * + * @param key the provided long + * @param appId application id to associate with this key + * @return the key for the long + */ + public static Key of(long key, ApplicationId appId) { + return new LongKey(key, appId); + } + + private static final class StringKey extends Key { + + private final ApplicationId appId; + private final String key; + + private StringKey(String key, ApplicationId appId) { + super(HASH_FN.newHasher() + .putShort(appId.id()) + .putString(key, StandardCharsets.UTF_8) + .hash().asLong()); + this.key = key; + this.appId = appId; + } + + @Override + public String toString() { + return key; + } + + // checkstyle requires this + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final StringKey other = (StringKey) obj; + return this.hash() == other.hash() && + Objects.equals(this.appId, other.appId) && + Objects.equals(this.key, other.key); + } + } + + private static final class LongKey extends Key { + + private final ApplicationId appId; + private final long key; + + private LongKey(long key, ApplicationId appId) { + super(HASH_FN.newHasher() + .putShort(appId.id()) + .putLong(key) + .hash().asLong()); + this.key = key; + this.appId = appId; + } + + @Override + public String toString() { + return "0x" + Long.toHexString(key); + } + + // checkstyle requires this + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final LongKey other = (LongKey) obj; + return this.hash() == other.hash() && + this.key == other.key && + Objects.equals(this.appId, other.appId); + } + } +} + + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java new file mode 100644 index 00000000..d7953fd8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java @@ -0,0 +1,241 @@ +/* + * Copyright 2014-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 java.util.List; +import java.util.Set; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Link; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; + +/** + * 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<ConnectPoint> ingressPoints; + private final Set<ConnectPoint> egressPoints; + + /** + * 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 ingress points + * @param egressPoints egress points + * @param constraints optional list of constraints + * @param priority priority to use for the flows generated by this intent + * @throws NullPointerException {@code path} is null + */ + private LinkCollectionIntent(ApplicationId appId, + Key key, + TrafficSelector selector, + TrafficTreatment treatment, + Set<Link> links, + Set<ConnectPoint> ingressPoints, + Set<ConnectPoint> egressPoints, + List<Constraint> constraints, + int priority) { + super(appId, key, resources(links), selector, treatment, constraints, priority); + this.links = links; + this.ingressPoints = ingressPoints; + this.egressPoints = egressPoints; + } + + /** + * Constructor for serializer. + */ + protected LinkCollectionIntent() { + super(); + this.links = null; + this.ingressPoints = null; + this.egressPoints = null; + } + + /** + * 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 { + Set<Link> links; + Set<ConnectPoint> ingressPoints; + Set<ConnectPoint> egressPoints; + + 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); + } + + /** + * Sets the ingress point of the single point to multi point intent + * that will be built. + * + * @param ingressPoints ingress connect points + * @return this builder + */ + public Builder ingressPoints(Set<ConnectPoint> ingressPoints) { + this.ingressPoints = ImmutableSet.copyOf(ingressPoints); + 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 + */ + public Builder egressPoints(Set<ConnectPoint> 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; + } + + + /** + * 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, + links, + ingressPoints, + egressPoints, + constraints, + priority + ); + } + } + + + /** + * 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() { + return ingressPoints; + } + + /** + * Returns the egress points of the intent. + * + * @return the egress points + */ + public Set<ConnectPoint> egressPoints() { + return egressPoints; + } + + @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()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java new file mode 100644 index 00000000..bf469dbe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java @@ -0,0 +1,261 @@ +package org.onosproject.net.intent; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import com.google.common.annotations.Beta; +import org.onlab.packet.MplsLabel; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + + +/** + * Abstraction of MPLS label-switched connectivity. + */ +@Beta +public final class MplsIntent extends ConnectivityIntent { + + private final ConnectPoint ingressPoint; + private final Optional<MplsLabel> ingressLabel; + private final ConnectPoint egressPoint; + private final Optional<MplsLabel> egressLabel; + + /** + * Creates a new point-to-point intent with the supplied ingress/egress + * ports, labels and constraints. + * + * @param appId application identifier + * @param selector traffic selector + * @param treatment treatment + * @param ingressPoint ingress port + * @param ingressLabel ingress MPLS label + * @param egressPoint egress port + * @param egressLabel egress MPLS label + * @param constraints optional list of constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null. + */ + private MplsIntent(ApplicationId appId, + Key key, + TrafficSelector selector, + TrafficTreatment treatment, + ConnectPoint ingressPoint, + Optional<MplsLabel> ingressLabel, + ConnectPoint egressPoint, + Optional<MplsLabel> egressLabel, + List<Constraint> constraints, + int priority) { + + super(appId, key, Collections.emptyList(), selector, treatment, constraints, + priority); + + this.ingressPoint = checkNotNull(ingressPoint); + this.ingressLabel = checkNotNull(ingressLabel); + this.egressPoint = checkNotNull(egressPoint); + this.egressLabel = checkNotNull(egressLabel); + + checkArgument(!ingressPoint.equals(egressPoint), + "ingress and egress should be different (ingress: %s, egress: %s)", + ingressPoint, egressPoint); + } + + /** + * Returns a new MPLS intent builder. The application id, + * ingress point, egress point, ingress label and egress label are + * required fields. If they are not set by calls to the appropriate + * methods, an exception will be thrown. + * + * @return point to point builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder of an MPLS intent. + */ + public static final class Builder extends ConnectivityIntent.Builder { + ConnectPoint ingressPoint; + ConnectPoint egressPoint; + Optional<MplsLabel> ingressLabel; + Optional<MplsLabel> egressLabel; + + 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); + } + + /** + * Sets the ingress point of the point to point intent that will be built. + * + * @param ingressPoint ingress connect point + * @return this builder + */ + public Builder ingressPoint(ConnectPoint ingressPoint) { + this.ingressPoint = ingressPoint; + return this; + } + + /** + * Sets the egress point of the point to point intent that will be built. + * + * @param egressPoint egress connect point + * @return this builder + */ + public Builder egressPoint(ConnectPoint egressPoint) { + this.egressPoint = egressPoint; + return this; + } + + /** + * Sets the ingress label of the intent that will be built. + * + * @param ingressLabel ingress label + * @return this builder + */ + public Builder ingressLabel(Optional<MplsLabel> ingressLabel) { + this.ingressLabel = ingressLabel; + return this; + } + + /** + * Sets the ingress label of the intent that will be built. + * + * @param egressLabel ingress label + * @return this builder + */ + public Builder egressLabel(Optional<MplsLabel> egressLabel) { + this.egressLabel = egressLabel; + return this; + } + + /** + * Builds a point to point intent from the accumulated parameters. + * + * @return point to point intent + */ + public MplsIntent build() { + + return new MplsIntent( + appId, + key, + selector, + treatment, + ingressPoint, + ingressLabel, + egressPoint, + egressLabel, + constraints, + priority + ); + } + } + + + + /** + * Constructor for serializer. + */ + protected MplsIntent() { + super(); + this.ingressPoint = null; + this.ingressLabel = null; + this.egressPoint = null; + this.egressLabel = null; + } + + /** + * Returns the port on which the ingress traffic should be connected to + * the egress. + * + * @return ingress switch port + */ + public ConnectPoint ingressPoint() { + return ingressPoint; + } + + /** + * Returns the port on which the traffic should egress. + * + * @return egress switch port + */ + public ConnectPoint egressPoint() { + return egressPoint; + } + + + /** + * Returns the MPLS label which the ingress traffic should tagged. + * + * @return ingress MPLS label + */ + public Optional<MplsLabel> ingressLabel() { + return ingressLabel; + } + + /** + * Returns the MPLS label which the egress traffic should tagged. + * + * @return egress MPLS label + */ + public Optional<MplsLabel> egressLabel() { + return egressLabel; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("id", id()) + .add("appId", appId()) + .add("key", key()) + .add("priority", priority()) + .add("selector", selector()) + .add("treatment", treatment()) + .add("ingressPoint", ingressPoint) + .add("ingressLabel", ingressLabel) + .add("egressPoint", egressPoint) + .add("egressLabel", egressLabel) + .add("constraints", constraints()) + .toString(); + } + + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java new file mode 100644 index 00000000..3c3c45ce --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java @@ -0,0 +1,167 @@ +package org.onosproject.net.intent; + +import java.util.List; +import java.util.Optional; + +import com.google.common.annotations.Beta; +import org.onlab.packet.MplsLabel; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.Path; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import static com.google.common.base.Preconditions.checkNotNull; + + +/** + * Abstraction of explicit MPLS label-switched path. + */ +@Beta +public final class MplsPathIntent extends PathIntent { + + private final Optional<MplsLabel> ingressLabel; + private final Optional<MplsLabel> egressLabel; + + /** + * Creates a new point-to-point intent with the supplied ingress/egress + * ports and using the specified explicit path. + * + * @param appId application identifier + * @param selector traffic selector + * @param treatment treatment + * @param path traversed links + * @param ingressLabel MPLS egress label + * @param egressLabel MPLS ingress label + * @param constraints optional list of constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException {@code path} is null + */ + private MplsPathIntent(ApplicationId appId, TrafficSelector selector, + TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel, + Optional<MplsLabel> egressLabel, List<Constraint> constraints, + int priority) { + super(appId, selector, treatment, path, constraints, + priority); + + this.ingressLabel = checkNotNull(ingressLabel); + this.egressLabel = checkNotNull(egressLabel); + } + + /** + * Returns a new host to host intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder of a host to host intent. + */ + public static final class Builder extends PathIntent.Builder { + private Optional<MplsLabel> ingressLabel = Optional.empty(); + private Optional<MplsLabel> egressLabel = Optional.empty(); + + 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 path(Path path) { + return (Builder) super.path(path); + } + + /** + * Sets the ingress label of the intent that will be built. + * + * @param ingressLabel ingress label + * @return this builder + */ + public Builder ingressLabel(Optional<MplsLabel> ingressLabel) { + this.ingressLabel = ingressLabel; + return this; + } + + /** + * Sets the ingress label of the intent that will be built. + * + * @param egressLabel ingress label + * @return this builder + */ + public Builder egressLabel(Optional<MplsLabel> egressLabel) { + this.egressLabel = egressLabel; + return this; + } + + + /** + * Builds a host to host intent from the accumulated parameters. + * + * @return point to point intent + */ + public MplsPathIntent build() { + + return new MplsPathIntent( + appId, + selector, + treatment, + path, + ingressLabel, + egressLabel, + constraints, + priority + ); + } + } + + + /** + * Returns the MPLS label which the ingress traffic should tagged. + * + * @return ingress MPLS label + */ + public Optional<MplsLabel> ingressLabel() { + return ingressLabel; + } + + /** + * Returns the MPLS label which the egress traffic should tagged. + * + * @return egress MPLS label + */ + public Optional<MplsLabel> egressLabel() { + return egressLabel; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java new file mode 100644 index 00000000..ac6061c7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java @@ -0,0 +1,223 @@ +/* + * Copyright 2014-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.ImmutableSet; +import com.google.common.collect.Sets; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of multiple source to single destination connectivity intent. + */ +@Beta +public final class MultiPointToSinglePointIntent extends ConnectivityIntent { + + private final Set<ConnectPoint> ingressPoints; + private final ConnectPoint egressPoint; + + /** + * Creates a new multi-to-single point connectivity intent for the specified + * traffic selector and treatment. + * + * @param appId application identifier + * @param key intent key + * @param selector traffic selector + * @param treatment treatment + * @param ingressPoints set of ports from which ingress traffic originates + * @param egressPoint port to which traffic will egress + * @param constraints constraints to apply to the intent + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code ingressPoints} or + * {@code egressPoint} is null. + * @throws IllegalArgumentException if the size of {@code ingressPoints} is + * not more than 1 + */ + private MultiPointToSinglePointIntent(ApplicationId appId, + Key key, + TrafficSelector selector, + TrafficTreatment treatment, + Set<ConnectPoint> ingressPoints, + ConnectPoint egressPoint, + List<Constraint> constraints, + int priority) { + super(appId, key, Collections.emptyList(), selector, treatment, constraints, + priority); + + checkNotNull(ingressPoints); + checkArgument(!ingressPoints.isEmpty(), "Ingress point set cannot be empty"); + checkNotNull(egressPoint); + checkArgument(!ingressPoints.contains(egressPoint), + "Set of ingresses should not contain egress (egress: %s)", egressPoint); + + this.ingressPoints = Sets.newHashSet(ingressPoints); + this.egressPoint = egressPoint; + } + + /** + * Constructor for serializer. + */ + protected MultiPointToSinglePointIntent() { + super(); + this.ingressPoints = null; + this.egressPoint = null; + } + + /** + * Returns a new multi point to single point intent builder. The application id, + * ingress points and egress point 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 multi point to single point intent. + */ + public static final class Builder extends ConnectivityIntent.Builder { + Set<ConnectPoint> ingressPoints; + ConnectPoint egressPoint; + + 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); + } + + /** + * Sets the ingress point of the single point to multi point intent + * that will be built. + * + * @param ingressPoints ingress connect points + * @return this builder + */ + public Builder ingressPoints(Set<ConnectPoint> ingressPoints) { + this.ingressPoints = ImmutableSet.copyOf(ingressPoints); + return this; + } + + /** + * Sets the egress point of the multi point to single point intent + * that will be built. + * + * @param egressPoint egress connect point + * @return this builder + */ + public Builder egressPoint(ConnectPoint egressPoint) { + this.egressPoint = egressPoint; + return this; + } + + /** + * Builds a multi point to single point intent from the + * accumulated parameters. + * + * @return point to point intent + */ + public MultiPointToSinglePointIntent build() { + + return new MultiPointToSinglePointIntent( + appId, + key, + selector, + treatment, + ingressPoints, + egressPoint, + constraints, + priority + ); + } + } + + + /** + * Returns the set of ports on which ingress traffic should be connected to + * the egress port. + * + * @return set of ingress ports + */ + public Set<ConnectPoint> ingressPoints() { + return ingressPoints; + } + + /** + * Returns the port on which the traffic should egress. + * + * @return egress port + */ + public ConnectPoint egressPoint() { + return egressPoint; + } + + @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("ingress", ingressPoints()) + .add("egress", egressPoint()) + .add("constraints", constraints()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalCircuitIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalCircuitIntent.java new file mode 100644 index 00000000..1e515c8c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalCircuitIntent.java @@ -0,0 +1,219 @@ +/* + * 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 org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.OduCltPort; + +import java.util.Collections; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An optical layer intent for circuits between two OduClt ports. + * No traffic selector or traffic treatment are needed. + */ +@Beta +public class OpticalCircuitIntent extends Intent { + private final ConnectPoint src; + private final ConnectPoint dst; + private final OduCltPort.SignalType signalType; + private final boolean isBidirectional; + + /** + * Creates an optical circuit intent between the specified + * connection points. + * + * @param appId application identification + * @param key intent key + * @param src the source transponder port + * @param dst the destination transponder port + * @param signalType ODU signal type + * @param isBidirectional indicate if intent is bidirectional + * @param priority priority to use for flows from this intent + */ + protected OpticalCircuitIntent(ApplicationId appId, Key key, ConnectPoint src, ConnectPoint dst, + OduCltPort.SignalType signalType, boolean isBidirectional, int priority) { + super(appId, key, Collections.emptyList(), priority); + this.src = checkNotNull(src); + this.dst = checkNotNull(dst); + this.signalType = checkNotNull(signalType); + this.isBidirectional = isBidirectional; + } + + /** + * Returns a new optical circuit intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + + /** + * Builder for optical circuit intents. + */ + public static class Builder extends Intent.Builder { + private ConnectPoint src; + private ConnectPoint dst; + private OduCltPort.SignalType signalType; + private boolean isBidirectional; + + @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 priority(int priority) { + return (Builder) super.priority(priority); + } + + /** + * Sets the source for the intent that will be built. + * + * @param src source to use for built intent + * @return this builder + */ + public Builder src(ConnectPoint src) { + this.src = src; + return this; + } + + /** + * Sets the destination for the intent that will be built. + * + * @param dst dest to use for built intent + * @return this builder + */ + public Builder dst(ConnectPoint dst) { + this.dst = dst; + return this; + } + + /** + * Sets the ODU signal type for the intent that will be built. + * + * @param signalType signal type to use for built intent + * @return this builder + */ + public Builder signalType(OduCltPort.SignalType signalType) { + this.signalType = signalType; + return this; + } + + /** + * Sets the directionality of the intent. + * + * @param isBidirectional true if bidirectional, false if unidirectional + * @return this builder + */ + public Builder bidirectional(boolean isBidirectional) { + this.isBidirectional = isBidirectional; + return this; + } + + /** + * Builds an optical circuit intent from the accumulated parameters. + * + * @return point to point intent + */ + public OpticalCircuitIntent build() { + + return new OpticalCircuitIntent( + appId, + key, + src, + dst, + signalType, + isBidirectional, + priority + ); + } + } + + /** + * Constructor for serializer. + */ + protected OpticalCircuitIntent() { + super(); + this.src = null; + this.dst = null; + this.signalType = null; + this.isBidirectional = false; + } + + /** + * Returns the source transponder port. + * + * @return source transponder port + */ + public ConnectPoint getSrc() { + return src; + } + + /** + * Returns the destination transponder port. + * + * @return source transponder port + */ + public ConnectPoint getDst() { + return dst; + } + + /** + * Returns the ODU signal type. + * + * @return ODU signal type + */ + public OduCltPort.SignalType getSignalType() { + return signalType; + } + + /** + * Returns the directionality of the intent. + * + * @return true if bidirectional, false if unidirectional + */ + public boolean isBidirectional() { + return isBidirectional; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id()) + .add("key", key()) + .add("appId", appId()) + .add("priority", priority()) + .add("resources", resources()) + .add("src", src) + .add("dst", dst) + .add("signalType", signalType) + .add("isBidirectional", isBidirectional) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java new file mode 100644 index 00000000..aeb0255f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalConnectivityIntent.java @@ -0,0 +1,223 @@ +/* + * Copyright 2014-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 org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.OduSignalType; + +import java.util.Collections; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An optical layer intent for connectivity between two OCh ports. + * No traffic selector or traffic treatment are needed. + */ +@Beta +public final class OpticalConnectivityIntent extends Intent { + private final ConnectPoint src; + private final ConnectPoint dst; + private final OduSignalType signalType; + private final boolean isBidirectional; + + /** + * Creates an optical connectivity intent between the specified + * connection points. + * + * @param appId application identification + * @param key intent key + * @param src the source transponder port + * @param dst the destination transponder port + * @param signalType signal type + * @param isBidirectional indicates if intent is unidirectional + * @param priority priority to use for flows from this intent + */ + protected OpticalConnectivityIntent(ApplicationId appId, + Key key, + ConnectPoint src, + ConnectPoint dst, + OduSignalType signalType, + boolean isBidirectional, + int priority) { + super(appId, key, Collections.emptyList(), priority); + this.src = checkNotNull(src); + this.dst = checkNotNull(dst); + this.signalType = checkNotNull(signalType); + this.isBidirectional = isBidirectional; + } + + /** + * Returns a new optical connectivity intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + + /** + * Builder for optical connectivity intents. + */ + public static class Builder extends Intent.Builder { + private ConnectPoint src; + private ConnectPoint dst; + private OduSignalType signalType; + private boolean isBidirectional; + + @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 priority(int priority) { + return (Builder) super.priority(priority); + } + + /** + * Sets the source for the intent that will be built. + * + * @param src source to use for built intent + * @return this builder + */ + public Builder src(ConnectPoint src) { + this.src = src; + return this; + } + + /** + * Sets the destination for the intent that will be built. + * + * @param dst dest to use for built intent + * @return this builder + */ + public Builder dst(ConnectPoint dst) { + this.dst = dst; + return this; + } + + /** + * Sets the ODU signal type for the intent that will be built. + * + * @param signalType ODU signal type + * @return this builder + */ + public Builder signalType(OduSignalType signalType) { + this.signalType = signalType; + return this; + } + + /** + * Sets the directionality of the intent. + * + * @param isBidirectional true if bidirectional, false if unidirectional + * @return this builder + */ + public Builder bidirectional(boolean isBidirectional) { + this.isBidirectional = isBidirectional; + return this; + } + + /** + * Builds an optical connectivity intent from the accumulated parameters. + * + * @return point to point intent + */ + public OpticalConnectivityIntent build() { + + return new OpticalConnectivityIntent( + appId, + key, + src, + dst, + signalType, + isBidirectional, + priority + ); + } + } + + /** + * Constructor for serializer. + */ + protected OpticalConnectivityIntent() { + super(); + this.src = null; + this.dst = null; + this.signalType = null; + this.isBidirectional = false; + } + + /** + * Returns the source transponder port. + * + * @return source transponder port + */ + public ConnectPoint getSrc() { + return src; + } + + /** + * Returns the destination transponder port. + * + * @return source transponder port + */ + public ConnectPoint getDst() { + return dst; + } + + /** + * Returns the ODU signal type. + * + * @return ODU signal type + */ + public OduSignalType getSignalType() { + return signalType; + } + + /** + * Returns the directionality of the intent. + * + * @return true if bidirectional, false if unidirectional + */ + public boolean isBidirectional() { + return isBidirectional; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id()) + .add("key", key()) + .add("appId", appId()) + .add("priority", priority()) + .add("resources", resources()) + .add("src", src) + .add("dst", dst) + .add("signalType", signalType) + .add("isBidirectional", isBidirectional) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java new file mode 100644 index 00000000..5a5461cb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java @@ -0,0 +1,234 @@ +/* + * Copyright 2014-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 org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.OchSignal; +import org.onosproject.net.OchSignalType; +import org.onosproject.net.Path; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An optical layer intent with explicitly selected path. + */ +@Beta +public final class OpticalPathIntent extends Intent { + + private final ConnectPoint src; + private final ConnectPoint dst; + private final Path path; + private final OchSignal lambda; + private final OchSignalType signalType; + private final boolean isBidirectional; + + private OpticalPathIntent(ApplicationId appId, + Key key, + ConnectPoint src, + ConnectPoint dst, + Path path, + OchSignal lambda, + OchSignalType signalType, + boolean isBidirectional, + int priority) { + super(appId, key, ImmutableSet.copyOf(path.links()), priority); + this.src = checkNotNull(src); + this.dst = checkNotNull(dst); + this.path = checkNotNull(path); + this.lambda = checkNotNull(lambda); + this.signalType = checkNotNull(signalType); + this.isBidirectional = isBidirectional; + } + + protected OpticalPathIntent() { + this.src = null; + this.dst = null; + this.path = null; + this.lambda = null; + this.signalType = null; + this.isBidirectional = true; + } + + /** + * Returns a new optical connectivity intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + + /** + * Builder for optical path intents. + */ + public static class Builder extends Intent.Builder { + private ConnectPoint src; + private ConnectPoint dst; + private Path path; + private OchSignal lambda; + private OchSignalType signalType; + private boolean isBidirectional; + Key key; + + @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 priority(int priority) { + return (Builder) super.priority(priority); + } + + /** + * Sets the source for the intent that will be built. + * + * @param src source to use for built intent + * @return this builder + */ + public Builder src(ConnectPoint src) { + this.src = src; + return this; + } + + /** + * Sets the destination for the intent that will be built. + * + * @param dst dest to use for built intent + * @return this builder + */ + public Builder dst(ConnectPoint dst) { + this.dst = dst; + return this; + } + + /** + * Sets the path for the intent that will be built. + * + * @param path path to use for built intent + * @return this builder + */ + public Builder path(Path path) { + this.path = path; + return this; + } + + /** + * Sets the optical channel (lambda) for the intent that will be built. + * + * @param lambda the optical channel + * @return this builder + */ + public Builder lambda(OchSignal lambda) { + this.lambda = lambda; + return this; + } + + /** + * Sets the optical signal type for the intent that will be built. + * + * @param signalType the optical signal type + * @return this builder + */ + public Builder signalType(OchSignalType signalType) { + this.signalType = signalType; + return this; + } + + /** + * Sets the intent's direction. + * + * @param isBidirectional indicates if intent is bidirectional + * @return this builder + */ + public Builder bidirectional(boolean isBidirectional) { + this.isBidirectional = isBidirectional; + return this; + } + + /** + * Builds an optical path intent from the accumulated parameters. + * + * @return optical path intent + */ + public OpticalPathIntent build() { + + return new OpticalPathIntent( + appId, + key, + src, + dst, + path, + lambda, + signalType, + isBidirectional, + priority + ); + } + } + + + public ConnectPoint src() { + return src; + } + + public ConnectPoint dst() { + return dst; + } + + public Path path() { + return path; + } + + public OchSignal lambda() { + return lambda; + } + + public OchSignalType signalType() { + return signalType; + } + + public boolean isBidirectional() { + return isBidirectional; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("id", id()) + .add("appId", appId()) + .add("key", key()) + .add("resources", resources()) + .add("ingressPort", src) + .add("egressPort", dst) + .add("path", path) + .add("lambda", lambda) + .add("signalType", signalType) + .add("isBidirectional", isBidirectional) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEvent.java new file mode 100644 index 00000000..c79a3818 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEvent.java @@ -0,0 +1,35 @@ +/* + * 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 org.onosproject.event.AbstractEvent; + +/** + * Partition event. + */ +//TODO change String into a proper object type +@Beta +public class PartitionEvent extends AbstractEvent<PartitionEvent.Type, String> { + + public enum Type { + LEADER_CHANGED + } + + public PartitionEvent(Type type, String partition) { + super(type, partition); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEventListener.java new file mode 100644 index 00000000..5f1da334 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionEventListener.java @@ -0,0 +1,26 @@ +/* + * 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 org.onosproject.event.EventListener; + +/** + * Entity capable of receiving device partition-related events. + */ +@Beta +public interface PartitionEventListener extends EventListener<PartitionEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionService.java new file mode 100644 index 00000000..02ccccac --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PartitionService.java @@ -0,0 +1,48 @@ +/* + * 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 org.onosproject.cluster.NodeId; +import org.onosproject.event.ListenerService; + +/** + * Service for interacting with the partition-to-instance assignments. + */ +@Beta +public interface PartitionService + extends ListenerService<PartitionEvent, PartitionEventListener> { + + /** + * Returns whether the given intent key is in a partition owned by this + * instance or not. + * + * @param intentKey intent key to query + * @return true if the key is owned by this instance, otherwise false + */ + boolean isMine(Key intentKey); + + /** + * Returns the leader for a particular key. + * + * @param intentKey intent key to query + * @return the leader node + */ + NodeId getLeader(Key intentKey); + + // TODO add API for rebalancing partitions + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java new file mode 100644 index 00000000..dffbabfe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java @@ -0,0 +1,202 @@ +/* + * Copyright 2014-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 java.util.List; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Abstraction of explicitly path specified connectivity intent. + */ +@Beta +public class PathIntent extends ConnectivityIntent { + + private final Path path; + + /** + * Creates a new point-to-point intent with the supplied ingress/egress + * ports and using the specified explicit path. + * + * @param appId application identifier + * @param selector traffic selector + * @param treatment treatment + * @param path traversed links + * @param constraints optional list of constraints + * @param priority priority to use for the generated flows + * @throws NullPointerException {@code path} is null + */ + protected PathIntent(ApplicationId appId, + TrafficSelector selector, + TrafficTreatment treatment, + Path path, + List<Constraint> constraints, + int priority) { + super(appId, null, resources(path.links()), selector, treatment, constraints, + priority); + PathIntent.validate(path.links()); + this.path = path; + } + + /** + * Constructor for serializer. + */ + protected PathIntent() { + super(); + this.path = null; + } + + /** + * Returns a new host to host intent builder. + * + * @return host to host intent builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder of a host to host intent. + */ + public static class Builder extends ConnectivityIntent.Builder { + Path path; + + protected Builder() { + // Hide default 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); + } + + /** + * Sets the path of the intent that will be built. + * + * @param path path for the intent + * @return this builder + */ + public Builder path(Path path) { + this.path = path; + return this; + } + + /** + * Builds a path intent from the accumulated parameters. + * + * @return point to point intent + */ + public PathIntent build() { + + return new PathIntent( + appId, + selector, + treatment, + path, + constraints, + priority + ); + } + } + + + + // NOTE: This methods takes linear time with the number of links. + /** + * Validates that source element ID and destination element ID of a link are + * different for the specified all links and that destination element ID of a link and source + * element ID of the next adjacent source element ID are same for the specified all links. + * + * @param links links to be validated + */ + public static void validate(List<Link> links) { + checkArgument(Iterables.all(links, new Predicate<Link>() { + @Override + public boolean apply(Link link) { + return !link.src().elementId().equals(link.dst().elementId()); + } + }), "element of src and dst in a link must be different: {}", links); + + boolean adjacentSame = true; + for (int i = 0; i < links.size() - 1; i++) { + if (!links.get(i).dst().elementId().equals(links.get(i + 1).src().elementId())) { + adjacentSame = false; + break; + } + } + checkArgument(adjacentSame, "adjacent links must share the same element: {}", links); + } + + /** + * Returns the links which the traffic goes along. + * + * @return traversed links + */ + public Path path() { + return path; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("id", id()) + .add("appId", appId()) + .add("priority", priority()) + .add("resources", resources()) + .add("selector", selector()) + .add("treatment", treatment()) + .add("constraints", constraints()) + .add("path", path) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java new file mode 100644 index 00000000..d3f7529d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java @@ -0,0 +1,215 @@ +/* + * Copyright 2014-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 java.util.Collections; +import java.util.List; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of point-to-point connectivity. + */ +@Beta +public final class PointToPointIntent extends ConnectivityIntent { + + private final ConnectPoint ingressPoint; + private final ConnectPoint egressPoint; + + /** + * Returns a new point to point intent builder. The application id, + * ingress point and egress point are required fields. If they are + * not set by calls to the appropriate methods, an exception will + * be thrown. + * + * @return point to point builder + */ + public static PointToPointIntent.Builder builder() { + return new Builder(); + } + + /** + * Builder of a point to point intent. + */ + public static final class Builder extends ConnectivityIntent.Builder { + ConnectPoint ingressPoint; + ConnectPoint egressPoint; + + 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); + } + + /** + * Sets the ingress point of the point to point intent that will be built. + * + * @param ingressPoint ingress connect point + * @return this builder + */ + public Builder ingressPoint(ConnectPoint ingressPoint) { + this.ingressPoint = ingressPoint; + return this; + } + + /** + * Sets the egress point of the point to point intent that will be built. + * + * @param egressPoint egress connect point + * @return this builder + */ + public Builder egressPoint(ConnectPoint egressPoint) { + this.egressPoint = egressPoint; + return this; + } + + /** + * Builds a point to point intent from the accumulated parameters. + * + * @return point to point intent + */ + public PointToPointIntent build() { + + return new PointToPointIntent( + appId, + key, + selector, + treatment, + ingressPoint, + egressPoint, + constraints, + priority + ); + } + } + + + + /** + * Creates a new point-to-point intent with the supplied ingress/egress + * ports and constraints. + * + * @param appId application identifier + * @param key key of the intent + * @param selector traffic selector + * @param treatment treatment + * @param ingressPoint ingress port + * @param egressPoint egress port + * @param constraints optional list of constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code ingressPoint} or + * {@code egressPoints} or {@code appId} is null. + */ + private PointToPointIntent(ApplicationId appId, + Key key, + TrafficSelector selector, + TrafficTreatment treatment, + ConnectPoint ingressPoint, + ConnectPoint egressPoint, + List<Constraint> constraints, + int priority) { + super(appId, key, Collections.emptyList(), selector, treatment, constraints, + priority); + + checkArgument(!ingressPoint.equals(egressPoint), + "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint); + + this.ingressPoint = checkNotNull(ingressPoint); + this.egressPoint = checkNotNull(egressPoint); + } + + /** + * Constructor for serializer. + */ + protected PointToPointIntent() { + super(); + this.ingressPoint = null; + this.egressPoint = null; + } + + /** + * Returns the port on which the ingress traffic should be connected to + * the egress. + * + * @return ingress port + */ + public ConnectPoint ingressPoint() { + return ingressPoint; + } + + /** + * Returns the port on which the traffic should egress. + * + * @return egress port + */ + public ConnectPoint egressPoint() { + return egressPoint; + } + + @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("ingress", ingressPoint) + .add("egress", egressPoint) + .add("constraints", constraints()) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java new file mode 100644 index 00000000..de555cf0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java @@ -0,0 +1,219 @@ +/* + * Copyright 2014-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.ImmutableSet; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Collections; +import java.util.Set; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of single source, multiple destination connectivity intent. + */ +@Beta +public final class SinglePointToMultiPointIntent extends ConnectivityIntent { + + private final ConnectPoint ingressPoint; + private final Set<ConnectPoint> egressPoints; + + /** + * Creates a new single-to-multi point connectivity intent. + * + * @param appId application identifier + * @param key intent key + * @param selector traffic selector + * @param treatment treatment + * @param ingressPoint port on which traffic will ingress + * @param egressPoints set of ports on which traffic will egress + * @param constraints constraints to apply to the intent + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code ingressPoint} or + * {@code egressPoints} is null + * @throws IllegalArgumentException if the size of {@code egressPoints} is + * not more than 1 + */ + private SinglePointToMultiPointIntent(ApplicationId appId, + Key key, + TrafficSelector selector, TrafficTreatment treatment, + ConnectPoint ingressPoint, Set<ConnectPoint> egressPoints, + List<Constraint> constraints, + int priority) { + super(appId, key, Collections.emptyList(), selector, treatment, constraints, + priority); + checkNotNull(egressPoints); + checkNotNull(ingressPoint); + checkArgument(!egressPoints.isEmpty(), "Egress point set cannot be empty"); + checkArgument(!egressPoints.contains(ingressPoint), + "Set of egresses should not contain ingress (ingress: %s)", ingressPoint); + + this.ingressPoint = checkNotNull(ingressPoint); + this.egressPoints = egressPoints; + } + + /** + * Returns a new single point to multi point 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 { + ConnectPoint ingressPoint; + Set<ConnectPoint> egressPoints; + + 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); + } + + /** + * Sets the ingress point of the single point to multi point intent + * that will be built. + * + * @param ingressPoint ingress connect point + * @return this builder + */ + public Builder ingressPoint(ConnectPoint ingressPoint) { + this.ingressPoint = ingressPoint; + 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 + */ + public Builder egressPoints(Set<ConnectPoint> egressPoints) { + this.egressPoints = ImmutableSet.copyOf(egressPoints); + return this; + } + + /** + * Builds a single point to multi point intent from the + * accumulated parameters. + * + * @return point to point intent + */ + public SinglePointToMultiPointIntent build() { + + return new SinglePointToMultiPointIntent( + appId, + key, + selector, + treatment, + ingressPoint, + egressPoints, + constraints, + priority + ); + } + } + + /** + * Constructor for serializer. + */ + protected SinglePointToMultiPointIntent() { + super(); + this.ingressPoint = null; + this.egressPoints = null; + } + + /** + * Returns the port on which the ingress traffic should be connected to the + * egress. + * + * @return ingress port + */ + public ConnectPoint ingressPoint() { + return ingressPoint; + } + + /** + * Returns the set of ports on which the traffic should egress. + * + * @return set of egress ports + */ + public Set<ConnectPoint> egressPoints() { + return egressPoints; + } + + @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("ingress", ingressPoint) + .add("egress", egressPoints) + .add("constraints", constraints()) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java new file mode 100644 index 00000000..b9f126f4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java @@ -0,0 +1,195 @@ +/* + * 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 java.util.Collections; +import java.util.List; + +import com.google.common.annotations.Beta; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of bidirectional connectivity between two points in the network. + */ +@Beta +public final class TwoWayP2PIntent extends ConnectivityIntent { + + private final ConnectPoint one; + private final ConnectPoint two; + + + /** + * Creates a new host-to-host intent with the supplied host pair. + * + * @param appId application identifier + * @param key intent key + * @param one first host + * @param two second host + * @param selector action + * @param treatment ingress port + * @param constraints optional prioritized list of path selection constraints + * @param priority priority to use for flows generated by this intent + * @throws NullPointerException if {@code one} or {@code two} is null. + */ + private TwoWayP2PIntent(ApplicationId appId, Key key, + ConnectPoint one, ConnectPoint two, + TrafficSelector selector, + TrafficTreatment treatment, + List<Constraint> constraints, + int priority) { + super(appId, key, Collections.emptyList(), selector, treatment, constraints, + priority); + + // TODO: consider whether the case one and two are same is allowed + this.one = checkNotNull(one); + this.two = checkNotNull(two); + + } + + /** + * Returns a new two way intent builder. + * + * @return two way intent builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder of a point to point intent. + */ + public static final class Builder extends ConnectivityIntent.Builder { + ConnectPoint one; + ConnectPoint two; + + 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); + } + + /** + * Sets the first connection point of the two way intent that will be built. + * + * @param one first connect point + * @return this builder + */ + public Builder one(ConnectPoint one) { + this.one = one; + return this; + } + + /** + * Sets the second connection point of the two way intent that will be built. + * + * @param two second connect point + * @return this builder + */ + public Builder two(ConnectPoint two) { + this.two = two; + return this; + } + + /** + * Builds a point to point intent from the accumulated parameters. + * + * @return point to point intent + */ + public TwoWayP2PIntent build() { + + return new TwoWayP2PIntent( + appId, + key, + one, + two, + selector, + treatment, + constraints, + priority + ); + } + } + + /** + * Returns identifier of the first host. + * + * @return first host identifier + */ + public ConnectPoint one() { + return one; + } + + /** + * Returns identifier of the second host. + * + * @return second host identifier + */ + public ConnectPoint two() { + return two; + } + + @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("constraints", constraints()) + .add("one", one) + .add("two", two) + .toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AnnotationConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AnnotationConstraint.java new file mode 100644 index 00000000..f5439efd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AnnotationConstraint.java @@ -0,0 +1,113 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.util.Objects; + +import static org.onosproject.net.AnnotationKeys.getAnnotatedValue; + +/** + * Constraint that evaluates an arbitrary link annotated value is under the specified threshold. + */ +@Beta +public class AnnotationConstraint extends BooleanConstraint { + + private final String key; + private final double threshold; + + /** + * Creates a new constraint to keep the value for the specified key + * of link annotation under the threshold. + * + * @param key key of link annotation + * @param threshold threshold value of the specified link annotation + */ + public AnnotationConstraint(String key, double threshold) { + this.key = key; + this.threshold = threshold; + } + + // Constructor for serialization + private AnnotationConstraint() { + this.key = ""; + this.threshold = 0; + } + + /** + * Returns the key of link annotation this constraint designates. + * @return key of link annotation + */ + public String key() { + return key; + } + + /** + * Returns the threshold this constraint ensures as link annotated value. + * + * @return threshold as link annotated value + */ + public double threshold() { + return threshold; + } + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + double value = getAnnotatedValue(link, key); + + return value <= threshold; + } + + @Override + public double cost(Link link, LinkResourceService resourceService) { + if (isValid(link, resourceService)) { + return getAnnotatedValue(link, key); + } else { + return -1; + } + } + + @Override + public int hashCode() { + return Objects.hash(key, threshold); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof AnnotationConstraint)) { + return false; + } + + final AnnotationConstraint other = (AnnotationConstraint) obj; + return Objects.equals(this.key, other.key) && Objects.equals(this.threshold, other.threshold); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("key", key) + .add("threshold", threshold) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AsymmetricPathConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AsymmetricPathConstraint.java new file mode 100644 index 00000000..e0f8614c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/AsymmetricPathConstraint.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Constraint that serves as a request for asymmetric bi-directional path. + */ +@Beta +public class AsymmetricPathConstraint implements Constraint { + + @Override + public double cost(Link link, LinkResourceService resourceService) { + return 1; + } + + @Override + public boolean validate(Path path, LinkResourceService resourceService) { + return true; + } + + @Override + public int hashCode() { + return Objects.hashCode(true); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + return true; + } + + @Override + public String toString() { + return toStringHelper(this).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java new file mode 100644 index 00000000..43b8e4b1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java @@ -0,0 +1,96 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.BandwidthResource; +import org.onosproject.net.resource.link.BandwidthResourceRequest; +import org.onosproject.net.resource.link.LinkResourceService; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Constraint that evaluates links based on available bandwidths. + */ +@Beta +public class BandwidthConstraint extends BooleanConstraint { + + private final BandwidthResource bandwidth; + + /** + * Creates a new bandwidth constraint. + * + * @param bandwidth required bandwidth + */ + public BandwidthConstraint(BandwidthResource bandwidth) { + this.bandwidth = checkNotNull(bandwidth, "Bandwidth cannot be null"); + } + + // Constructor for serialization + private BandwidthConstraint() { + this.bandwidth = null; + } + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + for (ResourceRequest request : resourceService.getAvailableResources(link)) { + if (request.type() == ResourceType.BANDWIDTH) { + BandwidthResourceRequest brr = (BandwidthResourceRequest) request; + if (brr.bandwidth().toDouble() >= bandwidth.toDouble()) { + return true; + } + } + } + return false; + } + + /** + * Returns the bandwidth required by this constraint. + * + * @return required bandwidth + */ + public BandwidthResource bandwidth() { + return bandwidth; + } + + @Override + public int hashCode() { + return Objects.hash(bandwidth); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final BandwidthConstraint other = (BandwidthConstraint) obj; + return Objects.equals(this.bandwidth, other.bandwidth); + } + + @Override + public String toString() { + return toStringHelper(this).add("bandwidth", bandwidth).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BooleanConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BooleanConstraint.java new file mode 100644 index 00000000..f1d4ad9f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BooleanConstraint.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.resource.link.LinkResourceService; + +/** + * Abstract base class for various constraints that evaluate link viability + * in a yes/no fashion. + */ +@Beta +public abstract class BooleanConstraint implements Constraint { + + /** + * Returns true if the specified link satisfies the constraint. + * + * @param link link to be validated + * @param resourceService resource service for checking available link resources + * @return true if link is viable + */ + public abstract boolean isValid(Link link, LinkResourceService resourceService); + + /** + * {@inheritDoc} + * + * Negative return value means the specified link does not satisfy this constraint. + * + * @param link {@inheritDoc} + * @param resourceService {@inheritDoc} + * @return {@inheritDoc} + */ + @Override + public double cost(Link link, LinkResourceService resourceService) { + return isValid(link, resourceService) ? +1 : -1; + } + + @Override + public boolean validate(Path path, LinkResourceService resourceService) { + for (Link link : path.links()) { + if (!isValid(link, resourceService)) { + return false; + } + } + return true; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java new file mode 100644 index 00000000..9dd813b2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java @@ -0,0 +1,91 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.LambdaResource; +import org.onosproject.net.resource.link.LinkResourceService; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Constraint that evaluates links based on available lambda. + */ +@Beta +public class LambdaConstraint extends BooleanConstraint { + + private final LambdaResource lambda; + + /** + * Creates a new optical lambda constraint. + * + * @param lambda optional lambda to indicate a specific lambda + */ + public LambdaConstraint(LambdaResource lambda) { + this.lambda = lambda; + } + + // Constructor for serialization + private LambdaConstraint() { + this.lambda = null; + } + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + for (ResourceRequest request : resourceService.getAvailableResources(link)) { + if (request.type() == ResourceType.LAMBDA) { + return true; + } + } + return false; + } + + /** + * Returns the lambda required by this constraint. + * + * @return required lambda + */ + public LambdaResource lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final LambdaConstraint other = (LambdaConstraint) obj; + return Objects.equals(this.lambda, other.lambda); + } + + @Override + public String toString() { + return toStringHelper(this).add("lambda", lambda).toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java new file mode 100644 index 00000000..54eb4ea5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java @@ -0,0 +1,93 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Objects; + +import static org.onosproject.net.AnnotationKeys.LATENCY; +import static org.onosproject.net.AnnotationKeys.getAnnotatedValue; + +/** + * Constraint that evaluates the latency through a path. + */ +@Beta +public class LatencyConstraint implements Constraint { + + private final Duration latency; + + /** + * Creates a new constraint to keep under specified latency through a path. + * @param latency latency to be kept + */ + public LatencyConstraint(Duration latency) { + this.latency = latency; + } + + // Constructor for serialization + private LatencyConstraint() { + this.latency = Duration.ZERO; + } + + public Duration latency() { + return latency; + } + + @Override + public double cost(Link link, LinkResourceService resourceService) { + return getAnnotatedValue(link, LATENCY); + } + + @Override + public boolean validate(Path path, LinkResourceService resourceService) { + double pathLatency = path.links().stream().mapToDouble(link -> cost(link, resourceService)).sum(); + return Duration.of((long) pathLatency, ChronoUnit.MICROS).compareTo(latency) <= 0; + } + + @Override + public int hashCode() { + return Objects.hash(latency); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof LatencyConstraint)) { + return false; + } + + final LatencyConstraint that = (LatencyConstraint) obj; + return Objects.equals(this.latency, that.latency); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("latency", latency) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LinkTypeConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LinkTypeConstraint.java new file mode 100644 index 00000000..ffa4405b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LinkTypeConstraint.java @@ -0,0 +1,108 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.util.Objects; +import java.util.Set; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Constraint that evaluates links based on their type. + */ +@Beta +public class LinkTypeConstraint extends BooleanConstraint { + + private final Set<Link.Type> types; + private final boolean isInclusive; + + /** + * Creates a new constraint for requesting connectivity using or avoiding + * the specified link types. + * + * @param inclusive indicates whether the given link types are to be + * permitted or avoided + * @param types link types + */ + public LinkTypeConstraint(boolean inclusive, Link.Type... types) { + checkNotNull(types, "Link types cannot be null"); + checkArgument(types.length > 0, "There must be more than one type"); + this.types = ImmutableSet.copyOf(types); + this.isInclusive = inclusive; + } + + // Constructor for serialization + private LinkTypeConstraint() { + this.types = null; + this.isInclusive = false; + } + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + boolean contains = types.contains(link.type()); + return isInclusive ? contains : !contains; + } + + /** + * Returns the set of link types. + * + * @return set of link types + */ + public Set<Link.Type> types() { + return types; + } + + /** + * Indicates if the constraint is inclusive or exclusive. + * + * @return true if inclusive + */ + public boolean isInclusive() { + return isInclusive; + } + + @Override + public int hashCode() { + return Objects.hash(types, isInclusive); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final LinkTypeConstraint other = (LinkTypeConstraint) obj; + return Objects.equals(this.types, other.types) && Objects.equals(this.isInclusive, other.isInclusive); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("inclusive", isInclusive) + .add("types", types) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java new file mode 100644 index 00000000..cb1e6b2b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java @@ -0,0 +1,92 @@ +/* + * Copyright 2014-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.constraint; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * Constraint that evaluates elements not passed through. + */ +@Beta +public class ObstacleConstraint extends BooleanConstraint { + + private final Set<DeviceId> obstacles; + + /** + * Creates a new constraint that the specified device are not passed through. + * @param obstacles devices not to be passed + */ + public ObstacleConstraint(DeviceId... obstacles) { + this.obstacles = ImmutableSet.copyOf(obstacles); + } + + // Constructor for serialization + private ObstacleConstraint() { + this.obstacles = Collections.emptySet(); + } + + /** + * Returns the obstacle device ids. + * + * @return Set of obstacle device ids + */ + public Set<DeviceId> obstacles() { + return obstacles; + } + + @Override + public boolean isValid(Link link, LinkResourceService resourceService) { + DeviceId src = link.src().deviceId(); + DeviceId dst = link.dst().deviceId(); + + return !(obstacles.contains(src) || obstacles.contains(dst)); + } + + @Override + public int hashCode() { + return Objects.hash(obstacles); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof ObstacleConstraint)) { + return false; + } + + final ObstacleConstraint that = (ObstacleConstraint) obj; + return Objects.equals(this.obstacles, that.obstacles); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("obstacles", obstacles) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/PartialFailureConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/PartialFailureConstraint.java new file mode 100644 index 00000000..827859b1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/PartialFailureConstraint.java @@ -0,0 +1,49 @@ +/* + * 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.constraint; + +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.intent.ConnectivityIntent; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.intent.Intent; +import org.onosproject.net.resource.link.LinkResourceService; + +/** + * A constraint that allows intents that can only be partially compiled + * (i.e. MultiPointToSinglePointIntent or SinglePointToMultiPointIntent) + * to be installed when some endpoints or paths are not found. + */ +public class PartialFailureConstraint implements Constraint { + @Override + public double cost(Link link, LinkResourceService resourceService) { + return 1; + } + + @Override + public boolean validate(Path path, LinkResourceService resourceService) { + return true; + } + + public static boolean intentAllowsPartialFailure(Intent intent) { + if (intent instanceof ConnectivityIntent) { + ConnectivityIntent connectivityIntent = (ConnectivityIntent) intent; + return connectivityIntent.constraints().stream() + .anyMatch(c -> c instanceof PartialFailureConstraint); + } + return false; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java new file mode 100644 index 00000000..1acf6dfe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014 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.constraint; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.resource.link.LinkResourceService; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Constraint that evaluates elements passed through in order. + */ +@Beta +public class WaypointConstraint implements Constraint { + + private final List<DeviceId> waypoints; + + /** + * Creates a new waypoint constraint. + * + * @param waypoints waypoints + */ + public WaypointConstraint(DeviceId... waypoints) { + checkNotNull(waypoints, "waypoints cannot be null"); + checkArgument(waypoints.length > 0, "length of waypoints should be more than 0"); + this.waypoints = ImmutableList.copyOf(waypoints); + } + + // Constructor for serialization + private WaypointConstraint() { + this.waypoints = Collections.emptyList(); + } + + public List<DeviceId> waypoints() { + return waypoints; + } + + @Override + public double cost(Link link, LinkResourceService resourceService) { + // Always consider the number of hops + return 1; + } + + @Override + public boolean validate(Path path, LinkResourceService resourceService) { + LinkedList<DeviceId> waypoints = new LinkedList<>(this.waypoints); + DeviceId current = waypoints.poll(); + // This is safe because Path class ensures the number of links are more than 0 + Link firstLink = path.links().get(0); + if (firstLink.src().elementId().equals(current)) { + current = waypoints.poll(); + } + + for (Link link : path.links()) { + if (link.dst().elementId().equals(current)) { + current = waypoints.poll(); + // Empty waypoints means passing through all waypoints in the specified order + if (current == null) { + return true; + } + } + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash(waypoints); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof WaypointConstraint)) { + return false; + } + + final WaypointConstraint that = (WaypointConstraint) obj; + return Objects.equals(this.waypoints, that.waypoints); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("waypoints", waypoints) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/package-info.java new file mode 100644 index 00000000..60d8df16 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Definitions of constraints used to refine intent specifications. + */ +package org.onosproject.net.intent.constraint; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/package-info.java new file mode 100644 index 00000000..a86b3118 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/package-info.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014-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. + */ + +/** + * Set of abstractions for conveying high-level intents for treatment of + * selected network traffic by allowing applications to express the + * <em>what</em> rather than the <em>how</em>. This makes such instructions + * largely independent of topology and device specifics, thus allowing them to + * survive topology mutations. + * <p> + * The controller core provides a suite of built-in intents and their compilers + * and installers. However, the intent framework is extensible in that it allows + * additional intents and their compilers or installers to be added + * dynamically at run-time. This allows others to enhance the initial arsenal of + * connectivity and policy-based intents available in base controller software. + * </p> + * <p> + * The following diagram depicts the state transition diagram for each top-level intent:<br> + * <img src="doc-files/intent-states.png" alt="ONOS intent states"> + * </p> + * <p> + * The controller core accepts the intent specifications and translates them, via a + * process referred to as intent compilation, to installable intents, which are + * essentially actionable operations on the network environment. + * These actions are carried out by intent installation process, which results + * in some changes to the environment, e.g. tunnel links being provisioned, + * flow rules being installed on the data-plane, optical lambdas being reserved. + * </p> + * <p> + * After an intent is submitted by an application, it will be sent immediately + * (but asynchronously) into a compiling phase, then to installing phase and if + * all goes according to plan into installed state. Once an application decides + * it no longer wishes the intent to hold, it can withdraw it. This describes + * the nominal flow. However, it may happen that some issue is encountered. + * For example, an application may ask for an objective that is not currently + * achievable, e.g. connectivity across to unconnected network segments. + * If this is the case, the compiling phase may fail to produce a set of + * installable intents and instead result in a failed compile. If this occurs, + * only a change in the environment can trigger a transition back to the + * compiling state. + * </p> + * <p> + * Similarly, an issue may be encountered during the installation phase in + * which case the framework will attempt to recompile the intent to see if an + * alternate approach is available. If so, the intent will be sent back to + * installing phase. Otherwise, it will be parked in the failed state. Another + * scenario that’s very likely to be encountered is where the intent is + * successfully compiled and installed, but due to some topology event, such + * as a downed or downgraded link, loss of throughput may occur or connectivity + * may be lost altogether, thus impacting the viability of a previously + * satisfied intent. If this occurs, the framework will attempt to recompile + * the intent, and if an alternate approach is available, its installation + * will be attempted. Otherwise, the original top-level intent will be parked + * in the failed state. + * </p> + * <p> + * Please note that all *ing states, depicted in orange, are transitional and + * are expected to last only a brief amount of time. The rest of the states + * are parking states where the intent may spent some time; except for the + * submitted state of course. There, the intent may pause, but only briefly, + * while the system determines where to perform the compilation or while it + * performs global recomputation/optimization across all prior intents. + * </p> + * <p> + * The figure below depicts the general interactions between different + * components of the intent subsystem.<br> + * <img src="doc-files/intent-design.png" alt="ONOS intent subsystem design"> + * </p> + */ +package org.onosproject.net.intent; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java new file mode 100644 index 00000000..891eb65d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 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.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Link; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable link description entity. + */ +public class DefaultLinkDescription extends AbstractDescription + implements LinkDescription { + + private final ConnectPoint src; + private final ConnectPoint dst; + private final Link.Type type; + + /** + * Creates a link description using the supplied information. + * + * @param src link source + * @param dst link destination + * @param type link type + * @param annotations optional key/value annotations + */ + public DefaultLinkDescription(ConnectPoint src, ConnectPoint dst, + Link.Type type, SparseAnnotations... annotations) { + super(annotations); + this.src = src; + this.dst = dst; + this.type = type; + } + + @Override + public ConnectPoint src() { + return src; + } + + @Override + public ConnectPoint dst() { + return dst; + } + + @Override + public Link.Type type() { + return type; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("src", src()) + .add("dst", dst()) + .add("type", type()).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkAdminService.java new file mode 100644 index 00000000..a0b5e1e2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkAdminService.java @@ -0,0 +1,50 @@ +/* + * Copyright 2014-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.link; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; + +/** + * Service for administering the inventory of infrastructure links. + */ +public interface LinkAdminService extends LinkService { + + /** + * Removes all infrastructure links leading to and from the + * specified connection point. + * + * @param connectPoint connection point + */ + void removeLinks(ConnectPoint connectPoint); + + /** + * Removes all infrastructure links leading to and from the + * specified device. + * + * @param deviceId device identifier + */ + void removeLinks(DeviceId deviceId); + + /** + * Removes all links between between the specified src and + * dst connection points. + * + * @param src link source + * @param dst link destination + */ + void removeLink(ConnectPoint src, ConnectPoint dst); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkDescription.java new file mode 100644 index 00000000..f85718b7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkDescription.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Description; +import org.onosproject.net.Link; + +/** + * Describes an infrastructure link. + */ +public interface LinkDescription extends Description { + + /** + * Returns the link source. + * + * @return links source + */ + ConnectPoint src(); + + /** + * Returns the link destination. + * + * @return links destination + */ + ConnectPoint dst(); + + /** + * Returns the link type. + * + * @return link type + */ + Link.Type type(); + + // Add further link attributes +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkEvent.java new file mode 100644 index 00000000..d87bce06 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkEvent.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.net.Link; + +/** + * Describes infrastructure link event. + */ +public class LinkEvent extends AbstractEvent<LinkEvent.Type, Link> { + + /** + * Type of link events. + */ + public enum Type { + /** + * Signifies that a new link has been detected. + */ + LINK_ADDED, + + /** + * Signifies that a link has been updated or changed state. + */ + LINK_UPDATED, + + /** + * Signifies that a link has been removed. + */ + LINK_REMOVED + } + + /** + * Creates an event of a given type and for the specified link and the + * current time. + * + * @param type link event type + * @param link event link subject + */ + public LinkEvent(Type type, Link link) { + super(type, link); + } + + /** + * Creates an event of a given type and for the specified link and time. + * + * @param type link event type + * @param link event link subject + * @param time occurrence time + */ + public LinkEvent(Type type, Link link, long time) { + super(type, link, time); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkListener.java new file mode 100644 index 00000000..82f6bdb9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving infrastructure link related events. + */ +public interface LinkListener extends EventListener<LinkEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProvider.java new file mode 100644 index 00000000..ed4348c7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of an entity providing information about infrastructure links + * to the core. + */ +public interface LinkProvider extends Provider { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderRegistry.java new file mode 100644 index 00000000..57a05d93 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of an infrastructure link provider registry. + */ +public interface LinkProviderRegistry + extends ProviderRegistry<LinkProvider, LinkProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderService.java new file mode 100644 index 00000000..f5ef52a2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkProviderService.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +/** + * Means for injecting link information into the core. + */ +public interface LinkProviderService extends ProviderService<LinkProvider> { + + /** + * Signals that an infrastructure link has been detected. + * + * @param linkDescription link information + */ + void linkDetected(LinkDescription linkDescription); + + /** + * Signals that an infrastructure link has disappeared. + * + * @param linkDescription link information + */ + void linkVanished(LinkDescription linkDescription); + + /** + * Signals that infrastructure links associated with the specified + * connect point have vanished. + * + * @param connectPoint connect point + */ + void linksVanished(ConnectPoint connectPoint); + + /** + * Signals that infrastructure links associated with the specified + * device have vanished. + * + * @param deviceId device identifier + */ + void linksVanished(DeviceId deviceId); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkService.java new file mode 100644 index 00000000..c27e3110 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkService.java @@ -0,0 +1,116 @@ +/* + * Copyright 2014 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.link; + +import java.util.Set; + +import org.onosproject.event.ListenerService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; + +/** + * Service for interacting with the inventory of infrastructure links. + */ +public interface LinkService + extends ListenerService<LinkEvent, LinkListener> { + + /** + * Returns the count of all known infrastructure links. + * + * @return number of infrastructure links + */ + int getLinkCount(); + + /** + * Returns a collection of all known infrastructure links. + * + * @return all infrastructure links + */ + Iterable<Link> getLinks(); + + /** + * Returns a collection of all active infrastructure links. + * + * @return all infrastructure links + */ + Iterable<Link> getActiveLinks(); + + /** + * Returns set of all infrastructure links leading to and from the + * specified device. + * + * @param deviceId device identifier + * @return set of device links + */ + Set<Link> getDeviceLinks(DeviceId deviceId); + + /** + * Returns set of all infrastructure links leading from the specified device. + * + * @param deviceId device identifier + * @return set of device egress links + */ + Set<Link> getDeviceEgressLinks(DeviceId deviceId); + + /** + * Returns set of all infrastructure links leading to the specified device. + * + * @param deviceId device identifier + * @return set of device ingress links + */ + Set<Link> getDeviceIngressLinks(DeviceId deviceId); + + /** + * Returns set of all infrastructure links leading to and from the + * specified connection point. + * + * @param connectPoint connection point + * @return set of links + */ + Set<Link> getLinks(ConnectPoint connectPoint); + + /** + * Returns set of all infrastructure links leading from the specified + * connection point. + * + * @param connectPoint connection point + * @return set of device egress links + */ + Set<Link> getEgressLinks(ConnectPoint connectPoint); + + /** + * Returns set of all infrastructure links leading to the specified + * connection point. + * + * @param connectPoint connection point + * @return set of device ingress links + */ + Set<Link> getIngressLinks(ConnectPoint connectPoint); + + // FIXME: I don't think this makes sense; discuss and remove or adjust return + // to be a Set<Link> or add Link.Type parameter + /** + * Returns the infrastructure links between the specified source + * and destination connection points. + * + * @param src source connection point + * @param dst destination connection point + * @return link from source to destination; null if none found + */ + Link getLink(ConnectPoint src, ConnectPoint dst); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStore.java new file mode 100644 index 00000000..04c8773b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStore.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Manages inventory of infrastructure links; not intended for direct use. + */ +public interface LinkStore extends Store<LinkEvent, LinkStoreDelegate> { + + /** + * Returns the number of links in the store. + * + * @return number of links + */ + int getLinkCount(); + + /** + * Returns an iterable collection of all links in the inventory. + * + * @return collection of all links + */ + Iterable<Link> getLinks(); + + /** + * Returns all links egressing from the specified device. + * + * @param deviceId device identifier + * @return set of device links + */ + Set<Link> getDeviceEgressLinks(DeviceId deviceId); + + /** + * Returns all links ingressing from the specified device. + * + * @param deviceId device identifier + * @return set of device links + */ + Set<Link> getDeviceIngressLinks(DeviceId deviceId); + + /** + * Returns the link between the two end-points. + * + * @param src source connection point + * @param dst destination connection point + * @return link or null if one not found between the end-points + */ + Link getLink(ConnectPoint src, ConnectPoint dst); + + /** + * Returns all links egressing from the specified connection point. + * + * @param src source connection point + * @return set of connection point links + */ + Set<Link> getEgressLinks(ConnectPoint src); + + /** + * Returns all links ingressing to the specified connection point. + * + * @param dst destination connection point + * @return set of connection point links + */ + Set<Link> getIngressLinks(ConnectPoint dst); + + /** + * Creates a new link, or updates an existing one, based on the given + * information. + * + * @param providerId provider identity + * @param linkDescription link description + * @return create or update link event, or null if no change resulted + */ + LinkEvent createOrUpdateLink(ProviderId providerId, + LinkDescription linkDescription); + + /** + * Removes the link, or marks it as inactive if the link is durable, + * based on the specified information. + * + * @param src link source + * @param dst link destination + * @return remove or update link event, or null if no change resulted + */ + LinkEvent removeOrDownLink(ConnectPoint src, ConnectPoint dst); + + /** + * Removes the link based on the specified information. + * + * @param src link source + * @param dst link destination + * @return remove link event, or null if no change resulted + */ + LinkEvent removeLink(ConnectPoint src, ConnectPoint dst); + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStoreDelegate.java new file mode 100644 index 00000000..1f66dd49 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/LinkStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.link; + +import org.onosproject.store.StoreDelegate; + +/** + * Infrastructure link store delegate abstraction. + */ +public interface LinkStoreDelegate extends StoreDelegate<LinkEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/package-info.java new file mode 100644 index 00000000..57aa5fa2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Infrastructure link model & related services API definitions. + */ +package org.onosproject.net.link; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Band.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Band.java new file mode 100644 index 00000000..2bfafad2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Band.java @@ -0,0 +1,133 @@ +/* + * 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.meter; + +/** + * Represents a band used within a meter. + */ +public interface Band { + + /** + * Specifies the type of band. + */ + enum Type { + /** + * Simple rate limiter which drops packets + * when the rate is exceeded. + */ + DROP, + + /** + * defines a simple DiffServ policer that remark + * the drop precedence of the DSCP field in the + * IP header of the packets that exceed the band + * rate value. + */ + REMARK + } + + /** + * The rate at which this meter applies. + * + * @return the long value of the rate + */ + long rate(); + + /** + * The burst size at which the meter applies. + * + * @return the long value of the size + */ + long burst(); + + /** + * Only meaningful in the case of a REMARK band type. + * indicates by which amount the drop precedence of + * the packet should be increase if the band is exceeded. + * + * @return a short value + */ + short dropPrecedence(); + + /** + * Signals the type of band to create. + * + * @return a band type + */ + Type type(); + + /** + * Returns the packets seen by this band. + * + * @return a long value + */ + long packets(); + + /** + * Return the bytes seen by this band. + * + * @return a byte counter + */ + long bytes(); + + interface Builder { + + /** + * Assigns a rate to this band. The units for this rate + * are defined in the encapsulating meter. + * + * @param rate a long value + * @return this + */ + Builder withRate(long rate); + + /** + * Assigns a burst size to this band. Only meaningful if + * the encapsulating meter is of burst type. + * + * @param burstSize a long value. + * @return this + */ + Builder burstSize(long burstSize); + + /** + * Assigns the drop precedence for this band. Only meaningful if + * the band is of REMARK type. + * + * @param prec a short value + * @return this + */ + Builder dropPrecedence(short prec); + + /** + * Assigns the @See Type of this band. + * + * @param type a band type + * @return this + */ + Builder ofType(Type type); + + /** + * Builds the band. + * + * @return a band + */ + Band build(); + + } + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/BandEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/BandEntry.java new file mode 100644 index 00000000..03145e91 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/BandEntry.java @@ -0,0 +1,37 @@ +/* + * 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.meter; + +/** + * Represents a stored band. + */ +public interface BandEntry extends Band { + + /** + * Sets the number of packets seen by this band. + * + * @param packets a packet count + */ + void setPackets(long packets); + + /** + * Sets the number of bytes seen by this band. + * + * @param bytes a byte counter + */ + void setBytes(long bytes); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java new file mode 100644 index 00000000..58a24766 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultBand.java @@ -0,0 +1,136 @@ +/* + * 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.meter; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; + +/** + * A default implementation for a Band. + */ +public final class DefaultBand implements Band, BandEntry { + + private final Type type; + private final long rate; + //TODO: should be made optional + private final Long burstSize; + private final Short prec; + private long packets; + private long bytes; + + public DefaultBand(Type type, long rate, + Long burstSize, Short prec) { + this.type = type; + this.rate = rate; + this.burstSize = burstSize; + this.prec = prec; + } + + @Override + public long rate() { + return rate; + } + + @Override + public long burst() { + return burstSize; + } + + @Override + public short dropPrecedence() { + return prec; + } + + @Override + public Type type() { + return type; + } + + @Override + public long packets() { + return packets; + } + + @Override + public long bytes() { + return bytes; + } + + @Override + public void setPackets(long packets) { + this.packets = packets; + } + + @Override + public void setBytes(long bytes) { + this.bytes = bytes; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("rate", rate) + .add("burst-size", burstSize) + .add("type", type) + .add("drop-precedence", prec).toString(); + } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder implements Band.Builder { + + private long rate; + private Long burstSize; + private Short prec; + private Type type; + + @Override + public Band.Builder withRate(long rate) { + this.rate = rate; + return this; + } + + @Override + public Band.Builder burstSize(long burstSize) { + this.burstSize = burstSize; + return this; + } + + @Override + public Band.Builder dropPrecedence(short prec) { + this.prec = prec; + return this; + } + + @Override + public Band.Builder ofType(Type type) { + this.type = type; + return this; + } + + @Override + public DefaultBand build() { + checkArgument(type != Type.REMARK && prec == null, + "Only REMARK bands can have a precendence."); + + return new DefaultBand(type, rate, burstSize, prec); + } + + + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeter.java new file mode 100644 index 00000000..f7d6210d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeter.java @@ -0,0 +1,233 @@ +/* + * 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.meter; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableSet; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +import java.util.Collection; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A default implementation of a meter. + */ +public final class DefaultMeter implements Meter, MeterEntry { + + + private final MeterId id; + private final ApplicationId appId; + private final Unit unit; + private final boolean burst; + private final Collection<Band> bands; + private final DeviceId deviceId; + + private MeterState state; + private long life; + private long refCount; + private long packets; + private long bytes; + + private DefaultMeter(DeviceId deviceId, MeterId id, ApplicationId appId, + Unit unit, boolean burst, + Collection<Band> bands) { + this.deviceId = deviceId; + this.id = id; + this.appId = appId; + this.unit = unit; + this.burst = burst; + this.bands = bands; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public MeterId id() { + return id; + } + + @Override + public ApplicationId appId() { + return appId; + } + + @Override + public Unit unit() { + return unit; + } + + @Override + public boolean isBurst() { + return burst; + } + + @Override + public Collection<Band> bands() { + return bands; + } + + @Override + public MeterState state() { + return state; + } + + @Override + public long life() { + return life; + } + + @Override + public long referenceCount() { + return refCount; + } + + @Override + public long packetsSeen() { + return packets; + } + + @Override + public long bytesSeen() { + return bytes; + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public void setState(MeterState state) { + this.state = state; + } + + @Override + public void setLife(long life) { + this.life = life; + } + + @Override + public void setReferenceCount(long count) { + this.refCount = count; + } + + @Override + public void setProcessedPackets(long packets) { + this.packets = packets; + } + + @Override + public void setProcessedBytes(long bytes) { + this.bytes = bytes; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("device", deviceId) + .add("id", id) + .add("appId", appId.name()) + .add("unit", unit) + .add("isBurst", burst) + .add("state", state) + .add("bands", bands).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DefaultMeter that = (DefaultMeter) o; + return Objects.equal(id, that.id) && + Objects.equal(appId, that.appId) && + Objects.equal(unit, that.unit) && + Objects.equal(deviceId, that.deviceId); + } + + @Override + public int hashCode() { + return Objects.hashCode(id, appId, unit, deviceId); + } + + public static final class Builder implements Meter.Builder { + + private MeterId id; + private ApplicationId appId; + private Unit unit = Unit.KB_PER_SEC; + private boolean burst = false; + private Collection<Band> bands; + private DeviceId deviceId; + + + @Override + public Meter.Builder forDevice(DeviceId deviceId) { + this.deviceId = deviceId; + return this; + } + + @Override + public Meter.Builder withId(MeterId id) { + this.id = id; + return this; + } + + @Override + public Meter.Builder fromApp(ApplicationId appId) { + this.appId = appId; + return this; + } + + @Override + public Meter.Builder withUnit(Unit unit) { + this.unit = unit; + return this; + } + + @Override + public Meter.Builder burst() { + this.burst = true; + return this; + } + + @Override + public Meter.Builder withBands(Collection<Band> bands) { + this.bands = ImmutableSet.copyOf(bands); + return this; + } + + @Override + public DefaultMeter build() { + checkNotNull(deviceId, "Must specify a device"); + checkNotNull(bands, "Must have bands."); + checkArgument(bands.size() > 0, "Must have at least one band."); + checkNotNull(appId, "Must have an application id"); + checkNotNull(id, "Must specify a meter id"); + return new DefaultMeter(deviceId, id, appId, unit, burst, bands); + } + + + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterRequest.java new file mode 100644 index 00000000..94cada47 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterRequest.java @@ -0,0 +1,171 @@ +/* + * 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.meter; + +import com.google.common.collect.ImmutableSet; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +import java.util.Collection; +import java.util.Optional; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A default implementation of a meter. + */ +public final class DefaultMeterRequest implements MeterRequest { + + + + private final ApplicationId appId; + private final Meter.Unit unit; + private final boolean burst; + private final Collection<Band> bands; + private final DeviceId deviceId; + private final Optional<MeterContext> context; + private final Type op; + + private DefaultMeterRequest(DeviceId deviceId, ApplicationId appId, + Meter.Unit unit, boolean burst, + Collection<Band> bands, MeterContext context, Type op) { + this.deviceId = deviceId; + this.appId = appId; + this.unit = unit; + this.burst = burst; + this.bands = bands; + this.context = Optional.ofNullable(context); + this.op = op; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public ApplicationId appId() { + return appId; + } + + @Override + public Meter.Unit unit() { + return unit; + } + + @Override + public boolean isBurst() { + return burst; + } + + @Override + public Collection<Band> bands() { + return bands; + } + + @Override + public Optional<MeterContext> context() { + return context; + } + + + + public static Builder builder() { + return new Builder(); + } + + @Override + public String toString() { + return toStringHelper(this) + .add("device", deviceId) + .add("appId", appId.name()) + .add("unit", unit) + .add("isBurst", burst) + .add("bands", bands).toString(); + } + + public static final class Builder implements MeterRequest.Builder { + + private ApplicationId appId; + private Meter.Unit unit = Meter.Unit.KB_PER_SEC; + private boolean burst = false; + private Collection<Band> bands; + private DeviceId deviceId; + private MeterContext context; + + + @Override + public MeterRequest.Builder forDevice(DeviceId deviceId) { + this.deviceId = deviceId; + return this; + } + + @Override + public MeterRequest.Builder fromApp(ApplicationId appId) { + this.appId = appId; + return this; + } + + @Override + public MeterRequest.Builder withUnit(Meter.Unit unit) { + this.unit = unit; + return this; + } + + @Override + public MeterRequest.Builder burst() { + this.burst = true; + return this; + } + + @Override + public MeterRequest.Builder withBands(Collection<Band> bands) { + this.bands = ImmutableSet.copyOf(bands); + return this; + } + + @Override + public MeterRequest.Builder withContext(MeterContext context) { + this.context = context; + return this; + } + + @Override + public MeterRequest add() { + validate(); + return new DefaultMeterRequest(deviceId, appId, unit, burst, bands, + context, Type.ADD); + } + + @Override + public MeterRequest remove() { + validate(); + return new DefaultMeterRequest(deviceId, appId, unit, burst, bands, + context, Type.REMOVE); + } + + private void validate() { + checkNotNull(deviceId, "Must specify a device"); + checkNotNull(bands, "Must have bands."); + checkArgument(bands.size() > 0, "Must have at least one band."); + checkNotNull(appId, "Must have an application id"); + } + + + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Meter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Meter.java new file mode 100644 index 00000000..98ebc350 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/Meter.java @@ -0,0 +1,179 @@ +/* + * 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.meter; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +import java.util.Collection; + +/** + * Represents a generalized meter to be deployed on a device. + */ +public interface Meter { + + enum Unit { + /** + * Packets per second. + */ + PKTS_PER_SEC, + + /** + * Kilo bits per second. + */ + KB_PER_SEC + } + + /** + * The target device for this meter. + * + * @return a device id + */ + DeviceId deviceId(); + + /** + * This meters id. + * + * @return a meter id + */ + MeterId id(); + + /** + * The id of the application which created this meter. + * + * @return an application id + */ + ApplicationId appId(); + + /** + * The unit used within this meter. + * + * @return the unit + */ + Unit unit(); + + /** + * Signals whether this meter applies to bursts only. + * + * @return a boolean + */ + boolean isBurst(); + + /** + * The collection of bands to apply on the dataplane. + * + * @return a collection of bands. + */ + Collection<Band> bands(); + + /** + * Fetches the state of this meter. + * + * @return a meter state + */ + MeterState state(); + + /** + * The lifetime in seconds of this meter. + * + * @return number of seconds + */ + long life(); + + /** + * The number of flows pointing to this meter. + * + * @return a reference count + */ + long referenceCount(); + + /** + * Number of packets processed by this meter. + * + * @return a packet count + */ + long packetsSeen(); + + /** + * Number of bytes processed by this meter. + * + * @return a byte count + */ + long bytesSeen(); + + /** + * A meter builder. + */ + interface Builder { + + /** + * Assigns the target device for this meter. + * + * @param deviceId a device id + * @return this + */ + Builder forDevice(DeviceId deviceId); + + /** + * Assigns the id to this meter. + * + * @param id a e + * @return this + */ + Builder withId(MeterId id); + + /** + * Assigns the application that built this meter. + * + * @param appId an application id + * @return this + */ + Builder fromApp(ApplicationId appId); + + /** + * Assigns the @See Unit to use for this meter. + * Defaults to kb/s + * + * @param unit a unit + * @return this + */ + Builder withUnit(Unit unit); + + /** + * Sets this meter as applicable to burst traffic only. + * Defaults to false. + * + * @return this + */ + Builder burst(); + + /** + * Assigns bands to this meter. There must be at least one band. + * + * @param bands a collection of bands + * @return this + */ + Builder withBands(Collection<Band> bands); + + /** + * Builds the meter based on the specified parameters. + * + * @return a meter + */ + Meter build(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterContext.java new file mode 100644 index 00000000..574bdca9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterContext.java @@ -0,0 +1,38 @@ +/* + * 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.meter; + +/** + * A context permitting the application to be notified when the + * meter installation has been successful. + */ +public interface MeterContext { + + /** + * Invoked on successful installation of the meter. + * + * @param op a meter + */ + default void onSuccess(MeterRequest op) {} + + /** + * Invoked when error is encountered while installing a meter. + * + * @param op a meter + * @param reason the reason why it failed + */ + default void onError(MeterRequest op, MeterFailReason reason) {} +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEntry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEntry.java new file mode 100644 index 00000000..178a564c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEntry.java @@ -0,0 +1,57 @@ +/* + * 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.meter; + +/** + * Represents a stored meter. + */ +public interface MeterEntry extends Meter { + + /** + * Updates the state of this meter. + * + * @param state a meter state + */ + void setState(MeterState state); + + /** + * Set the amount of time the meter has existed in seconds. + * + * @param life number of seconds + */ + void setLife(long life); + + /** + * Sets the number of flows which are using this meter. + * + * @param count a reference count. + */ + void setReferenceCount(long count); + + /** + * Updates the number of packets seen by this meter. + * + * @param packets a packet count. + */ + void setProcessedPackets(long packets); + + /** + * Updates the number of bytes seen by the meter. + * + * @param bytes a byte counter. + */ + void setProcessedBytes(long bytes); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java new file mode 100644 index 00000000..72f0a53a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java @@ -0,0 +1,62 @@ +/* + * 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.meter; + +import org.onosproject.event.AbstractEvent; + +/** + * Entity that represents Meter events. + */ +public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> { + + + public enum Type { + /** + * A meter addition was requested. + */ + METER_ADD_REQ, + + /** + * A meter removal was requested. + */ + METER_REM_REQ + } + + + /** + * Creates an event of a given type and for the specified meter and the + * current time. + * + * @param type meter event type + * @param meter event subject + */ + public MeterEvent(Type type, Meter meter) { + super(type, meter); + } + + /** + * Creates an event of a given type and for the specified meter and time. + * + * @param type meter event type + * @param meter event subject + * @param time occurrence time + */ + public MeterEvent(Type type, Meter meter, long time) { + super(type, meter, time); + } + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterFailReason.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterFailReason.java new file mode 100644 index 00000000..8683e2a2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterFailReason.java @@ -0,0 +1,89 @@ +/* + * 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.meter; + +/** + * Enum used to represent a meter failure condition. + */ +public enum MeterFailReason { + /** + * A meter with the same identifier already exists. + * Essentially a duplicate meter exists. + */ + EXISTING_METER, + + /** + * The device does not support any more meters. + */ + OUT_OF_METERS, + + /** + * The device does not support any more bands for this meter. + */ + OUT_OF_BANDS, + + /** + * The meter that was attempted to be modified is unknown. + */ + UNKNOWN, + + /** + * The operation for this meter installation timed out. + */ + TIMEOUT, + + /** + * Invalid meter definition. + */ + INVALID_METER, + + /** + * The target device is unknown. + */ + UNKNOWN_DEVICE, + + /** + * Unknown command. + */ + UNKNOWN_COMMAND, + + /** + * Unknown flags. + */ + UNKNOWN_FLAGS, + + /** + * Bad rate value. + */ + BAD_RATE, + + /** + * Bad burst size value. + */ + BAD_BURST, + + /** + * Bad band. + */ + BAD_BAND, + + /** + * Bad value value. + */ + BAD_BAND_VALUE + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterId.java new file mode 100644 index 00000000..872de2d8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterId.java @@ -0,0 +1,78 @@ +/* + * 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.meter; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * A representation of a meter id. + * Uniquely identifies a meter system wide. + */ +public final class MeterId { + + static final long MAX = 0xFFFF0000; + + private final long id; + + public static final MeterId SLOWPATH = new MeterId(0xFFFFFFFD); + public static final MeterId CONTROLLER = new MeterId(0xFFFFFFFE); + public static final MeterId ALL = new MeterId(0xFFFFFFFF); + + private MeterId(long id) { + checkArgument(id >= MAX, "id cannot be larger than 0xFFFF0000"); + this.id = id; + } + + /** + * The integer representation of the meter id. + * + * @return a long + */ + public long id() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + MeterId meterId = (MeterId) o; + + return id == meterId.id; + + } + + @Override + public int hashCode() { + return Long.hashCode(id); + } + + @Override + public String toString() { + return Long.toHexString(this.id); + } + + public static MeterId meterId(long id) { + return new MeterId(id); + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterListener.java new file mode 100644 index 00000000..0a5e203f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterListener.java @@ -0,0 +1,24 @@ +/* + * 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.meter; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving Meter related events. + */ +public interface MeterListener extends EventListener<MeterEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperation.java new file mode 100644 index 00000000..437dd269 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperation.java @@ -0,0 +1,88 @@ +/* + * 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.meter; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +/** + * Representation of an operation on the meter table. + */ +public class MeterOperation { + + + /** + * Tyoe of meter operation. + */ + public enum Type { + ADD, + REMOVE, + MODIFY + } + + private final Meter meter; + private final Type type; + + + public MeterOperation(Meter meter, Type type) { + this.meter = meter; + this.type = type; + } + + /** + * Returns the type of operation. + * + * @return type + */ + public Type type() { + return type; + } + + /** + * Returns the meter. + * + * @return a meter + */ + public Meter meter() { + return meter; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("meter", meter) + .add("type", type) + .toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MeterOperation that = (MeterOperation) o; + return Objects.equal(meter, that.meter) && + Objects.equal(type, that.type); + } + + @Override + public int hashCode() { + return Objects.hashCode(meter, type); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperations.java new file mode 100644 index 00000000..92b0c3aa --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterOperations.java @@ -0,0 +1,50 @@ +/* + * 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.meter; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Immutable collection of meter operation to be used between + * core and provider layers of group subsystem. + * + */ +public final class MeterOperations { + private final List<MeterOperation> operations; + + /** + * Creates a immutable list of meter operation. + * + * @param operations list of meter operation + */ + public MeterOperations(List<MeterOperation> operations) { + this.operations = ImmutableList.copyOf(checkNotNull(operations)); + } + + /** + * Returns immutable list of Meter operation. + * + * @return list of Meter operation + */ + public List<MeterOperation> operations() { + return operations; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProvider.java new file mode 100644 index 00000000..4655e234 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProvider.java @@ -0,0 +1,48 @@ +/* + * 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.meter; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of a Meter provider. + */ +public interface MeterProvider extends Provider { + + /** + * Performs a batch of meter operation on the specified device with the + * specified parameters. + * + * @param deviceId device identifier on which the batch of group + * operations to be executed + * @param meterOps immutable list of meter operation + */ + void performMeterOperation(DeviceId deviceId, + MeterOperations meterOps); + + + /** + * Performs a meter operation on the specified device with the + * specified parameters. + * + * @param deviceId device identifier on which the batch of group + * operations to be executed + * @param meterOp a meter operation + */ + void performMeterOperation(DeviceId deviceId, + MeterOperation meterOp); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderRegistry.java new file mode 100644 index 00000000..019ca19a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderRegistry.java @@ -0,0 +1,27 @@ +/* + * 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.meter; + + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction for a meter provider registry. + */ +public interface MeterProviderRegistry + extends ProviderRegistry<MeterProvider, MeterProviderService> { +} + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java new file mode 100644 index 00000000..85c0c43e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java @@ -0,0 +1,49 @@ +/* + * 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.meter; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +import java.util.Collection; + +/** + * Service through which meter providers can inject information + * into the core. + */ +public interface MeterProviderService extends ProviderService<MeterProvider> { + + /** + * Notifies the core that a meter operaton failed for a + * specific reason. + * @param operation the failed operation + * @param reason the failure reason + */ + void meterOperationFailed(MeterOperation operation, + MeterFailReason reason); + + /** + * Pushes the collection of meters observed on the data plane as + * well as their associated statistics. + * + * @param deviceId a device id + * @param meterEntries a collection of meter entries + */ + void pushMeterMetrics(DeviceId deviceId, + Collection<Meter> meterEntries); + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterRequest.java new file mode 100644 index 00000000..fd11ca41 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterRequest.java @@ -0,0 +1,147 @@ +/* + * 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.meter; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; + +import java.util.Collection; +import java.util.Optional; + +/** + * Represents a generalized meter request to be deployed on a device. + */ +public interface MeterRequest { + + enum Type { + ADD, + MODIFY, + REMOVE + } + + /** + * The target device for this meter. + * + * @return a device id + */ + DeviceId deviceId(); + + /** + * The id of the application which created this meter. + * + * @return an application id + */ + ApplicationId appId(); + + /** + * The unit used within this meter. + * + * @return the unit + */ + Meter.Unit unit(); + + /** + * Signals whether this meter applies to bursts only. + * + * @return a boolean + */ + boolean isBurst(); + + /** + * The collection of bands to apply on the dataplane. + * + * @return a collection of bands. + */ + Collection<Band> bands(); + + /** + * Returns the callback context for this meter. + * + * @return an optional meter context + */ + Optional<MeterContext> context(); + + /** + * A meter builder. + */ + interface Builder { + + /** + * Assigns the target device for this meter. + * + * @param deviceId a device id + * @return this + */ + Builder forDevice(DeviceId deviceId); + + /** + * Assigns the application that built this meter. + * + * @param appId an application id + * @return this + */ + Builder fromApp(ApplicationId appId); + + /** + * Assigns the @See Unit to use for this meter. + * Defaults to kb/s + * + * @param unit a unit + * @return this + */ + Builder withUnit(Meter.Unit unit); + + /** + * Sets this meter as applicable to burst traffic only. + * Defaults to false. + * + * @return this + */ + Builder burst(); + + /** + * Assigns bands to this meter. There must be at least one band. + * + * @param bands a collection of bands + * @return this + */ + Builder withBands(Collection<Band> bands); + + /** + * Assigns an execution context for this meter request. + * + * @param context a meter context + * @return this + */ + Builder withContext(MeterContext context); + + /** + * Requests the addition of a meter. + * + * @return a meter request + */ + MeterRequest add(); + + /** + * Requests the removal of a meter. + * + * @return a meter request + */ + MeterRequest remove(); + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterService.java new file mode 100644 index 00000000..bdc90eb7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterService.java @@ -0,0 +1,61 @@ +/* + * 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.meter; + +import org.onosproject.event.ListenerService; + +import java.util.Collection; + +/** + * Service for add/updating and removing meters. Meters are + * are assigned to flow to rate limit them and provide a certain + * quality of service. + */ +public interface MeterService + extends ListenerService<MeterEvent, MeterListener> { + + /** + * Adds a meter to the system and performs it installation. + * + * @param meter a meter + * @return a meter (with a meter id) + */ + Meter submit(MeterRequest meter); + + /** + * Remove a meter from the system and the dataplane. + * + * @param meter a meter to remove + * @param meterId the meter id of the meter to remove. + */ + void withdraw(MeterRequest meter, MeterId meterId); + + /** + * Fetch the meter by the meter id. + * + * @param id a meter id + * @return a meter + */ + Meter getMeter(MeterId id); + + /** + * Fetches all the meters. + * + * @return a collection of meters + */ + Collection<Meter> getAllMeters(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterState.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterState.java new file mode 100644 index 00000000..3b936099 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterState.java @@ -0,0 +1,43 @@ +/* + * 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.meter; + +/** + * Represents the state of the meter as seen by the store. + */ +public enum MeterState { + + /** + * The meter is in the process of being added. + */ + PENDING_ADD, + + /** + * THe meter has been added. + */ + ADDED, + + /** + * The meter is in the process of being removed. + */ + PENDING_REMOVE, + + /** + * The meter has been removed. + */ + REMOVED, + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java new file mode 100644 index 00000000..5112a4a3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java @@ -0,0 +1,90 @@ +/* + * 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.meter; + +import org.onosproject.store.Store; + +import java.util.Collection; +import java.util.concurrent.CompletableFuture; + +/** + * Entity that stores and distributed meter objects. + */ +public interface MeterStore extends Store<MeterEvent, MeterStoreDelegate> { + + /** + * Adds a meter to the store. + * + * @param meter a meter + * @return a future indicating the result of the store operation + */ + CompletableFuture<MeterStoreResult> storeMeter(Meter meter); + + /** + * Deletes a meter from the store. + * + * @param meter a meter + * @return a future indicating the result of the store operation + */ + CompletableFuture<MeterStoreResult> deleteMeter(Meter meter); + + /** + * Updates a meter whose meter id is the same as the passed meter. + * + * @param meter a new meter + * @return a future indicating the result of the store operation + */ + CompletableFuture<MeterStoreResult> updateMeter(Meter meter); + + /** + * Updates a given meter's state with the provided state. + * + * @param meter a meter + */ + void updateMeterState(Meter meter); + + /** + * Obtains a meter matching the given meter id. + * + * @param meterId a meter id + * @return a meter + */ + Meter getMeter(MeterId meterId); + + /** + * Returns all meters stored in the store. + * + * @return a collection of meters + */ + Collection<Meter> getAllMeters(); + + /** + * Update the store by deleting the failed meter. + * Notifies the delegate that the meter failed to allow it + * to nofity the app. + * + * @param op a failed meter operation + * @param reason a failure reason + */ + void failedMeter(MeterOperation op, MeterFailReason reason); + + /** + * Delete this meter immediately. + * @param m a meter + */ + void deleteMeterNow(Meter m); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreDelegate.java new file mode 100644 index 00000000..9bfeb42f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * 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.meter; + +import org.onosproject.store.StoreDelegate; + +/** + * Meter store delegate abstraction. + */ +public interface MeterStoreDelegate extends StoreDelegate<MeterEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreResult.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreResult.java new file mode 100644 index 00000000..7a26746f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/MeterStoreResult.java @@ -0,0 +1,66 @@ +/* + * 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.meter; + +import java.util.Optional; + +/** + * An entity used to indicate whether the store operation passed. + */ +public final class MeterStoreResult { + + + private final Type type; + private final Optional<MeterFailReason> reason; + + public enum Type { + SUCCESS, + FAIL + } + + private MeterStoreResult(Type type, MeterFailReason reason) { + this.type = type; + this.reason = Optional.ofNullable(reason); + } + + public Type type() { + return type; + } + + public Optional<MeterFailReason> reason() { + return reason; + } + + /** + * A successful store opertion. + * + * @return a meter store result + */ + public static MeterStoreResult success() { + return new MeterStoreResult(Type.SUCCESS, null); + } + + /** + * A failed store operation. + * + * @param reason a failure reason + * @return a meter store result + */ + public static MeterStoreResult fail(MeterFailReason reason) { + return new MeterStoreResult(Type.FAIL, reason); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/package-info.java new file mode 100644 index 00000000..258634da --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/meter/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Flow meter model and related services. + */ +package org.onosproject.net.meter;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java new file mode 100644 index 00000000..e94ee452 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java @@ -0,0 +1,75 @@ +/* + * 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.newresource; + +import com.google.common.annotations.Beta; + +import java.util.Arrays; +import java.util.List; + +/** + * Service for administering resource service behavior. + */ +@Beta +public interface ResourceAdminService { + /** + * Register resources as the children of the parent resource path. + * + * @param parent parent resource path under which the resource are registered + * @param children resources to be registered as the children of the parent + * @param <T> type of resources + * @return true if registration is successfully done, false otherwise. Registration + * succeeds when each resource is not registered or unallocated. + */ + default <T> boolean registerResources(ResourcePath parent, T... children) { + return registerResources(parent, Arrays.asList(children)); + } + + /** + * Register resources as the children of the parent resource path. + * + * @param parent parent resource path under which the resource are registered + * @param children resources to be registered as the children of the parent + * @param <T> type of resources + * @return true if registration is successfully done, false otherwise. Registration + * succeeds when each resource is not registered or unallocated. + */ + <T> boolean registerResources(ResourcePath parent, List<T> children); + + /** + * Unregister resources as the children of the parent resource path. + * + * @param parent parent resource path under which the resource are unregistered + * @param children resources to be unregistered as the children of the parent + * @param <T> type of resources + * @return true if unregistration is successfully done, false otherwise. Unregistration + * succeeds when each resource is not registered or unallocated. + */ + default <T> boolean unregisterResources(ResourcePath parent, T... children) { + return unregisterResources(parent, Arrays.asList(children)); + } + + /** + * Unregister resources as the children of the parent resource path. + * + * @param parent parent resource path under which the resource are unregistered + * @param children resources to be unregistered as the children of the parent + * @param <T> type of resources + * @return true if unregistration is successfully done, false otherwise. Unregistration + * succeeds when each resource is not registered or unallocated. + */ + <T> boolean unregisterResources(ResourcePath parent, List<T> children); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAllocation.java new file mode 100644 index 00000000..e6980267 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAllocation.java @@ -0,0 +1,94 @@ +/* + * 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.newresource; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents allocation of resource which is identified by the specifier. + */ +@Beta +public class ResourceAllocation { + + private final ResourcePath resource; + private final ResourceConsumer consumer; + + /** + * Creates an instance with the specified subject, resource and consumer. + * + * @param resource resource of the subject + * @param consumer consumer ot this resource + */ + public ResourceAllocation(ResourcePath resource, ResourceConsumer consumer) { + this.resource = checkNotNull(resource); + this.consumer = consumer; + } + + // for serialization + private ResourceAllocation() { + this.resource = null; + this.consumer = null; + } + + /** + * Returns the specifier of the resource this allocation uses. + * + * @return the specifier of the resource this allocation uses + */ + public ResourcePath resource() { + return resource; + } + + /** + * Returns the consumer of this resource. + * + * @return the consumer of this resource + */ + public ResourceConsumer consumer() { + return consumer; + } + + @Override + public int hashCode() { + return Objects.hash(resource, consumer); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ResourceAllocation)) { + return false; + } + final ResourceAllocation that = (ResourceAllocation) obj; + return Objects.equals(this.resource, that.resource) + && Objects.equals(this.consumer, that.consumer); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("resource", resource) + .add("consumer", consumer) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceConsumer.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceConsumer.java new file mode 100644 index 00000000..1f67e204 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceConsumer.java @@ -0,0 +1,25 @@ +/* + * 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.newresource; + +import com.google.common.annotations.Beta; + +/** + * Marker interface representing an entity using resource. + */ +@Beta +public interface ResourceConsumer { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java new file mode 100644 index 00000000..3aa29f6b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java @@ -0,0 +1,146 @@ +/* + * 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.newresource; + +import com.google.common.annotations.Beta; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An object that is used to locate a resource in a network. + * A ResourcePath represents a path that is hierarchical and composed of a sequence + * of elementary resources that are not globally identifiable. A ResourcePath can be a globally + * unique resource identifier. + * + * Users of this class must keep the semantics of resources regarding the hierarchical structure. + * For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1 + * is not valid because a link is not a sub-component of a VLAN ID. + */ +@Beta +public final class ResourcePath { + + private final List<Object> resources; + + public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of()); + + public static ResourcePath child(ResourcePath parent, Object child) { + ImmutableList<Object> components = ImmutableList.builder() + .addAll(parent.components()) + .add(child) + .build(); + return new ResourcePath(components); + } + + /** + * Creates an resource path from the specified components. + * + * @param components components of the path. The order represents hierarchical structure of the resource. + */ + public ResourcePath(Object... components) { + this(Arrays.asList(components)); + } + + /** + * Creates an resource path from the specified components. + * + * @param components components of the path. The order represents hierarchical structure of the resource. + */ + public ResourcePath(List<Object> components) { + checkNotNull(components); + + this.resources = ImmutableList.copyOf(components); + } + + // for serialization + private ResourcePath() { + this.resources = null; + } + + /** + * Returns the components of this resource path. + * + * @return the components of this resource path + */ + public List<Object> components() { + return resources; + } + + /** + * Returns the parent resource path of this instance. + * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1. + * + * @return the parent resource path of this instance. + * If there is no parent, empty instance will be returned. + */ + public Optional<ResourcePath> parent() { + if (!isRoot()) { + return Optional.of(new ResourcePath(resources.subList(0, resources.size() - 1))); + } + + return Optional.empty(); + } + + /** + * Returns true if the path represents root. + * + * @return true if the path represents root, false otherwise. + */ + public boolean isRoot() { + return resources.size() == 0; + } + + /** + * Returns the last component of this instance. + * + * @return the last component of this instance. + * The return value is equal to the last object of {@code components()}. + */ + public Object lastComponent() { + int last = resources.size() - 1; + return resources.get(last); + } + + @Override + public int hashCode() { + return resources.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ResourcePath)) { + return false; + } + final ResourcePath that = (ResourcePath) obj; + return Objects.equals(this.resources, that.resources); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("resources", resources) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java new file mode 100644 index 00000000..618042a3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java @@ -0,0 +1,155 @@ +/* + * 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.newresource; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Service for allocating/releasing resource(s) and retrieving allocation(s) and availability. + */ +@Beta +public interface ResourceService { + /** + * Allocates the specified resource to the specified user. + * + * @param consumer resource user which the resource is allocated to + * @param resource resource to be allocated + * @return allocation information enclosed by Optional. If the allocation fails, the return value is empty + */ + default Optional<ResourceAllocation> allocate(ResourceConsumer consumer, ResourcePath resource) { + checkNotNull(consumer); + checkNotNull(resource); + + List<ResourceAllocation> allocations = allocate(consumer, ImmutableList.of(resource)); + if (allocations.isEmpty()) { + return Optional.empty(); + } + + assert allocations.size() == 1; + + ResourceAllocation allocation = allocations.get(0); + + assert allocation.resource().equals(resource); + + // cast is ensured by the assertions above + return Optional.of(allocation); + } + + /** + * Transactionally allocates the specified resources to the specified user. + * All allocations are made when this method succeeds, or no allocation is made when this method fails. + * + * @param consumer resource user which the resources are allocated to + * @param resources resources to be allocated + * @return non-empty list of allocation information if succeeded, otherwise empty list + */ + List<ResourceAllocation> allocate(ResourceConsumer consumer, List<ResourcePath> resources); + + /** + * Transactionally allocates the specified resources to the specified user. + * All allocations are made when this method succeeds, or no allocation is made when this method fails. + * + * @param consumer resource user which the resources are allocated to + * @param resources resources to be allocated + * @return non-empty list of allocation information if succeeded, otherwise empty list + */ + default List<ResourceAllocation> allocate(ResourceConsumer consumer, ResourcePath... resources) { + checkNotNull(consumer); + checkNotNull(resources); + + return allocate(consumer, Arrays.asList(resources)); + } + + /** + * Releases the specified resource allocation. + * + * @param allocation resource allocation to be released + * @return true if succeeded, otherwise false + */ + default boolean release(ResourceAllocation allocation) { + checkNotNull(allocation); + + return release(ImmutableList.of(allocation)); + } + + /** + * Transactionally releases the specified resource allocations. + * All allocations are released when this method succeeded, or no allocation is released when this method fails. + * + * @param allocations resource allocations to be released + * @return true if succeeded, otherwise false + */ + boolean release(List<ResourceAllocation> allocations); + + /** + * Transactionally releases the specified resource allocations. + * All allocations are released when this method succeeded, or no allocation is released when this method fails. + * + * @param allocations resource allocations to be released + * @return true if succeeded, otherwise false + */ + default boolean release(ResourceAllocation... allocations) { + checkNotNull(allocations); + + return release(ImmutableList.copyOf(allocations)); + } + + /** + * Transactionally releases the resources allocated to the specified consumer. + * All allocations are released when this method succeeded, or no allocation is released when this method fails. + * + * @param consumer consumer whose allocated resources are to be released + * @return true if succeeded, otherwise false + */ + boolean release(ResourceConsumer consumer); + + /** + * Returns allocated resources being as children of the specified parent and being the specified resource type. + * + * @param parent parent resource path + * @param cls class to specify a type of resource + * @param <T> type of the resource + * @return non-empty collection of resource allocations if resources are allocated with the subject and type, + * empty collection if no resource is allocated with the subject and type + */ + <T> Collection<ResourceAllocation> getResourceAllocations(ResourcePath parent, Class<T> cls); + + /** + * Returns resources allocated to the specified consumer. + * + * @param consumer consumer whose allocated resources are to be returned + * @return resources allocated to the consumer + */ + Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer); + + /** + * Returns the availability of the specified resource. + * + * @param resource resource to check the availability + * @return true if available, otherwise false + */ + boolean isAvailable(ResourcePath resource); + + // TODO: listener and event mechanism need to be considered +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java new file mode 100644 index 00000000..fc2eba70 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java @@ -0,0 +1,90 @@ +package org.onosproject.net.newresource; + +import com.google.common.annotations.Beta; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * Service for storing resource and consumer information. + */ +@Beta +public interface ResourceStore { + + /** + * Registers the resources in transactional way. + * Resource registration must be done before resource allocation. The state after completion + * of this method is all the resources are registered, or none of the given resources is registered. + * The whole registration fails when any one of the resource can't be registered. + * + * @param resources resources to be registered + * @return true if the registration succeeds, false otherwise + */ + boolean register(List<ResourcePath> resources); + + /** + * Unregisters the resources in transactional way. + * The state after completion of this method is all the resources are unregistered, + * or none of the given resources is unregistered. The whole unregistration fails when any one of the + * resource can't be unregistered. + * + * @param resources resources to be unregistered + * @return true if the registration succeeds, false otherwise + */ + boolean unregister(List<ResourcePath> resources); + + /** + * Allocates the specified resources to the specified consumer in transactional way. + * The state after completion of this method is all the resources are allocated to the consumer, + * or no resource is allocated to the consumer. The whole allocation fails when any one of + * the resource can't be allocated. + * + * @param resources resources to be allocated + * @param consumer resource consumer which the resources are allocated to + * @return true if the allocation succeeds, false otherwise. + */ + boolean allocate(List<ResourcePath> resources, ResourceConsumer consumer); + + /** + * Releases the specified resources allocated to the specified corresponding consumers + * in transactional way. The state after completion of this method is all the resources + * are released from the consumer, or no resource is released. The whole release fails + * when any one of the resource can't be released. The size of the list of resources and + * that of consumers must be equal. The resource and consumer with the same position from + * the head of each list correspond to each other. + * + * @param resources resources to be released + * @param consumers resource consumers to whom the resource allocated to + * @return true if succeeds, otherwise false + */ + boolean release(List<ResourcePath> resources, List<ResourceConsumer> consumers); + + /** + * Returns the resource consumer to whom the specified resource is allocated. + * + * @param resource resource whose allocated consumer to be returned + * @return resource consumer who are allocated the resource + */ + Optional<ResourceConsumer> getConsumer(ResourcePath resource); + + /** + * Returns a collection of the resources allocated to the specified consumer. + * + * @param consumer resource consumer whose allocated resource are searched for + * @return a collection of the resources allocated to the specified consumer + */ + Collection<ResourcePath> getResources(ResourceConsumer consumer); + + /** + * Returns a collection of the resources which are children of the specified parent and + * whose type is the specified class. + * + * @param parent parent of the resources to be returned + * @param cls class instance of the children + * @param <T> type of the resource + * @return a collection of the resources which belongs to the specified subject and + * whose type is the specified class. + */ + <T> Collection<ResourcePath> getAllocatedResources(ResourcePath parent, Class<T> cls); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/package-info.java new file mode 100644 index 00000000..52bb8588 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Generic network resource model and services for resource allocation and + * resource tracking. + */ +package org.onosproject.net.newresource;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/package-info.java new file mode 100644 index 00000000..34b4de21 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Network model entities & service API definitions. + */ +package org.onosproject.net; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultInboundPacket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultInboundPacket.java new file mode 100644 index 00000000..96f872f5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultInboundPacket.java @@ -0,0 +1,91 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.ConnectPoint; +import org.onlab.packet.Ethernet; + +import java.nio.ByteBuffer; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of an immutable inbound packet. + */ +public final class DefaultInboundPacket implements InboundPacket { + + private final ConnectPoint receivedFrom; + private final Ethernet parsed; + private final ByteBuffer unparsed; + + /** + * Creates an immutable inbound packet. + * + * @param receivedFrom connection point where received + * @param parsed parsed ethernet frame + * @param unparsed unparsed raw bytes + */ + public DefaultInboundPacket(ConnectPoint receivedFrom, Ethernet parsed, + ByteBuffer unparsed) { + this.receivedFrom = receivedFrom; + this.parsed = parsed; + this.unparsed = unparsed; + } + + @Override + public ConnectPoint receivedFrom() { + return receivedFrom; + } + + @Override + public Ethernet parsed() { + return parsed; + } + + @Override + public ByteBuffer unparsed() { + // FIXME: figure out immutability here + return unparsed; + } + + @Override + public int hashCode() { + return Objects.hash(receivedFrom, parsed, unparsed); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof InboundPacket) { + final DefaultInboundPacket other = (DefaultInboundPacket) obj; + return Objects.equals(this.receivedFrom, other.receivedFrom) && + Objects.equals(this.parsed, other.parsed) && + Objects.equals(this.unparsed, other.unparsed); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("receivedFrom", receivedFrom) + .add("parsed", parsed) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java new file mode 100644 index 00000000..5bd4c986 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultOutboundPacket.java @@ -0,0 +1,89 @@ +/* + * Copyright 2014 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.packet; + +import java.nio.ByteBuffer; +import java.util.Objects; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.TrafficTreatment; + +import com.google.common.base.MoreObjects; + +/** + * Default implementation of an immutable outbound packet. + */ +public final class DefaultOutboundPacket implements OutboundPacket { + private final DeviceId sendThrough; + private final TrafficTreatment treatment; + private final ByteBuffer data; + + /** + * Creates an immutable outbound packet. + * + * @param sendThrough identifier through which to send the packet + * @param treatment list of packet treatments + * @param data raw packet data + */ + public DefaultOutboundPacket(DeviceId sendThrough, + TrafficTreatment treatment, ByteBuffer data) { + this.sendThrough = sendThrough; + this.treatment = treatment; + this.data = data; + } + + @Override + public DeviceId sendThrough() { + return sendThrough; + } + + @Override + public TrafficTreatment treatment() { + return treatment; + } + + @Override + public ByteBuffer data() { + // FIXME: figure out immutability here + return data; + } + + @Override + public int hashCode() { + return Objects.hash(sendThrough, treatment, data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof OutboundPacket) { + final DefaultOutboundPacket other = (DefaultOutboundPacket) obj; + return Objects.equals(this.sendThrough, other.sendThrough) && + Objects.equals(this.treatment, other.treatment) && + Objects.equals(this.data, other.data); + } + return false; + } + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("sendThrough", sendThrough) + .add("treatment", treatment) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketContext.java new file mode 100644 index 00000000..166269f9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketContext.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014-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.packet; + +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.TrafficTreatment.Builder; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.onosproject.security.AppGuard.checkPermission; +import static org.onosproject.security.AppPermission.Type.*; + +/** + * Default implementation of a packet context. + */ +public abstract class DefaultPacketContext implements PacketContext { + + private final long time; + private final InboundPacket inPkt; + private final OutboundPacket outPkt; + private final TrafficTreatment.Builder builder; + + private final AtomicBoolean block; + + /** + * Creates a new packet context. + * + * @param time creation time + * @param inPkt inbound packet + * @param outPkt outbound packet + * @param block whether the context is blocked or not + */ + protected DefaultPacketContext(long time, InboundPacket inPkt, + OutboundPacket outPkt, boolean block) { + super(); + this.time = time; + this.inPkt = inPkt; + this.outPkt = outPkt; + this.block = new AtomicBoolean(block); + this.builder = DefaultTrafficTreatment.builder(); + } + + @Override + public long time() { + checkPermission(PACKET_READ); + return time; + } + + @Override + public InboundPacket inPacket() { + checkPermission(PACKET_READ); + return inPkt; + } + + @Override + public OutboundPacket outPacket() { + checkPermission(PACKET_READ); + return outPkt; + } + + @Override + public Builder treatmentBuilder() { + checkPermission(PACKET_READ); + return builder; + } + + @Override + public abstract void send(); + + @Override + public boolean block() { + checkPermission(PACKET_WRITE); + return this.block.getAndSet(true); + } + + @Override + public boolean isHandled() { + checkPermission(PACKET_READ); + return this.block.get(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java new file mode 100644 index 00000000..ce2eb118 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java @@ -0,0 +1,84 @@ +/* + * 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.packet; + +import com.google.common.base.MoreObjects; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; + +import java.util.Objects; + +/** + * Default implementation of a packet request. + */ +public final class DefaultPacketRequest implements PacketRequest { + private final TrafficSelector selector; + private final PacketPriority priority; + private final ApplicationId appId; + + /** + * Creates a new packet request. + * + * @param selector traffic selector + * @param priority intercept priority + * @param appId application id + */ + public DefaultPacketRequest(TrafficSelector selector, PacketPriority priority, + ApplicationId appId) { + this.selector = selector; + this.priority = priority; + this.appId = appId; + } + + public TrafficSelector selector() { + return selector; + } + + public PacketPriority priority() { + return priority; + } + + public ApplicationId appId() { + return appId; + } + + @Override + public int hashCode() { + return Objects.hash(selector, priority, appId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final DefaultPacketRequest other = (DefaultPacketRequest) obj; + return Objects.equals(this.selector, other.selector) + && Objects.equals(this.priority, other.priority) + && Objects.equals(this.appId, other.appId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this.getClass()) + .add("selector", selector) + .add("priority", priority) + .add("appId", appId).toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/InboundPacket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/InboundPacket.java new file mode 100644 index 00000000..3fd58149 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/InboundPacket.java @@ -0,0 +1,50 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.ConnectPoint; +import org.onlab.packet.Ethernet; + +import java.nio.ByteBuffer; + +/** + * Represents a data packet intercepted from an infrastructure device. + */ +public interface InboundPacket { + + /** + * Returns the device and port from where the packet was received. + * + * @return connection point where received + */ + ConnectPoint receivedFrom(); + + /** + * Returns the parsed form of the packet. + * + * @return parsed Ethernet frame; null if the packet is not an Ethernet + * frame or one for which there is no parser + */ + Ethernet parsed(); + + /** + * Unparsed packet data. + * + * @return raw packet bytes + */ + ByteBuffer unparsed(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/OutboundPacket.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/OutboundPacket.java new file mode 100644 index 00000000..9e9329fa --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/OutboundPacket.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.flow.TrafficTreatment; + +import java.nio.ByteBuffer; + +/** + * Represents an outbound data packet that is to be emitted to network via + * an infrastructure device. + */ +public interface OutboundPacket { + + /** + * Returns the identity of a device through which this packet should be + * sent. + * + * @return device identity + */ + DeviceId sendThrough(); + + /** + * Returns how the outbound packet should be treated. + * + * @return output treatment + */ + TrafficTreatment treatment(); + + /** + * Returns immutable view of the raw data to be sent. + * + * @return data to emit + */ + ByteBuffer data(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketContext.java new file mode 100644 index 00000000..004adc87 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketContext.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.flow.TrafficTreatment; + +/** + * Represents context for processing an inbound packet, and (optionally) + * emitting a corresponding outbound packet. + */ +public interface PacketContext { + + /** + * Returns the time when the packet was received. + * + * @return the time in millis since start of epoch + */ + long time(); + + /** + * Returns the inbound packet being processed. + * + * @return inbound packet + */ + InboundPacket inPacket(); + + /** + * Returns the view of the outbound packet. + * + * @return outbound packet + */ + OutboundPacket outPacket(); + + /** + * Returns a builder for constructing traffic treatment. + * + * @return traffic treatment builder + */ + TrafficTreatment.Builder treatmentBuilder(); + + /** + * Triggers the outbound packet to be sent. + */ + void send(); + + /** + * Blocks the outbound packet from being sent from this point onward. + * + * @return whether the outbound packet is blocked. + */ + boolean block(); + + /** + * Indicates whether the outbound packet is handled, i.e. sent or blocked. + * + * @return true uf the packed is handled + */ + boolean isHandled(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketEvent.java new file mode 100644 index 00000000..7b0a5ed7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketEvent.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.event.AbstractEvent; + +/** + * Describes a packet event. + */ +public class PacketEvent extends AbstractEvent<PacketEvent.Type, OutboundPacket> { + + /** + * Type of packet events. + */ + public enum Type { + /** + * Signifies that the packet should be emitted out a local port. + */ + EMIT + } + + /** + * Creates an event of the given type for the specified packet. + * + * @param type the type of the event + * @param packet the packet the event is about + */ + public PacketEvent(Type type, OutboundPacket packet) { + super(type, packet); + } + + /** + * Creates an event of the given type for the specified packet at the given + * time. + * + * @param type the type of the event + * @param packet the packet the event is about + * @param time the time of the event + */ + public PacketEvent(Type type, OutboundPacket packet, long time) { + super(type, packet, time); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketPriority.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketPriority.java new file mode 100644 index 00000000..68c0a838 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketPriority.java @@ -0,0 +1,53 @@ +/* + * 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.packet; + +/** + * Priorities available to applications for requests for packets from the data + * plane. + */ +public enum PacketPriority { + /** + * High priority for control traffic. This will result in all traffic + * matching the selector being sent to the controller. + */ + CONTROL(40000), + + /** + * Low priority for reactive applications. Packets are only sent to the + * controller if they fail to match any of the rules installed in the switch. + */ + REACTIVE(5); + + private final int priorityValue; + + private PacketPriority(int priorityValue) { + this.priorityValue = priorityValue; + } + + /** + * Returns the integer value of the priority level. + * + * @return priority value + */ + public int priorityValue() { + return priorityValue; + } + + public String toString() { + return String.valueOf(priorityValue); + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProcessor.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProcessor.java new file mode 100644 index 00000000..98886775 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProcessor.java @@ -0,0 +1,83 @@ +/* + * Copyright 2014 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.packet; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Abstraction of an inbound packet processor. + */ +public interface PacketProcessor { + + static final int ADVISOR_MAX = Integer.MAX_VALUE / 3; + static final int DIRECTOR_MAX = (Integer.MAX_VALUE / 3) * 2; + static final int OBSERVER_MAX = Integer.MAX_VALUE; + + /** + * Returns a priority in the ADVISOR range, where processors can take early action and + * influence the packet context. However, they cannot handle the packet (i.e. call send() or block()). + * The valid range is from 1 to ADVISOR_MAX. + * Processors in this range get to see the packet first. + * + * @param priority priority within ADVISOR range + * @return overall priority + */ + static int advisor(int priority) { + int overallPriority = priority + 1; + checkArgument(overallPriority > 0 && overallPriority <= ADVISOR_MAX, + "Priority not within ADVISOR range"); + return overallPriority; + } + + /** + * Returns a priority in the DIRECTOR range, where processors can handle the packet. + * The valid range is from ADVISOR_MAX+1 to DIRECTOR_MAX. + * Processors in this range get to see the packet second, after ADVISORS. + * + * @param priority priority within the DIRECTOR range + * @return overall priority + */ + static int director(int priority) { + int overallPriority = ADVISOR_MAX + priority + 1; + checkArgument(overallPriority > ADVISOR_MAX && overallPriority <= DIRECTOR_MAX, + "Priority not within DIRECTOR range"); + return overallPriority; + } + + /** + * Returns a priority in the OBSERVER range, where processors cannot take any action, + * but can observe what action has been taken until then. + * The valid range is from DIRECTOR_MAX+1 to OBSERVER_MAX. + * Processors in this range get to see the packet last, after ADVISORS and DIRECTORS. + * + * @param priority priority within the OBSERVER range + * @return overall priority + */ + static int observer(int priority) { + int overallPriority = DIRECTOR_MAX + priority + 1; + checkArgument(overallPriority > DIRECTOR_MAX && overallPriority <= OBSERVER_MAX, + "Priority not within OBSERVER range"); + return overallPriority; + } + + /** + * Processes the inbound packet as specified in the given context. + * + * @param context packet processing context + */ + void process(PacketContext context); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProvider.java new file mode 100644 index 00000000..8d55f0d1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProvider.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of a packet provider capable of emitting packets. + */ +public interface PacketProvider extends Provider { + + /** + * Emits the specified outbound packet onto the network. + * + * @param packet outbound packet + */ + void emit(OutboundPacket packet); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderRegistry.java new file mode 100644 index 00000000..6e73253e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of an infrastructure packet provider registry. + */ +public interface PacketProviderRegistry +extends ProviderRegistry<PacketProvider, PacketProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderService.java new file mode 100644 index 00000000..1aaee65f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketProviderService.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.net.provider.ProviderService; + +/** + * Entity capable of processing inbound packets. + */ +public interface PacketProviderService extends ProviderService<PacketProvider> { + + /** + * Submits inbound packet context for processing. This processing will be + * done synchronously, i.e. run-to-completion. + * + * @param context inbound packet context + */ + void processPacket(PacketContext context); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java new file mode 100644 index 00000000..dc09219a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java @@ -0,0 +1,47 @@ +/* + * 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.packet; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; + +/** + * Represents a packet request made to devices. + */ +public interface PacketRequest { + + /** + * Obtain the traffic selector. + * + * @return a traffic selector + */ + TrafficSelector selector(); + + /** + * Obtain the priority. + * + * @return a PacketPriority + */ + PacketPriority priority(); + + /** + * Obtain the application id. + * + * @return an application id + */ + ApplicationId appId(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketService.java new file mode 100644 index 00000000..06c416ec --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketService.java @@ -0,0 +1,79 @@ +/* + * Copyright 2014-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.packet; + +import org.onosproject.core.ApplicationId; +import org.onosproject.net.flow.TrafficSelector; + +/** + * Service for intercepting data plane packets and for emitting synthetic + * outbound packets. + */ +public interface PacketService { + + // TODO: ponder better ordering scheme that does not require absolute numbers + + /** + * Adds the specified processor to the list of packet processors. + * It will be added into the list in the order of priority. The higher + * numbers will be processing the packets after the lower numbers. + * + * @param processor processor to be added + * @param priority priority in the reverse natural order + * @throws java.lang.IllegalArgumentException if a processor with the + * given priority already exists + */ + void addProcessor(PacketProcessor processor, int priority); + + // TODO allow processors to register for particular types of packets + + /** + * Removes the specified processor from the processing pipeline. + * + * @param processor packet processor + */ + void removeProcessor(PacketProcessor processor); + + /** + * Requests that packets matching the given selector are punted from the + * dataplane to the controller. + * + * @param selector the traffic selector used to match packets + * @param priority the priority of the rule + * @param appId the application ID of the requester + */ + void requestPackets(TrafficSelector selector, PacketPriority priority, + ApplicationId appId); + + /** + * Cancels previous packet requests for packets matching the given + * selector to be punted from the dataplane to the controller. + * + * @param selector the traffic selector used to match packets + * @param priority the priority of the rule + * @param appId the application ID of the requester + */ + void cancelPackets(TrafficSelector selector, PacketPriority priority, + ApplicationId appId); + + /** + * Emits the specified outbound packet onto the network. + * + * @param packet outbound packet + */ + void emit(OutboundPacket packet); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStore.java new file mode 100644 index 00000000..ff45cc0c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStore.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014-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.packet; + +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Manages routing of outbound packets. + */ +public interface PacketStore extends Store<PacketEvent, PacketStoreDelegate> { + + /** + * Decides which instance should emit the packet and forwards the packet to + * that instance. The relevant PacketManager is notified via the + * PacketStoreDelegate that it should emit the packet. + * + * @param packet the packet to emit + */ + void emit(OutboundPacket packet); + + /** + * Requests intercept of packets that match the given selector. + * + * @param request a packet request + * @return true if the first time the given selector was requested + */ + boolean requestPackets(PacketRequest request); + + /** + * Cancels intercept of packets that match the given selector. + * + * @param request a packet request + * @return true if there is no other application requesting the given selector + */ + boolean cancelPackets(PacketRequest request); + + /** + * Obtains all existing requests in the system. + * + * @return a set of packet requests + */ + Set<PacketRequest> existingRequests(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStoreDelegate.java new file mode 100644 index 00000000..bf5c3cc0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/PacketStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.packet; + +import org.onosproject.store.StoreDelegate; + +/** + * Packet store delegate abstraction. + */ +public interface PacketStoreDelegate extends StoreDelegate<PacketEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/package-info.java new file mode 100644 index 00000000..0b9ea377 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/packet/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2014 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. + */ + +/** + * Mechanism for processing inbound packets intercepted from the data plane and + * for emitting outbound packets onto the data plane. + */ +package org.onosproject.net.packet; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractListenerProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractListenerProviderRegistry.java new file mode 100644 index 00000000..ff67c6da --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractListenerProviderRegistry.java @@ -0,0 +1,66 @@ +/* + * 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.provider; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.event.Event; +import org.onosproject.event.EventDeliveryService; +import org.onosproject.event.EventListener; +import org.onosproject.event.ListenerRegistry; +import org.onosproject.event.ListenerService; + +/** + * Basis for components which need to export listener mechanism. + */ +@Component(componentAbstract = true) +public abstract class AbstractListenerProviderRegistry<E extends Event, L extends EventListener<E>, + P extends Provider, S extends ProviderService<P>> + extends AbstractProviderRegistry<P, S> implements ListenerService<E, L> { + + // If only Java supported mixins... + + protected final ListenerRegistry<E, L> listenerRegistry = new ListenerRegistry<>(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected EventDeliveryService eventDispatcher; + + @Override + public void addListener(L listener) { + listenerRegistry.addListener(listener); + } + + @Override + public void removeListener(L listener) { + listenerRegistry.removeListener(listener); + } + + + /** + * Safely posts the specified event to the local event dispatcher. + * If there is no event dispatcher or if the event is null, this method + * is a noop. + * + * @param event event to be posted; may be null + */ + protected void post(E event) { + if (event != null && eventDispatcher != null) { + eventDispatcher.post(event); + } + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProvider.java new file mode 100644 index 00000000..a4926dd3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProvider.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014 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.provider; + +/** + * Base provider implementation. + */ +public abstract class AbstractProvider implements Provider { + + private final ProviderId providerId; + + /** + * Creates a provider with the supplier identifier. + * + * @param id provider id + */ + protected AbstractProvider(ProviderId id) { + this.providerId = id; + } + + @Override + public ProviderId id() { + return providerId; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderRegistry.java new file mode 100644 index 00000000..bcf5fae0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderRegistry.java @@ -0,0 +1,111 @@ +/* + * Copyright 2014 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.provider; + +import com.google.common.collect.ImmutableSet; +import org.onosproject.net.DeviceId; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +/** + * Base implementation of provider registry. + * + * @param <P> type of the information provider + * @param <S> type of the provider service + */ +public abstract class AbstractProviderRegistry<P extends Provider, S extends ProviderService<P>> + implements ProviderRegistry<P, S> { + + private final Map<ProviderId, P> providers = new HashMap<>(); + private final Map<ProviderId, S> services = new HashMap<>(); + private final Map<String, P> providersByScheme = new HashMap<>(); + + /** + * Creates a new provider service bound to the specified provider. + * + * @param provider provider + * @return provider service + */ + protected abstract S createProviderService(P provider); + + @Override + public synchronized S register(P provider) { + checkNotNull(provider, "Provider cannot be null"); + checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id()); + + // If the provider is a primary one, check for a conflict. + ProviderId pid = provider.id(); + checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()), + "A primary provider with id %s is already registered", + providersByScheme.get(pid.scheme())); + + S service = createProviderService(provider); + services.put(provider.id(), service); + providers.put(provider.id(), provider); + + // Register the provider by URI scheme only if it is not ancillary. + if (!pid.isAncillary()) { + providersByScheme.put(pid.scheme(), provider); + } + + return service; + } + + @Override + public synchronized void unregister(P provider) { + checkNotNull(provider, "Provider cannot be null"); + S service = services.get(provider.id()); + if (service != null && service instanceof AbstractProviderService) { + ((AbstractProviderService) service).invalidate(); + services.remove(provider.id()); + providers.remove(provider.id()); + if (!provider.id().isAncillary()) { + providersByScheme.remove(provider.id().scheme()); + } + } + } + + @Override + public synchronized Set<ProviderId> getProviders() { + return ImmutableSet.copyOf(services.keySet()); + } + + /** + * Returns the provider registered with the specified provider ID. + * + * @param providerId provider identifier + * @return provider + */ + protected synchronized P getProvider(ProviderId providerId) { + return providers.get(providerId); + } + + /** + * Returns the provider for the specified device ID based on URI scheme. + * + * @param deviceId device identifier + * @return provider bound to the URI scheme + */ + protected synchronized P getProvider(DeviceId deviceId) { + return providersByScheme.get(deviceId.uri().getScheme()); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderService.java new file mode 100644 index 00000000..6c926d88 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/AbstractProviderService.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 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.provider; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Base implementation of a provider service, which tracks the provider to + * which it is issued and can be invalidated. + * + * @param <P> type of the information provider + */ +public abstract class AbstractProviderService<P extends Provider> implements ProviderService<P> { + + private boolean isValid = true; + private final P provider; + + /** + * Creates a provider service on behalf of the specified provider. + * + * @param provider provider to which this service is being issued + */ + protected AbstractProviderService(P provider) { + this.provider = provider; + } + + /** + * Invalidates this provider service. + */ + public void invalidate() { + isValid = false; + } + + /** + * Checks the validity of this provider service. + * + * @throws java.lang.IllegalStateException if the service is no longer valid + */ + public void checkValidity() { + checkState(isValid, "Provider service is no longer valid"); + } + + @Override + public P provider() { + return provider; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/Provider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/Provider.java new file mode 100644 index 00000000..84465ab7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/Provider.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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.provider; + +/** + * Abstraction of a provider of information about network environment. + */ +public interface Provider { + + /** + * Returns the provider identifier. + * + * @return provider identification + */ + ProviderId id(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderId.java new file mode 100644 index 00000000..2c959afd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderId.java @@ -0,0 +1,135 @@ +/* + * Copyright 2014 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.provider; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * External identity of a {@link org.onosproject.net.provider.Provider} family. + * It also carriers two designations of external characteristics, the URI + * scheme and primary/ancillary indicator. + * <p> + * The device URI scheme is used to determine applicability of a provider to + * operations on a specific device. The ancillary indicator serves to designate + * a provider as a primary or ancillary. + * </p> + * <p> + * A {@link org.onosproject.net.provider.ProviderRegistry} uses this designation + * to permit only one primary provider per device URI scheme. Multiple + * ancillary providers can register with the same device URI scheme however. + * </p> + */ +public class ProviderId { + + /** + * Represents no provider ID. + */ + public static final ProviderId NONE = new ProviderId("none", "none"); + + private final String scheme; + private final String id; + private final boolean ancillary; + + // For serialization + private ProviderId() { + scheme = null; + id = null; + ancillary = false; + } + + /** + * Creates a new primary provider identifier from the specified string. + * The providers are expected to follow the reverse DNS convention, e.g. + * {@code org.onosproject.provider.of.device} + * + * @param scheme device URI scheme to which this provider is bound, e.g. "of", "snmp" + * @param id string identifier + */ + public ProviderId(String scheme, String id) { + this(scheme, id, false); + } + + /** + * Creates a new provider identifier from the specified string. + * The providers are expected to follow the reverse DNS convention, e.g. + * {@code org.onosproject.provider.of.device} + * + * @param scheme device URI scheme to which this provider is bound, e.g. "of", "snmp" + * @param id string identifier + * @param ancillary ancillary provider indicator + */ + public ProviderId(String scheme, String id, boolean ancillary) { + this.scheme = checkNotNull(scheme, "Scheme cannot be null"); + this.id = checkNotNull(id, "ID cannot be null"); + this.ancillary = ancillary; + } + + /** + * Returns the device URI scheme to which this provider is bound. + * + * @return device URI scheme + */ + public String scheme() { + return scheme; + } + + /** + * Returns the device URI scheme specific id portion. + * + * @return id + */ + public String id() { + return id; + } + + /** + * Indicates whether this identifier designates an ancillary providers. + * + * @return true if the provider is ancillary; false if primary + */ + public boolean isAncillary() { + return ancillary; + } + + @Override + public int hashCode() { + return Objects.hash(scheme, id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ProviderId) { + final ProviderId other = (ProviderId) obj; + return Objects.equals(this.scheme, other.scheme) && + Objects.equals(this.id, other.id) && + this.ancillary == other.ancillary; + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("scheme", scheme).add("id", id) + .add("ancillary", ancillary).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderRegistry.java new file mode 100644 index 00000000..3c2009ad --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderRegistry.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 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.provider; + +import java.util.Set; + +/** + * Registry for tracking information providers with the core. + * + * @param <P> type of the information provider + * @param <S> type of the provider service + */ +public interface ProviderRegistry<P extends Provider, S extends ProviderService<P>> { + + /** + * Registers the supplied provider with the core. + * + * @param provider provider to be registered + * @return provider service for injecting information into core + * @throws java.lang.IllegalArgumentException if the provider is registered already + */ + S register(P provider); + + /** + * Unregisters the supplied provider. As a result the previously issued + * provider service will be invalidated and any subsequent invocations + * of its methods may throw {@link java.lang.IllegalStateException}. + * <p> + * Unregistering a provider that has not been previously registered results + * in a no-op. + * </p> + * + * @param provider provider to be unregistered + */ + void unregister(P provider); + + /** + * Returns a set of currently registered provider identities. + * + * @return set of provider identifiers + */ + Set<ProviderId> getProviders(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderService.java new file mode 100644 index 00000000..5c469276 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/ProviderService.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.provider; + +/** + * Abstraction of a service through which providers can inject information + * about the network environment into the core. + * + * @param <P> type of the information provider + */ +public interface ProviderService<P extends Provider> { + + /** + * Returns the provider to which this service has been issued. + * + * @return provider to which this service has been assigned + */ + P provider(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/package-info.java new file mode 100644 index 00000000..d279f56a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/provider/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Base abstractions related to network entity providers and their brokers. + */ +package org.onosproject.net.provider; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java new file mode 100644 index 00000000..8ffe17a4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014-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.proxyarp; + +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.packet.PacketContext; + +/** + * Service for processing arp requests on behalf of applications. + */ +// TODO: move to the peer host package +public interface ProxyArpService { + + /** + * Returns whether this particular IP address is known to the system. + * + * @param addr an IP address + * @return true if know, false otherwise + */ + boolean isKnown(IpAddress addr); + + /** + * Sends a reply for a given request. If the host is not known then the + * arp or neighbor solicitation will be flooded at all edge ports. + * + * @param eth an arp or neighbor solicitation request + * @param inPort the port the request was received on + */ + void reply(Ethernet eth, ConnectPoint inPort); + + /** + * Forwards an ARP or neighbor solicitation request to its destination. + * Floods at the edg the request if the destination is not known. + * + * @param eth an ethernet frame containing an ARP or neighbor solicitation + * request. + * @param inPort the port the request was received on + */ + void forward(Ethernet eth, ConnectPoint inPort); + + /** + * Handles a arp or neighbor solicitation packet. + * Replies to arp or neighbor solicitation requests and forwards request + * to the right place. + * @param context the packet context to handle + * @return true if handled, false otherwise. + */ + boolean handlePacket(PacketContext context); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStore.java new file mode 100644 index 00000000..b6564212 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStore.java @@ -0,0 +1,45 @@ +/* + * 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.proxyarp; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Host; + +import java.nio.ByteBuffer; + +/** + * State distribution mechanism for the proxy ARP service. + */ +public interface ProxyArpStore { + + /** + * Forwards an ARP or neighbor solicitation request to its destination. + * Floods at the edg the request if the destination is not known. + * + * @param outPort the port the request was received on + * @param subject subject host + * @param packet an ethernet frame containing an ARP or neighbor + * solicitation request + */ + void forward(ConnectPoint outPort, Host subject, ByteBuffer packet); + + /** + * Associates the specified delegate with the store. + * + * @param delegate store delegate + */ + void setDelegate(ProxyArpStoreDelegate delegate); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStoreDelegate.java new file mode 100644 index 00000000..d0e273c8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpStoreDelegate.java @@ -0,0 +1,35 @@ +/* + * 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.proxyarp; + +import org.onosproject.net.ConnectPoint; + +import java.nio.ByteBuffer; + +/** + * Proxy ARP store delegate. + */ +public interface ProxyArpStoreDelegate { + + /** + * Emits ARP or neighbour discovery response packet. + * + * @param outPort output connection point + * @param packet packet to emit + */ + void emitResponse(ConnectPoint outPort, ByteBuffer packet); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/package-info.java new file mode 100644 index 00000000..6ddd4926 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/proxyarp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Base abstractions related to the proxy arp service. + */ +package org.onosproject.net.proxyarp; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocation.java new file mode 100644 index 00000000..01b69b2a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocation.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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.resource; + +import com.google.common.annotations.Beta; + +/** + * Abstraction of allocated resource. + */ +@Beta +public interface ResourceAllocation { + /** + * Returns the resource type. + * + * @return the resource type + */ + ResourceType type(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocationException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocationException.java new file mode 100644 index 00000000..c3d1fcc7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceAllocationException.java @@ -0,0 +1,36 @@ +/* + * 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.resource; + +import com.google.common.annotations.Beta; + +/** + * Exception thrown for resource allocation errors. + */ +@Beta +public class ResourceAllocationException extends ResourceException { + public ResourceAllocationException() { + super(); + } + + public ResourceAllocationException(String message) { + super(message); + } + + public ResourceAllocationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceException.java new file mode 100644 index 00000000..31e82d5d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceException.java @@ -0,0 +1,51 @@ +/* + * 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.resource; + +import com.google.common.annotations.Beta; + +/** + * Represents a resource related error. + */ +@Beta +public class ResourceException extends RuntimeException { + + /** + * Constructs an exception with no message and no underlying cause. + */ + public ResourceException() { + } + + /** + * Constructs an exception with the specified message. + * + * @param message the message describing the specific nature of the error + */ + public ResourceException(String message) { + super(message); + } + + /** + * Constructs an exception with the specified message and the underlying cause. + * + * @param message the message describing the specific nature of the error + * @param cause the underlying cause of this error + */ + public ResourceException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceId.java new file mode 100644 index 00000000..722ec4d7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceId.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.resource; + +import com.google.common.annotations.Beta; + +/** + * Resource identifier. + */ +@Beta +public interface ResourceId { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceRequest.java new file mode 100644 index 00000000..fb53f120 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceRequest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 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.resource; + +import com.google.common.annotations.Beta; + +/** + * Abstraction of resource request. + */ +@Beta +public interface ResourceRequest { + /** + * Returns the resource type. + * + * @return the resource type + */ + ResourceType type(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceType.java new file mode 100644 index 00000000..75832134 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/ResourceType.java @@ -0,0 +1,39 @@ +/* + * Copyright 2014-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.resource; + +import com.google.common.annotations.Beta; + +/** + * Represents types for link resources. + */ +@Beta +public enum ResourceType { + /** + * Lambda resource type. + */ + LAMBDA, + + /** + * Bandwidth resource type. + */ + BANDWIDTH, + + /** + * MPLS label resource type. + */ + MPLS_LABEL, +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceService.java new file mode 100644 index 00000000..5468dfb7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceService.java @@ -0,0 +1,85 @@ +/* + * 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.resource.device; + +import com.google.common.annotations.Beta; +import org.onosproject.net.Port; +import org.onosproject.net.intent.Intent; +import org.onosproject.net.intent.IntentId; + +import java.util.Set; + +/** + * Service for providing device resources. + */ +@Beta +public interface DeviceResourceService { + /** + * Request a set of ports needed to satisfy the intent. + * + * @param ports set of ports to allocate + * @param intent the intent + * @return true if ports were successfully allocated, false otherwise + */ + boolean requestPorts(Set<Port> ports, Intent intent); + + /** + * Returns the set of ports allocated for an intent. + * + * @param intentId the intent ID + * @return set of allocated ports + */ + Set<Port> getAllocations(IntentId intentId); + + /** + * Returns the intent allocated to a port. + * + * @param port the port + * @return intent ID allocated to the port + */ + IntentId getAllocations(Port port); + + /** + * Request a mapping between the given intents. + * + * @param keyIntentId the key intent ID + * @param valIntentId the value intent ID + * @return true if mapping was successful, false otherwise + */ + boolean requestMapping(IntentId keyIntentId, IntentId valIntentId); + + /** + * Returns the intents mapped to a lower intent. + * + * @param intentId the intent ID + * @return the set of intent IDs + */ + Set<IntentId> getMapping(IntentId intentId); + + /** + * Release mapping of given intent. + * + * @param intentId intent ID + */ + void releaseMapping(IntentId intentId); + + /** + * Release ports associated with given intent ID. + * + * @param intentId intent ID + */ + void releasePorts(IntentId intentId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceStore.java new file mode 100644 index 00000000..a52a843f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/DeviceResourceStore.java @@ -0,0 +1,89 @@ +/* + * 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.resource.device; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.Port; +import org.onosproject.net.intent.IntentId; + +import java.util.Set; + +public interface DeviceResourceStore { + /** + * Returns unallocated ports on the given device. + * + * @param deviceId device ID + * @return set of unallocated ports + */ + Set<Port> getFreePorts(DeviceId deviceId); + + /** + * Allocates the given ports to the given intent. + * + * @param ports set of ports to allocate + * @param intentId intent ID + * @return true if allocation was successful, false otherwise + */ + boolean allocatePorts(Set<Port> ports, IntentId intentId); + + /** + * Returns set of ports allocated for an intent. + * + * @param intentId the intent ID + * @return set of allocated ports + */ + Set<Port> getAllocations(IntentId intentId); + + /** + * Returns intent allocated to a port. + * + * @param port the port + * @return intent ID allocated to the port + */ + IntentId getAllocations(Port port); + + /** + * Allocates the mapping between the given intents. + * + * @param keyIntentId key intent ID + * @param valIntentId value intent ID + * @return true if mapping was successful, false otherwise + */ + boolean allocateMapping(IntentId keyIntentId, IntentId valIntentId); + + /** + * Returns the set of intents mapped to a lower intent. + * + * @param intentId intent ID + * @return set of intent IDs + */ + Set<IntentId> getMapping(IntentId intentId); + + /** + * Releases the mapping of the given intent. + * + * @param intentId intent ID + */ + void releaseMapping(IntentId intentId); + + /** + * Releases the ports allocated to the given intent. + * + * @param intentId intent ID + * @return true if release was successful, false otherwise + */ + boolean releasePorts(IntentId intentId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/package-info.java new file mode 100644 index 00000000..3ced37dc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/device/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Services for reserving devices as network resources. + */ +package org.onosproject.net.resource.device; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java new file mode 100644 index 00000000..fe21e042 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java @@ -0,0 +1,72 @@ +/* + * Copyright 2014-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.resource.link; + +import org.onlab.util.Bandwidth; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of bandwidth resource in bps. + */ +public final class BandwidthResource implements LinkResource { + + private final Bandwidth bandwidth; + + /** + * Creates a new instance with given bandwidth. + * + * @param bandwidth bandwidth value to be assigned + */ + public BandwidthResource(Bandwidth bandwidth) { + this.bandwidth = checkNotNull(bandwidth); + } + + // Constructor for serialization + private BandwidthResource() { + this.bandwidth = null; + } + + /** + * Returns bandwidth as a double value. + * + * @return bandwidth as a double value + */ + public double toDouble() { + return bandwidth.bps(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BandwidthResource) { + BandwidthResource that = (BandwidthResource) obj; + return Objects.equals(this.bandwidth, that.bandwidth); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.bandwidth); + } + + @Override + public String toString() { + return String.valueOf(this.bandwidth); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java new file mode 100644 index 00000000..74f6e102 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java @@ -0,0 +1,77 @@ +/* + * Copyright 2014 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.resource.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceType; + +import java.util.Objects; + +/** + * Representation of allocated bandwidth resource. + */ +public class BandwidthResourceAllocation implements ResourceAllocation { + private final BandwidthResource bandwidth; + + /** + * Creates a new {@link BandwidthResourceRequest} with {@link BandwidthResource} + * object. + * + * @param bandwidth {@link BandwidthResource} object to be requested + */ + public BandwidthResourceAllocation(BandwidthResource bandwidth) { + this.bandwidth = bandwidth; + } + + /** + * Returns the bandwidth resource. + * + * @return the bandwidth resource + */ + public BandwidthResource bandwidth() { + return bandwidth; + } + + @Override + public ResourceType type() { + return ResourceType.BANDWIDTH; + } + + @Override + public int hashCode() { + return Objects.hash(bandwidth); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final BandwidthResourceAllocation other = (BandwidthResourceAllocation) obj; + return Objects.equals(this.bandwidth, other.bandwidth()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("bandwidth", bandwidth) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java new file mode 100644 index 00000000..91cc3d19 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2014-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.resource.link; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +/** + * Representation of a request for bandwidth resource. + */ +public class BandwidthResourceRequest implements ResourceRequest { + private final BandwidthResource bandwidth; + + /** + * Creates a new {@link BandwidthResourceRequest} with {@link BandwidthResource} + * object. + * + * @param bandwidth {@link BandwidthResource} object to be requested + */ + public BandwidthResourceRequest(BandwidthResource bandwidth) { + this.bandwidth = bandwidth; + } + + /** + * Returns the bandwidth resource. + * + * @return the bandwidth resource + */ + public BandwidthResource bandwidth() { + return bandwidth; + } + + @Override + public ResourceType type() { + return ResourceType.BANDWIDTH; + } + + @Override + public int hashCode() { + return Objects.hash(bandwidth); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final BandwidthResourceAllocation other = (BandwidthResourceAllocation) obj; + return Objects.equals(this.bandwidth, other.bandwidth()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("bandwidth", bandwidth) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java new file mode 100644 index 00000000..379bf71e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java @@ -0,0 +1,112 @@ +/* + * Copyright 2014 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.resource.link; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import org.onosproject.net.Link; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; +import java.util.Map.Entry; +import java.util.Set; + +/** + * Implementation of {@link LinkResourceAllocations}. + */ +public class DefaultLinkResourceAllocations implements LinkResourceAllocations { + private final LinkResourceRequest request; + // TODO: probably should be using LinkKey instead + private final Map<Link, Set<ResourceAllocation>> allocations; + + /** + * Creates a new link resource allocations. + * + * @param request requested resources + * @param allocations allocated resources + */ + public DefaultLinkResourceAllocations(LinkResourceRequest request, + Map<Link, Set<ResourceAllocation>> allocations) { + this.request = checkNotNull(request); + ImmutableMap.Builder<Link, Set<ResourceAllocation>> builder + = ImmutableMap.builder(); + for (Entry<Link, Set<ResourceAllocation>> e : allocations.entrySet()) { + builder.put(e.getKey(), ImmutableSet.copyOf(e.getValue())); + } + this.allocations = builder.build(); + } + + public IntentId intentId() { + return request.intentId(); + } + + public Collection<Link> links() { + return request.links(); + } + + public Set<ResourceRequest> resources() { + return request.resources(); + } + + @Override + public ResourceType type() { + return null; + } + + @Override + public Set<ResourceAllocation> getResourceAllocation(Link link) { + Set<ResourceAllocation> result = allocations.get(link); + if (result == null) { + result = Collections.emptySet(); + } + return result; + } + + @Override + public int hashCode() { + return Objects.hash(request, allocations); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final DefaultLinkResourceAllocations other = (DefaultLinkResourceAllocations) obj; + return Objects.equals(this.request, other.request) + && Objects.equals(this.allocations, other.allocations); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("allocations", allocations) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java new file mode 100644 index 00000000..5153aebf --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java @@ -0,0 +1,186 @@ +/* + * Copyright 2014-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.resource.link; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.Objects; + +import org.onlab.util.Bandwidth; +import org.onosproject.net.Link; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.intent.IntentId; + +import com.google.common.collect.ImmutableSet; + +import org.onosproject.net.intent.constraint.BandwidthConstraint; +import org.onosproject.net.intent.constraint.LambdaConstraint; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +/** + * Implementation of {@link LinkResourceRequest}. + */ +public final class DefaultLinkResourceRequest implements LinkResourceRequest { + + private final IntentId intentId; + private final Collection<Link> links; + private final Set<ResourceRequest> resources; + + /** + * Creates a new link resource request with the given ID, links, and + * resource requests. + * + * @param intentId intent ID related to this request + * @param links a set of links for the request + * @param resources a set of resources to be requested + */ + private DefaultLinkResourceRequest(IntentId intentId, + Collection<Link> links, + Set<ResourceRequest> resources) { + this.intentId = intentId; + this.links = ImmutableSet.copyOf(links); + this.resources = ImmutableSet.copyOf(resources); + } + + + @Override + public ResourceType type() { + return null; + } + + @Override + public IntentId intentId() { + return intentId; + } + + @Override + public Collection<Link> links() { + return links; + } + + @Override + public Set<ResourceRequest> resources() { + return resources; + } + + /** + * Returns builder of link resource request. + * + * @param intentId intent ID related to this request + * @param links a set of links for the request + * @return builder of link resource request + */ + public static LinkResourceRequest.Builder builder( + IntentId intentId, Collection<Link> links) { + return new Builder(intentId, links); + } + + /** + * Builder of link resource request. + */ + public static final class Builder implements LinkResourceRequest.Builder { + private IntentId intentId; + private Collection<Link> links; + private Set<ResourceRequest> resources; + + /** + * Creates a new link resource request. + * + * @param intentId intent ID related to this request + * @param links a set of links for the request + */ + private Builder(IntentId intentId, Collection<Link> links) { + this.intentId = intentId; + this.links = links; + this.resources = new HashSet<>(); + } + + /** + * Adds lambda request. + * + * @return self + */ + @Override + public Builder addLambdaRequest() { + resources.add(new LambdaResourceRequest()); + return this; + } + + /** + * Adds Mpls request. + * + * @return self + */ + @Override + public Builder addMplsRequest() { + resources.add(new MplsLabelResourceRequest()); + return this; + } + + /** + * Adds bandwidth request with bandwidth value. + * + * @param bandwidth bandwidth value in bits per second to be requested + * @return self + */ + @Override + public Builder addBandwidthRequest(double bandwidth) { + resources.add(new BandwidthResourceRequest(new BandwidthResource(Bandwidth.bps(bandwidth)))); + return this; + } + + @Override + public LinkResourceRequest.Builder addConstraint(Constraint constraint) { + if (constraint instanceof LambdaConstraint) { + return addLambdaRequest(); + } else if (constraint instanceof BandwidthConstraint) { + BandwidthConstraint bw = (BandwidthConstraint) constraint; + return addBandwidthRequest(bw.bandwidth().toDouble()); + } + return this; + } + + /** + * Returns link resource request. + * + * @return link resource request + */ + @Override + public LinkResourceRequest build() { + return new DefaultLinkResourceRequest(intentId, links, resources); + } + } + + @Override + public int hashCode() { + return Objects.hash(intentId, links); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final DefaultLinkResourceRequest other = (DefaultLinkResourceRequest) obj; + return Objects.equals(this.intentId, other.intentId) + && Objects.equals(this.links, other.links); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java new file mode 100644 index 00000000..3733e467 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java @@ -0,0 +1,93 @@ +/* + * Copyright 2014 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.resource.link; + +import org.onosproject.net.IndexedLambda; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of lambda resource. + */ +public final class LambdaResource implements LinkResource { + + private final IndexedLambda lambda; + + /** + * Creates a new instance with given lambda. + * + * @param lambda lambda to be assigned + */ + private LambdaResource(IndexedLambda lambda) { + this.lambda = checkNotNull(lambda); + } + + // Constructor for serialization + private LambdaResource() { + this.lambda = null; + } + + /** + * Creates a new instance with the given index of lambda. + * + * @param lambda index value of lambda to be assigned + * @return {@link LambdaResource} instance with the given lambda + */ + public static LambdaResource valueOf(int lambda) { + return valueOf(new IndexedLambda(lambda)); + } + + /** + * Creates a new instance with the given lambda. + * + * @param lambda lambda to be assigned + * @return {@link LambdaResource} instance with the given lambda + */ + public static LambdaResource valueOf(IndexedLambda lambda) { + return new LambdaResource(lambda); + } + + /** + * Returns lambda as an int value. + * + * @return lambda as an int value + */ + public int toInt() { + return (int) lambda.index(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof LambdaResource) { + LambdaResource that = (LambdaResource) obj; + return Objects.equals(this.lambda, that.lambda); + } + return false; + } + + @Override + public int hashCode() { + return lambda.hashCode(); + } + + @Override + public String toString() { + return String.valueOf(this.lambda); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java new file mode 100644 index 00000000..545f025f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java @@ -0,0 +1,77 @@ +/* + * Copyright 2014 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.resource.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceType; + +import java.util.Objects; + +/** + * Representation of allocated lambda resource. + */ +public class LambdaResourceAllocation implements ResourceAllocation { + private final LambdaResource lambda; + + @Override + public ResourceType type() { + return ResourceType.LAMBDA; + } + + /** + * Creates a new {@link LambdaResourceAllocation} with {@link LambdaResource} + * object. + * + * @param lambda allocated lambda + */ + public LambdaResourceAllocation(LambdaResource lambda) { + this.lambda = lambda; + } + + /** + * Returns the lambda resource. + * + * @return the lambda resource + */ + public LambdaResource lambda() { + return lambda; + } + + @Override + public int hashCode() { + return Objects.hash(lambda); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final LambdaResourceAllocation other = (LambdaResourceAllocation) obj; + return Objects.equals(this.lambda, other.lambda); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("lambda", lambda) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java new file mode 100644 index 00000000..b0391f5a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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.resource.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +/** + * Representation of a request for lambda resource. + */ +public class LambdaResourceRequest implements ResourceRequest { + + @Override + public ResourceType type() { + return ResourceType.LAMBDA; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java new file mode 100644 index 00000000..ec06611e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java @@ -0,0 +1,22 @@ +/* + * Copyright 2014 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.resource.link; + +/** + * Abstraction of link resource. + */ +public interface LinkResource { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java new file mode 100644 index 00000000..7828867c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java @@ -0,0 +1,59 @@ +/* + * Copyright 2014 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.resource.link; + +import java.util.Collection; +import java.util.Set; + +import org.onosproject.net.Link; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceRequest; + +/** + * Representation of allocated link resources. + */ +public interface LinkResourceAllocations extends ResourceAllocation { + + /** + * Returns the {@link IntentId} associated with the request. + * + * @return the {@link IntentId} associated with the request + */ + IntentId intentId(); + + /** + * Returns the set of target links. + * + * @return the set of target links + */ + Collection<Link> links(); + + /** + * Returns the set of resource requests. + * + * @return the set of resource requests + */ + Set<ResourceRequest> resources(); + + /** + * Returns allocated resource for the given link. + * + * @param link the target link + * @return allocated resource for the link + */ + Set<ResourceAllocation> getResourceAllocation(Link link); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java new file mode 100644 index 00000000..3edb386a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014 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.resource.link; + +import java.util.Collection; + +import org.onosproject.event.AbstractEvent; + +import com.google.common.collect.ImmutableList; + +/** + * Describes an event related to a Link Resource. + */ +public final class LinkResourceEvent + extends AbstractEvent<LinkResourceEvent.Type, Collection<LinkResourceAllocations>> { + + /** + * Type of resource this event is for. + */ + public enum Type { + /** Additional resources are now available. */ + ADDITIONAL_RESOURCES_AVAILABLE + } + + /** + * Constructs a link resource event. + * + * @param type type of resource event to create + * @param linkResourceAllocations allocations that are now available + */ + public LinkResourceEvent(Type type, + Collection<LinkResourceAllocations> linkResourceAllocations) { + super(type, ImmutableList.copyOf(linkResourceAllocations)); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java new file mode 100644 index 00000000..599dd4fb --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.resource.link; + +import org.onosproject.event.EventListener; + +/** + * Entity for receiving link resource events. + */ +public interface LinkResourceListener extends EventListener<LinkResourceEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java new file mode 100644 index 00000000..8023a92e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2014-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.resource.link; + +import java.util.Collection; +import java.util.Set; + +import org.onosproject.net.Link; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.ResourceRequest; + +/** + * Representation of a request for link resource. + */ +public interface LinkResourceRequest extends ResourceRequest { + + /** + * Returns the {@link IntentId} associated with the request. + * + * @return the {@link IntentId} associated with the request + */ + IntentId intentId(); + + /** + * Returns the set of target links. + * + * @return the set of target links + */ + Collection<Link> links(); + + /** + * Returns the set of resource requests. + * + * @return the set of resource requests + */ + Set<ResourceRequest> resources(); + + /** + * Builder of link resource request. + */ + interface Builder { + /** + * Adds lambda request. + * + * @return self + */ + Builder addLambdaRequest(); + + /** + * Adds MPLS request. + * + * @return self + */ + Builder addMplsRequest(); + + /** + * Adds bandwidth request with bandwidth value. + * + * @param bandwidth bandwidth value to be requested + * @return self + */ + Builder addBandwidthRequest(double bandwidth); + + /** + * Adds the resources required for a constraint. + * + * @param constraint the constraint + * @return self + */ + Builder addConstraint(Constraint constraint); + + /** + * Returns link resource request. + * + * @return link resource request + */ + LinkResourceRequest build(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceService.java new file mode 100644 index 00000000..6dc04dfc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceService.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 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.resource.link; + +import org.onosproject.event.ListenerService; +import org.onosproject.net.Link; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.ResourceRequest; + +/** + * Service for providing link resource allocation. + */ +public interface LinkResourceService + extends ListenerService<LinkResourceEvent, LinkResourceListener> { + + /** + * Requests resources. + * + * @param req resources to be allocated + * @return allocated resources + */ + LinkResourceAllocations requestResources(LinkResourceRequest req); + + /** + * Releases resources. + * + * @param allocations resources to be released + */ + void releaseResources(LinkResourceAllocations allocations); + + /** + * Updates previously made allocations with a new resource request. + * + * @param req updated resource request + * @param oldAllocations old resource allocations + * @return new resource allocations + */ + LinkResourceAllocations updateResources(LinkResourceRequest req, + LinkResourceAllocations oldAllocations); + + /** + * Returns all allocated resources. + * + * @return allocated resources + */ + Iterable<LinkResourceAllocations> getAllocations(); + + /** + * Returns all allocated resources to given link. + * + * @param link a target link + * @return allocated resources + */ + Iterable<LinkResourceAllocations> getAllocations(Link link); + + /** + * Returns the resources allocated for an Intent. + * + * @param intentId the target Intent's id + * @return allocated resources for Intent + */ + LinkResourceAllocations getAllocations(IntentId intentId); + + /** + * Returns available resources for given link. + * + * @param link a target link + * @return available resources for the target link + */ + Iterable<ResourceRequest> getAvailableResources(Link link); + + /** + * Returns available resources for given link. + * + * @param link a target link + * @param allocations allocations to be included as available + * @return available resources for the target link + */ + Iterable<ResourceRequest> getAvailableResources(Link link, + LinkResourceAllocations allocations); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java new file mode 100644 index 00000000..e6674dbd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java @@ -0,0 +1,73 @@ +/* + * Copyright 2014 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.resource.link; + +import java.util.Set; + +import org.onosproject.net.Link; +import org.onosproject.net.intent.IntentId; +import org.onosproject.net.resource.ResourceAllocation; + +/** + * Manages link resources. + */ +public interface LinkResourceStore { + /** + * Returns free resources for given link. + * + * @param link a target link + * @return free resources for given link + */ + Set<ResourceAllocation> getFreeResources(Link link); + + /** + * Allocates resources. + * + * @param allocations resources to be allocated + */ + void allocateResources(LinkResourceAllocations allocations); + + /** + * Releases resources. + * + * @param allocations resources to be released + * @return the link resource event + */ + LinkResourceEvent releaseResources(LinkResourceAllocations allocations); + + /** + * Returns resources allocated for an Intent. + * + * @param intentId the target Intent's ID + * @return allocated resources or null if no resource is allocated + */ + LinkResourceAllocations getAllocations(IntentId intentId); + + /** + * Returns resources allocated for a link. + * + * @param link the target link + * @return allocated resources + */ + Iterable<LinkResourceAllocations> getAllocations(Link link); + + /** + * Returns all allocated resources. + * + * @return allocated resources + */ + Iterable<LinkResourceAllocations> getAllocations(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java new file mode 100644 index 00000000..6c051d6a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.resource.link; + +import org.onosproject.store.StoreDelegate; + +/** + * Link resource store delegate abstraction. + */ +public interface LinkResourceStoreDelegate extends StoreDelegate<LinkResourceEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java new file mode 100644 index 00000000..dc005227 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java @@ -0,0 +1,63 @@ +/* + * Copyright 2014 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.resource.link; + +import java.util.Set; + +/** + * Abstraction of a resources of a link. + */ +public interface LinkResources { + + /** + * Returns resources as a set of {@link LinkResource}s. + * + * @return a set of {@link LinkResource}s + */ + Set<LinkResource> resources(); + + /** + * Builder of {@link LinkResources}. + */ + interface Builder { + + /** + * Adds bandwidth resource. + * <p> + * This operation adds given bandwidth to previous bandwidth and + * generates single bandwidth resource. + * + * @param bandwidth bandwidth value to be added + * @return self + */ + Builder addBandwidth(double bandwidth); + + /** + * Adds lambda resource. + * + * @param lambda lambda value to be added + * @return self + */ + Builder addLambda(int lambda); + + /** + * Builds an immutable link resources. + * + * @return link resources + */ + LinkResources build(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java new file mode 100644 index 00000000..89c87760 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java @@ -0,0 +1,75 @@ +/* + * Copyright 2014-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.resource.link; + +import java.util.Objects; + +/** + * Representation of MPLS label resource. + */ +public final class MplsLabel implements LinkResource { + + private final org.onlab.packet.MplsLabel mplsLabel; + + + /** + * Creates a new instance with given MPLS label. + * + * @param mplsLabel MPLS Label value to be assigned + */ + public MplsLabel(int mplsLabel) { + this.mplsLabel = org.onlab.packet.MplsLabel.mplsLabel(mplsLabel); + } + + /** + * Creates a new instance with given MPLS label. + * + * @param mplsLabel mplsLabel value to be assigned + * @return {@link MplsLabel} instance with given bandwidth + */ + public static MplsLabel valueOf(int mplsLabel) { + return new MplsLabel(mplsLabel); + } + + /** + * Returns MPLS Label as an MPLS Label Object. + * + * @return MPLS label as an MPLS Label Object. + */ + public org.onlab.packet.MplsLabel label() { + return mplsLabel; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MplsLabel) { + MplsLabel that = (MplsLabel) obj; + return Objects.equals(this.mplsLabel, that.mplsLabel); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hashCode(this.mplsLabel); + } + + @Override + public String toString() { + return String.valueOf(this.mplsLabel); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java new file mode 100644 index 00000000..10911539 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java @@ -0,0 +1,78 @@ + /* + * Copyright 2014-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.resource.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceAllocation; +import org.onosproject.net.resource.ResourceType; + +import java.util.Objects; + +/** + * Representation of allocated MPLS label resource. + */ +public class MplsLabelResourceAllocation implements ResourceAllocation { + private final MplsLabel mplsLabel; + + @Override + public ResourceType type() { + return ResourceType.MPLS_LABEL; + } + + /** + * Creates a new {@link MplsLabelResourceAllocation} with {@link MplsLabel} + * object. + * + * @param mplsLabel allocated MPLS Label + */ + public MplsLabelResourceAllocation(MplsLabel mplsLabel) { + this.mplsLabel = mplsLabel; + } + + /** + * Returns the MPLS label resource. + * + * @return the MPLS label resource + */ + public MplsLabel mplsLabel() { + return mplsLabel; + } + + @Override + public int hashCode() { + return Objects.hash(mplsLabel); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final MplsLabelResourceAllocation other = (MplsLabelResourceAllocation) obj; + return Objects.equals(this.mplsLabel, other.mplsLabel); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("mplsLabel", mplsLabel) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java new file mode 100644 index 00000000..0a03f450 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014-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.resource.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.resource.ResourceRequest; +import org.onosproject.net.resource.ResourceType; + +/** + * Representation of a request for lambda resource. + */ +public class MplsLabelResourceRequest implements ResourceRequest { + + @Override + public ResourceType type() { + return ResourceType.MPLS_LABEL; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java new file mode 100644 index 00000000..b10e4ba4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Services for reserving links and their capacity as network resources, + * e.g. bandwidth, lambdas. + */ +package org.onosproject.net.resource.link; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java new file mode 100644 index 00000000..e676fc87 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Abstractions for reserving network resources. + */ +package org.onosproject.net.resource; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java new file mode 100644 index 00000000..45e85372 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java @@ -0,0 +1,111 @@ +/* + * Copyright 2014 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.statistic; + +import com.google.common.base.MoreObjects; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Implementation of a load. + */ +public class DefaultLoad implements Load { + + private final boolean isValid; + private final long current; + private final long previous; + private final long time; + private final long interval; + + /** + * Indicates the flow statistics poll interval in seconds. + */ + private static long pollInterval = 10; + + /** + * Creates an invalid load. + */ + public DefaultLoad() { + this.isValid = false; + this.time = System.currentTimeMillis(); + this.current = -1; + this.previous = -1; + this.interval = pollInterval; + } + + /** + * Creates a load value from the parameters. + * + * @param current the current value + * @param previous the previous value + */ + public DefaultLoad(long current, long previous) { + this(current, previous, pollInterval); + } + + /** + * Creates a load value from the parameters. + * + * @param current the current value + * @param previous the previous value + * @param interval poll interval for this load + */ + public DefaultLoad(long current, long previous, long interval) { + checkArgument(interval > 0, "Interval must be greater than 0"); + this.current = current; + this.previous = previous; + this.time = System.currentTimeMillis(); + this.isValid = true; + this.interval = interval; + } + + /** + * Sets the poll interval in seconds. Used solely for the purpose of + * computing the load. + * + * @param newPollInterval poll interval duration in seconds + */ + public static void setPollInterval(long newPollInterval) { + pollInterval = newPollInterval; + } + + @Override + public long rate() { + return (current - previous) / interval; + } + + @Override + public long latest() { + return current; + } + + @Override + public boolean isValid() { + return isValid; + } + + @Override + public long time() { + return time; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper("Load").add("rate", rate()) + .add("latest", latest()).toString(); + + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/Load.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/Load.java new file mode 100644 index 00000000..38fed04e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/Load.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 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.statistic; + +/** + * Simple data repository for link load information. + */ +public interface Load { + + /** + * Obtain the current observed rate (in bytes/s) on a link. + * + * @return long value + */ + long rate(); + + /** + * Obtain the latest bytes counter viewed on that link. + * + * @return long value + */ + long latest(); + + /** + * Indicates whether this load was built on valid values. + * + * @return boolean + */ + boolean isValid(); + + /** + * Returns when this value was seen. + * + * @return epoch time + */ + long time(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticService.java new file mode 100644 index 00000000..b9f7cc91 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticService.java @@ -0,0 +1,85 @@ +/* + * Copyright 2014 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.statistic; + +import org.onosproject.core.ApplicationId; +import org.onosproject.core.GroupId; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.flow.FlowRule; + +import java.util.Optional; + +/** + * Service for obtaining statistic information about link in the system. + * Statistics are obtained from the FlowRuleService in order to minimize the + * amount of hammering occuring at the dataplane. + */ +public interface StatisticService { + + /** + * Obtain the load for a the ingress to the given link. + * + * @param link the link to query. + * @return a {@link org.onosproject.net.statistic.Load Load} + */ + Load load(Link link); + + /** + * Obtain the load for the given port. + * + * @param connectPoint the port to query + * @return a {@link org.onosproject.net.statistic.Load} + */ + Load load(ConnectPoint connectPoint); + + /** + * Find the most loaded link along a path. + * + * @param path the path to search in + * @return the most loaded {@link org.onosproject.net.Link}. + */ + Link max(Path path); + + /** + * Find the least loaded link along a path. + * + * @param path the path to search in + * @return the least loaded {@link org.onosproject.net.Link}. + */ + Link min(Path path); + + /** + * Returns the highest hitter (a flow rule) for a given port, ie. the + * flow rule which is generating the most load. + * + * @param connectPoint the port + * @return the flow rule + */ + FlowRule highestHitter(ConnectPoint connectPoint); + + /** + * Obtain the load for a the ingress to the given link used by + * the specified application ID and group ID. + * + * @param link link to query + * @param appId application ID to filter with + * @param groupId group ID to filter with + * @return {@link Load Load} + */ + Load load(Link link, ApplicationId appId, Optional<GroupId> groupId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticStore.java new file mode 100644 index 00000000..8566ef5b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/StatisticStore.java @@ -0,0 +1,65 @@ +/* + * Copyright 2014 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.statistic; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.flow.FlowEntry; +import org.onosproject.net.flow.FlowRule; + +import java.util.Set; + +/** + * Store to house the computed statistics. + */ +public interface StatisticStore { + + /** + * Lay the foundation for receiving flow stats for this rule. + * + * @param rule a {@link org.onosproject.net.flow.FlowRule} + */ + void prepareForStatistics(FlowRule rule); + + /** + * Remove entries associated with this rule. + * + * @param rule {@link org.onosproject.net.flow.FlowRule} + */ + void removeFromStatistics(FlowRule rule); + + /** + * Adds a stats observation for a flow rule. + * + * @param rule a {@link org.onosproject.net.flow.FlowEntry} + */ + void addOrUpdateStatistic(FlowEntry rule); + + /** + * Fetches the current observed stats values. + * + * @param connectPoint the port to fetch information for + * @return set of current flow rules + */ + Set<FlowEntry> getCurrentStatistic(ConnectPoint connectPoint); + + /** + * Fetches the current observed stats values. + * + * @param connectPoint the port to fetch information for + * @return set of current values + */ + Set<FlowEntry> getPreviousStatistic(ConnectPoint connectPoint); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/package-info.java new file mode 100644 index 00000000..37889f3d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/statistic/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Service for looking up statistics on links. + */ +package org.onosproject.net.statistic; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java new file mode 100644 index 00000000..676f0068 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java @@ -0,0 +1,76 @@ +/* + * Copyright 2014 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.topology; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Representation of the topology cluster identity. + */ +public final class ClusterId { + + private final int id; + + // Public construction is prohibit + private ClusterId(int id) { + this.id = id; + } + + /** + * Returns the cluster identifier, represented by the specified integer + * serial number. + * + * @param id integer serial number + * @return cluster identifier + */ + public static ClusterId clusterId(int id) { + return new ClusterId(id); + } + + /** + * Returns the backing integer index. + * + * @return backing integer index + */ + public int index() { + return id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ClusterId) { + final ClusterId other = (ClusterId) obj; + return Objects.equals(this.id, other.id); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("id", id).toString(); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultGraphDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultGraphDescription.java new file mode 100644 index 00000000..f1e20dac --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultGraphDescription.java @@ -0,0 +1,141 @@ +/* + * Copyright 2014-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.topology; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.SparseAnnotations; +import org.slf4j.Logger; + +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Default implementation of an immutable topology graph data carrier. + */ +public class DefaultGraphDescription extends AbstractDescription + implements GraphDescription { + + private static final Logger log = getLogger(DefaultGraphDescription.class); + + private final long nanos; + private final long creationTime; + private final ImmutableSet<TopologyVertex> vertexes; + private final ImmutableSet<TopologyEdge> edges; + + private final Map<DeviceId, TopologyVertex> vertexesById = Maps.newHashMap(); + + /** + * Creates a minimal topology graph description to allow core to construct + * and process the topology graph. + * + * @param nanos time in nanos of when the topology description was created + * @param devices collection of infrastructure devices + * @param links collection of infrastructure links + * @param annotations optional key/value annotations map + * @deprecated in Cardinal Release + */ + @Deprecated + public DefaultGraphDescription(long nanos, Iterable<Device> devices, + Iterable<Link> links, + SparseAnnotations... annotations) { + this(nanos, System.currentTimeMillis(), devices, links, annotations); + } + + /** + * Creates a minimal topology graph description to allow core to construct + * and process the topology graph. + * + * @param nanos time in nanos of when the topology description was created + * @param millis time in millis of when the topology description was created + * @param devices collection of infrastructure devices + * @param links collection of infrastructure links + * @param annotations optional key/value annotations map + */ + public DefaultGraphDescription(long nanos, long millis, + Iterable<Device> devices, + Iterable<Link> links, + SparseAnnotations... annotations) { + super(annotations); + this.nanos = nanos; + this.creationTime = millis; + this.vertexes = buildVertexes(devices); + this.edges = buildEdges(links); + vertexesById.clear(); + } + + @Override + public long timestamp() { + return nanos; + } + + @Override + public long creationTime() { + return creationTime; + } + + @Override + public ImmutableSet<TopologyVertex> vertexes() { + return vertexes; + } + + @Override + public ImmutableSet<TopologyEdge> edges() { + return edges; + } + + // Builds a set of topology vertexes from the specified list of devices + private ImmutableSet<TopologyVertex> buildVertexes(Iterable<Device> devices) { + ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder(); + for (Device device : devices) { + TopologyVertex vertex = new DefaultTopologyVertex(device.id()); + vertexes.add(vertex); + vertexesById.put(vertex.deviceId(), vertex); + } + return vertexes.build(); + } + + // Builds a set of topology vertexes from the specified list of links + private ImmutableSet<TopologyEdge> buildEdges(Iterable<Link> links) { + ImmutableSet.Builder<TopologyEdge> edges = ImmutableSet.builder(); + for (Link link : links) { + try { + edges.add(new DefaultTopologyEdge(vertexOf(link.src()), + vertexOf(link.dst()), + link)); + } catch (IllegalArgumentException e) { + log.debug("Ignoring {}, missing vertex", link); + } + } + return edges.build(); + } + + // Fetches a vertex corresponding to the given connection point device. + private TopologyVertex vertexOf(ConnectPoint connectPoint) { + DeviceId id = connectPoint.deviceId(); + TopologyVertex vertex = vertexesById.get(id); + checkArgument(vertex != null, "Vertex missing for %s", id); + return vertex; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyCluster.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyCluster.java new file mode 100644 index 00000000..ac32316c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyCluster.java @@ -0,0 +1,97 @@ +/* + * Copyright 2014-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.topology; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Default implementation of a network topology cluster. + */ +public class DefaultTopologyCluster implements TopologyCluster { + + private final ClusterId id; + private final int deviceCount; + private final int linkCount; + private final TopologyVertex root; + + /** + * Creates a new topology cluster descriptor with the specified attributes. + * + * @param id cluster id + * @param deviceCount number of devices in the cluster + * @param linkCount number of links in the cluster + * @param root cluster root node + */ + public DefaultTopologyCluster(ClusterId id, int deviceCount, int linkCount, + TopologyVertex root) { + this.id = id; + this.deviceCount = deviceCount; + this.linkCount = linkCount; + this.root = root; + } + + @Override + public ClusterId id() { + return id; + } + + @Override + public int deviceCount() { + return deviceCount; + } + + @Override + public int linkCount() { + return linkCount; + } + + @Override + public TopologyVertex root() { + return root; + } + + @Override + public int hashCode() { + return Objects.hash(id, deviceCount, linkCount, root); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTopologyCluster) { + final DefaultTopologyCluster other = (DefaultTopologyCluster) obj; + return Objects.equals(this.id, other.id) && + Objects.equals(this.deviceCount, other.deviceCount) && + Objects.equals(this.linkCount, other.linkCount) && + Objects.equals(this.root, other.root); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("id", id) + .add("deviceCount", deviceCount) + .add("linkCount", linkCount) + .add("root", root) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java new file mode 100644 index 00000000..dacb5fd8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java @@ -0,0 +1,84 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.net.Link; + +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Implementation of the topology edge backed by a link. + */ +public class DefaultTopologyEdge implements TopologyEdge { + + private final Link link; + private final TopologyVertex src; + private final TopologyVertex dst; + + /** + * Creates a new topology edge. + * + * @param src source vertex + * @param dst destination vertex + * @param link infrastructure link + */ + public DefaultTopologyEdge(TopologyVertex src, TopologyVertex dst, Link link) { + this.src = src; + this.dst = dst; + this.link = link; + } + + @Override + public Link link() { + return link; + } + + @Override + public TopologyVertex src() { + return src; + } + + @Override + public TopologyVertex dst() { + return dst; + } + + @Override + public int hashCode() { + return Objects.hash(link); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTopologyEdge) { + final DefaultTopologyEdge other = (DefaultTopologyEdge) obj; + return Objects.equals(this.link, other.link); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this).add("src", src).add("dst", dst).toString(); + } + +} + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java new file mode 100644 index 00000000..07a09cbd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java @@ -0,0 +1,66 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.net.DeviceId; + +import java.util.Objects; + +/** + * Implementation of the topology vertex backed by a device id. + */ +public class DefaultTopologyVertex implements TopologyVertex { + + private final DeviceId deviceId; + + /** + * Creates a new topology vertex. + * + * @param deviceId backing infrastructure device identifier + */ + public DefaultTopologyVertex(DeviceId deviceId) { + this.deviceId = deviceId; + } + + @Override + public DeviceId deviceId() { + return deviceId; + } + + @Override + public int hashCode() { + return Objects.hash(deviceId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof DefaultTopologyVertex) { + final DefaultTopologyVertex other = (DefaultTopologyVertex) obj; + return Objects.equals(this.deviceId, other.deviceId); + } + return false; + } + + @Override + public String toString() { + return deviceId.toString(); + } + +} + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GraphDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GraphDescription.java new file mode 100644 index 00000000..806a5a45 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/GraphDescription.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014-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.topology; + +import org.onosproject.net.Description; + +import com.google.common.collect.ImmutableSet; + +/** + * Describes attribute(s) of a network graph. + */ +public interface GraphDescription extends Description { + + /** + * Returns the creation timestamp of the graph description. This is + * expressed in system nanos to allow proper sequencing. + * + * @return graph description creation timestamp + */ + long timestamp(); + + /** + * Returns the creation timestamp of the graph description. This is + * expressed in system millis to allow proper date and time formatting. + * + * @return graph description creation timestamp in millis + */ + long creationTime(); + + /** + * Returns the set of topology graph vertexes. + * + * @return set of graph vertexes + */ + ImmutableSet<TopologyVertex> vertexes(); + + /** + * Returns the set of topology graph edges. + * + * @return set of graph edges + */ + ImmutableSet<TopologyEdge> edges(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/LinkWeight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/LinkWeight.java new file mode 100644 index 00000000..a19abd40 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/LinkWeight.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.topology; + +import org.onlab.graph.EdgeWeight; + +/** + * Entity capable of determining cost or weight of a specified topology + * graph edge. + */ +public interface LinkWeight extends EdgeWeight<TopologyVertex, TopologyEdge> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java new file mode 100644 index 00000000..be8c7cfc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/PathService.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.net.ElementId; +import org.onosproject.net.Path; + +import java.util.Set; + +/** + * Service for obtaining pre-computed paths or for requesting computation of + * paths using the current topology snapshot. + */ +public interface PathService { + + /** + * Returns the set of all shortest paths, precomputed in terms of hop-count, + * between the specified source and destination elements. + * + * @param src source element + * @param dst destination element + * @return set of all shortest paths between the two elements + */ + Set<Path> getPaths(ElementId src, ElementId dst); + + /** + * Returns the set of all shortest paths, computed using the supplied + * edge-weight entity, between the specified source and destination + * network elements. + * + * @param src source element + * @param dst destination element + * @param weight edge-weight entity + * @return set of all shortest paths between the two element + */ + Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/Topology.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/Topology.java new file mode 100644 index 00000000..6337807c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/Topology.java @@ -0,0 +1,71 @@ +/* + * Copyright 2014-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.topology; + +import org.onosproject.net.Provided; + +/** + * Represents a network topology computation snapshot. + */ +public interface Topology extends Provided { + + /** + * Returns the time, specified in system nanos of when the topology became + * available. + * + * @return time in system nanos + */ + long time(); + + /** + * Returns the time, specified in system millis of when the topology became + * available. + * + * @return time in system nanos + */ + long creationTime(); + + /** + * Returns the time, specified in system nanos of how long the topology took + * to compute. + * + * @return elapsed time in system nanos + */ + long computeCost(); + + /** + * Returns the number of SCCs (strongly connected components) in the + * topology. + * + * @return number of clusters + */ + int clusterCount(); + + /** + * Returns the number of infrastructure devices in the topology. + * + * @return number of devices + */ + int deviceCount(); + + /** + * Returns the number of infrastructure links in the topology. + * + * @return number of links + */ + int linkCount(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyCluster.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyCluster.java new file mode 100644 index 00000000..8e685534 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyCluster.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-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.topology; + +/** + * Representation of an SCC (strongly-connected component) in a network topology. + */ +public interface TopologyCluster { + + /** + * Returns the cluster id. + * + * @return cluster identifier + */ + ClusterId id(); + + /** + * Returns the number of devices in the cluster. + * + * @return number of cluster devices + */ + int deviceCount(); + + /** + * Returns the number of infrastructure links in the cluster. + * + * @return number of cluster links + */ + int linkCount(); + + /** + * Returns the cluster root vertex. + * + * @return cluster root vertex + */ + TopologyVertex root(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEdge.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEdge.java new file mode 100644 index 00000000..008c8c44 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEdge.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.topology; + +import org.onlab.graph.Edge; +import org.onosproject.net.Link; + +/** + * Represents an edge in the topology graph. + */ +public interface TopologyEdge extends Edge<TopologyVertex> { + + /** + * Returns the associated infrastructure link. + * + * @return backing infrastructure link + */ + Link link(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEvent.java new file mode 100644 index 00000000..10c8dfc3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyEvent.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.event.Event; + +import java.util.List; + +/** + * Describes network topology event. + */ +public class TopologyEvent extends AbstractEvent<TopologyEvent.Type, Topology> { + + private final List<Event> reasons; + + /** + * Type of topology events. + */ + public enum Type { + /** + * Signifies that topology has changed. + */ + TOPOLOGY_CHANGED + } + + /** + * Creates an event of a given type and for the specified topology and the + * current time. + * + * @param type topology event type + * @param topology event topology subject + * @param reasons list of events that triggered topology change + */ + public TopologyEvent(Type type, Topology topology, List<Event> reasons) { + super(type, topology); + this.reasons = reasons; + } + + /** + * Creates an event of a given type and for the specified topology and time. + * + * @param type link event type + * @param topology event topology subject + * @param reasons list of events that triggered topology change + * @param time occurrence time + */ + public TopologyEvent(Type type, Topology topology, List<Event> reasons, + long time) { + super(type, topology, time); + this.reasons = reasons; + } + + + /** + * Returns the list of events that triggered the topology change. + * + * @return list of events responsible for change in topology; null if + * initial topology computation + */ + public List<Event> reasons() { + return reasons; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyGraph.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyGraph.java new file mode 100644 index 00000000..f3565fa4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyGraph.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.topology; + +import org.onlab.graph.Graph; + +/** + * Represents an immutable topology graph. + */ +public interface TopologyGraph extends Graph<TopologyVertex, TopologyEdge> { + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyListener.java new file mode 100644 index 00000000..625587b0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving network topology related events. + */ +public interface TopologyListener extends EventListener<TopologyEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProvider.java new file mode 100644 index 00000000..f52b798b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.net.provider.Provider; + +/** + * Means for injecting topology information into the core. + */ +public interface TopologyProvider extends Provider { + + /** + * Triggers topology recomputation. + */ + void triggerRecompute(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderRegistry.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderRegistry.java new file mode 100644 index 00000000..15eeed45 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of a network topology provider registry. + */ +public interface TopologyProviderRegistry extends + ProviderRegistry<TopologyProvider, TopologyProviderService> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderService.java new file mode 100644 index 00000000..742110a2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyProviderService.java @@ -0,0 +1,37 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.event.Event; +import org.onosproject.net.provider.ProviderService; + +import java.util.List; + +/** + * Means for injecting topology information into the core. + */ +public interface TopologyProviderService extends ProviderService<TopologyProvider> { + + /** + * Signals the core that some aspect of the topology has changed. + * + * @param graphDescription information about the network graph + * @param reasons events that triggered topology change + */ + void topologyChanged(GraphDescription graphDescription, + List<Event> reasons); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java new file mode 100644 index 00000000..41eac2c4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java @@ -0,0 +1,135 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.event.ListenerService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.Path; + +import java.util.Set; + +/** + * Service for providing network topology information. + */ +public interface TopologyService + extends ListenerService<TopologyEvent, TopologyListener> { + + /** + * Returns the current topology descriptor. + * + * @return current topology + */ + Topology currentTopology(); + + /** + * Indicates whether the specified topology is the latest or not. + * + * @param topology topology descriptor + * @return true if the topology is the most recent; false otherwise + */ + boolean isLatest(Topology topology); + + /** + * Returns the graph view of the specified topology. + * + * @param topology topology descriptor + * @return topology graph view + */ + TopologyGraph getGraph(Topology topology); + + /** + * Returns the set of clusters in the specified topology. + * + * @param topology topology descriptor + * @return set of topology clusters + */ + Set<TopologyCluster> getClusters(Topology topology); + + /** + * Returns the cluster with the specified ID. + * + * @param topology topology descriptor + * @param clusterId cluster identifier + * @return topology cluster + */ + TopologyCluster getCluster(Topology topology, ClusterId clusterId); + + /** + * Returns the set of devices that belong to the specified cluster. + * + * @param topology topology descriptor + * @param cluster topology cluster + * @return set of cluster devices + */ + Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster); + + /** + * Returns the set of links that form the specified cluster. + * + * @param topology topology descriptor + * @param cluster topology cluster + * @return set of cluster links + */ + Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster); + + /** + * Returns the set of all shortest paths, precomputed in terms of hop-count, + * between the specified source and destination devices. + * + * @param topology topology descriptor + * @param src source device + * @param dst destination device + * @return set of all shortest paths between the two devices + */ + Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst); + + /** + * Returns the set of all shortest paths, computed using the supplied + * edge-weight entity, between the specified source and destination devices. + * + * @param topology topology descriptor + * @param src source device + * @param dst destination device + * @param weight edge-weight entity + * @return set of all shortest paths between the two devices + */ + Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, + LinkWeight weight); + + /** + * Indicates whether the specified connection point is part of the network + * infrastructure or part of network edge. + * + * @param topology topology descriptor + * @param connectPoint connection point + * @return true of connection point is in infrastructure; false if edge + */ + boolean isInfrastructure(Topology topology, ConnectPoint connectPoint); + + + /** + * Indicates whether broadcast is allowed for traffic received on the + * specified connection point. + * + * @param topology topology descriptor + * @param connectPoint connection point + * @return true if broadcast is permissible + */ + boolean isBroadcastPoint(Topology topology, ConnectPoint connectPoint); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java new file mode 100644 index 00000000..983e616e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java @@ -0,0 +1,144 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.event.Event; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.List; +import java.util.Set; + +/** + * Manages inventory of topology snapshots; not intended for direct use. + */ +public interface TopologyStore extends Store<TopologyEvent, TopologyStoreDelegate> { + + /** + * Returns the current topology snapshot. + * + * @return current topology descriptor + */ + Topology currentTopology(); + + /** + * Indicates whether the topology is the latest. + * + * @param topology topology descriptor + * @return true if topology is the most recent one + */ + boolean isLatest(Topology topology); + + /** + * Returns the immutable graph view of the current topology. + * + * @param topology topology descriptor + * @return graph view + */ + TopologyGraph getGraph(Topology topology); + + /** + * Returns the set of topology SCC clusters. + * + * @param topology topology descriptor + * @return set of clusters + */ + Set<TopologyCluster> getClusters(Topology topology); + + /** + * Returns the cluster of the specified topology. + * + * @param topology topology descriptor + * @param clusterId cluster identity + * @return topology cluster + */ + TopologyCluster getCluster(Topology topology, ClusterId clusterId); + + /** + * Returns the cluster of the specified topology. + * + * @param topology topology descriptor + * @param cluster topology cluster + * @return set of cluster links + */ + Set<DeviceId> getClusterDevices(Topology topology, TopologyCluster cluster); + + /** + * Returns the cluster of the specified topology. + * + * @param topology topology descriptor + * @param cluster topology cluster + * @return set of cluster links + */ + Set<Link> getClusterLinks(Topology topology, TopologyCluster cluster); + + /** + * Returns the set of pre-computed shortest paths between src and dest. + * + * @param topology topology descriptor + * @param src source device + * @param dst destination device + * @return set of shortest paths + */ + Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst); + + /** + * Computes and returns the set of shortest paths between src and dest. + * + * @param topology topology descriptor + * @param src source device + * @param dst destination device + * @param weight link weight function + * @return set of shortest paths + */ + Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, + LinkWeight weight); + + /** + * Indicates whether the given connect point is part of the network fabric. + * + * @param topology topology descriptor + * @param connectPoint connection point + * @return true if infrastructure; false otherwise + */ + boolean isInfrastructure(Topology topology, ConnectPoint connectPoint); + + /** + * Indicates whether broadcast is allowed for traffic received on the + * given connection point. + * + * @param topology topology descriptor + * @param connectPoint connection point + * @return true if broadcast allowed; false otherwise + */ + boolean isBroadcastPoint(Topology topology, ConnectPoint connectPoint); + + /** + * Generates a new topology snapshot from the specified description. + * + * @param providerId provider identification + * @param graphDescription topology graph description + * @param reasons list of events that triggered the update + * @return topology update event or null if the description is old + */ + TopologyEvent updateTopology(ProviderId providerId, + GraphDescription graphDescription, + List<Event> reasons); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStoreDelegate.java new file mode 100644 index 00000000..c425970b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 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.topology; + +import org.onosproject.store.StoreDelegate; + +/** + * Topology store delegate abstraction. + */ +public interface TopologyStoreDelegate extends StoreDelegate<TopologyEvent> { +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyVertex.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyVertex.java new file mode 100644 index 00000000..9f37dcb4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/TopologyVertex.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.topology; + +import org.onlab.graph.Vertex; +import org.onosproject.net.DeviceId; + +/** + * Represents a vertex in the topology graph. + */ +public interface TopologyVertex extends Vertex { + + /** + * Returns the associated infrastructure device identification. + * + * @return device identifier + */ + DeviceId deviceId(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/package-info.java new file mode 100644 index 00000000..3cd6ceb8 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Network topology model & related services API definitions. + */ +package org.onosproject.net.topology; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractApiDocRegistrator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractApiDocRegistrator.java new file mode 100644 index 00000000..7349c69e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractApiDocRegistrator.java @@ -0,0 +1,53 @@ +/* + * 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.rest; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; + +/** + * Self-registering REST API provider. + */ +@Component(immediate = true, componentAbstract = true) +public abstract class AbstractApiDocRegistrator { + + protected final ApiDocProvider provider; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ApiDocService service; + + /** + * Creates registrator for the specified REST API doc provider. + * + * @param provider REST API provider + */ + protected AbstractApiDocRegistrator(ApiDocProvider provider) { + this.provider = provider; + } + + @Activate + protected void activate() { + service.register(provider); + } + + @Deactivate + protected void deactivate() { + service.unregister(provider); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractInjectionResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractInjectionResource.java new file mode 100644 index 00000000..de182f03 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractInjectionResource.java @@ -0,0 +1,78 @@ +/* + * 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.rest; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Resource for serving semi-static resources. + */ +public class AbstractInjectionResource extends AbstractWebResource { + + /** + * Returns the index into the supplied string where the end of the + * specified pattern is located. + * + * @param string string to split + * @param start index where to start looking for pattern + * @param stopPattern optional pattern where to stop + * @return index where the split should occur + */ + protected int split(String string, int start, String stopPattern) { + int i = stopPattern != null ? string.indexOf(stopPattern, start) : string.length(); + checkArgument(i >= 0, "Unable to locate pattern %s", stopPattern); + return i + (stopPattern != null ? stopPattern.length() : 0); + } + + /** + * Produces an input stream from the bytes of the specified sub-string. + * + * @param string source string + * @param start index where to start stream + * @param end index where to end stream + * @return input stream + */ + protected InputStream stream(String string, int start, int end) { + return new ByteArrayInputStream(string.substring(start, end).getBytes()); + } + + /** + * Auxiliary enumeration to sequence input streams. + */ + protected class StreamEnumeration implements Enumeration<InputStream> { + private final Iterator<InputStream> iterator; + + public StreamEnumeration(List<InputStream> streams) { + this.iterator = streams.iterator(); + } + + @Override + public boolean hasMoreElements() { + return iterator.hasNext(); + } + + @Override + public InputStream nextElement() { + return iterator.next(); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractWebResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractWebResource.java new file mode 100644 index 00000000..d3249ba5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/AbstractWebResource.java @@ -0,0 +1,98 @@ +/* + * Copyright 2014-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.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.CodecService; +import org.onosproject.codec.JsonCodec; + +/** + * Abstract REST resource. + */ +public class AbstractWebResource extends BaseResource implements CodecContext { + + private final ObjectMapper mapper = new ObjectMapper(); + + @Override + public ObjectMapper mapper() { + return mapper; + } + + /** + * Returns the JSON codec for the specified entity class. + * + * @param entityClass entity class + * @param <T> entity type + * @return JSON codec + */ + public <T> JsonCodec<T> codec(Class<T> entityClass) { + return get(CodecService.class).getCodec(entityClass); + } + + /** + * Returns JSON object wrapping the array encoding of the specified + * collection of items. + * + * @param codecClass codec item class + * @param field field holding the array + * @param items collection of items to be encoded into array + * @param <T> item type + * @return JSON object + */ + protected <T> ObjectNode encodeArray(Class<T> codecClass, String field, + Iterable<T> items) { + ObjectNode result = mapper().createObjectNode(); + result.set(field, codec(codecClass).encode(items, this)); + return result; + } + + @Override + public <T> T getService(Class<T> serviceClass) { + return get(serviceClass); + } + + /** + * Creates and returns a new child object within the specified parent and + * bound to the given key. + * + * @param parent parent object + * @param key key for the new child object + * @return child object + */ + public ObjectNode newObject(ObjectNode parent, String key) { + ObjectNode node = mapper.createObjectNode(); + parent.set(key, node); + return node; + } + + /** + * Creates and returns a new child array within the specified parent and + * bound to the given key. + * + * @param parent parent object + * @param key key for the new child array + * @return child array + */ + public ArrayNode newArray(ObjectNode parent, String key) { + ArrayNode node = mapper.createArrayNode(); + parent.set(key, node); + return node; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocProvider.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocProvider.java new file mode 100644 index 00000000..50cac4cd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocProvider.java @@ -0,0 +1,98 @@ +/* + * 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.rest; + +import com.google.common.annotations.Beta; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Entity capable of providing REST API documentation resources. + */ +@Beta +public class ApiDocProvider { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final String DOCS = "/apidoc/swagger.json"; + private static final String MODEL = "/apidoc/model.json"; + + private final String key; + private final String name; + private final ClassLoader classLoader; + + /** + * Creates a new REST API documentation provider. + * + * @param key REST API key + * @param name REST API name + * @param classLoader class loader + */ + public ApiDocProvider(String key, String name, ClassLoader classLoader) { + this.key = checkNotNull(key, "Key cannot be null"); + this.name = checkNotNull(name, "Name cannot be null"); + this.classLoader = checkNotNull(classLoader, "Class loader cannot be null"); + } + + /** + * Returns the REST API key. + * + * @return REST API key + */ + public String key() { + return key; + } + + /** + * Returns the REST API name. + * + * @return REST API name + */ + public String name() { + return name; + } + + /** + * Returns input stream containing Swagger UI compatible JSON. + * + * @return input stream with Swagger JSON data + */ + public InputStream docs() { + return get(DOCS); + } + + /** + * Returns input stream containing JSON model schema. + * + * @return input stream with JSON model schema + */ + public InputStream model() { + return get(MODEL); + } + + private InputStream get(String resource) { + InputStream stream = classLoader.getResourceAsStream(resource); + if (stream == null) { + log.warn("Unable to find JSON resource {}", resource); + } + return stream; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocService.java new file mode 100644 index 00000000..f7268532 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/ApiDocService.java @@ -0,0 +1,58 @@ +/* + * 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.rest; + +import com.google.common.annotations.Beta; + +import java.util.Set; + +/** + * Service for registering REST API documentation resources. + */ +@Beta +public interface ApiDocService { + + /** + * Registers the specified REST API documentation provider. + * + * @param provider REST API documentation provider + */ + void register(ApiDocProvider provider); + + /** + * Unregisters the specified REST API documentation provider. + * + * @param provider REST API documentation provider + */ + void unregister(ApiDocProvider provider); + + /** + * Returns the set of all registered REST API documentation providers. + * + * @return set of registered documentation providers + */ + Set<ApiDocProvider> getDocProviders(); + + /** + * Returns the specified REST API documentation provider with the specified + * key. + * + * @param key REST API key + * @return documentation provider + */ + ApiDocProvider getDocProvider(String key); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/rest/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/package-info.java new file mode 100644 index 00000000..15e5d20d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/rest/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Base abstractions and utilities for developing REST APIs. + */ +package org.onosproject.rest;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppGuard.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppGuard.java new file mode 100644 index 00000000..800135f4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppGuard.java @@ -0,0 +1,38 @@ +/* + * 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.security; + + +/** + * Aids SM-ONOS to perform API-level permission checking. + */ +public final class AppGuard { + + private AppGuard() { + } + + /** + * Checks if the caller has the required permission only when security-mode is enabled. + * @param permission permission to be checked + */ + public static void checkPermission(AppPermission.Type permission) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + System.getSecurityManager().checkPermission(new AppPermission(permission)); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppPermission.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppPermission.java new file mode 100644 index 00000000..21a70d2b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/AppPermission.java @@ -0,0 +1,110 @@ +/* + * 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.security; + +import java.security.BasicPermission; + +/** + * Implementation of API access permission. + */ +public class AppPermission extends BasicPermission { + + public enum Type { + APP_READ, + APP_EVENT, + CONFIG_READ, + CONFIG_WRITE, + CLUSTER_READ, + CLUSTER_WRITE, + CLUSTER_EVENT, + DEVICE_READ, + DEVICE_EVENT, + DRIVER_READ, + DRIVER_WRITE, + FLOWRULE_READ, + FLOWRULE_WRITE, + FLOWRULE_EVENT, + GROUP_READ, + GROUP_WRITE, + GROUP_EVENT, + HOST_READ, + HOST_WRITE, + HOST_EVENT, + INTENT_READ, + INTENT_WRITE, + INTENT_EVENT, + LINK_READ, + LINK_WRITE, + LINK_EVENT, + PACKET_READ, + PACKET_WRITE, + PACKET_EVENT, + STATISTIC_READ, + TOPOLOGY_READ, + TOPOLOGY_EVENT, + TUNNEL_READ, + TUNNEL_WRITE, + TUNNEL_EVENT, + STORAGE_WRITE + } + + protected Type type; + /** + * Creates new application permission using the supplied data. + * @param name permission name + */ + public AppPermission(String name) { + super(name.toUpperCase(), ""); + try { + type = Type.valueOf(name); + } catch (IllegalArgumentException e) { + type = null; + } + } + + /** + * Creates new application permission using the supplied data. + * @param name permission name + * @param actions permission action + */ + public AppPermission(String name, String actions) { + super(name.toUpperCase(), actions); + try { + type = Type.valueOf(name); + } catch (IllegalArgumentException e) { + type = null; + } + } + + /** + * Crates new application permission using the supplied data. + * @param type permission type + */ + public AppPermission(Type type) { + super(type.name(), ""); + this.type = type; + } + + /** + * Returns type of permission. + * @return application permission type + */ + public Type getType() { + return this.type; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/Permission.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/Permission.java new file mode 100644 index 00000000..75d9433f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/Permission.java @@ -0,0 +1,77 @@ +/* + * 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.security; + +public class Permission { + + protected String classname; + protected String name; + protected String actions; + + public Permission(String classname, String name, String actions) { + this.classname = classname; + this.name = name; + if (actions == null) { + this.actions = ""; + } else { + this.actions = actions; + } + } + + public Permission(String classname, String name) { + this.classname = classname; + this.name = name; + this.actions = ""; + } + + public String getClassName() { + return classname; + } + + public String getName() { + return name; + } + + public String getActions() { + return actions; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public boolean equals(Object thatPerm) { + if (this == thatPerm) { + return true; + } + + if (!(thatPerm instanceof Permission)) { + return false; + } + + Permission that = (Permission) thatPerm; + return (this.classname.equals(that.classname)) && (this.name.equals(that.name)) + && (this.actions.equals(that.actions)); + } + + @Override + public String toString() { + return String.format("(%s, %s, %s)", classname, name, actions); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityAdminService.java new file mode 100644 index 00000000..16ea94d1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityAdminService.java @@ -0,0 +1,77 @@ +/* + * 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.security; + +import org.onosproject.core.ApplicationId; + +import java.security.Permission; +import java.util.List; +import java.util.Map; + +/** + * Security-Mode ONOS service. + */ +public interface SecurityAdminService { + + /** + * Returns true if security policy has been enforced to specified application. + * @param appId application identifier + * @return true if secured. + */ + boolean isSecured(ApplicationId appId); + + /** + * Changes SecurityModeState of specified application to REVIEWED. + * @param appId application identifier + */ + void review(ApplicationId appId); + + /** + * Accepts and enforces security policy to specified application. + * @param appId application identifier + */ + void acceptPolicy(ApplicationId appId); + + /** + * Register application to SM-ONOS subsystem. + * @param appId application identifier + */ + void register(ApplicationId appId); + + /** + * Returns sorted developer specified permission Map. + * @param appId application identifier + * @return Map of list of permissions sorted by permission type + */ + Map<Integer, List<Permission>> getPrintableSpecifiedPermissions(ApplicationId appId); + + /** + * Returns sorted granted permission Map. + * @param appId application identifier + * @return Map of list of permissions sorted by permission type + */ + Map<Integer, List<Permission>> getPrintableGrantedPermissions(ApplicationId appId); + + /** + * Returns sorted requested permission Map. + * @param appId application identifier + * @return Map of list of permissions sorted by permission type + */ + Map<Integer, List<Permission>> getPrintableRequestedPermissions(ApplicationId appId); + + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityUtil.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityUtil.java new file mode 100644 index 00000000..34b4e78a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/SecurityUtil.java @@ -0,0 +1,82 @@ +/* + * 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.security; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.ServiceNotFoundException; +import org.onosproject.core.ApplicationId; + +/** + * Utility class to aid Security-Mode ONOS. + */ +public final class SecurityUtil { + + protected static ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + + private SecurityUtil() { + } + + public static boolean isSecurityModeEnabled() { + if (System.getSecurityManager() != null) { + try { + SecurityAdminService securityService = serviceDirectory.get(SecurityAdminService.class); + if (securityService != null) { + return true; + } + } catch (ServiceNotFoundException e) { + return false; + } + } + return false; + } + + public static SecurityAdminService getSecurityService() { + if (System.getSecurityManager() != null) { + try { + SecurityAdminService securityService = serviceDirectory.get(SecurityAdminService.class); + if (securityService != null) { + return securityService; + } + } catch (ServiceNotFoundException e) { + return null; + } + } + return null; + } + + public static boolean isAppSecured(ApplicationId appId) { + SecurityAdminService service = getSecurityService(); + if (service != null) { + if (!service.isSecured(appId)) { + System.out.println("\n*******************************"); + System.out.println(" SM-ONOS APP WARNING "); + System.out.println("*******************************"); + System.out.println(appId.name() + " has not been secured."); + System.out.println("Please review before activating."); + return false; + } + } + return true; + } + public static void register(ApplicationId appId) { + SecurityAdminService service = getSecurityService(); + if (service != null) { + service.register(appId); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/security/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/security/package-info.java new file mode 100644 index 00000000..88c3529d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/security/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Application security constructs. + */ +package org.onosproject.security;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/AbstractStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/AbstractStore.java new file mode 100644 index 00000000..a3005e45 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/AbstractStore.java @@ -0,0 +1,72 @@ +/* + * Copyright 2014 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.store; + +import java.util.List; + +import org.onosproject.event.Event; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Base implementation of a store. + */ +public class AbstractStore<E extends Event, D extends StoreDelegate<E>> + implements Store<E, D> { + + protected D delegate; + + @Override + public void setDelegate(D delegate) { + checkState(this.delegate == null || this.delegate == delegate, + "Store delegate already set"); + this.delegate = delegate; + } + + @Override + public void unsetDelegate(D delegate) { + if (this.delegate == delegate) { + this.delegate = null; + } + } + + @Override + public boolean hasDelegate() { + return delegate != null; + } + + /** + * Notifies the delegate with the specified event. + * + * @param event event to delegate + */ + protected void notifyDelegate(E event) { + if (delegate != null) { + delegate.notify(event); + } + } + + /** + * Notifies the delegate with the specified list of events. + * + * @param events list of events to delegate + */ + protected void notifyDelegate(List<E> events) { + for (E event: events) { + notifyDelegate(event); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/Store.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/Store.java new file mode 100644 index 00000000..8d5b53c4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/Store.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 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.store; + +import org.onosproject.event.Event; + +/** + * Abstraction of a entity capable of storing and/or distributing information + * across a cluster. + */ +public interface Store<E extends Event, D extends StoreDelegate<E>> { + + /** + * Sets the delegate on the store. + * + * @param delegate new store delegate + * @throws java.lang.IllegalStateException if a delegate is already + * currently set on the store and is a different one that + */ + void setDelegate(D delegate); + + /** + * Withdraws the delegate from the store. + * + * @param delegate store delegate to withdraw + * @throws java.lang.IllegalArgumentException if the delegate is not + * currently set on the store + */ + void unsetDelegate(D delegate); + + /** + * Indicates whether the store has a delegate. + * + * @return true if delegate is set + */ + boolean hasDelegate(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/StoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/StoreDelegate.java new file mode 100644 index 00000000..71ca8cc0 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/StoreDelegate.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014 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.store; + +import org.onosproject.event.Event; + +/** + * Entity associated with a store and capable of receiving notifications of + * events within the store. + */ +public interface StoreDelegate<E extends Event> { + + /** + * Notifies the delegate via the specified event. + * + * @param event store generated event + */ + void notify(E event); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/Timestamp.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/Timestamp.java new file mode 100644 index 00000000..44238ff2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/Timestamp.java @@ -0,0 +1,53 @@ +/* + * Copyright 2014-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.store; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Opaque version structure. + * <p> + * Classes implementing this interface must also implement + * {@link #hashCode()} and {@link #equals(Object)}. + */ +public interface Timestamp extends Comparable<Timestamp> { + + @Override + int hashCode(); + + @Override + boolean equals(Object obj); + + /** + * Tests if this timestamp is newer than the specified timestamp. + * + * @param other timestamp to compare against + * @return true if this instance is newer + */ + default boolean isNewerThan(Timestamp other) { + return this.compareTo(checkNotNull(other)) > 0; + } + + /** + * Tests if this timestamp is older than the specified timestamp. + * + * @param other timestamp to compare against + * @return true if this instance is older + */ + default boolean isOlderThan(Timestamp other) { + return this.compareTo(checkNotNull(other)) < 0; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java new file mode 100644 index 00000000..161a8528 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java @@ -0,0 +1,166 @@ +/* + * Copyright 2014-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.store.cluster.messaging; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.onosproject.cluster.NodeId; + +/** + * Service for assisting communications between controller cluster nodes. + */ +public interface ClusterCommunicationService { + + /** + * Adds a new subscriber for the specified message subject. + * + * @param subject message subject + * @param subscriber message subscriber + * @param executor executor to use for running handler. + * @deprecated in Cardinal Release + */ + @Deprecated + void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber, ExecutorService executor); + + /** + * Broadcasts a message to all controller nodes. + * + * @param message message to send + * @param subject message subject + * @param encoder function for encoding message to byte[] + * @param <M> message type + */ + <M> void broadcast(M message, + MessageSubject subject, + Function<M, byte[]> encoder); + + /** + * Broadcasts a message to all controller nodes including self. + * + * @param message message to send + * @param subject message subject + * @param encoder function for encoding message to byte[] + * @param <M> message type + */ + <M> void broadcastIncludeSelf(M message, + MessageSubject subject, + Function<M, byte[]> encoder); + + /** + * Sends a message to the specified controller node. + * + * @param message message to send + * @param subject message subject + * @param encoder function for encoding message to byte[] + * @param toNodeId destination node identifier + * @param <M> message type + * @return future that is completed when the message is sent + */ + <M> CompletableFuture<Void> unicast(M message, + MessageSubject subject, + Function<M, byte[]> encoder, + NodeId toNodeId); + + /** + * Multicasts a message to a set of controller nodes. + * + * @param message message to send + * @param subject message subject + * @param encoder function for encoding message to byte[] + * @param nodeIds recipient node identifiers + * @param <M> message type + */ + <M> void multicast(M message, + MessageSubject subject, + Function<M, byte[]> encoder, + Set<NodeId> nodeIds); + + /** + * Sends a message and expects a reply. + * + * @param message message to send + * @param subject message subject + * @param encoder function for encoding request to byte[] + * @param decoder function for decoding response from byte[] + * @param toNodeId recipient node identifier + * @param <M> request type + * @param <R> reply type + * @return reply future + */ + <M, R> CompletableFuture<R> sendAndReceive(M message, + MessageSubject subject, + Function<M, byte[]> encoder, + Function<byte[], R> decoder, + NodeId toNodeId); + + /** + * Adds a new subscriber for the specified message subject. + * + * @param subject message subject + * @param decoder decoder for resurrecting incoming message + * @param handler handler function that processes the incoming message and produces a reply + * @param encoder encoder for serializing reply + * @param executor executor to run this handler on + * @param <M> incoming message type + * @param <R> reply message type + */ + <M, R> void addSubscriber(MessageSubject subject, + Function<byte[], M> decoder, + Function<M, R> handler, + Function<R, byte[]> encoder, + Executor executor); + + /** + * Adds a new subscriber for the specified message subject. + * + * @param subject message subject + * @param decoder decoder for resurrecting incoming message + * @param handler handler function that processes the incoming message and produces a reply + * @param encoder encoder for serializing reply + * @param <M> incoming message type + * @param <R> reply message type + */ + <M, R> void addSubscriber(MessageSubject subject, + Function<byte[], M> decoder, + Function<M, CompletableFuture<R>> handler, + Function<R, byte[]> encoder); + + /** + * Adds a new subscriber for the specified message subject. + * + * @param subject message subject + * @param decoder decoder to resurrecting incoming message + * @param handler handler for handling message + * @param executor executor to run this handler on + * @param <M> incoming message type + */ + <M> void addSubscriber(MessageSubject subject, + Function<byte[], M> decoder, + Consumer<M> handler, + Executor executor); + + /** + * Removes a subscriber for the specified message subject. + * + * @param subject message subject + */ + void removeSubscriber(MessageSubject subject); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessage.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessage.java new file mode 100644 index 00000000..46560e4c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessage.java @@ -0,0 +1,160 @@ +/* + * Copyright 2014-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.store.cluster.messaging; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Objects; + +import org.onlab.util.ByteArraySizeHashPrinter; +import org.onosproject.cluster.NodeId; + +import com.google.common.base.Charsets; +import com.google.common.base.MoreObjects; + +// TODO: Should payload type be ByteBuffer? +/** + * Base message for cluster-wide communications. + */ +public class ClusterMessage { + + private final NodeId sender; + private final MessageSubject subject; + private final byte[] payload; + private transient byte[] response; + + /** + * Creates a cluster message. + * + * @param sender message sender + * @param subject message subject + * @param payload message payload + */ + public ClusterMessage(NodeId sender, MessageSubject subject, byte[] payload) { + this.sender = sender; + this.subject = subject; + this.payload = payload; + } + + /** + * Returns the id of the controller sending this message. + * + * @return message sender id. + */ + public NodeId sender() { + return sender; + } + + /** + * Returns the message subject indicator. + * + * @return message subject + */ + public MessageSubject subject() { + return subject; + } + + /** + * Returns the message payload. + * + * @return message payload. + */ + public byte[] payload() { + return payload; + } + + /** + * Records the response to be sent to the sender. + * + * @param data response payload + */ + public void respond(byte[] data) { + response = data; + } + + /** + * Returns the response to be sent to the sender. + * + * @return response bytes + */ + public byte[] response() { + return response; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("sender", sender) + .add("subject", subject) + .add("payload", ByteArraySizeHashPrinter.of(payload)) + .toString(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ClusterMessage)) { + return false; + } + + ClusterMessage that = (ClusterMessage) o; + + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.subject, that.subject) && + Arrays.equals(this.payload, that.payload); + } + + /** + * Serializes this instance. + * @return bytes + */ + public byte[] getBytes() { + byte[] senderBytes = sender.toString().getBytes(Charsets.UTF_8); + byte[] subjectBytes = subject.value().getBytes(Charsets.UTF_8); + int capacity = 12 + senderBytes.length + subjectBytes.length + payload.length; + ByteBuffer buffer = ByteBuffer.allocate(capacity); + buffer.putInt(senderBytes.length); + buffer.put(senderBytes); + buffer.putInt(subjectBytes.length); + buffer.put(subjectBytes); + buffer.putInt(payload.length); + buffer.put(payload); + return buffer.array(); + } + + /** + * Decodes a new ClusterMessage from raw bytes. + * @param bytes raw bytes + * @return cluster message + */ + public static ClusterMessage fromBytes(byte[] bytes) { + ByteBuffer buffer = ByteBuffer.wrap(bytes); + byte[] senderBytes = new byte[buffer.getInt()]; + buffer.get(senderBytes); + byte[] subjectBytes = new byte[buffer.getInt()]; + buffer.get(subjectBytes); + byte[] payloadBytes = new byte[buffer.getInt()]; + buffer.get(payloadBytes); + + return new ClusterMessage(new NodeId(new String(senderBytes, Charsets.UTF_8)), + new MessageSubject(new String(subjectBytes, Charsets.UTF_8)), + payloadBytes); + } + + @Override + public int hashCode() { + return Objects.hash(sender, subject, payload); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessageHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessageHandler.java new file mode 100644 index 00000000..ce770a81 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterMessageHandler.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 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.store.cluster.messaging; + +/** + * Interface for handling cluster messages. + */ +public interface ClusterMessageHandler { + + /** + * Handles/Processes the cluster message. + * @param message cluster message. + */ + void handle(ClusterMessage message); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/Endpoint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/Endpoint.java new file mode 100644 index 00000000..2ac50dfd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/Endpoint.java @@ -0,0 +1,75 @@ +/* + * Copyright 2014-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.store.cluster.messaging; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +import org.onlab.packet.IpAddress; + +import com.google.common.base.MoreObjects; + +/** + * Representation of a TCP/UDP communication end point. + */ +public final class Endpoint { + + private final int port; + private final IpAddress ip; + + public Endpoint(IpAddress host, int port) { + this.ip = checkNotNull(host); + this.port = port; + } + + public IpAddress host() { + return ip; + } + + public int port() { + return port; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("ip", ip) + .add("port", port) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(ip, port); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Endpoint that = (Endpoint) obj; + return Objects.equals(this.port, that.port) && + Objects.equals(this.ip, that.ip); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessageSubject.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessageSubject.java new file mode 100644 index 00000000..8d5e313d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessageSubject.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 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.store.cluster.messaging; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Objects; + +/** + * Representation of a message subject. + * Cluster messages have associated subjects that dictate how they get handled + * on the receiving side. + */ +public final class MessageSubject { + + private final String value; + + public MessageSubject(String value) { + this.value = checkNotNull(value); + } + + public String value() { + return value; + } + + @Override + public String toString() { + return value; + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + MessageSubject that = (MessageSubject) obj; + return Objects.equals(this.value, that.value); + } + + // for serializer + protected MessageSubject() { + this.value = ""; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessagingService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessagingService.java new file mode 100644 index 00000000..6ccd4835 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/MessagingService.java @@ -0,0 +1,75 @@ +/* + * Copyright 2014-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.store.cluster.messaging; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Interface for low level messaging primitives. + */ +public interface MessagingService { + + /** + * Sends a message asynchronously to the specified communication end point. + * The message is specified using the type and payload. + * @param ep end point to send the message to. + * @param type type of message. + * @param payload message payload bytes. + * @return future that is completed when the message is sent + */ + CompletableFuture<Void> sendAsync(Endpoint ep, String type, byte[] payload); + + /** + * Sends a message synchronously and waits for a response. + * @param ep end point to send the message to. + * @param type type of message. + * @param payload message payload. + * @return a response future + */ + CompletableFuture<byte[]> sendAndReceive(Endpoint ep, String type, byte[] payload); + + /** + * Registers a new message handler for message type. + * @param type message type. + * @param handler message handler + * @param executor executor to use for running message handler logic. + */ + void registerHandler(String type, Consumer<byte[]> handler, Executor executor); + + /** + * Registers a new message handler for message type. + * @param type message type. + * @param handler message handler + * @param executor executor to use for running message handler logic. + */ + void registerHandler(String type, Function<byte[], byte[]> handler, Executor executor); + + /** + * Registers a new message handler for message type. + * @param type message type. + * @param handler message handler + */ + void registerHandler(String type, Function<byte[], CompletableFuture<byte[]>> handler); + + /** + * Unregister current handler, if one exists for message type. + * @param type message type + */ + void unregisterHandler(String type); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/package-info.java new file mode 100644 index 00000000..582c50ed --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/cluster/messaging/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Cluster messaging APIs for the use by the various distributed stores. + */ +package org.onosproject.store.cluster.messaging; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/package-info.java new file mode 100644 index 00000000..b6269ea5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Abstractions for creating and interacting with distributed stores. + */ +package org.onosproject.store; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncAtomicCounter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncAtomicCounter.java new file mode 100644 index 00000000..a879cc59 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncAtomicCounter.java @@ -0,0 +1,61 @@ +/* + * 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.store.service; + +import java.util.concurrent.CompletableFuture; + +/** + * An async atomic counter dispenses monotonically increasing values. + */ +public interface AsyncAtomicCounter { + + /** + * Atomically increment by one the current value. + * + * @return updated value + */ + CompletableFuture<Long> incrementAndGet(); + + /** + * Atomically increment by one the current value. + * + * @return previous value + */ + CompletableFuture<Long> getAndIncrement(); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return previous value + */ + CompletableFuture<Long> getAndAdd(long delta); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return updated value + */ + CompletableFuture<Long> addAndGet(long delta); + + /** + * Returns the current value of the counter without modifying it. + * + * @return current value + */ + CompletableFuture<Long> get(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java new file mode 100644 index 00000000..fee8cfa6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AsyncConsistentMap.java @@ -0,0 +1,283 @@ +/* + * 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.store.service; + +import java.util.Collection; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * A distributed, strongly consistent map whose methods are all executed asynchronously. + * <p> + * This map offers strong read-after-update (where update == create/update/delete) + * consistency. All operations to the map are serialized and applied in a consistent + * manner. + * <p> + * The stronger consistency comes at the expense of availability in + * the event of a network partition. A network partition can be either due to + * a temporary disruption in network connectivity between participating nodes + * or due to a node being temporarily down. + * </p><p> + * All values stored in this map are versioned and the API supports optimistic + * concurrency by allowing conditional updates that take into consideration + * the version or value that was previously read. + * </p><p> + * This map does not allow null values. All methods can throw a ConsistentMapException + * (which extends RuntimeException) to indicate failures. + * + */ +public interface AsyncConsistentMap<K, V> { + + /** + * Returns the number of entries in the map. + * + * @return a future for map size. + */ + CompletableFuture<Integer> size(); + + /** + * Returns true if the map is empty. + * + * @return a future whose value will be true if map has no entries, false otherwise. + */ + CompletableFuture<Boolean> isEmpty(); + + /** + * Returns true if this map contains a mapping for the specified key. + * + * @param key key + * @return a future whose value will be true if map contains key, false otherwise. + */ + CompletableFuture<Boolean> containsKey(K key); + + /** + * Returns true if this map contains the specified value. + * + * @param value value + * @return a future whose value will be true if map contains value, false otherwise. + */ + CompletableFuture<Boolean> containsValue(V value); + + /** + * Returns the value (and version) to which the specified key is mapped, or null if this + * map contains no mapping for the key. + * + * @param key the key whose associated value (and version) is to be returned + * @return a future value (and version) to which the specified key is mapped, or null if + * this map contains no mapping for the key + */ + CompletableFuture<Versioned<V>> get(K key); + + /** + * If the specified key is not already associated with a value (or is mapped to null), + * attempts to compute its value using the given mapping function and enters it into + * this map unless null. + * If a conflicting concurrent modification attempt is detected, the returned future + * will be completed exceptionally with ConsistentMapException.ConcurrentModification. + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with the specified key, + * or null if the computed value is null + */ + CompletableFuture<Versioned<V>> computeIfAbsent(K key, + Function<? super K, ? extends V> mappingFunction); + + /** + * If the value for the specified key is present and non-null, attempts to compute a new + * mapping given the key and its current mapped value. + * If the computed value is null, the current mapping will be removed from the map. + * If a conflicting concurrent modification attempt is detected, the returned future + * will be completed exceptionally with ConsistentMapException.ConcurrentModification. + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if computed value is null + */ + CompletableFuture<Versioned<V>> computeIfPresent(K key, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * Attempts to compute a mapping for the specified key and its current mapped value (or + * null if there is no current mapping). + * If the computed value is null, the current mapping (if one exists) will be removed from the map. + * If a conflicting concurrent modification attempt is detected, the returned future + * will be completed exceptionally with ConsistentMapException.ConcurrentModification. + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if computed value is null + */ + CompletableFuture<Versioned<V>> compute(K key, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * If the value for the specified key satisfies a condition, attempts to compute a new + * mapping given the key and its current mapped value. + * If the computed value is null, the current mapping will be removed from the map. + * If a conflicting concurrent modification attempt is detected, the returned future + * will be completed exceptionally with ConsistentMapException.ConcurrentModification. + * @param key key with which the specified value is to be associated + * @param condition condition that should evaluate to true for the computation to proceed + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or the old value if condition evaluates to false + */ + CompletableFuture<Versioned<V>> computeIf(K key, + Predicate<? super V> condition, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * Associates the specified value with the specified key in this map (optional operation). + * If the map previously contained a mapping for the key, the old value is replaced by the + * specified value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value (and version) associated with key, or null if there was + * no mapping for key. + */ + CompletableFuture<Versioned<V>> put(K key, V value); + + /** + * Associates the specified value with the specified key in this map (optional operation). + * If the map previously contained a mapping for the key, the old value is replaced by the + * specified value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return new value. + */ + CompletableFuture<Versioned<V>> putAndGet(K key, V value); + + /** + * Removes the mapping for a key from this map if it is present (optional operation). + * + * @param key key whose value is to be removed from the map + * @return the value (and version) to which this map previously associated the key, + * or null if the map contained no mapping for the key. + */ + CompletableFuture<Versioned<V>> remove(K key); + + /** + * Removes all of the mappings from this map (optional operation). + * The map will be empty after this call returns. + * @return future that will be successfully completed when the map is cleared + */ + CompletableFuture<Void> clear(); + + /** + * Returns a Set view of the keys contained in this map. + * This method differs from the behavior of java.util.Map.keySet() in that + * what is returned is a unmodifiable snapshot view of the keys in the ConsistentMap. + * Attempts to modify the returned set, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return a set of the keys contained in this map + */ + CompletableFuture<Set<K>> keySet(); + + /** + * Returns the collection of values (and associated versions) contained in this map. + * This method differs from the behavior of java.util.Map.values() in that + * what is returned is a unmodifiable snapshot view of the values in the ConsistentMap. + * Attempts to modify the returned collection, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return a collection of the values (and associated versions) contained in this map + */ + CompletableFuture<Collection<Versioned<V>>> values(); + + /** + * Returns the set of entries contained in this map. + * This method differs from the behavior of java.util.Map.entrySet() in that + * what is returned is a unmodifiable snapshot view of the entries in the ConsistentMap. + * Attempts to modify the returned set, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return set of entries contained in this map. + */ + CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet(); + + /** + * If the specified key is not already associated with a value + * associates it with the given value and returns null, else returns the current value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key or null + * if key does not already mapped to a value. + */ + CompletableFuture<Versioned<V>> putIfAbsent(K key, V value); + + /** + * Removes the entry for the specified key only if it is currently + * mapped to the specified value. + * + * @param key key with which the specified value is associated + * @param value value expected to be associated with the specified key + * @return true if the value was removed + */ + CompletableFuture<Boolean> remove(K key, V value); + + /** + * Removes the entry for the specified key only if its current + * version in the map is equal to the specified version. + * + * @param key key with which the specified version is associated + * @param version version expected to be associated with the specified key + * @return true if the value was removed + */ + CompletableFuture<Boolean> remove(K key, long version); + + /** + * Replaces the entry for the specified key only if currently mapped + * to the specified value. + * + * @param key key with which the specified value is associated + * @param oldValue value expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return true if the value was replaced + */ + CompletableFuture<Boolean> replace(K key, V oldValue, V newValue); + + /** + * Replaces the entry for the specified key only if it is currently mapped to the + * specified version. + * + * @param key key key with which the specified value is associated + * @param oldVersion version expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return true if the value was replaced + */ + CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue); + + /** + * Registers the specified listener to be notified whenever the map is updated. + * + * @param listener listener to notify about map events + */ + void addListener(MapEventListener<K, V> listener); + + /** + * Unregisters the specified listener such that it will no longer + * receive map change notifications. + * + * @param listener listener to unregister + */ + void removeListener(MapEventListener<K, V> listener); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounter.java new file mode 100644 index 00000000..f620e082 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounter.java @@ -0,0 +1,59 @@ +/* + * 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.store.service; + +/** + * Distributed version of java.util.concurrent.atomic.AtomicLong. + */ +public interface AtomicCounter { + + /** + * Atomically increment by one the current value. + * + * @return updated value + */ + long incrementAndGet(); + + /** + * Atomically increment by one the current value. + * + * @return previous value + */ + long getAndIncrement(); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return previous value + */ + long getAndAdd(long delta); + + /** + * Atomically adds the given value to the current value. + * + * @param delta the value to add + * @return updated value + */ + long addAndGet(long delta); + + /** + * Returns the current value of the counter without modifying it. + * + * @return current value + */ + long get(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java new file mode 100644 index 00000000..41a19f0d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java @@ -0,0 +1,75 @@ +/* + * 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.store.service; + +/** + * Builder for AtomicCounter. + */ +public interface AtomicCounterBuilder { + + /** + * Sets the name for the atomic counter. + * <p> + * Each atomic counter is identified by a unique name. + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the atomic counter + * @return this AtomicCounterBuilder + */ + AtomicCounterBuilder withName(String name); + + /** + * Creates this counter on the partition that spans the entire cluster. + * <p> + * When partitioning is disabled, the counter state will be + * ephemeral and does not survive a full cluster restart. + * </p> + * <p> + * Note: By default partitions are enabled. + * </p> + * @return this AtomicCounterBuilder + */ + AtomicCounterBuilder withPartitionsDisabled(); + + /** + * Instantiates Metering service to gather usage and performance metrics. + * By default, usage data will be stored. + * + * @return this AtomicCounterBuilder + */ + AtomicCounterBuilder withMeteringDisabled(); + + /** + * Builds a AtomicCounter based on the configuration options + * supplied to this builder. + * + * @return new AtomicCounter + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + AtomicCounter build(); + + /** + * Builds a AsyncAtomicCounter based on the configuration options + * supplied to this builder. + * + * @return new AsyncAtomicCounter + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + AsyncAtomicCounter buildAsyncCounter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java new file mode 100644 index 00000000..dfa0fb3c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java @@ -0,0 +1,69 @@ +/* + * 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.store.service; + +/** + * Distributed version of java.util.concurrent.atomic.AtomicReference. + * + * @param <V> value type + */ +public interface AtomicValue<V> { + + /** + * Atomically sets the value to the given updated value if the current value is equal to the expected value. + * <p> + * IMPORTANT: Equality is based on the equality of the serialized byte[] representations. + * <p> + * @param expect the expected value + * @param update the new value + * @return true if successful. false return indicates that the actual value was not equal to the expected value. + */ + boolean compareAndSet(V expect, V update); + + /** + * Gets the current value. + * @return current value + */ + V get(); + + /** + * Atomically sets to the given value and returns the old value. + * @param value the new value + * @return previous value + */ + V getAndSet(V value); + + /** + * Sets to the given value. + * @param value new value + */ + void set(V value); + + /** + * Registers the specified listener to be notified whenever the atomic value is updated. + * + * @param listener listener to notify about events + */ + void addListener(AtomicValueEventListener<V> listener); + + /** + * Unregisters the specified listener such that it will no longer + * receive atomic value update notifications. + * + * @param listener listener to unregister + */ + void removeListener(AtomicValueEventListener<V> listener); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java new file mode 100644 index 00000000..3478ce00 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java @@ -0,0 +1,78 @@ +/* + * 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.store.service; + +/** + * Builder for constructing new AtomicValue instances. + * + * @param <V> atomic value type + */ +public interface AtomicValueBuilder<V> { + /** + * Sets the name for the atomic value. + * <p> + * Each atomic value is identified by a unique name. + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the atomic value + * @return this AtomicValueBuilder for method chaining + */ + AtomicValueBuilder<V> withName(String name); + + /** + * Sets a serializer that can be used to serialize the value. + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param serializer serializer + * @return this AtomicValueBuilder for method chaining + */ + AtomicValueBuilder<V> withSerializer(Serializer serializer); + + /** + * Creates this atomic value on the partition that spans the entire cluster. + * <p> + * When partitioning is disabled, the value state will be + * ephemeral and does not survive a full cluster restart. + * </p> + * <p> + * Note: By default partitions are enabled. + * </p> + * @return this AtomicValueBuilder for method chaining + */ + AtomicValueBuilder<V> withPartitionsDisabled(); + + /** + * Instantiates Metering service to gather usage and performance metrics. + * By default, usage data will be stored. + * + * @return this AtomicValueBuilder for method chaining + */ + AtomicValueBuilder<V> withMeteringDisabled(); + + /** + * Builds a AtomicValue based on the configuration options + * supplied to this builder. + * + * @return new AtomicValue + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + AtomicValue<V> build(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEvent.java new file mode 100644 index 00000000..1bce1365 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEvent.java @@ -0,0 +1,109 @@ +/* + * 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.store.service; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +/** + * Representation of a AtomicValue update notification. + * + * @param <V> atomic value type + */ +public final class AtomicValueEvent<V> { + + /** + * AtomicValueEvent type. + */ + public enum Type { + + /** + * Value was updated. + */ + UPDATE, + } + + private final String name; + private final Type type; + private final V value; + + /** + * Creates a new event object. + * + * @param name AtomicValue name + * @param type the type of the event + * @param value the new value + */ + public AtomicValueEvent(String name, Type type, V value) { + this.name = name; + this.type = type; + this.value = value; + } + + /** + * Returns the AtomicValue name. + * + * @return name of atomic value + */ + public String name() { + return name; + } + + /** + * Returns the type of the event. + * + * @return the type of the event + */ + public Type type() { + return type; + } + + /** + * Returns the new updated value. + * + * @return the value + */ + public V value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof AtomicValueEvent)) { + return false; + } + + AtomicValueEvent that = (AtomicValueEvent) o; + return Objects.equals(this.name, that.name) && + Objects.equals(this.type, that.type) && + Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(name, type, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("name", name) + .add("type", type) + .add("value", value) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEventListener.java new file mode 100644 index 00000000..b29d903b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/AtomicValueEventListener.java @@ -0,0 +1,28 @@ +/* + * 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.store.service; + +/** + * Listener to be notified about updates to a AtomicValue. + */ +public interface AtomicValueEventListener<V> { + /** + * Reacts to the specified event. + * + * @param event the event + */ + void event(AtomicValueEvent<V> event); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java new file mode 100644 index 00000000..289da202 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java @@ -0,0 +1,291 @@ +/* + * 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.store.service; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * A distributed, strongly consistent key-value map. + * <p> + * This map offers strong read-after-update (where update == create/update/delete) + * consistency. All operations to the map are serialized and applied in a consistent + * manner. + * <p> + * The stronger consistency comes at the expense of availability in + * the event of a network partition. A network partition can be either due to + * a temporary disruption in network connectivity between participating nodes + * or due to a node being temporarily down. + * </p><p> + * All values stored in this map are versioned and the API supports optimistic + * concurrency by allowing conditional updates that take into consideration + * the version or value that was previously read. + * </p><p> + * This map does not allow null values. All methods can throw a ConsistentMapException + * (which extends RuntimeException) to indicate failures. + * + */ +public interface ConsistentMap<K, V> { + + /** + * Returns the number of entries in the map. + * + * @return map size. + */ + int size(); + + /** + * Returns true if the map is empty. + * + * @return true if map has no entries, false otherwise + */ + boolean isEmpty(); + + /** + * Returns true if this map contains a mapping for the specified key. + * + * @param key key + * @return true if map contains key, false otherwise + */ + boolean containsKey(K key); + + /** + * Returns true if this map contains the specified value. + * + * @param value value + * @return true if map contains value, false otherwise. + */ + boolean containsValue(V value); + + /** + * Returns the value (and version) to which the specified key is mapped, or null if this + * map contains no mapping for the key. + * + * @param key the key whose associated value (and version) is to be returned + * @return the value (and version) to which the specified key is mapped, or null if + * this map contains no mapping for the key + */ + Versioned<V> get(K key); + + /** + * If the specified key is not already associated with a value (or is mapped to null), + * attempts to compute its value using the given mapping function and enters it into + * this map unless null. + * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with the specified key, + * or null if the computed value is null. Method throws {@code ConsistentMapException.ConcurrentModification} + * if a concurrent modification of map is detected + */ + Versioned<V> computeIfAbsent(K key, + Function<? super K, ? extends V> mappingFunction); + + /** + * Attempts to compute a mapping for the specified key and its current mapped value (or + * null if there is no current mapping). + * If the computed value is null, the current mapping will be removed from the map. + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none. + * This method throws {@code ConsistentMapException.ConcurrentModification} + * if a concurrent modification of map is detected + */ + Versioned<V> compute(K key, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * If the value for the specified key is present and non-null, attempts to compute a new + * mapping given the key and its current mapped value. + * If the computed value is null, the current mapping will be removed from the map. + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none. + * This method throws {@code ConsistentMapException.ConcurrentModification} + * if a concurrent modification of map is detected + */ + Versioned<V> computeIfPresent(K key, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * If the value for the specified key satisfies a condition, attempts to compute a new + * mapping given the key and its current mapped value. + * If the computed value is null, the current mapping will be removed from the map. + * + * @param key key with which the specified value is to be associated + * @param condition condition that should evaluate to true for the computation to proceed + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or the old value if condition evaluates to false. + * This method throws {@code ConsistentMapException.ConcurrentModification} if a concurrent + * modification of map is detected + */ + Versioned<V> computeIf(K key, + Predicate<? super V> condition, + BiFunction<? super K, ? super V, ? extends V> remappingFunction); + + /** + * Associates the specified value with the specified key in this map (optional operation). + * If the map previously contained a mapping for the key, the old value is replaced by the + * specified value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value (and version) associated with key, or null if there was + * no mapping for key. + */ + Versioned<V> put(K key, V value); + + /** + * Associates the specified value with the specified key in this map (optional operation). + * If the map previously contained a mapping for the key, the old value is replaced by the + * specified value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return new value. + */ + Versioned<V> putAndGet(K key, V value); + + /** + * Removes the mapping for a key from this map if it is present (optional operation). + * + * @param key key whose value is to be removed from the map + * @return the value (and version) to which this map previously associated the key, + * or null if the map contained no mapping for the key. + */ + Versioned<V> remove(K key); + + /** + * Removes all of the mappings from this map (optional operation). + * The map will be empty after this call returns. + */ + void clear(); + + /** + * Returns a Set view of the keys contained in this map. + * This method differs from the behavior of java.util.Map.keySet() in that + * what is returned is a unmodifiable snapshot view of the keys in the ConsistentMap. + * Attempts to modify the returned set, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return a set of the keys contained in this map + */ + Set<K> keySet(); + + /** + * Returns the collection of values (and associated versions) contained in this map. + * This method differs from the behavior of java.util.Map.values() in that + * what is returned is a unmodifiable snapshot view of the values in the ConsistentMap. + * Attempts to modify the returned collection, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return a collection of the values (and associated versions) contained in this map + */ + Collection<Versioned<V>> values(); + + /** + * Returns the set of entries contained in this map. + * This method differs from the behavior of java.util.Map.entrySet() in that + * what is returned is a unmodifiable snapshot view of the entries in the ConsistentMap. + * Attempts to modify the returned set, whether direct or via its iterator, + * result in an UnsupportedOperationException. + * + * @return set of entries contained in this map. + */ + Set<Entry<K, Versioned<V>>> entrySet(); + + /** + * If the specified key is not already associated with a value + * associates it with the given value and returns null, else returns the current value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key or null + * if key does not already mapped to a value. + */ + Versioned<V> putIfAbsent(K key, V value); + + /** + * Removes the entry for the specified key only if it is currently + * mapped to the specified value. + * + * @param key key with which the specified value is associated + * @param value value expected to be associated with the specified key + * @return true if the value was removed + */ + boolean remove(K key, V value); + + /** + * Removes the entry for the specified key only if its current + * version in the map is equal to the specified version. + * + * @param key key with which the specified version is associated + * @param version version expected to be associated with the specified key + * @return true if the value was removed + */ + boolean remove(K key, long version); + + /** + * Replaces the entry for the specified key only if currently mapped + * to the specified value. + * + * @param key key with which the specified value is associated + * @param oldValue value expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return true if the value was replaced + */ + boolean replace(K key, V oldValue, V newValue); + + /** + * Replaces the entry for the specified key only if it is currently mapped to the + * specified version. + * + * @param key key key with which the specified value is associated + * @param oldVersion version expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return true if the value was replaced + */ + boolean replace(K key, long oldVersion, V newValue); + + /** + * Registers the specified listener to be notified whenever the map is updated. + * + * @param listener listener to notify about map events + */ + void addListener(MapEventListener<K, V> listener); + + /** + * Unregisters the specified listener such that it will no longer + * receive map change notifications. + * + * @param listener listener to unregister + */ + void removeListener(MapEventListener<K, V> listener); + + /** + * Returns a java.util.Map instance backed by this ConsistentMap. + * @return java.util.Map + */ + Map<K, V> asJavaMap(); +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java new file mode 100644 index 00000000..847adaf6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java @@ -0,0 +1,143 @@ +/* + * 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.store.service; + +import org.onosproject.core.ApplicationId; + +/** + * Builder for consistent maps. + * + * @param <K> type for map key + * @param <V> type for map value + */ +public interface ConsistentMapBuilder<K, V> { + + /** + * Sets the name of the map. + * <p> + * Each consistent map is identified by a unique map name. + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the consistent map + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withName(String name); + + /** + * Sets the owner applicationId for the map. + * <p> + * Note: If {@code purgeOnUninstall} option is enabled, applicationId + * must be specified. + * </p> + * + * @param id applicationId owning the consistent map + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withApplicationId(ApplicationId id); + + /** + * Sets a serializer that can be used to serialize + * both the keys and values inserted into the map. The serializer + * builder should be pre-populated with any classes that will be + * put into the map. + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param serializer serializer + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withSerializer(Serializer serializer); + + /** + * Disables distribution of map entries across multiple database partitions. + * <p> + * When partitioning is disabled, the returned map will have a single partition + * that spans the entire cluster. Furthermore, the changes made to the map are + * ephemeral and do not survive a full cluster restart. + * </p> + * <p> + * Disabling partitions is more appropriate when the returned map is used for + * coordination activities such as leader election and not for long term data persistence. + * </p> + * <p> + * Note: By default partitions are enabled and entries in the map are durable. + * </p> + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withPartitionsDisabled(); + + /** + * Disables map updates. + * <p> + * Attempt to update the built map will throw {@code UnsupportedOperationException}. + * + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withUpdatesDisabled(); + + /** + * Purges map contents when the application owning the map is uninstalled. + * <p> + * When this option is enabled, the caller must provide a applicationId via + * the {@code withAppliationId} builder method. + * <p> + * By default map entries will NOT be purged when owning application is uninstalled. + * + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withPurgeOnUninstall(); + + /** + * Instantiates Metering service to gather usage and performance metrics. + * By default, usage data will be stored. + * + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withMeteringDisabled(); + + /** + * Provides weak consistency for map gets. + * <p> + * While this can lead to improved read performance, it can also make the behavior + * heard to reason. Only turn this on if you know what you are doing. By default + * reads are strongly consistent. + * + * @return this ConsistentMapBuilder + */ + ConsistentMapBuilder<K, V> withRelaxedReadConsistency(); + + /** + * Builds an consistent map based on the configuration options + * supplied to this builder. + * + * @return new consistent map + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + ConsistentMap<K, V> build(); + + /** + * Builds an async consistent map based on the configuration options + * supplied to this builder. + * + * @return new async consistent map + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + AsyncConsistentMap<K, V> buildAsyncMap(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapException.java new file mode 100644 index 00000000..94ed649f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/ConsistentMapException.java @@ -0,0 +1,48 @@ +/* + * 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.store.service; + +/** + * Top level exception for ConsistentMap failures. + */ +@SuppressWarnings("serial") +public class ConsistentMapException extends StorageException { + public ConsistentMapException() { + } + + public ConsistentMapException(Throwable t) { + super(t); + } + + /** + * ConsistentMap operation timeout. + */ + public static class Timeout extends ConsistentMapException { + } + + /** + * ConsistentMap update conflicts with an in flight transaction. + */ + public static class ConcurrentModification extends ConsistentMapException { + } + + /** + * ConsistentMap operation interrupted. + */ + public static class Interrupted extends ConsistentMapException { + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DatabaseUpdate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DatabaseUpdate.java new file mode 100644 index 00000000..8cac5968 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DatabaseUpdate.java @@ -0,0 +1,220 @@ +/* + * 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.store.service; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.MoreObjects; + +/** + * Database update operation. + * + */ +public final class DatabaseUpdate { + + /** + * Type of database update operation. + */ + public static enum Type { + /** + * Insert/Update entry without any checks. + */ + PUT, + /** + * Insert an entry iff there is no existing entry for that key. + */ + PUT_IF_ABSENT, + + /** + * Update entry if the current version matches specified version. + */ + PUT_IF_VERSION_MATCH, + + /** + * Update entry if the current value matches specified value. + */ + PUT_IF_VALUE_MATCH, + + /** + * Remove entry without any checks. + */ + REMOVE, + + /** + * Remove entry if the current version matches specified version. + */ + REMOVE_IF_VERSION_MATCH, + + /** + * Remove entry if the current value matches specified value. + */ + REMOVE_IF_VALUE_MATCH, + } + + private Type type; + private String mapName; + private String key; + private byte[] value; + private byte[] currentValue; + private long currentVersion = -1; + + /** + * Returns the type of update operation. + * @return type of update. + */ + public Type type() { + return type; + } + + /** + * Returns the name of map being updated. + * @return map name. + */ + public String mapName() { + return mapName; + } + + /** + * Returns the item key being updated. + * @return item key + */ + public String key() { + return key; + } + + /** + * Returns the new value. + * @return item's target value. + */ + public byte[] value() { + return value; + } + + /** + * Returns the expected current value in the database value for the key. + * @return current value in database. + */ + public byte[] currentValue() { + return currentValue; + } + + /** + * Returns the expected current version in the database for the key. + * @return expected version. + */ + public long currentVersion() { + return currentVersion; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("type", type) + .add("mapName", mapName) + .add("key", key) + .add("value", value) + .add("currentValue", currentValue) + .add("currentVersion", currentVersion) + .toString(); + } + + /** + * Creates a new builder instance. + * + * @return builder. + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * DatabaseUpdate builder. + * + */ + public static final class Builder { + + private DatabaseUpdate update = new DatabaseUpdate(); + + public DatabaseUpdate build() { + validateInputs(); + return update; + } + + public Builder withType(Type type) { + update.type = checkNotNull(type, "type cannot be null"); + return this; + } + + public Builder withMapName(String mapName) { + update.mapName = checkNotNull(mapName, "mapName cannot be null"); + return this; + } + + public Builder withKey(String key) { + update.key = checkNotNull(key, "key cannot be null"); + return this; + } + + public Builder withCurrentValue(byte[] value) { + update.currentValue = checkNotNull(value, "currentValue cannot be null"); + return this; + } + + public Builder withValue(byte[] value) { + update.value = checkNotNull(value, "value cannot be null"); + return this; + } + + public Builder withCurrentVersion(long version) { + checkArgument(version >= 0, "version cannot be negative"); + update.currentVersion = version; + return this; + } + + private void validateInputs() { + checkNotNull(update.type, "type must be specified"); + checkNotNull(update.mapName, "map name must be specified"); + checkNotNull(update.key, "key must be specified"); + switch (update.type) { + case PUT: + case PUT_IF_ABSENT: + checkNotNull(update.value, "value must be specified."); + break; + case PUT_IF_VERSION_MATCH: + checkNotNull(update.value, "value must be specified."); + checkState(update.currentVersion >= 0, "current version must be specified"); + break; + case PUT_IF_VALUE_MATCH: + checkNotNull(update.value, "value must be specified."); + checkNotNull(update.currentValue, "currentValue must be specified."); + break; + case REMOVE: + break; + case REMOVE_IF_VERSION_MATCH: + checkState(update.currentVersion >= 0, "current version must be specified"); + break; + case REMOVE_IF_VALUE_MATCH: + checkNotNull(update.currentValue, "currentValue must be specified."); + break; + default: + throw new IllegalStateException("Unknown operation type"); + } + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueue.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueue.java new file mode 100644 index 00000000..cc0b00d3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueue.java @@ -0,0 +1,62 @@ +/* + * 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.store.service; + +import java.util.concurrent.CompletableFuture; + +/** + * A distributed collection designed for holding elements prior to processing. + * A queue provides insertion, extraction and inspection operations. The extraction operation + * is designed to be non-blocking. + * + * @param <E> queue entry type + */ +public interface DistributedQueue<E> { + + /** + * Returns total number of entries in the queue. + * @return queue size + */ + long size(); + + /** + * Returns true if queue has elements in it. + * @return true is queue has elements, false otherwise + */ + default boolean isEmpty() { + return size() == 0; + } + + /** + * Inserts an entry into the queue. + * @param entry entry to insert + */ + void push(E entry); + + /** + * If the queue is non-empty, an entry will be removed from the queue and the returned future + * will be immediately completed with it. If queue is empty when this call is made, the returned + * future will be eventually completed when an entry is added to the queue. + * @return queue entry + */ + CompletableFuture<E> pop(); + + /** + * Returns an entry from the queue without removing it. If the queue is empty returns null. + * @return queue entry or null if queue is empty + */ + E peek(); +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueueBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueueBuilder.java new file mode 100644 index 00000000..646dc28c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedQueueBuilder.java @@ -0,0 +1,79 @@ +/* + * 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.store.service; + +/** + * Builder for distributed queue. + * + * @param <E> type queue elements. + */ +public interface DistributedQueueBuilder<E> { + + /** + * Sets the name of the queue. + * <p> + * Each queue is identified by a unique name. + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the queue + * @return this DistributedQueueBuilder for method chaining + */ + DistributedQueueBuilder<E> withName(String name); + + /** + * Sets a serializer that can be used to serialize + * the elements pushed into the queue. The serializer + * builder should be pre-populated with any classes that will be + * put into the queue. + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param serializer serializer + * @return this DistributedQueueBuilder for method chaining + */ + DistributedQueueBuilder<E> withSerializer(Serializer serializer); + + /** + * + * + * @return this DistributedQueueBuilder for method chaining + */ + DistributedQueueBuilder<E> withMeteringDisabled(); + + + /** + * Disables persistence of queues entries. + * <p> + * When persistence is disabled, a full cluster restart will wipe out all + * queue entries. + * </p> + * @return this DistributedQueueBuilder for method chaining + */ + DistributedQueueBuilder<E> withPersistenceDisabled(); + + /** + * Builds a queue based on the configuration options + * supplied to this builder. + * + * @return new distributed queue + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + DistributedQueue<E> build(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSet.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSet.java new file mode 100644 index 00000000..460206ec --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSet.java @@ -0,0 +1,41 @@ +/* + * 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.store.service; + +import java.util.Set; + +/** + * A distributed collection designed for holding unique elements. + * + * @param <E> set entry type + */ +public interface DistributedSet<E> extends Set<E> { + + /** + * Registers the specified listener to be notified whenever + * the set is updated. + * + * @param listener listener to notify about set update events + */ + void addListener(SetEventListener<E> listener); + + /** + * Unregisters the specified listener. + * + * @param listener listener to unregister. + */ + void removeListener(SetEventListener<E> listener); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java new file mode 100644 index 00000000..f5a44c93 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java @@ -0,0 +1,132 @@ +/* + * 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.store.service; + +import org.onosproject.core.ApplicationId; + +/** + * Builder for distributed set. + * + * @param <E> type set elements. + */ +public interface DistributedSetBuilder<E> { + + /** + * Sets the name of the set. + * <p> + * Each set is identified by a unique name. + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the set + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withName(String name); + + /** + * Sets the owner applicationId for the set. + * <p> + * Note: If {@code purgeOnUninstall} option is enabled, applicationId + * must be specified. + * </p> + * + * @param id applicationId owning the set + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withApplicationId(ApplicationId id); + + /** + * Sets a serializer that can be used to serialize + * the elements add to the set. The serializer + * builder should be pre-populated with any classes that will be + * put into the set. + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param serializer serializer + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withSerializer(Serializer serializer); + + /** + * Disables set updates. + * <p> + * Attempt to update the built set will throw {@code UnsupportedOperationException}. + * + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withUpdatesDisabled(); + + /** + * Provides weak consistency for set reads. + * <p> + * While this can lead to improved read performance, it can also make the behavior + * heard to reason. Only turn this on if you know what you are doing. By default + * reads are strongly consistent. + * + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withRelaxedReadConsistency(); + + /** + * Disables distribution of set entries across multiple database partitions. + * <p> + * When partitioning is disabled, the returned set will have a single partition + * that spans the entire cluster. Furthermore, the changes made to the set are + * ephemeral and do not survive a full cluster restart. + * </p> + * <p> + * Disabling partitions is more appropriate when the returned set is used for + * simple coordination activities and not for long term data persistence. + * </p> + * <p> + * Note: By default partitions are enabled and entries in the set are durable. + * </p> + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withPartitionsDisabled(); + + /** + * Instantiate Metrics service to gather usage and performance metrics. + * By default usage information is enabled + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withMeteringDisabled(); + + /** + * Purges set contents when the application owning the set is uninstalled. + * <p> + * When this option is enabled, the caller must provide a applicationId via + * the {@code withAppliationId} builder method. + * <p> + * By default set contents will NOT be purged when owning application is uninstalled. + * + * @return this DistributedSetBuilder + */ + DistributedSetBuilder<E> withPurgeOnUninstall(); + + /** + * Builds an set based on the configuration options + * supplied to this builder. + * + * @return new set + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + DistributedSet<E> build(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMap.java new file mode 100644 index 00000000..06395b8e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMap.java @@ -0,0 +1,207 @@ +/* + * 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.store.service; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.function.BiFunction; + +/** + * A distributed, eventually consistent map. + * <p> + * This map does not offer read after writes consistency. Operations are + * serialized via the timestamps issued by the clock service. If two updates + * are in conflict, the update with the more recent timestamp will endure. + * </p><p> + * The interface is mostly similar to {@link java.util.Map} with some minor + * semantic changes and the addition of a listener framework (because the map + * can be mutated by clients on other instances, not only through the local Java + * API). + * </p><p> + * Clients are expected to register an + * {@link EventuallyConsistentMapListener} if they + * are interested in receiving notifications of update to the map. + * </p><p> + * Null values are not allowed in this map. + * </p> + */ +public interface EventuallyConsistentMap<K, V> { + + /** + * Returns the number of key-value mappings in this map. + * + * @return number of key-value mappings + */ + int size(); + + /** + * Returns true if this map is empty. + * + * @return true if this map is empty, otherwise false + */ + boolean isEmpty(); + + /** + * Returns true if the map contains a mapping for the specified key. + * + * @param key the key to check if this map contains + * @return true if this map has a mapping for the key, otherwise false + */ + boolean containsKey(K key); + + /** + * Returns true if the map contains a mapping from any key to the specified + * value. + * + * @param value the value to check if this map has a mapping for + * @return true if this map has a mapping to this value, otherwise false + */ + boolean containsValue(V value); + + /** + * Returns the value mapped to the specified key. + * + * @param key the key to look up in this map + * @return the value mapped to the key, or null if no mapping is found + */ + V get(K key); + + /** + * Associates the specified value to the specified key in this map. + * <p> + * Note: this differs from the specification of {@link java.util.Map} + * because it does not return the previous value associated with the key. + * Clients are expected to register an + * {@link EventuallyConsistentMapListener} if + * they are interested in receiving notification of updates to the map. + * </p><p> + * Null values are not allowed in the map. + * </p> + * + * @param key the key to add a mapping for in this map + * @param value the value to associate with the key in this map + */ + void put(K key, V value); + + /** + * Removes the mapping associated with the specified key from the map. + * <p> + * Clients are expected to register an {@link EventuallyConsistentMapListener} if + * they are interested in receiving notification of updates to the map. + * </p> + * + * @param key the key to remove the mapping for + * @return previous value associated with key, or null if there was no mapping for key. + */ + V remove(K key); + + /** + * Removes the given key-value mapping from the map, if it exists. + * <p> + * This actually means remove any values up to and including the timestamp + * given by the map's timestampProvider. + * Any mappings that produce an earlier timestamp than this given key-value + * pair will be removed, and any mappings that produce a later timestamp + * will supersede this remove. + * </p><p> + * Note: this differs from the specification of {@link java.util.Map} + * because it does not return a boolean indication whether a value was removed. + * Clients are expected to register an + * {@link EventuallyConsistentMapListener} if + * they are interested in receiving notification of updates to the map. + * </p> + * + * @param key the key to remove the mapping for + * @param value the value mapped to the key + */ + void remove(K key, V value); + + /** + * Attempts to compute a mapping for the specified key and its current mapped + * value (or null if there is no current mapping). + * <p> + * If the function returns null, the mapping is removed (or remains absent if initially absent). + * @param key map key + * @param recomputeFunction function to recompute a new value + * @return new value + */ + V compute(K key, BiFunction<K, V, V> recomputeFunction); + + /** + * Adds mappings for all key-value pairs in the specified map to this map. + * <p> + * This will be more efficient in communication than calling individual put + * operations. + * </p> + * + * @param m a map of values to add to this map + */ + void putAll(Map<? extends K, ? extends V> m); + + /** + * Removes all mappings from this map. + */ + void clear(); + + /** + * Returns a set of the keys in this map. Changes to the set are not + * reflected back to the map. + * + * @return set of keys in the map + */ + Set<K> keySet(); + + /** + * Returns a collections of values in this map. Changes to the collection + * are not reflected back to the map. + * + * @return collection of values in the map + */ + Collection<V> values(); + + /** + * Returns a set of mappings contained in this map. Changes to the set are + * not reflected back to the map. + * + * @return set of key-value mappings in this map + */ + Set<Map.Entry<K, V>> entrySet(); + + /** + * Adds the specified listener to the map which will be notified whenever + * the mappings in the map are changed. + * + * @param listener listener to register for events + */ + void addListener(EventuallyConsistentMapListener<K, V> listener); + + /** + * Removes the specified listener from the map such that it will no longer + * receive change notifications. + * + * @param listener listener to deregister for events + */ + void removeListener(EventuallyConsistentMapListener<K, V> listener); + + /** + * Shuts down the map and breaks communication between different instances. + * This allows the map objects to be cleaned up and garbage collected. + * Calls to any methods on the map subsequent to calling destroy() will + * throw a {@link java.lang.RuntimeException}. + */ + void destroy(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapBuilder.java new file mode 100644 index 00000000..9471321c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapBuilder.java @@ -0,0 +1,187 @@ +/* + * 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.store.service; + +import org.onlab.util.KryoNamespace; +import org.onosproject.cluster.NodeId; +import org.onosproject.store.Timestamp; + +import java.util.Collection; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.BiFunction; + +/** + * Builder for eventually consistent maps. + * + * @param <K> type for map keys + * @param <V> type for map values + */ +public interface EventuallyConsistentMapBuilder<K, V> { + + /** + * Sets the name of the map. + * <p> + * Each map is identified by a string map name. EventuallyConsistentMapImpl + * objects in different JVMs that use the same map name will form a + * distributed map across JVMs (provided the cluster service is aware of + * both nodes). + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param name name of the map + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withName(String name); + + /** + * Sets a serializer builder that can be used to create a serializer that + * can serialize both the keys and values put into the map. The serializer + * builder should be pre-populated with any classes that will be put into + * the map. + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param serializerBuilder serializer builder + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withSerializer( + KryoNamespace.Builder serializerBuilder); + + /** + * Sets the function to use for generating timestamps for map updates. + * <p> + * The client must provide an {@code BiFunction<K, V, Timestamp>} + * which can generate timestamps for a given key. The function is free + * to generate timestamps however it wishes, however these timestamps will + * be used to serialize updates to the map so they must be strict enough + * to ensure updates are properly ordered for the use case (i.e. in some + * cases wallclock time will suffice, whereas in other cases logical time + * will be necessary). + * </p> + * <p> + * Note: This is a mandatory parameter. + * </p> + * + * @param timestampProvider provides a new timestamp + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withTimestampProvider( + BiFunction<K, V, Timestamp> timestampProvider); + + /** + * Sets the executor to use for processing events coming in from peers. + * + * @param executor event executor + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withEventExecutor( + ExecutorService executor); + + /** + * Sets the executor to use for sending events to peers. + * + * @param executor event executor + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor( + ExecutorService executor); + + /** + * Sets the executor to use for background anti-entropy tasks. + * + * @param executor event executor + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor( + ScheduledExecutorService executor); + + /** + * Sets a function that can determine which peers to replicate updates to. + * <p> + * The default function replicates to all nodes. + * </p> + * + * @param peerUpdateFunction function that takes a K, V input and returns + * a collection of NodeIds to replicate the event + * to + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withPeerUpdateFunction( + BiFunction<K, V, Collection<NodeId>> peerUpdateFunction); + + /** + * Prevents this map from writing tombstones of items that have been + * removed. This may result in zombie items reappearing after they have + * been removed. + * <p> + * The default behavior is tombstones are enabled. + * </p> + * + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled(); + + /** + * Configures how often to run the anti-entropy background task. + * <p> + * The default anti-entropy period is 5 seconds. + * </p> + * + * @param period anti-entropy period + * @param unit time unit for the period + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod( + long period, TimeUnit unit); + + /** + * Configure anti-entropy to converge faster at the cost of doing more work + * for each anti-entropy cycle. Suited to maps with low update rate where + * convergence time is more important than throughput. + * <p> + * The default behavior is to do less anti-entropy work at the cost of + * slower convergence. + * </p> + * + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withFasterConvergence(); + + /** + * Configure the map to persist data to disk. + * <p> + * The default behavior is no persistence + * </p> + * + * @return this EventuallyConsistentMapBuilder + */ + EventuallyConsistentMapBuilder<K, V> withPersistence(); + + /** + * Builds an eventually consistent map based on the configuration options + * supplied to this builder. + * + * @return new eventually consistent map + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + EventuallyConsistentMap<K, V> build(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapEvent.java new file mode 100644 index 00000000..5814534e --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapEvent.java @@ -0,0 +1,124 @@ +/* + * 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.store.service; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Representation of a EventuallyConsistentMap update notification. + */ +public final class EventuallyConsistentMapEvent<K, V> { + + public enum Type { + /** + * Entry added to map or existing entry updated. + */ + PUT, + + /** + * Entry removed from map. + */ + REMOVE + } + + private final String name; + private final Type type; + private final K key; + private final V value; + + /** + * Creates a new event object. + * + * @param name map name + * @param type the type of the event + * @param key the key the event concerns + * @param value the value mapped to the key + */ + public EventuallyConsistentMapEvent(String name, Type type, K key, V value) { + this.name = name; + this.type = type; + this.key = key; + this.value = value; + } + + /** + * Returns the map name. + * + * @return name of map + */ + public String name() { + return name; + } + + /** + * Returns the type of the event. + * + * @return the type of the event + */ + public Type type() { + return type; + } + + /** + * Returns the key this event concerns. + * + * @return the key + */ + public K key() { + return key; + } + + /** + * Returns the value associated with this event. If type is REMOVE, + * this is the value that was removed. If type is PUT, this is + * the new value. + * + * @return the value + */ + public V value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof EventuallyConsistentMapEvent)) { + return false; + } + + EventuallyConsistentMapEvent that = (EventuallyConsistentMapEvent) o; + return Objects.equals(this.type, that.type) && + Objects.equals(this.key, that.key) && + Objects.equals(this.value, that.value) && + Objects.equals(this.name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(type, key, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("name", name) + .add("type", type) + .add("key", key) + .add("value", value) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapListener.java new file mode 100644 index 00000000..b2399a48 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/EventuallyConsistentMapListener.java @@ -0,0 +1,29 @@ +/* + * 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.store.service; + +/** + * Listener to be notified about updates to a EventuallyConsistentMap. + */ +public interface EventuallyConsistentMapListener<K, V> { + + /** + * Reacts to the specified event. + * + * @param event the event + */ + void event(EventuallyConsistentMapEvent<K, V> event); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/LogicalClockService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/LogicalClockService.java new file mode 100644 index 00000000..7592b126 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/LogicalClockService.java @@ -0,0 +1,35 @@ +/* + * 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.store.service; + +import org.onosproject.store.Timestamp; + +/** + * Service that issues logical timestamps. + * <p> + * Logical timestamps are useful for establishing a total ordering of + * arbitrary cluster wide events without relying on a fully synchronized + * system clock (wall clock) + */ +public interface LogicalClockService { + + /** + * Generates a new logical timestamp. + * + * @return timestamp + */ + Timestamp getTimestamp(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEvent.java new file mode 100644 index 00000000..6e671351 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEvent.java @@ -0,0 +1,135 @@ +/* + * 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.store.service; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +/** + * Representation of a ConsistentMap update notification. + * + * @param <K> key type + * @param <V> value type + */ +public class MapEvent<K, V> { + + /** + * MapEvent type. + */ + public enum Type { + /** + * Entry inserted into the map. + */ + INSERT, + + /** + * Existing map entry updated. + */ + UPDATE, + + /** + * Entry removed from map. + */ + REMOVE + } + + private final String name; + private final Type type; + private final K key; + private final Versioned<V> value; + + /** + * Creates a new event object. + * + * @param name map name + * @param type type of event + * @param key key the event concerns + * @param value value key is mapped to + */ + public MapEvent(String name, Type type, K key, Versioned<V> value) { + this.name = name; + this.type = type; + this.key = key; + this.value = value; + } + + /** + * Returns the map name. + * + * @return name of map + */ + public String name() { + return name; + } + + /** + * Returns the type of the event. + * + * @return the type of event + */ + public Type type() { + return type; + } + + /** + * Returns the key this event concerns. + * + * @return the key + */ + public K key() { + return key; + } + + /** + * Returns the value associated with this event. If type is REMOVE, + * this is the value that was removed. If type is INSERT/UPDATE, this is + * the new value. + * + * @return the value + */ + public Versioned<V> value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof MapEvent)) { + return false; + } + + MapEvent<K, V> that = (MapEvent) o; + return Objects.equals(this.name, that.name) && + Objects.equals(this.type, that.type) && + Objects.equals(this.key, that.key) && + Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(name, type, key, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("name", name) + .add("type", type) + .add("key", key) + .add("value", value) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEventListener.java new file mode 100644 index 00000000..359f4653 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapEventListener.java @@ -0,0 +1,28 @@ +/* + * 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.store.service; + +/** + * Listener to be notified about updates to a ConsistentMap. + */ +public interface MapEventListener<K, V> { + /** + * Reacts to the specified event. + * + * @param event the event + */ + void event(MapEvent<K, V> event); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapInfo.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapInfo.java new file mode 100644 index 00000000..5db17049 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MapInfo.java @@ -0,0 +1,47 @@ +/* + * 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.store.service; + +/** + * Metadata information for a consistent map. + */ +public class MapInfo { + private final String name; + private final int size; + + public MapInfo(String name, int size) { + this.name = name; + this.size = size; + } + + /** + * Returns the name of the map. + * + * @return map name + */ + public String name() { + return name; + } + + /** + * Returns the number of entries in the map. + * + * @return map size + */ + public int size() { + return size; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MultiValuedTimestamp.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MultiValuedTimestamp.java new file mode 100644 index 00000000..e068b8e9 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/MultiValuedTimestamp.java @@ -0,0 +1,111 @@ +/* + * 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.store.service; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ComparisonChain; +import org.onosproject.store.Timestamp; + +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A logical timestamp that derives its value from two input values. The first + * value always takes precedence over the second value when comparing timestamps. + */ +public class MultiValuedTimestamp<T extends Comparable<T>, U extends Comparable<U>> + implements Timestamp { + + private final T value1; + private final U value2; + + /** + * Creates a new timestamp based on two values. The first value has higher + * precedence than the second when comparing timestamps. + * + * @param value1 first value + * @param value2 second value + */ + public MultiValuedTimestamp(T value1, U value2) { + this.value1 = checkNotNull(value1); + this.value2 = checkNotNull(value2); + } + + @Override + public int compareTo(Timestamp o) { + checkArgument(o instanceof MultiValuedTimestamp, + "Must be MultiValuedTimestamp", o); + MultiValuedTimestamp that = (MultiValuedTimestamp) o; + + return ComparisonChain.start() + .compare(this.value1, that.value1) + .compare(this.value2, that.value2) + .result(); + } + + @Override + public int hashCode() { + return Objects.hash(value1, value2); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof MultiValuedTimestamp)) { + return false; + } + MultiValuedTimestamp that = (MultiValuedTimestamp) obj; + return Objects.equals(this.value1, that.value1) && + Objects.equals(this.value2, that.value2); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("value1", value1) + .add("value2", value2) + .toString(); + } + + /** + * Returns the first value. + * + * @return first value + */ + public T value1() { + return value1; + } + + /** + * Returns the second value. + * + * @return second value + */ + public U value2() { + return value2; + } + + // Default constructor for serialization + @SuppressWarnings("unused") + private MultiValuedTimestamp() { + this.value1 = null; + this.value2 = null; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java new file mode 100644 index 00000000..a0f06481 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java @@ -0,0 +1,81 @@ +/* + * 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.store.service; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * Contains information about a database partition. + */ +public class PartitionInfo { + private final String name; + private final long term; + private final List<String> members; + private final String leader; + + /** + * Class constructor. + * + * @param name partition name + * @param term term number + * @param members partition members + * @param leader leader name + */ + public PartitionInfo(String name, long term, List<String> members, String leader) { + this.name = name; + this.term = term; + this.members = ImmutableList.copyOf(members); + this.leader = leader; + } + + /** + * Returns the name of the partition. + * + * @return partition name + */ + public String name() { + return name; + } + + /** + * Returns the term number. + * + * @return term number + */ + public long term() { + return term; + } + + /** + * Returns the list of partition members. + * + * @return partition members + */ + public List<String> members() { + return members; + } + + /** + * Returns the partition leader. + * + * @return partition leader + */ + public String leader() { + return leader; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Serializer.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Serializer.java new file mode 100644 index 00000000..6245175f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Serializer.java @@ -0,0 +1,81 @@ +/* + * 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.store.service; + +import java.util.Arrays; +import java.util.List; + +import org.onlab.util.KryoNamespace; + +import com.google.common.collect.Lists; + +/** + * Interface for serialization of store artifacts. + */ +public interface Serializer { + /** + * Serialize the specified object. + * @param object object to serialize. + * @return serialized bytes. + * @param <T> encoded type + */ + <T> byte[] encode(T object); + + /** + * Deserialize the specified bytes. + * @param bytes byte array to deserialize. + * @return deserialized object. + * @param <T> decoded type + */ + <T> T decode(byte[] bytes); + + /** + * Creates a new Serializer instance from a KryoNamespace. + * + * @param kryo kryo namespace + * @return Serializer instance + */ + static Serializer using(KryoNamespace kryo) { + return using(Arrays.asList(kryo)); + } + + static Serializer using(List<KryoNamespace> namespaces, Class<?>... classes) { + KryoNamespace.Builder builder = new KryoNamespace.Builder(); + namespaces.forEach(builder::register); + Lists.newArrayList(classes).forEach(builder::register); + builder.register(MapEvent.class, MapEvent.Type.class, Versioned.class); + KryoNamespace namespace = builder.build(); + return new Serializer() { + @Override + public <T> byte[] encode(T object) { + return namespace.serialize(object); + } + + @Override + public <T> T decode(byte[] bytes) { + return namespace.deserialize(bytes); + } + }; + } + + static Serializer forTypes(Class<?>... classes) { + return using(KryoNamespace.newBuilder() + .register(classes) + .register(MapEvent.class, MapEvent.Type.class) + .build()); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEvent.java new file mode 100644 index 00000000..a869e722 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEvent.java @@ -0,0 +1,113 @@ +/* + * 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.store.service; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +/** + * Representation of a DistributedSet update notification. + * + * @param <E> set element type + */ +public final class SetEvent<E> { + + /** + * SetEvent type. + */ + public enum Type { + /** + * Entry added to the set. + */ + ADD, + + /** + * Entry removed from the set. + */ + REMOVE + } + + private final String name; + private final Type type; + private final E entry; + + /** + * Creates a new event object. + * + * @param name set name + * @param type type of the event + * @param entry entry the event concerns + */ + public SetEvent(String name, Type type, E entry) { + this.name = name; + this.type = type; + this.entry = entry; + } + + /** + * Returns the set name. + * + * @return name of set + */ + public String name() { + return name; + } + + /** + * Returns the type of the event. + * + * @return type of the event + */ + public Type type() { + return type; + } + + /** + * Returns the entry this event concerns. + * + * @return the entry + */ + public E entry() { + return entry; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof SetEvent)) { + return false; + } + + SetEvent that = (SetEvent) o; + return Objects.equals(this.name, that.name) && + Objects.equals(this.type, that.type) && + Objects.equals(this.entry, that.entry); + } + + @Override + public int hashCode() { + return Objects.hash(name, type, entry); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("name", name) + .add("type", type) + .add("entry", entry) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEventListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEventListener.java new file mode 100644 index 00000000..a64994ef --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/SetEventListener.java @@ -0,0 +1,28 @@ +/* + * 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.store.service; + +/** + * Listener to be notified about updates to a DistributedSet. + */ +public interface SetEventListener<E> { + /** + * Reacts to the specified event. + * + * @param event the event + */ + void event(SetEvent<E> event); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java new file mode 100644 index 00000000..22591044 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java @@ -0,0 +1,75 @@ +/* + * 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.store.service; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Service for administering storage instances. + */ +public interface StorageAdminService { + + /** + * Returns information about all partitions in the system. + * + * @return list of partition information + */ + List<PartitionInfo> getPartitionInfo(); + + /** + * Returns information about all the consistent maps in the system. + * + * @return list of map information + */ + List<MapInfo> getMapInfo(); + + /** + * Returns information about all the atomic counters in the system. + * If 2 counters belonging to 2 different databases have the same name, + * then only one counter from one database is returned. + * + * @return mapping from counter name to that counter's next value + */ + Map<String, Long> getCounters(); + + /** + * Returns information about all the atomic partitioned database counters in the system. + * + * @return mapping from counter name to that counter's next value + */ + Map<String, Long> getPartitionedDatabaseCounters(); + + /** + * Returns information about all the atomic in-memory database counters in the system. + * + * @return mapping from counter name to that counter's next value + */ + Map<String, Long> getInMemoryDatabaseCounters(); + + /** + * Returns all the transactions in the system. + * + * @return collection of transactions + */ + Collection<Transaction> getTransactions(); + + /** + * Redrives stuck transactions while removing those that are done. + */ + void redriveTransactions(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageException.java new file mode 100644 index 00000000..a66fc3ed --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageException.java @@ -0,0 +1,48 @@ +/* + * 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.store.service; + +/** + * Top level exception for Store failures. + */ +@SuppressWarnings("serial") +public class StorageException extends RuntimeException { + public StorageException() { + } + + public StorageException(Throwable t) { + super(t); + } + + /** + * Store operation timeout. + */ + public static class Timeout extends StorageException { + } + + /** + * Store update conflicts with an in flight transaction. + */ + public static class ConcurrentModification extends StorageException { + } + + /** + * Store operation interrupted. + */ + public static class Interrupted extends StorageException { + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageService.java new file mode 100644 index 00000000..f6b411d3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/StorageService.java @@ -0,0 +1,83 @@ +/* + * 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.store.service; + +/** + * Storage service. + * <p> + * This service provides builders for various distributed primitives. + * <p> + * It is expected that services and applications will leverage the primitives indirectly provided by + * this service for their distributed state management and coordination. + */ +public interface StorageService { + + /** + * Creates a new EventuallyConsistentMapBuilder. + * + * @param <K> key type + * @param <V> value type + * @return builder for an eventually consistent map + */ + <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder(); + + /** + * Creates a new ConsistentMapBuilder. + * + * @param <K> key type + * @param <V> value type + * @return builder for a consistent map + */ + <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder(); + + /** + * Creates a new DistributedSetBuilder. + * + * @param <E> set element type + * @return builder for an distributed set + */ + <E> DistributedSetBuilder<E> setBuilder(); + + /** + * Creates a new DistributedQueueBuilder. + * + * @param <E> queue entry type + * @return builder for an distributed queue + */ + <E> DistributedQueueBuilder<E> queueBuilder(); + + /** + * Creates a new AtomicCounterBuilder. + * + * @return atomic counter builder + */ + AtomicCounterBuilder atomicCounterBuilder(); + + /** + * Creates a new AtomicValueBuilder. + * + * @param <V> atomic value type + * @return atomic value builder + */ + <V> AtomicValueBuilder<V> atomicValueBuilder(); + + /** + * Creates a new transaction context builder. + * + * @return a builder for a transaction context. + */ + TransactionContextBuilder transactionContextBuilder(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Transaction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Transaction.java new file mode 100644 index 00000000..330d8468 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Transaction.java @@ -0,0 +1,102 @@ +/* + * 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.store.service; + +import java.util.List; + +/** + * An immutable transaction object. + */ +public interface Transaction { + + enum State { + /** + * Indicates a new transaction that is about to be prepared. All transactions + * start their life in this state. + */ + PREPARING, + + /** + * Indicates a transaction that is successfully prepared i.e. all participants voted to commit + */ + PREPARED, + + /** + * Indicates a transaction that is about to be committed. + */ + COMMITTING, + + /** + * Indicates a transaction that has successfully committed. + */ + COMMITTED, + + /** + * Indicates a transaction that is about to be rolled back. + */ + ROLLINGBACK, + + /** + * Indicates a transaction that has been rolled back and all locks are released. + */ + ROLLEDBACK + } + + /** + * Returns the transaction Id. + * + * @return transaction id + */ + long id(); + + /** + * Returns the list of updates that are part of this transaction. + * + * @return list of database updates + */ + List<DatabaseUpdate> updates(); + + /** + * Returns the current state of this transaction. + * + * @return transaction state + */ + State state(); + + /** + * Returns true if this transaction has completed execution. + * + * @return true is yes, false otherwise + */ + default boolean isDone() { + return state() == State.COMMITTED || state() == State.ROLLEDBACK; + } + + /** + * Returns a new transaction that is created by transitioning this one to the specified state. + * + * @param newState destination state + * @return a new transaction instance similar to the current one but its state set to specified state + */ + Transaction transition(State newState); + + /** + * Returns the system time when the transaction was last updated. + * + * @return last update time + */ + long lastUpdated(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContext.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContext.java new file mode 100644 index 00000000..94942e20 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContext.java @@ -0,0 +1,78 @@ +/* + * 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.store.service; + +/** + * Provides a context for transactional operations. + * <p> + * A transaction context is a vehicle for grouping operations into a unit with the + * properties of atomicity, isolation, and durability. Transactions also provide the + * ability to maintain an application's invariants or integrity constraints, + * supporting the property of consistency. Together these properties are known as ACID. + * <p> + * A transaction context provides a boundary within which transactions + * are run. It also is a place where all modifications made within a transaction + * are cached until the point when the transaction commits or aborts. It thus ensures + * isolation of work happening with in the transaction boundary. Within a transaction + * context isolation level is REPEATABLE_READS i.e. only data that is committed can be read. + * The only uncommitted data that can be read is the data modified by the current transaction. + */ +public interface TransactionContext { + + /** + * Returns the unique transactionId. + * + * @return transaction id + */ + long transactionId(); + + /** + * Returns if this transaction context is open. + * + * @return true if open, false otherwise + */ + boolean isOpen(); + + /** + * Starts a new transaction. + */ + void begin(); + + /** + * Commits a transaction that was previously started thereby making its changes permanent + * and externally visible. + * + * @throws TransactionException if transaction fails to commit + */ + void commit(); + + /** + * Aborts any changes made in this transaction context and discarding all locally cached updates. + */ + void abort(); + + /** + * Returns a transactional map data structure with the specified name. + * + * @param <K> key type + * @param <V> value type + * @param mapName name of the transactional map + * @param serializer serializer to use for encoding/decoding keys and values of the map + * @return Transactional Map + */ + <K, V> TransactionalMap<K, V> getTransactionalMap(String mapName, Serializer serializer); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java new file mode 100644 index 00000000..e9f3a020 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java @@ -0,0 +1,47 @@ +/* + * 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.store.service; + +/** + * Interface definition for a transaction context builder. + */ +public interface TransactionContextBuilder { + + /** + * Disables distribution of map entries across multiple database partitions. + * <p> + * When partitioning is disabled, the returned map will have a single + * partition that spans the entire cluster. Furthermore, the changes made to + * the map are ephemeral and do not survive a full cluster restart. + * </p> + * <p> + * Note: By default, partitions are enabled. This feature is intended to + * simplify debugging. + * </p> + * + * @return this TransactionalContextBuilder + */ + TransactionContextBuilder withPartitionsDisabled(); + + /** + * Builds a TransactionContext based on configuration options supplied to this + * builder. + * + * @return a new TransactionalContext + * @throws java.lang.RuntimeException if a mandatory parameter is missing + */ + TransactionContext build(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionException.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionException.java new file mode 100644 index 00000000..a3723ee7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionException.java @@ -0,0 +1,54 @@ +/* + * 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.store.service; + +/** + * Top level exception for Transaction failures. + */ +@SuppressWarnings("serial") +public class TransactionException extends StorageException { + public TransactionException() { + } + + public TransactionException(Throwable t) { + super(t); + } + + /** + * Transaction timeout. + */ + public static class Timeout extends TransactionException { + } + + /** + * Transaction interrupted. + */ + public static class Interrupted extends TransactionException { + } + + /** + * Transaction failure due to optimistic concurrency violation. + */ + public static class OptimisticConcurrencyFailure extends TransactionException { + } + + /** + * Transaction failure due to a conflicting transaction in progress. + */ + public static class ConcurrentModification extends TransactionException { + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionalMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionalMap.java new file mode 100644 index 00000000..657d9331 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/TransactionalMap.java @@ -0,0 +1,93 @@ +/* + * 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.store.service; + +/** + * Transactional Map data structure. + * <p> + * A TransactionalMap is created by invoking {@link TransactionContext#getTransactionalMap getTransactionalMap} + * method. All operations performed on this map within a transaction boundary are invisible externally + * until the point when the transaction commits. A commit usually succeeds in the absence of conflicts. + * + * @param <K> type of key. + * @param <V> type of value. + */ +public interface TransactionalMap<K, V> { + + /** + * Returns the value to which the specified key is mapped, or null if this + * map contains no mapping for the key. + * + * @param key the key whose associated value is to be returned + * @return the value to which the specified key is mapped, or null if + * this map contains no mapping for the key + */ + V get(K key); + + /** + * Associates the specified value with the specified key in this map (optional operation). + * If the map previously contained a mapping for the key, the old value is replaced by the + * specified value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with key, or null if there was + * no mapping for key. + */ + V put(K key, V value); + + /** + * Removes the mapping for a key from this map if it is present (optional operation). + * + * @param key key whose value is to be removed from the map + * @return the value to which this map previously associated the key, + * or null if the map contained no mapping for the key. + */ + V remove(K key); + + /** + * If the specified key is not already associated with a value + * associates it with the given value and returns null, else returns the current value. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with the specified key or null + * if key does not already mapped to a value. + */ + V putIfAbsent(K key, V value); + + /** + * Removes the entry for the specified key only if it is currently + * mapped to the specified value. + * + * @param key key with which the specified value is associated + * @param value value expected to be associated with the specified key + * @return true if the value was removed + */ + boolean remove(K key, V value); + + /** + * Replaces the entry for the specified key only if currently mapped + * to the specified value. + * + * @param key key with which the specified value is associated + * @param oldValue value expected to be associated with the specified key + * @param newValue value to be associated with the specified key + * @return true if the value was replaced + */ + boolean replace(K key, V oldValue, V newValue); +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Versioned.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Versioned.java new file mode 100644 index 00000000..89bd3029 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/Versioned.java @@ -0,0 +1,138 @@ +/* + * 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.store.service; + +import java.util.function.Function; + +import org.joda.time.DateTime; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +/** + * Versioned value. + * + * @param <V> value type. + */ +public class Versioned<V> { + + private final V value; + private final long version; + private final long creationTime; + + /** + * Constructs a new versioned value. + * @param value value + * @param version version + * @param creationTime milliseconds of the creation event + * from the Java epoch of 1970-01-01T00:00:00Z + */ + public Versioned(V value, long version, long creationTime) { + this.value = value; + this.version = version; + this.creationTime = creationTime; + } + + /** + * Constructs a new versioned value. + * @param value value + * @param version version + */ + public Versioned(V value, long version) { + this(value, version, System.currentTimeMillis()); + } + + /** + * Returns the value. + * + * @return value. + */ + public V value() { + return value; + } + + /** + * Returns the version. + * + * @return version + */ + public long version() { + return version; + } + + /** + * Returns the system time when this version was created. + * <p> + * Care should be taken when relying on creationTime to + * implement any behavior in a distributed setting. Due + * to the possibility of clock skew it is likely that + * even creationTimes of causally related versions can be + * out or order. + * @return creation time + */ + public long creationTime() { + return creationTime; + } + + /** + * Maps this instance into another after transforming its + * value while retaining the same version and creationTime. + * @param transformer function for mapping the value + * @param <U> value type of the returned instance + * @return mapped instance + */ + public <U> Versioned<U> map(Function<V, U> transformer) { + return new Versioned<>(transformer.apply(value), version, creationTime); + } + + /** + * Returns the value of the specified Versioned object if non-null or else returns + * a default value. + * @param versioned versioned object + * @param defaultValue default value to return if versioned object is null + * @param <U> type of the versioned value + * @return versioned value or default value if versioned object is null + */ + public static <U> U valueOrElse(Versioned<U> versioned, U defaultValue) { + return versioned == null ? defaultValue : versioned.value(); + } + + @Override + public int hashCode() { + return Objects.hashCode(value, version, creationTime); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Versioned)) { + return false; + } + Versioned<V> that = (Versioned) other; + return Objects.equal(this.value, that.value) && + Objects.equal(this.version, that.version) && + Objects.equal(this.creationTime, that.creationTime); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("value", value) + .add("version", version) + .add("creationTime", new DateTime(creationTime)) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java new file mode 100644 index 00000000..0cc7b453 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java @@ -0,0 +1,85 @@ +/* + * Copyright 2014 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.store.service; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Objects; + +import org.onosproject.store.Timestamp; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ComparisonChain; + +/** + * A Timestamp that derives its value from the prevailing + * wallclock time on the controller where it is generated. + */ +public class WallClockTimestamp implements Timestamp { + + private final long unixTimestamp; + + public WallClockTimestamp() { + unixTimestamp = System.currentTimeMillis(); + } + + public WallClockTimestamp(long timestamp) { + unixTimestamp = timestamp; + } + + @Override + public int compareTo(Timestamp o) { + checkArgument(o instanceof WallClockTimestamp, + "Must be WallClockTimestamp", o); + WallClockTimestamp that = (WallClockTimestamp) o; + + return ComparisonChain.start() + .compare(this.unixTimestamp, that.unixTimestamp) + .result(); + } + @Override + public int hashCode() { + return Objects.hash(unixTimestamp); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof WallClockTimestamp)) { + return false; + } + WallClockTimestamp that = (WallClockTimestamp) obj; + return Objects.equals(this.unixTimestamp, that.unixTimestamp); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("unixTimestamp", unixTimestamp) + .toString(); + } + + /** + * Returns the unixTimestamp. + * + * @return unix timestamp + */ + public long unixTimestamp() { + return unixTimestamp; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/package-info.java new file mode 100644 index 00000000..3d86e351 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2014 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. + */ + +/** + * Distributed core state management services. + */ +package org.onosproject.store.service; + diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/JsonUtils.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/JsonUtils.java new file mode 100644 index 00000000..2ebb5545 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/JsonUtils.java @@ -0,0 +1,143 @@ +/* + * 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.ui; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Provides convenience methods for dealing with JSON nodes, arrays etc. + */ +public final class JsonUtils { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + // non-instantiable + private JsonUtils() { } + + /** + * Wraps a message payload into an event structure for the given event + * type and sequence ID. Generally, the sequence ID should be a copy of + * the ID from the client request event. + * + * @param type event type + * @param sid sequence ID + * @param payload event payload + * @return the object node representation + */ + public static ObjectNode envelope(String type, long sid, ObjectNode payload) { + ObjectNode event = MAPPER.createObjectNode(); + event.put("event", type); + if (sid > 0) { + event.put("sid", sid); + } + event.set("payload", payload); + return event; + } + + /** + * Composes a message structure for the given message type and payload. + * + * @param type message type + * @param payload message payload + * @return the object node representation + */ + public static ObjectNode envelope(String type, ObjectNode payload) { + ObjectNode event = MAPPER.createObjectNode(); + event.put("event", type); + event.set("payload", payload); + return event; + } + + /** + * Returns the event type from the specified event. + * If the node does not have an "event" property, "unknown" is returned. + * + * @param event message event + * @return extracted event type + */ + public static String eventType(ObjectNode event) { + return string(event, "event", "unknown"); + } + + /** + * Returns the sequence identifier from the specified event, or 0 (zero) + * if the "sid" property does not exist. + * + * @param event message event + * @return extracted sequence identifier + */ + public static long sid(ObjectNode event) { + return number(event, "sid"); + } + + /** + * Returns the payload from the specified event. + * + * @param event message event + * @return extracted payload object + */ + public static ObjectNode payload(ObjectNode event) { + return (ObjectNode) event.path("payload"); + } + + /** + * Returns the specified node property as a number. + * + * @param node message event + * @param name property name + * @return property as number + */ + public static long number(ObjectNode node, String name) { + return node.path(name).asLong(); + } + + /** + * Returns the specified node property as a string. + * + * @param node message event + * @param name property name + * @return property as a string + */ + public static String string(ObjectNode node, String name) { + return node.path(name).asText(); + } + + /** + * Returns the specified node property as a string, with a default fallback. + * + * @param node object node + * @param name property name + * @param defaultValue fallback value if property is absent + * @return property as a string + */ + public static String string(ObjectNode node, String name, String defaultValue) { + return node.path(name).asText(defaultValue); + } + + /** + * Returns the specified node property as an object node. + * + * @param node object node + * @param name property name + * @return property as a node + */ + public static ObjectNode node(ObjectNode node, String name) { + return (ObjectNode) node.path(name); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/RequestHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/RequestHandler.java new file mode 100644 index 00000000..1678923d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/RequestHandler.java @@ -0,0 +1,142 @@ +/* + * 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.ui; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Abstraction of an entity that handles a specific request from the + * user interface client. + * + * @see UiMessageHandler + */ +public abstract class RequestHandler { + + protected static final ObjectMapper MAPPER = new ObjectMapper(); + + private final String eventType; + private UiMessageHandler parent; + + + public RequestHandler(String eventType) { + this.eventType = eventType; + } + + // package private + void setParent(UiMessageHandler parent) { + this.parent = parent; + } + + /** + * Returns the event type that this handler handles. + * + * @return event type + */ + public String eventType() { + return eventType; + } + + /** + * Processes the incoming message payload from the client. + * + * @param sid message sequence identifier + * @param payload request message payload + */ + // TODO: remove sid from signature + public abstract void process(long sid, ObjectNode payload); + + + + // =================================================================== + // === Convenience methods... + + /** + * Returns implementation of the specified service class. + * + * @param serviceClass service class + * @param <T> type of service + * @return implementation class + * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found + */ + protected <T> T get(Class<T> serviceClass) { + return parent.directory().get(serviceClass); + } + + /** + * Sends a message back to the client. + * + * @param eventType message event type + * @param sid message sequence identifier + * @param payload message payload + */ + // TODO: remove sid from signature + protected void sendMessage(String eventType, long sid, ObjectNode payload) { + parent.connection().sendMessage(eventType, sid, payload); + } + + /** + * Sends a message back to the client. + * Here, the message is preformatted; the assumption is it has its + * eventType, sid and payload attributes already filled in. + * + * @param message the message to send + */ + protected void sendMessage(ObjectNode message) { + parent.connection().sendMessage(message); + } + + /** + * Allows one request handler to pass the event on to another for + * further processing. + * Note that the message handlers must be defined in the same parent. + * + * @param eventType event type + * @param sid sequence identifier + * @param payload message payload + */ + // TODO: remove sid from signature + protected void chain(String eventType, long sid, ObjectNode payload) { + parent.exec(eventType, sid, payload); + } + + // =================================================================== + + + /** + * Returns the specified node property as a string. + * + * @param node message event + * @param key property name + * @return property as a string + */ + protected String string(ObjectNode node, String key) { + return JsonUtils.string(node, key); + } + + /** + * Returns the specified node property as a string, with a default fallback. + * + * @param node object node + * @param key property name + * @param defValue fallback value if property is absent + * @return property as a string + */ + protected String string(ObjectNode node, String key, String defValue) { + return JsonUtils.string(node, key, defValue); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiConnection.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiConnection.java new file mode 100644 index 00000000..ead7b0dc --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiConnection.java @@ -0,0 +1,42 @@ +/* + * 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.ui; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Abstraction of a user interface session connection. + */ +public interface UiConnection { + + /** + * Sends the specified JSON message to the user interface client. + * + * @param message message to send + */ + void sendMessage(ObjectNode message); + + /** + * Composes a message into JSON and sends it to the user interface client. + * + * @param type message type + * @param sid message sequence number + * @param payload message payload + */ + // TODO: remove sid parameter + void sendMessage(String type, long sid, ObjectNode payload); + +}
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtension.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtension.java new file mode 100644 index 00000000..1f5fbd48 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtension.java @@ -0,0 +1,200 @@ +/* + * 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.ui; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * User interface extension. + */ +public final class UiExtension { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final String VIEW_PREFIX = "app/view/"; + private static final String EMPTY = ""; + private static final String SLASH = "/"; + private static final String CSS_HTML = "css.html"; + private static final String JS_HTML = "js.html"; + + private final ClassLoader classLoader; + private final String resourcePath; + private final List<UiView> views; + private final UiMessageHandlerFactory messageHandlerFactory; + private final UiTopoOverlayFactory topoOverlayFactory; + + + // private constructor - only the builder calls this + private UiExtension(ClassLoader cl, String path, List<UiView> views, + UiMessageHandlerFactory mhFactory, + UiTopoOverlayFactory toFactory) { + this.classLoader = cl; + this.resourcePath = path; + this.views = views; + this.messageHandlerFactory = mhFactory; + this.topoOverlayFactory = toFactory; + } + + + /** + * Returns input stream containing CSS inclusion statements. + * + * @return CSS inclusion statements + */ + public InputStream css() { + return getStream(resourcePath + CSS_HTML); + } + + /** + * Returns input stream containing JavaScript inclusion statements. + * + * @return JavaScript inclusion statements + */ + public InputStream js() { + return getStream(resourcePath + JS_HTML); + } + + /** + * Returns list of user interface views contributed by this extension. + * + * @return contributed view descriptors + */ + public List<UiView> views() { + return views; + } + + /** + * Returns input stream containing specified view-specific resource. + * + * @param viewId view identifier + * @param path resource path, relative to the view directory + * @return resource input stream + */ + public InputStream resource(String viewId, String path) { + return getStream(VIEW_PREFIX + viewId + SLASH + path); + } + + /** + * Returns message handler factory, if one was defined. + * + * @return message handler factory + */ + public UiMessageHandlerFactory messageHandlerFactory() { + return messageHandlerFactory; + } + + /** + * Returns the topology overlay factory, if one was defined. + * + * @return topology overlay factory + */ + public UiTopoOverlayFactory topoOverlayFactory() { + return topoOverlayFactory; + } + + + // Returns the resource input stream from the specified class-loader. + private InputStream getStream(String path) { + InputStream stream = classLoader.getResourceAsStream(path); + if (stream == null) { + log.warn("Unable to find resource {}", path); + } + return stream; + } + + + /** + * UI Extension Builder. + */ + public static class Builder { + private ClassLoader classLoader; + + private String resourcePath = EMPTY; + private List<UiView> views = new ArrayList<>(); + private UiMessageHandlerFactory messageHandlerFactory = null; + private UiTopoOverlayFactory topoOverlayFactory = null; + + /** + * Create a builder with the given class loader. + * Resource path defaults to "". + * Views defaults to an empty list. + * Both Message and TopoOverlay factories default to null. + * + * @param cl the class loader + * @param views list of views contributed by this extension + */ + public Builder(ClassLoader cl, List<UiView> views) { + checkNotNull(cl, "Must provide a class loader"); + checkArgument(views.size() > 0, "Must provide at least one view"); + this.classLoader = cl; + this.views = views; + } + + /** + * Set the resource path. That is, path to where the CSS and JS + * files are located. This value should + * + * @param path resource path + * @return self, for chaining + */ + public Builder resourcePath(String path) { + this.resourcePath = path == null ? EMPTY : path + SLASH; + return this; + } + + /** + * Sets the message handler factory for this extension. + * + * @param mhFactory message handler factory + * @return self, for chaining + */ + public Builder messageHandlerFactory(UiMessageHandlerFactory mhFactory) { + this.messageHandlerFactory = mhFactory; + return this; + } + + /** + * Sets the topology overlay factory for this extension. + * + * @param toFactory topology overlay factory + * @return self, for chaining + */ + public Builder topoOverlayFactory(UiTopoOverlayFactory toFactory) { + this.topoOverlayFactory = toFactory; + return this; + } + + /** + * Builds the UI extension. + * + * @return UI extension instance + */ + public UiExtension build() { + return new UiExtension(classLoader, resourcePath, views, + messageHandlerFactory, topoOverlayFactory); + } + + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtensionService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtensionService.java new file mode 100644 index 00000000..330fbb7a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiExtensionService.java @@ -0,0 +1,53 @@ +/* + * 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.ui; + +import java.util.List; + +/** + * Service for registering user interface extensions. + */ +public interface UiExtensionService { + + /** + * Registers the specified user interface extension. + * + * @param extension GUI extension to register + */ + void register(UiExtension extension); + + /** + * Unregisters the specified user interface extension. + * + * @param extension GUI extension to unregister + */ + void unregister(UiExtension extension); + + /** + * Returns the list of user interface extensions. + * + * @return list of extensions + */ + List<UiExtension> getExtensions(); + + /** + * Returns the user interface extension that contributed the specified view. + * + * @param viewId view identifier + * @return user interface extension + */ + UiExtension getViewExtension(String viewId); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java new file mode 100644 index 00000000..9b9a406c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java @@ -0,0 +1,207 @@ +/* + * 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.ui; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onlab.osgi.ServiceDirectory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of an entity capable of processing JSON messages from the user + * interface client. + * <p> + * The message structure is: + * </p> + * <pre> + * { + * "type": "<em>event-type</em>", + * "payload": { + * <em>arbitrary JSON object structure</em> + * } + * } + * </pre> + * On {@link #init initialization} the handler will create and cache + * {@link RequestHandler} instances, each of which are bound to a particular + * <em>event-type</em>. On {@link #process arrival} of a new message, + * the <em>event-type</em> is determined, and the message dispatched to the + * corresponding <em>RequestHandler</em>'s + * {@link RequestHandler#process process} method. + */ +public abstract class UiMessageHandler { + + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Map<String, RequestHandler> handlerMap = new HashMap<>(); + private final ObjectMapper mapper = new ObjectMapper(); + + private UiConnection connection; + private ServiceDirectory directory; + + + /** + * Subclasses must create and return the collection of request handlers + * for the message types they handle. + * <p> + * Note that request handlers should be stateless. When we are + * {@link #destroy destroyed}, we will simply drop our references to them + * and allow them to be garbage collected. + * + * @return the message handler instances + */ + protected abstract Collection<RequestHandler> createRequestHandlers(); + + /** + * Returns the set of message types which this handler is capable of + * processing. + * + * @return set of message types + */ + public Set<String> messageTypes() { + return Collections.unmodifiableSet(handlerMap.keySet()); + } + + /** + * Processes a JSON message from the user interface client. + * + * @param message JSON message + */ + public void process(ObjectNode message) { + String type = JsonUtils.eventType(message); + ObjectNode payload = JsonUtils.payload(message); + // TODO: remove sid + exec(type, 0, payload); + } + + /** + * Finds the appropriate handler and executes the process method. + * + * @param eventType event type + * @param sid sequence identifier + * @param payload message payload + */ + // TODO: remove sid from signature + void exec(String eventType, long sid, ObjectNode payload) { + RequestHandler requestHandler = handlerMap.get(eventType); + if (requestHandler != null) { + requestHandler.process(sid, payload); + } else { + log.warn("no request handler for event type {}", eventType); + } + } + + /** + * Initializes the handler with the user interface connection and + * service directory context. + * + * @param connection user interface connection + * @param directory service directory + */ + public void init(UiConnection connection, ServiceDirectory directory) { + this.connection = connection; + this.directory = directory; + + Collection<RequestHandler> handlers = createRequestHandlers(); + checkNotNull(handlers, "Handlers cannot be null"); + checkArgument(!handlers.isEmpty(), "Handlers cannot be empty"); + + for (RequestHandler h : handlers) { + h.setParent(this); + handlerMap.put(h.eventType(), h); + } + } + + /** + * Destroys the message handler context. + */ + public void destroy() { + this.connection = null; + this.directory = null; + handlerMap.clear(); + } + + /** + * Returns the user interface connection with which this handler was primed. + * + * @return user interface connection + */ + public UiConnection connection() { + return connection; + } + + /** + * Returns the user interface connection with which this handler was primed. + * + * @return user interface connection + */ + public ServiceDirectory directory() { + return directory; + } + + /** + * Returns implementation of the specified service class. + * + * @param serviceClass service class + * @param <T> type of service + * @return implementation class + * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found + */ + protected <T> T get(Class<T> serviceClass) { + return directory.get(serviceClass); + } + + /** + * Returns a freshly minted object node. + * + * @return new object node + */ + protected ObjectNode objectNode() { + return mapper.createObjectNode(); + } + + /** + * Returns a freshly minted array node. + * + * @return new array node + */ + protected ArrayNode arrayNode() { + return mapper.createArrayNode(); + } + + /** + * Sends the specified data to the client. + * It is expected that the data is in the prescribed JSON format for + * events to the client. + * + * @param data data to be sent + */ + protected synchronized void sendMessage(ObjectNode data) { + UiConnection connection = connection(); + if (connection != null) { + connection.sendMessage(data); + } + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java new file mode 100644 index 00000000..522daa8f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java @@ -0,0 +1,33 @@ +/* + * 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.ui; + +import java.util.Collection; + +/** + * Abstraction of an entity capable of producing a set of message handlers + * specific to the given user interface connection. + */ +public interface UiMessageHandlerFactory { + + /** + * Produces a collection of new message handlers. + * + * @return collection of new handlers + */ + Collection<UiMessageHandler> newHandlers(); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java new file mode 100644 index 00000000..2889422a --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java @@ -0,0 +1,122 @@ +/* + * 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.ui; + +import org.onosproject.ui.topo.PropertyPanel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Represents user interface topology view overlay. + */ +public class UiTopoOverlay { + + /** + * Logger for this overlay. + */ + protected final Logger log = LoggerFactory.getLogger(getClass()); + + private final String id; + + private boolean isActive = false; + + /** + * Creates a new user interface topology view overlay descriptor. + * + * @param id overlay identifier + */ + public UiTopoOverlay(String id) { + this.id = id; + } + + /** + * Returns the identifier for this overlay. + * + * @return the identifier + */ + public String id() { + return id; + } + + /** + * Callback invoked to initialize this overlay, soon after creation. + * This default implementation does nothing. + */ + public void init() { + } + + /** + * Callback invoked when this overlay is activated. + */ + public void activate() { + isActive = true; + } + + /** + * Callback invoked when this overlay is deactivated. + */ + public void deactivate() { + isActive = false; + } + + /** + * Returns true if this overlay is currently active. + * + * @return true if overlay active + */ + public boolean isActive() { + return isActive; + } + + /** + * Callback invoked to destroy this instance by cleaning up any + * internal state ready for garbage collection. + * This default implementation holds no state and does nothing. + */ + public void destroy() { + } + + /** + * Callback to modify the contents of the summary panel. + * This default implementation does nothing. + * + * @param pp property panel model of summary data + */ + public void modifySummary(PropertyPanel pp) { + } + + /** + * Callback to modify the contents of the details panel for + * a selected device. + * This default implementation does nothing. + * + * @param pp property panel model of summary data + */ + public void modifyDeviceDetails(PropertyPanel pp) { + } + + /** + * Callback to modify the contents of the details panel for + * a selected host. + * This default implementation does nothing. + * + * @param pp property panel model of summary data + */ + public void modifyHostDetails(PropertyPanel pp) { + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlayFactory.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlayFactory.java new file mode 100644 index 00000000..bd2f2fe6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiTopoOverlayFactory.java @@ -0,0 +1,34 @@ +/* + * 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.ui; + +import java.util.Collection; + +/** + * Abstraction of an entity capable of producing one or more topology + * overlay handlers specific to a given user interface connection. + */ +public interface UiTopoOverlayFactory { + + /** + * Produces a collection of new overlay handlers. + * + * @return collection of new overlay handlers + */ + Collection<UiTopoOverlay> newOverlays(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java new file mode 100644 index 00000000..2b8b7fa2 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java @@ -0,0 +1,165 @@ +/* + * 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.ui; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Represents user interface view addition. + */ +public class UiView { + + /** + * Designates navigation menu category. + */ + public enum Category { + /** + * Represents platform related views. + */ + PLATFORM("Platform"), + + /** + * Represents network-control related views. + */ + NETWORK("Network"), + + /** + * Represents miscellaneous views. + */ + OTHER("Other"), + + /** + * Represents views that do not show in the navigation menu. + * This category should not be specified directly; rather, use + * the {@link UiViewHidden} constructor instead of {@link UiView}. + */ + HIDDEN("(hidden)"); + + private final String label; + + Category(String label) { + this.label = label; + } + + /** + * Returns display label for the category. + * + * @return display label + */ + public String label() { + return label; + } + } + + private final Category category; + private final String id; + private final String label; + private final String iconId; + + /** + * Creates a new user interface view descriptor. The navigation item + * will appear in the navigation menu under the specified category. + * + * @param category view category + * @param id view identifier + * @param label view label + */ + public UiView(Category category, String id, String label) { + this(category, id, label, null); + } + + /** + * Creates a new user interface view descriptor. The navigation item + * will appear in the navigation menu under the specified category, + * with the specified icon adornment. + * + * @param category view category + * @param id view identifier + * @param label view label + * @param iconId icon id + */ + public UiView(Category category, String id, String label, String iconId) { + this.category = category; + this.id = id; + this.label = label; + this.iconId = iconId; + } + + /** + * Returns the navigation category. + * + * @return navigation category + */ + public Category category() { + return category; + } + + /** + * Returns the view identifier. + * + * @return view id + */ + public String id() { + return id; + } + + /** + * Returns the view label. + * + * @return view label + */ + public String label() { + return label; + } + + /** + * Returns the icon ID. + * + * @return icon ID + */ + public String iconId() { + return iconId; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final UiView other = (UiView) obj; + return Objects.equals(this.id, other.id); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("category", category) + .add("id", id) + .add("label", label) + .add("iconId", iconId) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiViewHidden.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiViewHidden.java new file mode 100644 index 00000000..b7fea8fe --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiViewHidden.java @@ -0,0 +1,41 @@ +/* + * 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.ui; + +import com.google.common.base.MoreObjects; + +/** + * Represents user interface view addition, except that this one should not + * have an entry in the navigation panel. + */ +public class UiViewHidden extends UiView { + + /** + * Creates a new user interface hidden view descriptor. + * + * @param id view identifier + */ + public UiViewHidden(String id) { + super(Category.HIDDEN, id, null); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id()) + .toString(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/package-info.java new file mode 100644 index 00000000..dd832a59 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Mechanism for managing dynamically registered user interface extensions. + */ +package org.onosproject.ui; diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellComparator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellComparator.java new file mode 100644 index 00000000..84d11344 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellComparator.java @@ -0,0 +1,46 @@ +/* + * 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.ui.table; + +/** + * Defines a comparator for cell values. + */ +public interface CellComparator { + + /** + * Compares its two arguments for order. Returns a negative integer, + * zero, or a positive integer as the first argument is less than, equal + * to, or greater than the second.<p> + * + * Note that nulls are permitted, and should be sorted to the beginning + * of an ascending sort; i.e. null is considered to be "smaller" than + * non-null values. + * + * @see java.util.Comparator#compare(Object, Object) + * + * @param o1 the first object to be compared. + * @param o2 the second object to be compared. + * @return a negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + * @throws ClassCastException if the arguments' types prevent them from + * being compared by this comparator. + */ + int compare(Object o1, Object o2); + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellFormatter.java new file mode 100644 index 00000000..854ac27f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/CellFormatter.java @@ -0,0 +1,34 @@ +/* + * 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.ui.table; + +/** + * Defines a formatter for cell values. + */ +public interface CellFormatter { + + /** + * Formats the specified value into a string appropriate for displaying + * in a table cell. Note that null values are acceptable, and will result + * in the empty string. + * + * @param value the value + * @return the formatted string + */ + String format(Object value); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java new file mode 100644 index 00000000..d0fccb65 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableModel.java @@ -0,0 +1,304 @@ +/* + * 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.ui.table; + +import com.google.common.collect.Sets; +import org.onosproject.ui.table.cell.DefaultCellComparator; +import org.onosproject.ui.table.cell.DefaultCellFormatter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A simple model of table data. + * <p> + * Note that this is not a full MVC type model; the expected usage pattern + * is to create an empty table, add rows (by consulting the business model), + * sort rows (based on client request parameters), and finally produce the + * sorted list of rows. + * <p> + * The table also provides a mechanism for defining how cell values for a + * particular column should be formatted into strings, to help facilitate + * the encoding of the table data into a JSON structure. + * <p> + * Note that it is expected that all values for a particular column will + * be the same class. + */ +public class TableModel { + + private static final CellComparator DEF_CMP = DefaultCellComparator.INSTANCE; + private static final CellFormatter DEF_FMT = DefaultCellFormatter.INSTANCE; + + private final String[] columnIds; + private final Set<String> idSet; + private final Map<String, CellComparator> comparators = new HashMap<>(); + private final Map<String, CellFormatter> formatters = new HashMap<>(); + private final List<Row> rows = new ArrayList<>(); + + + /** + * Constructs a table (devoid of data) with the given column IDs. + * + * @param columnIds column identifiers + */ + public TableModel(String... columnIds) { + checkNotNull(columnIds, "columnIds cannot be null"); + checkArgument(columnIds.length > 0, "must be at least one column"); + + idSet = Sets.newHashSet(columnIds); + if (idSet.size() != columnIds.length) { + throw new IllegalArgumentException("duplicate column ID(s) detected"); + } + + this.columnIds = Arrays.copyOf(columnIds, columnIds.length); + } + + private void checkId(String id) { + checkNotNull(id, "must provide a column ID"); + if (!idSet.contains(id)) { + throw new IllegalArgumentException("unknown column id: " + id); + } + } + + /** + * Returns the number of rows in this table model. + * + * @return number of rows + */ + public int rowCount() { + return rows.size(); + } + + /** + * Returns the number of columns in this table model. + * + * @return number of columns + */ + public int columnCount() { + return columnIds.length; + } + + /** + * Returns the array of column IDs for this table model. + * <p> + * Implementation note: we are knowingly passing you a reference to + * our internal array to avoid copying. Don't mess with it. It's your + * table you'll break if you do! + * + * @return the column identifiers + */ + public String[] getColumnIds() { + return columnIds; + } + + /** + * Returns the raw {@link Row} representation of the rows in this table. + * + * @return raw table rows + */ + public Row[] getRows() { + return rows.toArray(new Row[rows.size()]); + } + + /** + * Sets a cell comparator for the specified column. + * + * @param columnId column identifier + * @param comparator comparator to use + */ + public void setComparator(String columnId, CellComparator comparator) { + checkNotNull(comparator, "must provide a comparator"); + checkId(columnId); + comparators.put(columnId, comparator); + } + + /** + * Returns the cell comparator to use on values in the specified column. + * + * @param columnId column identifier + * @return an appropriate cell comparator + */ + private CellComparator getComparator(String columnId) { + checkId(columnId); + CellComparator cmp = comparators.get(columnId); + return cmp == null ? DEF_CMP : cmp; + } + + /** + * Sets a cell formatter for the specified column. + * + * @param columnId column identifier + * @param formatter formatter to use + */ + public void setFormatter(String columnId, CellFormatter formatter) { + checkNotNull(formatter, "must provide a formatter"); + checkId(columnId); + formatters.put(columnId, formatter); + } + + /** + * Returns the cell formatter to use on values in the specified column. + * + * @param columnId column identifier + * @return an appropriate cell formatter + */ + public CellFormatter getFormatter(String columnId) { + checkId(columnId); + CellFormatter fmt = formatters.get(columnId); + return fmt == null ? DEF_FMT : fmt; + } + + /** + * Adds a row to the table model. + * + * @return the row, for chaining + */ + public Row addRow() { + Row r = new Row(); + rows.add(r); + return r; + } + + /** + * Sorts the table rows based on the specified column, in the + * specified direction. + * + * @param columnId column identifier + * @param dir sort direction + */ + public void sort(String columnId, SortDir dir) { + Collections.sort(rows, new RowComparator(columnId, dir)); + } + + + /** Designates sorting direction. */ + public enum SortDir { + /** Designates an ascending sort. */ + ASC, + /** Designates a descending sort. */ + DESC + } + + /** + * Row comparator. + */ + private class RowComparator implements Comparator<Row> { + private final String columnId; + private final SortDir dir; + private final CellComparator cellComparator; + + /** + * Constructs a row comparator based on the specified + * column identifier and sort direction. + * + * @param columnId column identifier + * @param dir sort direction + */ + public RowComparator(String columnId, SortDir dir) { + this.columnId = columnId; + this.dir = dir; + cellComparator = getComparator(columnId); + } + + @Override + public int compare(Row a, Row b) { + Object cellA = a.get(columnId); + Object cellB = b.get(columnId); + int result = cellComparator.compare(cellA, cellB); + return dir == SortDir.ASC ? result : -result; + } + } + + /** + * Model of a row. + */ + public class Row { + private final Map<String, Object> cells = new HashMap<>(); + + /** + * Sets the cell value for the given column of this row. + * + * @param columnId column identifier + * @param value value to set + * @return self, for chaining + */ + public Row cell(String columnId, Object value) { + checkId(columnId); + cells.put(columnId, value); + return this; + } + + /** + * Returns the value of the cell in the given column for this row. + * + * @param columnId column identifier + * @return cell value + */ + public Object get(String columnId) { + return cells.get(columnId); + } + + /** + * Returns the value of the cell as a string, using the + * formatter appropriate for the column. + * + * @param columnId column identifier + * @return formatted cell value + */ + String getAsString(String columnId) { + return getFormatter(columnId).format(get(columnId)); + } + + /** + * Returns the row as an array of formatted strings. + * + * @return the formatted row data + */ + public String[] getAsFormattedStrings() { + List<String> formatted = new ArrayList<>(columnCount()); + for (String c : columnIds) { + formatted.add(getAsString(c)); + } + return formatted.toArray(new String[formatted.size()]); + } + } + + private static final String DESC = "desc"; + + /** + * Returns the appropriate sort direction for the given string. + * <p> + * The expected strings are "asc" for {@link SortDir#ASC ascending} and + * "desc" for {@link SortDir#DESC descending}. Any other value will + * default to ascending. + * + * @param s sort direction string encoding + * @return sort direction + */ + public static SortDir sortDir(String s) { + return !DESC.equals(s) ? SortDir.ASC : SortDir.DESC; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableRequestHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableRequestHandler.java new file mode 100644 index 00000000..b8d48575 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableRequestHandler.java @@ -0,0 +1,111 @@ +/* + * 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.ui.table; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.ui.JsonUtils; +import org.onosproject.ui.RequestHandler; + +/** + * Message handler specifically for table views. + */ +public abstract class TableRequestHandler extends RequestHandler { + + private final String respType; + private final String nodeName; + + /** + * Constructs a table request handler for a specific table view. When + * table requests come in, the handler will generate the appropriate + * table rows, sort them according the the request sort parameters, and + * send back the response to the client. + * + * @param reqType type of the request event + * @param respType type of the response event + * @param nodeName name of JSON node holding row data + */ + public TableRequestHandler(String reqType, String respType, String nodeName) { + super(reqType); + this.respType = respType; + this.nodeName = nodeName; + } + + @Override + public void process(long sid, ObjectNode payload) { + TableModel tm = createTableModel(); + populateTable(tm, payload); + + String sortCol = JsonUtils.string(payload, "sortCol", defaultColumnId()); + String sortDir = JsonUtils.string(payload, "sortDir", "asc"); + tm.sort(sortCol, TableModel.sortDir(sortDir)); + + ObjectNode rootNode = MAPPER.createObjectNode(); + rootNode.set(nodeName, TableUtils.generateArrayNode(tm)); + sendMessage(respType, 0, rootNode); + } + + /** + * Creates the table model (devoid of data) using {@link #getColumnIds()} + * to initialize it, ready to be populated. + * <p> + * This default implementation returns a table model with default + * formatters and comparators for all columns. + * + * @return an empty table model + */ + protected TableModel createTableModel() { + return new TableModel(getColumnIds()); + } + + /** + * Returns the default column ID to be used when one is not supplied in + * the payload as the column on which to sort. + * <p> + * This default implementation returns "id". + * + * @return default sort column identifier + */ + protected String defaultColumnId() { + return "id"; + } + + /** + * Subclasses should return the array of column IDs with which + * to initialize their table model. + * + * @return the column IDs + */ + protected abstract String[] getColumnIds(); + + /** + * Subclasses should populate the table model by adding + * {@link TableModel.Row rows}. + * <pre> + * tm.addRow() + * .cell(COL_ONE, ...) + * .cell(COL_TWO, ...) + * ... ; + * </pre> + * The request payload is provided in case there are request filtering + * parameters (other than sort column and sort direction) that are required + * to generate the appropriate data. + * + * @param tm the table model + * @param payload request payload + */ + protected abstract void populateTable(TableModel tm, ObjectNode payload); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableUtils.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableUtils.java new file mode 100644 index 00000000..eb2dff78 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/TableUtils.java @@ -0,0 +1,58 @@ +/* + * 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.ui.table; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Provides static utility methods for dealing with tables. + */ +public final class TableUtils { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + // non-instantiable + private TableUtils() { } + + /** + * Generates a JSON array node from a table model. + * + * @param tm the table model + * @return the array node representation + */ + public static ArrayNode generateArrayNode(TableModel tm) { + ArrayNode array = MAPPER.createArrayNode(); + for (TableModel.Row r : tm.getRows()) { + array.add(toJsonNode(r, tm)); + } + return array; + } + + private static JsonNode toJsonNode(TableModel.Row row, TableModel tm) { + ObjectNode result = MAPPER.createObjectNode(); + String[] keys = tm.getColumnIds(); + String[] cells = row.getAsFormattedStrings(); + int n = keys.length; + for (int i = 0; i < n; i++) { + result.put(keys[i], cells[i]); + } + return result; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellComparator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellComparator.java new file mode 100644 index 00000000..6113fc3f --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellComparator.java @@ -0,0 +1,61 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellComparator; + +/** + * Base implementation of a {@link CellComparator}. This class takes care + * of dealing with null inputs; subclasses should implement their comparison + * knowing that both inputs are guaranteed to be non-null. + */ +public abstract class AbstractCellComparator implements CellComparator { + + @Override + public int compare(Object o1, Object o2) { + if (o1 == null && o2 == null) { + return 0; // o1 == o2 + } + if (o1 == null) { + return -1; // o1 < o2 + } + if (o2 == null) { + return 1; // o1 > o2 + } + return nonNullCompare(o1, o2); + } + + /** + * Compares its two arguments for order. Returns a negative integer, + * zero, or a positive integer as the first argument is less than, equal + * to, or greater than the second.<p> + * + * Note that both objects are guaranteed to be non-null. + * + * @see java.util.Comparator#compare(Object, Object) + * + * @param o1 the first object to be compared. + * @param o2 the second object to be compared. + * @return a negative integer, zero, or a positive integer as the + * first argument is less than, equal to, or greater than the + * second. + * @throws ClassCastException if the arguments' types prevent them from + * being compared by this comparator. + */ + protected abstract int nonNullCompare(Object o1, Object o2); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellFormatter.java new file mode 100644 index 00000000..33ce2ab5 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AbstractCellFormatter.java @@ -0,0 +1,42 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellFormatter; + +/** + * Base implementation of a {@link CellFormatter}. This class takes care of + * dealing with null inputs; subclasses should implement their format method + * knowing that the input is guaranteed to be non-null. + */ +public abstract class AbstractCellFormatter implements CellFormatter { + + @Override + public String format(Object value) { + return value == null ? "" : nonNullFormat(value); + } + + /** + * Formats the specified value into a string appropriate for displaying + * in a table cell. Note that value is guaranteed to be non-null. + * + * @param value the value + * @return the formatted string + */ + protected abstract String nonNullFormat(Object value); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java new file mode 100644 index 00000000..42d684b6 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java @@ -0,0 +1,41 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.core.ApplicationId; +import org.onosproject.ui.table.CellFormatter; + +/** + * Formats an application identifier as "(app-id) : (app-name)". + */ +public final class AppIdFormatter extends AbstractCellFormatter { + + // non-instantiable + private AppIdFormatter() { } + + @Override + protected String nonNullFormat(Object value) { + ApplicationId appId = (ApplicationId) value; + return appId.id() + " : " + appId.name(); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new AppIdFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/ConnectPointFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/ConnectPointFormatter.java new file mode 100644 index 00000000..fee26154 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/ConnectPointFormatter.java @@ -0,0 +1,41 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.net.ConnectPoint; +import org.onosproject.ui.table.CellFormatter; + +/** + * Formats a connect point as "(element-id)/(port)". + */ +public final class ConnectPointFormatter extends AbstractCellFormatter { + + // non-instantiable + private ConnectPointFormatter() { } + + @Override + protected String nonNullFormat(Object value) { + ConnectPoint cp = (ConnectPoint) value; + return cp.elementId() + "/" + cp.port(); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new ConnectPointFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellComparator.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellComparator.java new file mode 100644 index 00000000..093a20d3 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellComparator.java @@ -0,0 +1,52 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellComparator; + +/** + * A default cell comparator. + * <p> + * Verifies that the objects being compared are the same class. + * Looks to see if the objects being compared implement comparable and, if so, + * delegates to that; otherwise, implements a lexicographical compare function + * (i.e. string sorting). Uses the objects' toString() method and then + * compares the resulting strings. Note that null values are acceptable and + * are considered "smaller" than any non-null value. + */ +public final class DefaultCellComparator extends AbstractCellComparator { + + // non-instantiable + private DefaultCellComparator() { } + + @Override + @SuppressWarnings("unchecked") + protected int nonNullCompare(Object o1, Object o2) { + if (o1 instanceof Comparable) { + // if o2 is not the same class as o1, then compareTo will + // throw ClassCastException for us + return ((Comparable) o1).compareTo(o2); + } + return o1.toString().compareTo(o2.toString()); + } + + /** + * An instance of this class. + */ + public static final CellComparator INSTANCE = new DefaultCellComparator(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellFormatter.java new file mode 100644 index 00000000..0efa2ebd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/DefaultCellFormatter.java @@ -0,0 +1,39 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellFormatter; + +/** + * A default cell formatter. Uses the object's toString() method. + */ +public final class DefaultCellFormatter extends AbstractCellFormatter { + + // non-instantiable + private DefaultCellFormatter() { } + + @Override + public String nonNullFormat(Object value) { + return value.toString(); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new DefaultCellFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/EnumFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/EnumFormatter.java new file mode 100644 index 00000000..5b89a0b7 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/EnumFormatter.java @@ -0,0 +1,40 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellFormatter; + +import static org.apache.commons.lang.WordUtils.capitalizeFully; + +/** + * Formats enum types to be readable strings. + */ +public final class EnumFormatter extends AbstractCellFormatter { + + // non-instantiable + private EnumFormatter() { } + + @Override + protected String nonNullFormat(Object value) { + return capitalizeFully(value.toString().replace("_", " ")); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new EnumFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HexFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HexFormatter.java new file mode 100644 index 00000000..e09982ea --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HexFormatter.java @@ -0,0 +1,39 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.ui.table.CellFormatter; + +/** + * Formats integer values as hex strings with a "0x" prefix. + */ +public final class HexFormatter extends AbstractCellFormatter { + + // non-instantiable + private HexFormatter() { } + + @Override + protected String nonNullFormat(Object value) { + return "0x" + Integer.toHexString((Integer) value); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new HexFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HostLocationFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HostLocationFormatter.java new file mode 100644 index 00000000..fe87c61b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/HostLocationFormatter.java @@ -0,0 +1,41 @@ +/* + * 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.ui.table.cell; + +import org.onosproject.net.HostLocation; +import org.onosproject.ui.table.CellFormatter; + +/** + * Formats a host location as "(device-id)/(port)". + */ +public final class HostLocationFormatter extends AbstractCellFormatter { + + // non-instantiable + private HostLocationFormatter() { } + + @Override + protected String nonNullFormat(Object value) { + HostLocation loc = (HostLocation) value; + return loc.deviceId() + "/" + loc.port(); + } + + /** + * An instance of this class. + */ + public static final CellFormatter INSTANCE = new HostLocationFormatter(); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/TimeFormatter.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/TimeFormatter.java new file mode 100644 index 00000000..44dc1940 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/TimeFormatter.java @@ -0,0 +1,72 @@ +/* + * 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.ui.table.cell; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import java.util.Locale; + +/** + * Formats time values using {@link DateTimeFormatter}. + */ +public final class TimeFormatter extends AbstractCellFormatter { + + private DateTimeFormatter dtf; + + // NOTE: Unlike other formatters in this package, this one is not + // implemented as a Singleton, because instances may be + // decorated with alternate locale and/or timezone. + + /** + * Constructs a time formatter that uses the default locale and timezone. + */ + public TimeFormatter() { + dtf = DateTimeFormat.longTime(); + } + + /** + * Sets the locale to use for formatting the time. + * + * @param locale locale to use for formatting + * @return self, for chaining + */ + public TimeFormatter withLocale(Locale locale) { + dtf = dtf.withLocale(locale); + return this; + } + + /** + * Sets the time zone to use for formatting the time. + * + * @param zone time zone to use + * @return self, for chaining + */ + public TimeFormatter withZone(DateTimeZone zone) { + dtf = dtf.withZone(zone); + return this; + } + + @Override + protected String nonNullFormat(Object value) { + return dtf.print((DateTime) value); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/package-info.java new file mode 100644 index 00000000..c25bcb06 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/cell/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Set of table cell renderers and comparators for use by GUI apps. + */ +package org.onosproject.ui.table.cell;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/package-info.java new file mode 100644 index 00000000..ee975d11 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/table/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Facilities for creating tabular models of data for the GUI. + */ +package org.onosproject.ui.table;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/AbstractHighlight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/AbstractHighlight.java new file mode 100644 index 00000000..ab2ced36 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/AbstractHighlight.java @@ -0,0 +1,75 @@ +/* + * 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.ui.topo; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Partial implementation of the highlighting to apply to topology + * view elements. + */ +public abstract class AbstractHighlight { + private final TopoElementType type; + private final String elementId; + private boolean keepSubdued = false; + + /** + * Constructs the highlight. + * + * @param type highlight element type + * @param elementId element identifier + */ + public AbstractHighlight(TopoElementType type, String elementId) { + this.type = checkNotNull(type); + this.elementId = checkNotNull(elementId); + } + + /** + * Sets a flag to tell the renderer to keep this element subdued. + */ + public void keepSubdued() { + keepSubdued = true; + } + + /** + * Returns the element type. + * + * @return element type + */ + public TopoElementType type() { + return type; + } + + /** + * Returns the element identifier. + * + * @return element identifier + */ + public String elementId() { + return elementId; + } + + /** + * Returns the subdued flag. + * + * @return subdued flag + */ + public boolean subdued() { + return keepSubdued; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLink.java new file mode 100644 index 00000000..c37c129b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLink.java @@ -0,0 +1,43 @@ +/* + * 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.ui.topo; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +/** + * A simple concrete implementation of a {@link BiLink}. + * Note that this implementation does not generate any link highlights. + */ +public class BaseLink extends BiLink { + + /** + * Constructs a base link for the given key and initial link. + * + * @param key canonical key for this base link + * @param link first link + */ + public BaseLink(LinkKey key, Link link) { + super(key, link); + } + + @Override + public LinkHighlight highlight(Enum<?> type) { + return null; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLinkMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLinkMap.java new file mode 100644 index 00000000..720eca49 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BaseLinkMap.java @@ -0,0 +1,31 @@ +/* + * 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.ui.topo; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +/** + * Collection of {@link BaseLink}s. + */ +public class BaseLinkMap extends BiLinkMap<BaseLink> { + @Override + public BaseLink create(LinkKey key, Link link) { + return new BaseLink(key, link); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLink.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLink.java new file mode 100644 index 00000000..8c95e15d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLink.java @@ -0,0 +1,104 @@ +/* + * 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.ui.topo; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Representation of a link and its inverse, as a partial implementation. + * <p> + * Subclasses will decide how to generate the link highlighting (coloring + * and labeling) for the topology view. + */ +public abstract class BiLink { + + private final LinkKey key; + private final Link one; + private Link two; + + /** + * Constructs a bi-link for the given key and initial link. It is expected + * that the caller will have used {@link TopoUtils#canonicalLinkKey(Link)} + * to generate the key. + * + * @param key canonical key for this bi-link + * @param link first link + */ + public BiLink(LinkKey key, Link link) { + this.key = checkNotNull(key); + this.one = checkNotNull(link); + } + + /** + * Sets the second link for this bi-link. + * + * @param link second link + */ + public void setOther(Link link) { + this.two = checkNotNull(link); + } + + /** + * Returns the link identifier in the form expected on the Topology View + * in the web client. + * + * @return link identifier + */ + public String linkId() { + return TopoUtils.compactLinkString(one); + } + + /** + * Returns the key for this bi-link. + * + * @return the key + */ + public LinkKey key() { + return key; + } + + /** + * Returns the first link in this bi-link. + * + * @return the first link + */ + public Link one() { + return one; + } + + /** + * Returns the second link in this bi-link. + * + * @return the second link + */ + public Link two() { + return two; + } + + /** + * Returns the link highlighting to use, based on this bi-link's current + * state. + * + * @param type optional highlighting type parameter + * @return link highlighting model + */ + public abstract LinkHighlight highlight(Enum<?> type); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLinkMap.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLinkMap.java new file mode 100644 index 00000000..7bc0e65d --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/BiLinkMap.java @@ -0,0 +1,90 @@ +/* + * 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.ui.topo; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a collection of {@link BiLink} concrete classes. These maps + * are used to collate a set of unidirectional {@link Link}s into a smaller + * set of bi-directional {@link BiLink} derivatives. + * <p> + * @param <B> the type of bi-link subclass + */ +public abstract class BiLinkMap<B extends BiLink> { + + private final Map<LinkKey, B> map = new HashMap<>(); + + /** + * Creates a new instance of a bi-link. Concrete subclasses should + * instantiate and return the appropriate bi-link subclass. + * + * @param key the link key + * @param link the initial link + * @return a new instance + */ + protected abstract B create(LinkKey key, Link link); + + /** + * Adds the given link to our collection, returning the corresponding + * bi-link (creating one if needed necessary). + * + * @param link the link to add to the collection + * @return the corresponding bi-link wrapper + */ + public B add(Link link) { + LinkKey key = TopoUtils.canonicalLinkKey(checkNotNull(link)); + B blink = map.get(key); + if (blink == null) { + // no bi-link yet exists for this link + blink = create(key, link); + map.put(key, blink); + } else { + // we have a bi-link for this link. + if (!blink.one().equals(link)) { + blink.setOther(link); + } + } + return blink; + } + + /** + * Returns the bi-link instances in the collection. + * + * @return the bi-links in this map + */ + public Collection<B> biLinks() { + return map.values(); + } + + /** + * Returns the number of bi-links in the collection. + * + * @return number of bi-links + */ + public int size() { + return map.size(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/ButtonId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/ButtonId.java new file mode 100644 index 00000000..ca2ecccd --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/ButtonId.java @@ -0,0 +1,70 @@ +/* + * 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.ui.topo; + +import com.google.common.base.MoreObjects; + +/** + * Designates the identity of a button on the topology view panels. + */ +public class ButtonId { + + private final String id; + + /** + * Creates a button ID with the given identifier. + * + * @param id identifier for the button + */ + public ButtonId(String id) { + this.id = id; + } + + /** + * Returns the identifier for this button. + * + * @return identifier + */ + public String id() { + return id; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("id", id()).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ButtonId that = (ButtonId) o; + return id.equals(that.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java new file mode 100644 index 00000000..2985d3d4 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/DeviceHighlight.java @@ -0,0 +1,33 @@ +/* + * 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.ui.topo; + +/** + * Denotes the highlighting to apply to a device. + */ +public class DeviceHighlight extends NodeHighlight { + + public DeviceHighlight(String deviceId) { + super(TopoElementType.DEVICE, deviceId); + } + + // TODO: implement device highlighting: + // - visual highlight + // - badging + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Highlights.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Highlights.java new file mode 100644 index 00000000..be59c26b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Highlights.java @@ -0,0 +1,190 @@ +/* + * 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.ui.topo; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Encapsulates highlights to be applied to the topology view, such as + * highlighting links, displaying link labels, perhaps even decorating + * nodes with badges, etc. + */ +public class Highlights { + + private static final String EMPTY = ""; + private static final String MIN = "min"; + private static final String MAX = "max"; + + /** + * A notion of amount. + */ + public enum Amount { + ZERO(EMPTY), + MINIMALLY(MIN), + MAXIMALLY(MAX); + + private final String s; + Amount(String str) { + s = str; + } + + @Override + public String toString() { + return s; + } + } + + private final Map<String, DeviceHighlight> devices = new HashMap<>(); + private final Map<String, HostHighlight> hosts = new HashMap<>(); + private final Map<String, LinkHighlight> links = new HashMap<>(); + + private Amount subdueLevel = Amount.ZERO; + + + /** + * Adds highlighting information for a device. + * + * @param dh device highlight + * @return self, for chaining + */ + public Highlights add(DeviceHighlight dh) { + devices.put(dh.elementId(), dh); + return this; + } + + /** + * Adds highlighting information for a host. + * + * @param hh host highlight + * @return self, for chaining + */ + public Highlights add(HostHighlight hh) { + hosts.put(hh.elementId(), hh); + return this; + } + + /** + * Adds highlighting information for a link. + * + * @param lh link highlight + * @return self, for chaining + */ + public Highlights add(LinkHighlight lh) { + links.put(lh.elementId(), lh); + return this; + } + + /** + * Marks the amount by which all other elements (devices, hosts, links) + * not explicitly referenced here will be "subdued" visually. + * + * @param amount amount to subdue other elements + * @return self, for chaining + */ + public Highlights subdueAllElse(Amount amount) { + subdueLevel = checkNotNull(amount); + return this; + } + + /** + * Returns the collection of device highlights. + * + * @return device highlights + */ + public Collection<DeviceHighlight> devices() { + return Collections.unmodifiableCollection(devices.values()); + } + + /** + * Returns the collection of host highlights. + * + * @return host highlights + */ + public Collection<HostHighlight> hosts() { + return Collections.unmodifiableCollection(hosts.values()); + } + + /** + * Returns the collection of link highlights. + * + * @return link highlights + */ + public Collection<LinkHighlight> links() { + return Collections.unmodifiableCollection(links.values()); + } + + /** + * Returns the amount by which all other elements not explicitly + * referenced here should be "subdued". + * + * @return amount to subdue other elements + */ + public Amount subdueLevel() { + return subdueLevel; + } + + /** + * Returns the node highlight (device or host) for the given element + * identifier, or null if no match. + * + * @param id element identifier + * @return corresponding node highlight + */ + public NodeHighlight getNode(String id) { + NodeHighlight nh = devices.get(id); + return nh != null ? nh : hosts.get(id); + } + + /** + * Returns the device highlight for the given device identifier, + * or null if no match. + * + * @param id device identifier + * @return corresponding device highlight + */ + public DeviceHighlight getDevice(String id) { + return devices.get(id); + } + + /** + * Returns the host highlight for the given host identifier, + * or null if no match. + * + * @param id host identifier + * @return corresponding host highlight + */ + public HostHighlight getHost(String id) { + return hosts.get(id); + } + + /** + * Returns the link highlight for the given link identifier, + * or null if no match. + * + * @param id link identifier + * @return corresponding link highlight + */ + public LinkHighlight getLink(String id) { + return links.get(id); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/HostHighlight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/HostHighlight.java new file mode 100644 index 00000000..76669a84 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/HostHighlight.java @@ -0,0 +1,33 @@ +/* + * 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.ui.topo; + +/** + * Denotes the highlighting to apply to a host. + */ +public class HostHighlight extends NodeHighlight { + + public HostHighlight(String hostId) { + super(TopoElementType.HOST, hostId); + } + + // TODO: implement host highlighting: + // - visual highlight + // - badging + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/LinkHighlight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/LinkHighlight.java new file mode 100644 index 00000000..b4e43304 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/LinkHighlight.java @@ -0,0 +1,147 @@ +/* + * 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.ui.topo; + +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Denotes the highlighting to be applied to a link. + * {@link Flavor} is a closed set of NO-, PRIMARY-, or SECONDARY- highlighting. + * {@link Mod} is an open ended set of additional modifications (CSS classes) + * that may also be applied. + * Note that {@link #MOD_OPTICAL} and {@link #MOD_ANIMATED} are pre-defined mods. + * Label text may be set, which will also be displayed on the link. + */ +public class LinkHighlight extends AbstractHighlight { + + private static final String PLAIN = "plain"; + private static final String PRIMARY = "primary"; + private static final String SECONDARY = "secondary"; + private static final String EMPTY = ""; + private static final String SPACE = " "; + + private final Flavor flavor; + private final Set<Mod> mods = new TreeSet<>(); + private String label = EMPTY; + + /** + * Constructs a link highlight entity. + * + * @param linkId the link identifier + * @param flavor the highlight flavor + */ + public LinkHighlight(String linkId, Flavor flavor) { + super(TopoElementType.LINK, linkId); + this.flavor = checkNotNull(flavor); + } + + /** + * Adds a highlighting modification to this link highlight. + * + * @param mod mod to be added + * @return self, for chaining + */ + public LinkHighlight addMod(Mod mod) { + mods.add(checkNotNull(mod)); + return this; + } + + /** + * Adds a label to be displayed on the link. + * + * @param label the label text + * @return self, for chaining + */ + public LinkHighlight setLabel(String label) { + this.label = label == null ? EMPTY : label; + return this; + } + + /** + * Returns the highlight flavor. + * + * @return highlight flavor + */ + public Flavor flavor() { + return flavor; + } + + /** + * Returns the highlight modifications. + * + * @return highlight modifications + */ + public Set<Mod> mods() { + return Collections.unmodifiableSet(mods); + } + + /** + * Generates the CSS classes string from the {@link #flavor} and + * any optional {@link #mods}. + * + * @return CSS classes string + */ + public String cssClasses() { + StringBuilder sb = new StringBuilder(flavor.toString()); + mods.forEach(m -> sb.append(SPACE).append(m)); + return sb.toString(); + } + + /** + * Returns the label text. + * + * @return label text + */ + public String label() { + return label; + } + + /** + * Link highlighting flavor. + */ + public enum Flavor { + NO_HIGHLIGHT(PLAIN), + PRIMARY_HIGHLIGHT(PRIMARY), + SECONDARY_HIGHLIGHT(SECONDARY); + + private String cssName; + + Flavor(String s) { + cssName = s; + } + + @Override + public String toString() { + return cssName; + } + } + + /** + * Denotes a link to be tagged as an optical link. + */ + public static final Mod MOD_OPTICAL = new Mod("optical"); + + /** + * Denotes a link to be tagged with animated traffic ("marching ants"). + */ + public static final Mod MOD_ANIMATED = new Mod("animated"); +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Mod.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Mod.java new file mode 100644 index 00000000..d21a8724 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/Mod.java @@ -0,0 +1,66 @@ +/* + * 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.ui.topo; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Highlighting modification. + * <p> + * Note that (for link highlights) this translates to a CSS class name + * that is applied to the link in the Topology UI. + */ +public final class Mod implements Comparable<Mod> { + private final String modId; + + /** + * Constructs a mod with the given identifier. + * + * @param modId modification identifier + */ + public Mod(String modId) { + this.modId = checkNotNull(modId); + } + + @Override + public String toString() { + return modId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Mod mod = (Mod) o; + return modId.equals(mod.modId); + } + + @Override + public int hashCode() { + return modId.hashCode(); + } + + @Override + public int compareTo(Mod o) { + return this.modId.compareTo(o.modId); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java new file mode 100644 index 00000000..735f8166 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeHighlight.java @@ -0,0 +1,27 @@ +/* + * 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.ui.topo; + +/** + * Parent class of {@link DeviceHighlight} and {@link HostHighlight}. + */ +public abstract class NodeHighlight extends AbstractHighlight { + public NodeHighlight(TopoElementType type, String elementId) { + super(type, elementId); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeSelection.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeSelection.java new file mode 100644 index 00000000..b284de1b --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/NodeSelection.java @@ -0,0 +1,252 @@ +/* + * 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.ui.topo; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onosproject.net.Device; +import org.onosproject.net.Element; +import org.onosproject.net.Host; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.host.HostService; +import org.onosproject.ui.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static org.onosproject.net.DeviceId.deviceId; +import static org.onosproject.net.HostId.hostId; + +/** + * Encapsulates a selection of devices and/or hosts from the topology view. + */ +public class NodeSelection { + + private static final Logger log = + LoggerFactory.getLogger(NodeSelection.class); + + private static final String IDS = "ids"; + private static final String HOVER = "hover"; + + private final DeviceService deviceService; + private final HostService hostService; + + private final Set<String> ids; + private final String hover; + + private final Set<Device> devices = new HashSet<>(); + private final Set<Host> hosts = new HashSet<>(); + private Element hovered; + + /** + * Creates a node selection entity, from the given payload, using the + * supplied device and host services. Note that if a device or host was + * hovered over by the mouse, it is available via {@link #hovered()}. + * + * @param payload message payload + * @param deviceService device service + * @param hostService host service + */ + public NodeSelection(ObjectNode payload, + DeviceService deviceService, + HostService hostService) { + this.deviceService = deviceService; + this.hostService = hostService; + + ids = extractIds(payload); + hover = extractHover(payload); + + // start by extracting the hovered element if any + if (isNullOrEmpty(hover)) { + hovered = null; + } else { + setHoveredElement(); + } + + // now go find the devices and hosts that are in the selection list + Set<String> unmatched = findDevices(ids); + unmatched = findHosts(unmatched); + if (unmatched.size() > 0) { + log.debug("Skipping unmatched IDs {}", unmatched); + } + + } + + /** + * Returns a view of the selected devices (hover not included). + * + * @return selected devices + */ + public Set<Device> devices() { + return Collections.unmodifiableSet(devices); + } + + /** + * Returns a view of the selected devices, including the hovered device + * if there was one. + * + * @return selected (plus hovered) devices + */ + public Set<Device> devicesWithHover() { + Set<Device> withHover; + if (hovered != null && hovered instanceof Device) { + withHover = new HashSet<>(devices); + withHover.add((Device) hovered); + } else { + withHover = devices; + } + return Collections.unmodifiableSet(withHover); + } + + /** + * Returns a view of the selected hosts (hover not included). + * + * @return selected hosts + */ + public Set<Host> hosts() { + return Collections.unmodifiableSet(hosts); + } + + /** + * Returns a view of the selected hosts, including the hovered host + * if thee was one. + * + * @return selected (plus hovered) hosts + */ + public Set<Host> hostsWithHover() { + Set<Host> withHover; + if (hovered != null && hovered instanceof Host) { + withHover = new HashSet<>(hosts); + withHover.add((Host) hovered); + } else { + withHover = hosts; + } + return Collections.unmodifiableSet(withHover); + } + + /** + * Returns the element (host or device) over which the mouse was hovering, + * or null. + * + * @return element hovered over + */ + public Element hovered() { + return hovered; + } + + /** + * Returns true if nothing is selected. + * + * @return true if nothing selected + */ + public boolean none() { + return devices().size() == 0 && hosts().size() == 0; + } + + @Override + public String toString() { + return "NodeSelection{" + + "ids=" + ids + + ", hover='" + hover + '\'' + + ", #devices=" + devices.size() + + ", #hosts=" + hosts.size() + + '}'; + } + + // == helper methods + + private Set<String> extractIds(ObjectNode payload) { + ArrayNode array = (ArrayNode) payload.path(IDS); + if (array == null || array.size() == 0) { + return Collections.emptySet(); + } + + Set<String> ids = new HashSet<>(); + for (JsonNode node : array) { + ids.add(node.asText()); + } + return ids; + } + + private String extractHover(ObjectNode payload) { + return JsonUtils.string(payload, HOVER); + } + + private void setHoveredElement() { + Set<String> unmatched; + unmatched = new HashSet<>(); + unmatched.add(hover); + unmatched = findDevices(unmatched); + if (devices.size() == 1) { + hovered = devices.iterator().next(); + devices.clear(); + } else { + unmatched = findHosts(unmatched); + if (hosts.size() == 1) { + hovered = hosts.iterator().next(); + hosts.clear(); + } else { + hovered = null; + log.debug("Skipping unmatched HOVER {}", unmatched); + } + } + } + + private Set<String> findDevices(Set<String> ids) { + Set<String> unmatched = new HashSet<>(); + Device device; + + for (String id : ids) { + try { + device = deviceService.getDevice(deviceId(id)); + if (device != null) { + devices.add(device); + } else { + unmatched.add(id); + } + } catch (Exception e) { + unmatched.add(id); + } + } + return unmatched; + } + + private Set<String> findHosts(Set<String> ids) { + Set<String> unmatched = new HashSet<>(); + Host host; + + for (String id : ids) { + try { + host = hostService.getHost(hostId(id)); + if (host != null) { + hosts.add(host); + } else { + unmatched.add(id); + } + } catch (Exception e) { + unmatched.add(id); + } + } + return unmatched; + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java new file mode 100644 index 00000000..121e0834 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java @@ -0,0 +1,353 @@ +/* + * 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.ui.topo; + +import com.google.common.collect.Sets; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Models a panel displayed on the Topology View. + */ +public class PropertyPanel { + + private static final DecimalFormat DF0 = new DecimalFormat("#,###"); + + private String title; + private String typeId; + private String id; + private List<Prop> properties = new ArrayList<>(); + private List<ButtonId> buttons = new ArrayList<>(); + + /** + * Constructs a property panel model with the given title and + * type identifier (icon to display). + * + * @param title title text + * @param typeId type (icon) ID + */ + public PropertyPanel(String title, String typeId) { + this.title = title; + this.typeId = typeId; + } + + /** + * Adds an ID field to the panel data, to be included in + * the returned JSON data to the client. + * + * @param id the identifier + * @return self, for chaining + */ + public PropertyPanel id(String id) { + this.id = id; + return this; + } + + /** + * Adds a property to the panel data. + * + * @param key property key + * @param value property value + * @return self, for chaining + */ + public PropertyPanel addProp(String key, String value) { + properties.add(new Prop(key, value)); + return this; + } + + /** + * Adds a property to the panel data, using a decimal formatter. + * + * @param key property key + * @param value property value + * @return self, for chaining + */ + public PropertyPanel addProp(String key, int value) { + properties.add(new Prop(key, DF0.format(value))); + return this; + } + + /** + * Adds a property to the panel data, using a decimal formatter. + * + * @param key property key + * @param value property value + * @return self, for chaining + */ + public PropertyPanel addProp(String key, long value) { + properties.add(new Prop(key, DF0.format(value))); + return this; + } + + /** + * Adds a property to the panel data. Note that the value's + * {@link Object#toString toString()} method is used to convert the + * value to a string. + * + * @param key property key + * @param value property value + * @return self, for chaining + */ + public PropertyPanel addProp(String key, Object value) { + properties.add(new Prop(key, value.toString())); + return this; + } + + /** + * Adds a property to the panel data. Note that the value's + * {@link Object#toString toString()} method is used to convert the + * value to a string, from which the characters defined in the given + * regular expression string are stripped. + * + * @param key property key + * @param value property value + * @param reStrip regexp characters to strip from value string + * @return self, for chaining + */ + public PropertyPanel addProp(String key, Object value, String reStrip) { + String val = value.toString().replaceAll(reStrip, ""); + properties.add(new Prop(key, val)); + return this; + } + + /** + * Adds a separator to the panel data. + * + * @return self, for chaining + */ + public PropertyPanel addSeparator() { + properties.add(new Separator()); + return this; + } + + /** + * Returns the title text. + * + * @return title text + */ + public String title() { + return title; + } + + /** + * Returns the type identifier. + * + * @return type identifier + */ + public String typeId() { + return typeId; + } + + /** + * Returns the internal ID. + * + * @return the ID + */ + public String id() { + return id; + } + + /** + * Returns the list of properties to be displayed. + * + * @return the property list + */ + // TODO: consider protecting this? + public List<Prop> properties() { + return properties; + } + + /** + * Returns the list of button descriptors. + * + * @return the button list + */ + // TODO: consider protecting this? + public List<ButtonId> buttons() { + return buttons; + } + + // == MUTATORS + + /** + * Sets the title text. + * + * @param title title text + * @return self, for chaining + */ + public PropertyPanel title(String title) { + this.title = title; + return this; + } + + /** + * Sets the type identifier (icon ID). + * + * @param typeId type identifier + * @return self, for chaining + */ + public PropertyPanel typeId(String typeId) { + this.typeId = typeId; + return this; + } + + /** + * Removes properties with the given keys from the list. + * + * @param keys keys of properties to remove + * @return self, for chaining + */ + public PropertyPanel removeProps(String... keys) { + Set<String> forRemoval = Sets.newHashSet(keys); + List<Prop> toKeep = new ArrayList<>(); + for (Prop p: properties) { + if (!forRemoval.contains(p.key())) { + toKeep.add(p); + } + } + properties = toKeep; + return this; + } + + /** + * Removes all currently defined properties. + * + * @return self, for chaining + */ + public PropertyPanel removeAllProps() { + properties.clear(); + return this; + } + + /** + * Adds the given button descriptor to the panel data. + * + * @param button button descriptor + * @return self, for chaining + */ + public PropertyPanel addButton(ButtonId button) { + buttons.add(button); + return this; + } + + /** + * Removes buttons with the given descriptors from the list. + * + * @param descriptors descriptors to remove + * @return self, for chaining + */ + public PropertyPanel removeButtons(ButtonId... descriptors) { + Set<ButtonId> forRemoval = Sets.newHashSet(descriptors); + List<ButtonId> toKeep = new ArrayList<>(); + for (ButtonId bd: buttons) { + if (!forRemoval.contains(bd)) { + toKeep.add(bd); + } + } + buttons = toKeep; + return this; + } + + /** + * Removes all currently defined buttons. + * + * @return self, for chaining + */ + public PropertyPanel removeAllButtons() { + buttons.clear(); + return this; + } + + // ==================== + + + /** + * Simple data carrier for a property, composed of a key/value pair. + */ + public static class Prop { + private final String key; + private final String value; + + /** + * Constructs a property data value. + * + * @param key property key + * @param value property value + */ + public Prop(String key, String value) { + this.key = key; + this.value = value; + } + + /** + * Returns the property's key. + * + * @return the key + */ + public String key() { + return key; + } + + /** + * Returns the property's value. + * + * @return the value + */ + public String value() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Prop prop = (Prop) o; + return key.equals(prop.key) && value.equals(prop.value); + } + + @Override + public int hashCode() { + int result = key.hashCode(); + result = 31 * result + value.hashCode(); + return result; + } + + @Override + public String toString() { + return "{" + key + " -> " + value + "}"; + } + } + + /** + * Auxiliary class representing a separator property. + */ + public static class Separator extends Prop { + public Separator() { + super("-", ""); + } + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java new file mode 100644 index 00000000..38a8f036 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoConstants.java @@ -0,0 +1,129 @@ +/* + * 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.ui.topo; + +/** + * Defines string constants used in the Topology View of the ONOS GUI. + * <p> + * See also: + * <ul> + * <li> https://wiki.onosproject.org/display/ONOS/UI+Service+-+GlyphService </li> + * </ul> + */ +public final class TopoConstants { + + /** + * Defines constants for standard glyph identifiers. + */ + public static final class Glyphs { + public static final String UNKNOWN = "unknown"; + public static final String BIRD = "bird"; + public static final String NODE = "node"; + public static final String SWITCH = "switch"; + public static final String ROADM = "roadm"; + public static final String ENDSTATION = "endstation"; + public static final String ROUTER = "router"; + public static final String BGP_SPEAKER = "bgpSpeaker"; + public static final String CHAIN = "chain"; + public static final String CROWN = "crown"; + public static final String TOPO = "topo"; + public static final String REFRESH = "refresh"; + public static final String GARBAGE = "garbage"; + public static final String FLOW_TABLE = "flowTable"; + public static final String PORT_TABLE = "portTable"; + public static final String GROUP_TABLE = "groupTable"; + public static final String SUMMARY = "summary"; + public static final String DETAILS = "details"; + public static final String PORTS = "ports"; + public static final String MAP = "map"; + public static final String CYCLE_LABELS = "cycleLabels"; + public static final String OBLIQUE = "oblique"; + public static final String FILTERS = "filters"; + public static final String RESET_ZOOM = "resetZoom"; + public static final String RELATED_INTENTS = "relatedIntents"; + public static final String NEXT_INTENT = "nextIntent"; + public static final String PREV_INTENT = "prevIntent"; + public static final String INTENT_TRAFFIC = "intentTraffic"; + public static final String ALL_TRAFFIC = "allTraffic"; + public static final String FLOWS = "flows"; + public static final String EQ_MASTER = "eqMaster"; + public static final String UI_ATTACHED = "uiAttached"; + public static final String CHECK_MARK = "checkMark"; + public static final String X_MARK = "xMark"; + public static final String TRIANGLE_UP = "triangleUp"; + public static final String TRIANGLE_DOWN = "triangleDown"; + public static final String PLUS = "plus"; + public static final String MINUS = "minus"; + public static final String PLAY = "play"; + public static final String STOP = "stop"; + public static final String CLOUD = "cloud"; + } + + /** + * Defines constants for property names on the default summary and + * details panels. + */ + public static final class Properties { + public static final String SEPARATOR = "-"; + + // summary panel + public static final String DEVICES = "Devices"; + public static final String LINKS = "Links"; + public static final String HOSTS = "Hosts"; + public static final String TOPOLOGY_SSCS = "Topology SCCs"; + public static final String INTENTS = "Intents"; + public static final String TUNNELS = "Tunnels"; + public static final String FLOWS = "Flows"; + public static final String VERSION = "Version"; + + // device details + public static final String URI = "URI"; + public static final String VENDOR = "Vendor"; + public static final String HW_VERSION = "H/W Version"; + public static final String SW_VERSION = "S/W Version"; + public static final String SERIAL_NUMBER = "Serial Number"; + public static final String PROTOCOL = "Protocol"; + public static final String LATITUDE = "Latitude"; + public static final String LONGITUDE = "Longitude"; + public static final String PORTS = "Ports"; + + // host details + public static final String MAC = "MAC"; + public static final String IP = "IP"; + public static final String VLAN = "VLAN"; + } + + /** + * Defines identities of core buttons that appear on the topology + * details panel. + */ + public static final class CoreButtons { + public static final ButtonId SHOW_DEVICE_VIEW = + new ButtonId("showDeviceView"); + + public static final ButtonId SHOW_FLOW_VIEW = + new ButtonId("showFlowView"); + + public static final ButtonId SHOW_PORT_VIEW = + new ButtonId("showPortView"); + + public static final ButtonId SHOW_GROUP_VIEW = + new ButtonId("showGroupView"); + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoElementType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoElementType.java new file mode 100644 index 00000000..dc327464 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoElementType.java @@ -0,0 +1,25 @@ +/* + * 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.ui.topo; + +/** + * The topology element types to which a highlight can be applied. + */ +public enum TopoElementType { + DEVICE, HOST, LINK +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java new file mode 100644 index 00000000..a94068ee --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoJson.java @@ -0,0 +1,160 @@ +/* + * 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.ui.topo; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import static org.onosproject.ui.JsonUtils.envelope; + +/** + * JSON utilities for the Topology View. + */ +public final class TopoJson { + // package-private for unit test access + static final String SHOW_HIGHLIGHTS = "showHighlights"; + + static final String DEVICES = "devices"; + static final String HOSTS = "hosts"; + static final String LINKS = "links"; + static final String SUBDUE = "subdue"; + + static final String ID = "id"; + static final String LABEL = "label"; + static final String CSS = "css"; + + static final String TITLE = "title"; + static final String TYPE = "type"; + static final String PROP_ORDER = "propOrder"; + static final String PROPS = "props"; + static final String BUTTONS = "buttons"; + + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + private static ObjectNode objectNode() { + return MAPPER.createObjectNode(); + } + + private static ArrayNode arrayNode() { + return MAPPER.createArrayNode(); + } + + // non-instantiable + private TopoJson() { } + + /** + * Returns a formatted message ready to send to the topology view + * to render highlights. + * + * @param highlights highlights model to transform + * @return fully formatted "show highlights" message + */ + public static ObjectNode highlightsMessage(Highlights highlights) { + return envelope(SHOW_HIGHLIGHTS, json(highlights)); + } + + /** + * Transforms the given highlights model into a JSON message payload. + * + * @param highlights the model to transform + * @return JSON payload + */ + public static ObjectNode json(Highlights highlights) { + ObjectNode payload = objectNode(); + + ArrayNode devices = arrayNode(); + ArrayNode hosts = arrayNode(); + ArrayNode links = arrayNode(); + + payload.set(DEVICES, devices); + payload.set(HOSTS, hosts); + payload.set(LINKS, links); + + highlights.devices().forEach(dh -> devices.add(json(dh))); + highlights.hosts().forEach(hh -> hosts.add(json(hh))); + highlights.links().forEach(lh -> links.add(json(lh))); + + Highlights.Amount toSubdue = highlights.subdueLevel(); + if (!toSubdue.equals(Highlights.Amount.ZERO)) { + payload.put(SUBDUE, toSubdue.toString()); + } + return payload; + } + + private static ObjectNode json(DeviceHighlight dh) { + ObjectNode n = objectNode() + .put(ID, dh.elementId()); + if (dh.subdued()) { + n.put(SUBDUE, true); + } + return n; + } + + private static ObjectNode json(HostHighlight hh) { + ObjectNode n = objectNode() + .put(ID, hh.elementId()); + if (hh.subdued()) { + n.put(SUBDUE, true); + } + return n; + } + + private static ObjectNode json(LinkHighlight lh) { + ObjectNode n = objectNode() + .put(ID, lh.elementId()) + .put(LABEL, lh.label()) + .put(CSS, lh.cssClasses()); + if (lh.subdued()) { + n.put(SUBDUE, true); + } + return n; + } + + /** + * Translates the given property panel into JSON, for returning + * to the client. + * + * @param pp the property panel model + * @return JSON payload + */ + public static ObjectNode json(PropertyPanel pp) { + ObjectNode result = objectNode() + .put(TITLE, pp.title()) + .put(TYPE, pp.typeId()) + .put(ID, pp.id()); + + ObjectNode pnode = objectNode(); + ArrayNode porder = arrayNode(); + for (PropertyPanel.Prop p : pp.properties()) { + porder.add(p.key()); + pnode.put(p.key(), p.value()); + } + result.set(PROP_ORDER, porder); + result.set(PROPS, pnode); + + ArrayNode buttons = arrayNode(); + for (ButtonId b : pp.buttons()) { + buttons.add(b.id()); + } + result.set(BUTTONS, buttons); + return result; + } + +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoUtils.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoUtils.java new file mode 100644 index 00000000..f92d5798 --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/TopoUtils.java @@ -0,0 +1,159 @@ +/* + * 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.ui.topo; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; + +import java.text.DecimalFormat; + +import static org.onosproject.net.LinkKey.linkKey; + +/** + * Utility methods for helping out with formatting data for the Topology View + * in the web client. + */ +public final class TopoUtils { + + // explicit decision made to not 'javadoc' these self explanatory constants + public static final double KILO = 1024; + public static final double MEGA = 1024 * KILO; + public static final double GIGA = 1024 * MEGA; + + public static final String GBITS_UNIT = "Gb"; + public static final String MBITS_UNIT = "Mb"; + public static final String KBITS_UNIT = "Kb"; + public static final String BITS_UNIT = "b"; + public static final String GBYTES_UNIT = "GB"; + public static final String MBYTES_UNIT = "MB"; + public static final String KBYTES_UNIT = "KB"; + public static final String BYTES_UNIT = "B"; + + + private static final DecimalFormat DF2 = new DecimalFormat("#,###.##"); + + private static final String COMPACT = "%s/%s-%s/%s"; + private static final String EMPTY = ""; + private static final String SPACE = " "; + private static final String PER_SEC = "ps"; + private static final String FLOW = "flow"; + private static final String FLOWS = "flows"; + + // non-instantiable + private TopoUtils() { } + + /** + * Returns a compact identity for the given link, in the form + * used to identify links in the Topology View on the client. + * + * @param link link + * @return compact link identity + */ + public static String compactLinkString(Link link) { + return String.format(COMPACT, link.src().elementId(), link.src().port(), + link.dst().elementId(), link.dst().port()); + } + + /** + * Produces a canonical link key, that is, one that will match both a link + * and its inverse. + * + * @param link the link + * @return canonical key + */ + public static LinkKey canonicalLinkKey(Link link) { + String sn = link.src().elementId().toString(); + String dn = link.dst().elementId().toString(); + return sn.compareTo(dn) < 0 ? + linkKey(link.src(), link.dst()) : linkKey(link.dst(), link.src()); + } + + /** + * Returns human readable count of bytes, to be displayed as a label. + * + * @param bytes number of bytes + * @return formatted byte count + */ + public static String formatBytes(long bytes) { + String unit; + double value; + if (bytes > GIGA) { + value = bytes / GIGA; + unit = GBYTES_UNIT; + } else if (bytes > MEGA) { + value = bytes / MEGA; + unit = MBYTES_UNIT; + } else if (bytes > KILO) { + value = bytes / KILO; + unit = KBYTES_UNIT; + } else { + value = bytes; + unit = BYTES_UNIT; + } + return DF2.format(value) + SPACE + unit; + } + + /** + * Returns human readable bit rate, to be displayed as a label. + * + * @param bytes bytes per second + * @return formatted bits per second + */ + public static String formatBitRate(long bytes) { + String unit; + double value; + + //Convert to bits + long bits = bytes * 8; + if (bits > GIGA) { + value = bits / GIGA; + unit = GBITS_UNIT; + + // NOTE: temporary hack to clip rate at 10.0 Gbps + // Added for the CORD Fabric demo at ONS 2015 + // TODO: provide a more elegant solution to this issue + if (value > 10.0) { + value = 10.0; + } + + } else if (bits > MEGA) { + value = bits / MEGA; + unit = MBITS_UNIT; + } else if (bits > KILO) { + value = bits / KILO; + unit = KBITS_UNIT; + } else { + value = bits; + unit = BITS_UNIT; + } + return DF2.format(value) + SPACE + unit + PER_SEC; + } + + /** + * Returns human readable flow count, to be displayed as a label. + * + * @param flows number of flows + * @return formatted flow count + */ + public static String formatFlows(long flows) { + if (flows < 1) { + return EMPTY; + } + return String.valueOf(flows) + SPACE + (flows > 1 ? FLOWS : FLOW); + } +} diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/package-info.java new file mode 100644 index 00000000..85ac7fea --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Mechanism for dynamically extending topology view with information and + * behaviour overlays. + */ +package org.onosproject.ui.topo;
\ No newline at end of file diff --git a/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/flow/doc-files/flow-design.png b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/flow/doc-files/flow-design.png Binary files differnew file mode 100644 index 00000000..e08745d1 --- /dev/null +++ b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/flow/doc-files/flow-design.png diff --git a/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-design.png b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-design.png Binary files differnew file mode 100644 index 00000000..4392ad45 --- /dev/null +++ b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-design.png diff --git a/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-states.png b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-states.png Binary files differnew file mode 100644 index 00000000..32804191 --- /dev/null +++ b/framework/src/onos/core/api/src/main/javadoc/org/onosproject/net/intent/doc-files/intent-states.png |