Thomas Vachuska
Committed by Gerrit Code Review

ONOS-542 Defining application subsystem interfaces & public constructs.

Change-Id: Iba0d2cb69dace5beee8a68def9918059ce755b5c
Showing 64 changed files with 3200 additions and 34 deletions
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cli;
import org.apache.karaf.shell.commands.Command;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Lists application ID information.
*/
@Command(scope = "onos", name = "app-install",
description = "Lists application ID information")
public class ApplicationInstallCommand extends AbstractShellCommand {
@Override
protected void execute() {
// FIXME: merely an experiment for now
try (InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
print("%s", line.toUpperCase());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
......@@ -21,6 +21,10 @@
</command>
<command>
<action class="org.onosproject.cli.ApplicationInstallCommand"/>
</command>
<command>
<action class="org.onosproject.cli.MetricsListCommand"/>
</command>
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.core.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.
*
* @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);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.Permission;
import org.onosproject.core.Version;
import java.net.URI;
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 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 set of features comprising the application. At least one
* feature must be given.
*
* @return application features
*/
Set<String> features();
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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> {
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.core.Permission;
import java.util.Set;
/**
* Service for inspecting inventory of network control applications.
*/
public interface ApplicationService {
/**
* 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);
/**
* Adds the given listener for application lifecycle events.
*
* @param listener listener to be added
*/
void addListener(ApplicationListener listener);
/**
* Removes the specified listener for application lifecycle events.
*
* @param listener listener to be removed
*/
void removeListener(ApplicationListener listener);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.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
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.core.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);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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> {
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.Permission;
import org.onosproject.core.Version;
import java.net.URI;
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 Set<Permission> permissions;
private final Optional<URI> featuresRepo;
private final Set<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 permissions requested permissions
* @param featuresRepo optional features repo URI
* @param features application features
*/
public DefaultApplicationDescription(String name, Version version,
String description, String origin,
Set<Permission> permissions,
URI featuresRepo, Set<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.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 Set<Permission> permissions() {
return permissions;
}
@Override
public Optional<URI> featuresRepo() {
return featuresRepo;
}
@Override
public Set<String> features() {
return features;
}
@Override
public String toString() {
return toStringHelper(this)
.add("name", name)
.add("version", version)
.add("description", description)
.add("origin", origin)
.add("permissions", permissions)
.add("featuresRepo", featuresRepo)
.add("features", features)
.toString();
}
}
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -15,6 +15,6 @@
*/
/**
* Implementation of JSON codec factory and of the builtin codecs.
* Set of abstractions for managing network control applications.
*/
package org.onosproject.json.impl;
package org.onosproject.app;
\ No newline at end of file
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.core;
import java.net.URI;
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 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 set of features comprising the application. At least one
* feature must be given.
*
* @return application features
*/
Set<String> features();
}
......@@ -14,6 +14,7 @@
* limitations under the License.
*/
package org.onosproject.core;
// FIXME: Move to org.onosproject.app package
import java.util.Set;
......@@ -31,12 +32,21 @@ public interface ApplicationIdStore {
/**
* Returns an existing application id from a given id.
*
* @param id the short value of the id
* @return an application 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}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.net.URI;
import java.util.Objects;
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 DefaultApplication implements Application {
private final ApplicationId appId;
private final Version version;
private final String description;
private final String origin;
private final Set<Permission> permissions;
private final Optional<URI> featuresRepo;
private final Set<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 permissions requested permissions
* @param featuresRepo optional features repo URI
* @param features application features
*/
public DefaultApplication(ApplicationId appId, Version version,
String description, String origin,
Set<Permission> permissions,
Optional<URI> featuresRepo, Set<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.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 Set<Permission> permissions() {
return permissions;
}
@Override
public Optional<URI> featuresRepo() {
return featuresRepo;
}
@Override
public Set<String> features() {
return features;
}
@Override
public int hashCode() {
return Objects.hash(appId, version, description, origin, 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.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("permissions", permissions)
.add("featuresRepo", featuresRepo)
.add("features", features)
.toString();
}
}
......@@ -18,6 +18,7 @@ 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.
......@@ -33,8 +34,9 @@ public class DefaultApplicationId implements ApplicationId {
* @param id application identifier
* @param name application name
*/
public DefaultApplicationId(Short id, String name) {
this.id = id;
public DefaultApplicationId(int id, String name) {
checkArgument(0 <= id && id <= Short.MAX_VALUE, "id is outside range");
this.id = (short) id;
this.name = name;
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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;
/**
* Representation of an application permission.
*/
public interface Permission {
// TODO: to be fleshed out
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.core.Permission;
import java.io.InputStream;
import java.util.Set;
/**
* Adapter for testing against application admin service.
*/
public class ApplicationAdminServiceAdapter extends ApplicationServiceAdapter
implements ApplicationAdminService {
@Override
public Set<Application> getApplications() {
return null;
}
@Override
public Application getApplication(ApplicationId appId) {
return null;
}
@Override
public ApplicationState getState(ApplicationId appId) {
return null;
}
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
return null;
}
@Override
public void addListener(ApplicationListener listener) {
}
@Override
public void removeListener(ApplicationListener listener) {
}
@Override
public Application install(InputStream appDescStream) {
return null;
}
@Override
public void uninstall(ApplicationId appId) {
}
@Override
public void activate(ApplicationId appId) {
}
@Override
public void deactivate(ApplicationId appId) {
}
@Override
public void setPermissions(ApplicationId appId, Set<Permission> permissions) {
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.junit.Test;
import org.onosproject.core.Application;
import org.onosproject.core.DefaultApplication;
import org.onosproject.event.AbstractEventTest;
import java.util.Optional;
import static org.onosproject.app.ApplicationEvent.Type.APP_ACTIVATED;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
import static org.onosproject.core.DefaultApplicationTest.APP_ID;
/**
* Test of the application event.
*/
public class ApplicationEventTest extends AbstractEventTest {
private Application createApp() {
return new DefaultApplication(APP_ID, VER, DESC, ORIGIN,
PERMS, Optional.of(FURL), FEATURES);
}
@Test
public void withoutTime() {
Application app = createApp();
ApplicationEvent event = new ApplicationEvent(APP_ACTIVATED, app, 123L);
validateEvent(event, APP_ACTIVATED, app, 123L);
}
@Test
public void withTime() {
Application app = createApp();
long before = System.currentTimeMillis();
ApplicationEvent event = new ApplicationEvent(APP_ACTIVATED, app);
long after = System.currentTimeMillis();
validateEvent(event, APP_ACTIVATED, app, before, after);
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.app;
import org.onlab.junit.ExceptionTest;
public class ApplicationExceptionTest extends ExceptionTest {
@Override
protected Exception getDefault() {
return new ApplicationException();
}
@Override
protected Exception getWithMessage() {
return new ApplicationException(MESSAGE);
}
@Override
protected Exception getWithMessageAndCause() {
return new ApplicationException(MESSAGE, CAUSE);
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.app;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.Permission;
import java.util.Set;
/**
* Adapter for testing against application service.
*/
public class ApplicationServiceAdapter implements ApplicationService {
@Override
public Set<Application> getApplications() {
return null;
}
@Override
public ApplicationId getId(String name) {
return null;
}
@Override
public Application getApplication(ApplicationId appId) {
return null;
}
@Override
public ApplicationState getState(ApplicationId appId) {
return null;
}
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
return null;
}
@Override
public void addListener(ApplicationListener listener) {
}
@Override
public void removeListener(ApplicationListener listener) {
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.app;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.Permission;
import org.onosproject.store.AbstractStore;
import java.io.InputStream;
import java.util.Set;
/**
* Adapter for application testing against application store.
*/
public class ApplicationStoreAdapter
extends AbstractStore<ApplicationEvent, ApplicationStoreDelegate>
implements ApplicationStore {
@Override
public Set<Application> getApplications() {
return null;
}
@Override
public ApplicationId getId(String name) {
return null;
}
@Override
public Application getApplication(ApplicationId appId) {
return null;
}
@Override
public ApplicationState getState(ApplicationId appId) {
return null;
}
@Override
public Application create(InputStream appDescStream) {
return null;
}
@Override
public void remove(ApplicationId appId) {
}
@Override
public void activate(ApplicationId appId) {
}
@Override
public void deactivate(ApplicationId appId) {
}
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
return null;
}
@Override
public void setPermissions(ApplicationId appId, Set<Permission> permissions) {
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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 com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.onosproject.core.Permission;
import org.onosproject.core.Version;
import java.net.URI;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Basic tests of the default app description.
*/
public class DefaultApplicationDescriptionTest {
public static final String APP_NAME = "org.foo.app";
public static final Version VER = Version.version(1, 2, "a", null);
public static final String DESC = "Awesome application from Circus";
public static final String ORIGIN = "Circus";
public static final Set<Permission> PERMS = ImmutableSet.of();
public static final URI FURL = URI.create("mvn:org.foo-features/1.2a/xml/features");
public static final Set<String> FEATURES = ImmutableSet.of("foo");
@Test
public void basics() {
ApplicationDescription app =
new DefaultApplicationDescription(APP_NAME, VER, DESC, ORIGIN,
PERMS, FURL, FEATURES);
assertEquals("incorrect id", APP_NAME, app.name());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect description", DESC, app.description());
assertEquals("incorrect origin", ORIGIN, app.origin());
assertEquals("incorrect permissions", PERMS, app.permissions());
assertEquals("incorrect features repo", FURL, app.featuresRepo().get());
assertEquals("incorrect features", FEATURES, app.features());
assertTrue("incorrect toString", app.toString().contains(APP_NAME));
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.core;
import java.util.Set;
/**
* Adapter for testing against app id store.
*/
public class ApplicationIdStoreAdapter implements ApplicationIdStore {
@Override
public Set<ApplicationId> getAppIds() {
return null;
}
@Override
public ApplicationId getAppId(Short id) {
return null;
}
@Override
public ApplicationId getAppId(String name) {
return null;
}
@Override
public ApplicationId registerApplication(String identifier) {
return null;
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.core;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
/**
* Basic tests of the default app descriptor.
*/
public class DefaultApplicationTest {
public static final ApplicationId APP_ID = new DefaultApplicationId(2, APP_NAME);
@Test
public void basics() {
Application app = new DefaultApplication(APP_ID, VER, DESC, ORIGIN,
PERMS, Optional.of(FURL), FEATURES);
assertEquals("incorrect id", APP_ID, app.id());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect description", DESC, app.description());
assertEquals("incorrect origin", ORIGIN, app.origin());
assertEquals("incorrect permissions", PERMS, app.permissions());
assertEquals("incorrect features repo", FURL, app.featuresRepo().get());
assertEquals("incorrect features", FEATURES, app.features());
assertTrue("incorrect toString", app.toString().contains(APP_NAME));
}
@Test
public void testEquality() {
Application a1 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN,
PERMS, Optional.of(FURL), FEATURES);
Application a2 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN,
PERMS, Optional.of(FURL), FEATURES);
Application a3 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN,
PERMS, Optional.empty(), FEATURES);
Application a4 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN + "asd",
PERMS, Optional.of(FURL), FEATURES);
new EqualsTester().addEqualityGroup(a1, a2)
.addEqualityGroup(a3).addEqualityGroup(a4).testEquals();
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.core;
import org.onlab.junit.ExceptionTest;
public class UnavailableIdExceptionTest extends ExceptionTest {
@Override
protected Exception getDefault() {
return new UnavailableIdException();
}
@Override
protected Exception getWithMessage() {
return new UnavailableIdException(MESSAGE);
}
@Override
protected Exception getWithMessageAndCause() {
return new UnavailableIdException(MESSAGE, CAUSE);
}
}
\ No newline at end of file
......@@ -45,7 +45,7 @@ public class IntentOperationsTest {
final TrafficSelector selector = new IntentTestsMocks.MockSelector();
final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
private final ApplicationId appId = new DefaultApplicationId((short) 1, "IntentOperationsTest");
private final ApplicationId appId = new DefaultApplicationId(1, "IntentOperationsTest");
private Intent intent;
protected IdGenerator idGenerator = new MockIdGenerator();
......
......@@ -26,16 +26,17 @@
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-json</artifactId>
<artifactId>onos-core-common</artifactId>
<packaging>bundle</packaging>
<description>ONOS JSON encode/decode facilities</description>
<description>ONOS utilities common to the core modules</description>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
......@@ -44,13 +45,17 @@
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-trivial</artifactId>
<version>${project.version}</version>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
</dependency>
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.common.app;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.onlab.util.Tools;
import org.onosproject.app.ApplicationDescription;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationException;
import org.onosproject.app.ApplicationStoreDelegate;
import org.onosproject.app.DefaultApplicationDescription;
import org.onosproject.core.Permission;
import org.onosproject.core.Version;
import org.onosproject.store.AbstractStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static com.google.common.io.ByteStreams.toByteArray;
import static com.google.common.io.Files.createParentDirs;
import static com.google.common.io.Files.write;
/**
* Facility for reading application archive stream and managing application
* directory structure.
*/
public class ApplicationArchive
extends AbstractStore<ApplicationEvent, ApplicationStoreDelegate> {
private static final String NAME = "[@name]";
private static final String ORIGIN = "[@origin]";
private static final String VERSION = "[@version]";
private static final String FEATURES_REPO = "[@featuresRepo]";
private static final String FEATURES = "[@features]";
private static final String DESCRIPTION = "description";
private static Logger log = LoggerFactory.getLogger(ApplicationArchive.class);
private static final String APP_XML = "app.xml";
private static final String APPS_ROOT = "data/apps/";
private File appsDir = new File(APPS_ROOT);
/**
* Sets the root directory where application artifacts are kept.
*
* @param appsRoot top-level applications directory path
*/
protected void setAppsRoot(String appsRoot) {
this.appsDir = new File(appsRoot);
}
/**
* Returns the root directory where application artifacts are kept.
*
* @return top-level applications directory path
*/
protected String getAppsRoot() {
return appsDir.getPath();
}
/**
* Returns the set of installed application names.
*
* @return installed application names
*/
public Set<String> getApplicationNames() {
ImmutableSet.Builder<String> names = ImmutableSet.builder();
File[] files = appsDir.listFiles(File::isDirectory);
if (files != null) {
for (File file : files) {
names.add(file.getName());
}
}
return names.build();
}
/**
* Loads the application descriptor from the specified application archive
* stream and saves the stream in the appropriate application archive
* directory.
*
* @param appName application name
* @return application descriptor
* @throws org.onosproject.app.ApplicationException if unable to read application description
*/
public ApplicationDescription getApplicationDescription(String appName) {
try {
return loadAppDescription(new XMLConfiguration(appFile(appName, APP_XML)));
} catch (Exception e) {
throw new ApplicationException("Unable to get app description", e);
}
}
/**
* Loads the application descriptor from the specified application archive
* stream and saves the stream in the appropriate application archive
* directory.
*
* @param stream application archive stream
* @return application descriptor
* @throws org.onosproject.app.ApplicationException if unable to read the
* archive stream or store
* the application archive
*/
public ApplicationDescription saveApplication(InputStream stream) {
try (InputStream ais = stream) {
byte[] cache = toByteArray(ais);
InputStream bis = new ByteArrayInputStream(cache);
ApplicationDescription desc = parseAppDescription(bis);
bis.reset();
expandApplication(bis, desc);
bis.reset();
saveApplication(bis, desc);
installArtifacts(desc);
return desc;
} catch (IOException e) {
throw new ApplicationException("Unable to save application", e);
}
}
/**
* Purges the application archive directory.
*
* @param appName application name
*/
public void purgeApplication(String appName) {
try {
Tools.removeDirectory(new File(appsDir, appName));
} catch (IOException e) {
throw new ApplicationException("Unable to purge application " + appName, e);
}
}
/**
* Returns application archive stream for the specified application.
*
* @param appName application name
* @return application archive stream
*/
public InputStream getApplicationInputStream(String appName) {
try {
return new FileInputStream(appFile(appName, appName + ".zip"));
} catch (FileNotFoundException e) {
throw new ApplicationException("Application " + appName + " not found");
}
}
// Scans the specified ZIP stream for app.xml entry and parses it producing
// an application descriptor.
private ApplicationDescription parseAppDescription(InputStream stream)
throws IOException {
try (ZipInputStream zis = new ZipInputStream(stream)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().equals(APP_XML)) {
byte[] data = new byte[(int) entry.getSize()];
ByteStreams.readFully(zis, data);
XMLConfiguration cfg = new XMLConfiguration();
try {
cfg.load(new ByteArrayInputStream(data));
return loadAppDescription(cfg);
} catch (ConfigurationException e) {
throw new IOException("Unable to parse " + APP_XML, e);
}
}
zis.closeEntry();
}
}
throw new IOException("Unable to locate " + APP_XML);
}
private ApplicationDescription loadAppDescription(XMLConfiguration cfg) {
cfg.setAttributeSplittingDisabled(true);
String name = cfg.getString(NAME);
Version version = Version.version(cfg.getString(VERSION));
String desc = cfg.getString(DESCRIPTION);
String origin = cfg.getString(ORIGIN);
Set<Permission> perms = ImmutableSet.of();
String featRepo = cfg.getString(FEATURES_REPO);
URI featuresRepo = featRepo != null ? URI.create(featRepo) : null;
Set<String> features = ImmutableSet.copyOf(cfg.getString(FEATURES).split(","));
return new DefaultApplicationDescription(name, version, desc, origin,
perms, featuresRepo, features);
}
// Expands the specified ZIP stream into app-specific directory.
private void expandApplication(InputStream stream, ApplicationDescription desc)
throws IOException {
ZipInputStream zis = new ZipInputStream(stream);
ZipEntry entry;
File appDir = new File(appsDir, desc.name());
while ((entry = zis.getNextEntry()) != null) {
byte[] data = new byte[(int) entry.getSize()];
ByteStreams.readFully(zis, data);
zis.closeEntry();
File file = new File(appDir, entry.getName());
createParentDirs(file);
write(data, file);
}
zis.close();
}
// Saves the specified ZIP stream into a file under app-specific directory.
private void saveApplication(InputStream stream, ApplicationDescription desc)
throws IOException {
Files.write(toByteArray(stream), appFile(desc.name(), desc.name() + ".zip"));
}
// Installs application artifacts into M2 repository.
private void installArtifacts(ApplicationDescription desc) {
// FIXME: implement M2 repository copy
}
protected boolean setActive(String appName) {
try {
return appFile(appName, "active").createNewFile();
} catch (IOException e) {
throw new ApplicationException("Unable to mark app as active", e);
}
}
protected boolean clearActive(String appName) {
return appFile(appName, "active").delete();
}
protected boolean isActive(String appName) {
return appFile(appName, "active").exists();
}
// Returns the name of the file located under the specified app directory.
private File appFile(String appName, String fileName) {
return new File(new File(appsDir, appName), fileName);
}
}
/*
* Copyright 2014 Open Networking Laboratory
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -13,10 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.json.impl;
/**
* Created by tom on 10/16/14.
* Common facilities for construction of application management subsystem.
*/
public class DeleteMe {
}
package org.onosproject.common.app;
\ No newline at end of file
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.common.app;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.app.ApplicationDescription;
import org.onosproject.app.ApplicationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
public class ApplicationArchiveTest {
static final String ROOT = "/tmp/app-junit";
private ApplicationArchive aar = new ApplicationArchive();
@Before
public void setUp() {
aar.setAppsRoot(ROOT);
}
private void validate(ApplicationDescription app) {
assertEquals("incorrect name", APP_NAME, app.name());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect origin", ORIGIN, app.origin());
assertEquals("incorrect description", DESC, app.description());
assertEquals("incorrect features URI", FURL, app.featuresRepo().get());
assertEquals("incorrect permissions", PERMS, app.permissions());
assertEquals("incorrect features", FEATURES, app.features());
}
@Test
public void saveApp() throws IOException {
InputStream stream = getClass().getResourceAsStream("app.zip");
ApplicationDescription app = aar.saveApplication(stream);
validate(app);
}
@Test
public void loadApp() throws IOException {
saveApp();
ApplicationDescription app = aar.getApplicationDescription(APP_NAME);
validate(app);
}
@Test
public void getAppNames() throws IOException {
saveApp();
Set<String> names = aar.getApplicationNames();
assertEquals("incorrect names", ImmutableSet.of(APP_NAME), names);
}
@Test
public void purgeApp() throws IOException {
saveApp();
aar.purgeApplication(APP_NAME);
assertEquals("incorrect names", ImmutableSet.of(), aar.getApplicationNames());
}
@Test
public void getAppStream() throws IOException {
saveApp();
InputStream stream = aar.getApplicationInputStream(APP_NAME);
byte[] orig = ByteStreams.toByteArray(getClass().getResourceAsStream("app.zip"));
byte[] loaded = ByteStreams.toByteArray(stream);
assertArrayEquals("incorrect stream", orig, loaded);
}
@Test(expected = ApplicationException.class)
public void getBadAppDesc() throws IOException {
aar.getApplicationDescription("org.foo.BAD");
}
@Test(expected = ApplicationException.class)
public void getBadAppStream() throws IOException {
aar.getApplicationInputStream("org.foo.BAD");
}
}
\ No newline at end of file
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<app name="org.foo.app" origin="Circus" version="1.2.a"
featuresRepo="mvn:org.foo-features/1.2a/xml/features"
features="foo,bar">
<description>Awesome application from Circus, Inc.</description>
</app>
......@@ -52,6 +52,14 @@
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
......@@ -66,6 +74,12 @@
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>org.apache.karaf.features.core</artifactId>
<version>3.0.2</version>
</dependency>
</dependencies>
<build>
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.impl;
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;
import org.apache.felix.scr.annotations.Service;
import org.apache.karaf.features.FeaturesService;
import org.onosproject.app.ApplicationAdminService;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationListener;
import org.onosproject.app.ApplicationService;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStore;
import org.onosproject.app.ApplicationStoreDelegate;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.Permission;
import org.onosproject.event.AbstractListenerRegistry;
import org.onosproject.event.EventDeliveryService;
import org.slf4j.Logger;
import java.io.InputStream;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of the application management service.
*/
@Component(immediate = true)
@Service
public class ApplicationManager implements ApplicationService, ApplicationAdminService {
private final Logger log = getLogger(getClass());
private static final String APP_ID_NULL = "Application ID cannot be null";
protected final AbstractListenerRegistry<ApplicationEvent, ApplicationListener>
listenerRegistry = new AbstractListenerRegistry<>();
private final ApplicationStoreDelegate delegate = new InternalStoreDelegate();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ApplicationStore store;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FeaturesService featuresService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EventDeliveryService eventDispatcher;
@Activate
public void activate() {
store.setDelegate(delegate);
eventDispatcher.addSink(ApplicationEvent.class, listenerRegistry);
log.info("Started");
}
@Deactivate
public void deactivate() {
store.unsetDelegate(delegate);
eventDispatcher.removeSink(ApplicationEvent.class);
log.info("Stopped");
}
@Override
public Set<Application> getApplications() {
return store.getApplications();
}
@Override
public ApplicationId getId(String name) {
checkNotNull(name, "Name cannot be null");
return store.getId(name);
}
@Override
public Application getApplication(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
return store.getApplication(appId);
}
@Override
public ApplicationState getState(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
return store.getState(appId);
}
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
return store.getPermissions(appId);
}
@Override
public Application install(InputStream appDescStream) {
checkNotNull(appDescStream, "Application archive stream cannot be null");
return store.create(appDescStream);
}
@Override
public void uninstall(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
try {
store.remove(appId);
} catch (Exception e) {
log.warn("Unable to purge application directory for {}", appId.name());
}
}
@Override
public void activate(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
store.activate(appId);
}
@Override
public void deactivate(ApplicationId appId) {
checkNotNull(appId, APP_ID_NULL);
store.deactivate(appId);
}
@Override
public void setPermissions(ApplicationId appId, Set<Permission> permissions) {
checkNotNull(appId, APP_ID_NULL);
checkNotNull(permissions, "Permissions cannot be null");
store.setPermissions(appId, permissions);
}
@Override
public void addListener(ApplicationListener listener) {
listenerRegistry.addListener(listener);
}
@Override
public void removeListener(ApplicationListener listener) {
listenerRegistry.removeListener(listener);
}
private class InternalStoreDelegate implements ApplicationStoreDelegate {
@Override
public void notify(ApplicationEvent event) {
ApplicationEvent.Type type = event.type();
Application app = event.subject();
try {
if (type == APP_ACTIVATED) {
installAppFeatures(app);
log.info("Application {} has been activated", app.id().name());
} else if (type == APP_DEACTIVATED) {
uninstallAppFeatures(app);
log.info("Application {} has been deactivated", app.id().name());
} else if (type == APP_INSTALLED) {
installAppArtifacts(app);
log.info("Application {} has been installed", app.id().name());
} else if (type == APP_UNINSTALLED) {
uninstallAppFeatures(app);
uninstallAppArtifacts(app);
log.info("Application {} has been uninstalled", app.id().name());
}
eventDispatcher.post(event);
} catch (Exception e) {
log.warn("Unable to perform operation on application " + app.id().name(), e);
}
}
}
private void installAppArtifacts(Application app) throws Exception {
if (app.featuresRepo().isPresent()) {
featuresService.addRepository(app.featuresRepo().get());
}
}
private void uninstallAppArtifacts(Application app) throws Exception {
if (app.featuresRepo().isPresent()) {
featuresService.removeRepository(app.featuresRepo().get());
}
}
private void installAppFeatures(Application app) throws Exception {
for (String name : app.features()) {
featuresService.installFeature(name);
}
}
private void uninstallAppFeatures(Application app) throws Exception {
for (String name : app.features()) {
featuresService.uninstallFeature(name);
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 managing applications.
*/
package org.onosproject.app.impl;
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.app.impl;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationListener;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStoreAdapter;
import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.impl.TestEventDispatcher;
import java.io.InputStream;
import java.net.URI;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
/**
* Test of the application manager implementation.
*/
public class ApplicationManagerTest {
public static final DefaultApplicationId APP_ID = new DefaultApplicationId(1, APP_NAME);
private ApplicationManager mgr = new ApplicationManager();
private ApplicationListener listener = new TestListener();
@Before
public void setUp() {
mgr.eventDispatcher = new TestEventDispatcher();
mgr.featuresService = new TestFeaturesService();
mgr.store = new TestStore();
mgr.activate();
mgr.addListener(listener);
}
@After
public void tearDown() {
mgr.removeListener(listener);
mgr.deactivate();
}
private void validate(Application app) {
assertEquals("incorrect name", APP_NAME, app.id().name());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect origin", ORIGIN, app.origin());
assertEquals("incorrect description", DESC, app.description());
assertEquals("incorrect features URI", FURL, app.featuresRepo().get());
assertEquals("incorrect features", FEATURES, app.features());
}
@Test
public void install() {
InputStream stream = ApplicationArchive.class.getResourceAsStream("app.zip");
Application app = mgr.install(stream);
validate(app);
assertEquals("incorrect features URI used", app.featuresRepo().get(),
((TestFeaturesService) mgr.featuresService).uri);
assertEquals("incorrect app count", 1, mgr.getApplications().size());
assertEquals("incorrect app", app, mgr.getApplication(APP_ID));
assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
}
@Test
public void uninstall() {
install();
mgr.uninstall(APP_ID);
assertEquals("incorrect app count", 0, mgr.getApplications().size());
}
@Test
public void activate() {
install();
mgr.activate(APP_ID);
assertEquals("incorrect app state", ACTIVE, mgr.getState(APP_ID));
}
@Test
public void deactivate() {
activate();
mgr.deactivate(APP_ID);
assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
}
private class TestListener implements ApplicationListener {
private ApplicationEvent event;
@Override
public void event(ApplicationEvent event) {
this.event = event;
}
}
private class TestStore extends ApplicationStoreAdapter {
private Application app;
private ApplicationState state;
@Override
public Application create(InputStream appDescStream) {
app = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, PERMS,
Optional.of(FURL), FEATURES);
state = INSTALLED;
delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
return app;
}
@Override
public Set<Application> getApplications() {
return app != null ? ImmutableSet.of(app) : ImmutableSet.of();
}
@Override
public Application getApplication(ApplicationId appId) {
return app;
}
@Override
public void remove(ApplicationId appId) {
delegate.notify(new ApplicationEvent(APP_UNINSTALLED, app));
app = null;
state = null;
}
@Override
public ApplicationState getState(ApplicationId appId) {
return state;
}
@Override
public void activate(ApplicationId appId) {
state = ApplicationState.ACTIVE;
delegate.notify(new ApplicationEvent(APP_ACTIVATED, app));
}
@Override
public void deactivate(ApplicationId appId) {
state = INSTALLED;
delegate.notify(new ApplicationEvent(APP_DEACTIVATED, app));
}
}
private class TestFeaturesService extends FeaturesServiceAdapter {
private URI uri;
private Set<String> features = new HashSet<>();
@Override
public void addRepository(URI uri) throws Exception {
this.uri = uri;
}
@Override
public void removeRepository(URI uri) throws Exception {
this.uri = null;
}
@Override
public void installFeature(String name) throws Exception {
features.add(name);
}
@Override
public void uninstallFeature(String name) throws Exception {
features.remove(name);
}
}
}
\ No newline at end of file
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.app.impl;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.Repository;
import java.net.URI;
import java.util.EnumSet;
import java.util.Set;
/**
* Adapter for testing against Apache Karaf feature service.
*/
public class FeaturesServiceAdapter implements org.apache.karaf.features.FeaturesService {
@Override
public void validateRepository(URI uri) throws Exception {
}
@Override
public void addRepository(URI uri) throws Exception {
}
@Override
public void addRepository(URI uri, boolean install) throws Exception {
}
@Override
public void removeRepository(URI uri) throws Exception {
}
@Override
public void removeRepository(URI uri, boolean uninstall) throws Exception {
}
@Override
public void restoreRepository(URI uri) throws Exception {
}
@Override
public Repository[] listRepositories() {
return new Repository[0];
}
@Override
public Repository getRepository(String repoName) {
return null;
}
@Override
public void installFeature(String name) throws Exception {
}
@Override
public void installFeature(String name, EnumSet<Option> options) throws Exception {
}
@Override
public void installFeature(String name, String version) throws Exception {
}
@Override
public void installFeature(String name, String version, EnumSet<Option> options) throws Exception {
}
@Override
public void installFeature(Feature f, EnumSet<Option> options) throws Exception {
}
@Override
public void installFeatures(Set<Feature> features, EnumSet<Option> options) throws Exception {
}
@Override
public void uninstallFeature(String name, EnumSet<Option> options) throws Exception {
}
@Override
public void uninstallFeature(String name) throws Exception {
}
@Override
public void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception {
}
@Override
public void uninstallFeature(String name, String version) throws Exception {
}
@Override
public Feature[] listFeatures() throws Exception {
return new Feature[0];
}
@Override
public Feature[] listInstalledFeatures() {
return new Feature[0];
}
@Override
public boolean isInstalled(Feature f) {
return false;
}
@Override
public Feature getFeature(String name, String version) throws Exception {
return null;
}
@Override
public Feature getFeature(String name) throws Exception {
return null;
}
@Override
public void refreshRepository(URI uri) throws Exception {
}
}
......@@ -110,7 +110,7 @@ public class FlowRuleManagerTest {
mgr.addListener(listener);
provider = new TestProvider(PID);
providerService = registry.register(provider);
appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
appId = new TestApplicationId(0, "FlowRuleManagerTest");
assertTrue("provider should be registered",
registry.getProviders().contains(provider.id()));
}
......@@ -639,8 +639,7 @@ public class FlowRuleManagerTest {
}
public class TestApplicationId extends DefaultApplicationId {
public TestApplicationId(short id, String name) {
public TestApplicationId(int id, String name) {
super(id, name);
}
}
......
......@@ -33,9 +33,9 @@
<modules>
<module>api</module>
<module>common</module>
<module>net</module>
<module>store</module>
<module>json</module>
</modules>
<dependencies>
......
......@@ -103,6 +103,11 @@ public class DistributedApplicationIdStore
return appId;
}
@Override
public ApplicationId getAppId(String name) {
return appIdsByName.get(name);
}
private void primeAppIds() {
for (DefaultApplicationId appId : appIdsByName.values()) {
appIds.put(appId.id(), appId);
......@@ -113,7 +118,7 @@ public class DistributedApplicationIdStore
public ApplicationId registerApplication(String name) {
DefaultApplicationId appId = appIdsByName.get(name);
if (appId == null) {
short id = (short) lastAppId.getAndIncrement();
int id = (int) lastAppId.getAndIncrement();
appId = putIfAbsent(appIdsByName, name,
new DefaultApplicationId(id, name));
}
......
......@@ -44,6 +44,14 @@
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
</dependency>
......
......@@ -39,6 +39,11 @@
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
......
......@@ -51,6 +51,11 @@ public class SimpleApplicationIdStore implements ApplicationIdStore {
}
@Override
public ApplicationId getAppId(String name) {
return appIdsByName.get(name);
}
@Override
public ApplicationId registerApplication(String name) {
DefaultApplicationId appId = appIdsByName.get(name);
if (appId == null) {
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.store.trivial.impl;
import com.google.common.collect.ImmutableSet;
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;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.app.ApplicationDescription;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStore;
import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.Permission;
import org.slf4j.Logger;
import java.io.InputStream;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Manages inventory of network control applications.
*/
@Component(immediate = true)
@Service
public class SimpleApplicationStore extends ApplicationArchive implements ApplicationStore {
private final Logger log = getLogger(getClass());
// App inventory & states
private final ConcurrentMap<ApplicationId, DefaultApplication> apps = new ConcurrentHashMap<>();
private final ConcurrentMap<ApplicationId, ApplicationState> states = new ConcurrentHashMap<>();
private final ConcurrentMap<ApplicationId, Set<Permission>> permissions = new ConcurrentHashMap<>();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ApplicationIdStore idStore;
@Activate
public void activate() {
loadFromDisk();
log.info("Started");
}
private void loadFromDisk() {
for (String name : getApplicationNames()) {
ApplicationId appId = idStore.registerApplication(name);
ApplicationDescription appDesc = getApplicationDescription(name);
DefaultApplication app =
new DefaultApplication(appId, appDesc.version(),
appDesc.description(), appDesc.origin(),
appDesc.permissions(),
appDesc.featuresRepo(), appDesc.features());
apps.put(appId, app);
states.put(appId, isActive(name) ? INSTALLED : ACTIVE);
// load app permissions
}
}
@Deactivate
public void deactivate() {
apps.clear();
states.clear();
permissions.clear();
log.info("Stopped");
}
@Override
public Set<Application> getApplications() {
return ImmutableSet.copyOf(apps.values());
}
@Override
public ApplicationId getId(String name) {
return idStore.getAppId(name);
}
@Override
public Application getApplication(ApplicationId appId) {
return apps.get(appId);
}
@Override
public ApplicationState getState(ApplicationId appId) {
return states.get(appId);
}
@Override
public Application create(InputStream appDescStream) {
ApplicationDescription appDesc = saveApplication(appDescStream);
ApplicationId appId = idStore.registerApplication(appDesc.name());
DefaultApplication app =
new DefaultApplication(appId, appDesc.version(), appDesc.description(),
appDesc.origin(), appDesc.permissions(),
appDesc.featuresRepo(), appDesc.features());
apps.put(appId, app);
states.put(appId, INSTALLED);
delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
return app;
}
@Override
public void remove(ApplicationId appId) {
Application app = apps.remove(appId);
if (app != null) {
states.remove(appId);
delegate.notify(new ApplicationEvent(APP_UNINSTALLED, app));
purgeApplication(app.id().name());
}
}
@Override
public void activate(ApplicationId appId) {
Application app = apps.get(appId);
if (app != null) {
setActive(appId.name());
states.put(appId, ACTIVE);
delegate.notify(new ApplicationEvent(APP_ACTIVATED, app));
}
}
@Override
public void deactivate(ApplicationId appId) {
Application app = apps.get(appId);
if (app != null) {
clearActive(appId.name());
states.put(appId, INSTALLED);
delegate.notify(new ApplicationEvent(APP_DEACTIVATED, app));
}
}
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
return permissions.get(appId);
}
@Override
public void setPermissions(ApplicationId appId, Set<Permission> permissions) {
Application app = getApplication(appId);
if (app != null) {
this.permissions.put(appId, permissions);
delegate.notify(new ApplicationEvent(APP_PERMISSIONS_CHANGED, app));
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.trivial.impl;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.app.ApplicationEvent;
import org.onosproject.app.ApplicationStoreDelegate;
import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStoreAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.core.Permission;
import static org.junit.Assert.assertEquals;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
/**
* Test of the trivial application store implementation.
*/
public class SimpleApplicationStoreTest {
private SimpleApplicationStore store = new SimpleApplicationStore();
private TestDelegate delegate = new TestDelegate();
@Before
public void setUp() {
store.idStore = new TestIdStore();
store.setDelegate(delegate);
store.activate();
}
@After
public void tearDown() {
store.deactivate();
}
private Application createTestApp() {
return store.create(ApplicationArchive.class.getResourceAsStream("app.zip"));
}
@Test
public void create() {
Application app = createTestApp();
assertEquals("incorrect name", "org.foo.app", app.id().name());
assertEquals("incorrect app count", 1, store.getApplications().size());
assertEquals("incorrect app", app, store.getApplication(app.id()));
assertEquals("incorrect app state", INSTALLED, store.getState(app.id()));
assertEquals("incorrect event type", APP_INSTALLED, delegate.event.type());
assertEquals("incorrect event app", app, delegate.event.subject());
}
@Test
public void remove() {
Application app = createTestApp();
store.remove(app.id());
assertEquals("incorrect app count", 0, store.getApplications().size());
assertEquals("incorrect event type", APP_UNINSTALLED, delegate.event.type());
assertEquals("incorrect event app", app, delegate.event.subject());
}
@Test
public void activate() {
Application app = createTestApp();
store.activate(app.id());
assertEquals("incorrect app count", 1, store.getApplications().size());
assertEquals("incorrect app state", ACTIVE, store.getState(app.id()));
assertEquals("incorrect event type", APP_ACTIVATED, delegate.event.type());
assertEquals("incorrect event app", app, delegate.event.subject());
}
@Test
public void deactivate() {
Application app = createTestApp();
store.deactivate(app.id());
assertEquals("incorrect app count", 1, store.getApplications().size());
assertEquals("incorrect app state", INSTALLED, store.getState(app.id()));
assertEquals("incorrect event type", APP_DEACTIVATED, delegate.event.type());
assertEquals("incorrect event app", app, delegate.event.subject());
}
@Test
public void permissions() {
Application app = createTestApp();
ImmutableSet<Permission> permissions = ImmutableSet.of(new Permission() {
});
store.setPermissions(app.id(), permissions);
assertEquals("incorrect app perms", 1, store.getPermissions(app.id()).size());
assertEquals("incorrect app state", INSTALLED, store.getState(app.id()));
assertEquals("incorrect event type", APP_PERMISSIONS_CHANGED, delegate.event.type());
assertEquals("incorrect event app", app, delegate.event.subject());
}
private class TestIdStore extends ApplicationIdStoreAdapter {
@Override
public ApplicationId registerApplication(String name) {
return new DefaultApplicationId(1, name);
}
@Override
public ApplicationId getAppId(String name) {
return new DefaultApplicationId(1, name);
}
}
private class TestDelegate implements ApplicationStoreDelegate {
private ApplicationEvent event;
@Override
public void notify(ApplicationEvent event) {
this.event = event;
}
}
}
\ No newline at end of file
......@@ -49,7 +49,7 @@
<version>2.10.1</version>
<configuration>
<show>package</show>
<excludePackageNames>org.onlab.thirdparty:*.impl:*.impl.*:org.onosproject.provider.*:org.onosproject.gui:org.onosproject.rest:org.onosproject.cli*:org.onosproject.tvue:org.onosproject.foo:org.onosproject.mobility:org.onosproject.proxyarp:org.onosproject.fwd:org.onosproject.ifwd:org.onosproject.optical:org.onosproject.config:org.onosproject.calendar:org.onosproject.sdnip*:org.onosproject.oecfg:org.onosproject.metrics:org.onosproject.store.*:org.onosproject.openflow.*</excludePackageNames>
<excludePackageNames>org.onlab.thirdparty:*.impl:*.impl.*:org.onosproject.provider.*:org.onosproject.gui:org.onosproject.rest:org.onosproject.cli*:org.onosproject.tvue:org.onosproject.foo:org.onosproject.mobility:org.onosproject.proxyarp:org.onosproject.fwd:org.onosproject.ifwd:org.onosproject.optical:org.onosproject.config:org.onosproject.calendar:org.onosproject.sdnip*:org.onosproject.oecfg:org.onosproject.metrics:org.onosproject.store.*:org.onosproject.openflow.*:org.onosproject.common.*</excludePackageNames>
<docfilessubdirs>true</docfilessubdirs>
<doctitle>ONOS Java API</doctitle>
<groups>
......
......@@ -61,7 +61,7 @@
<group>
<title>Core Subsystems</title>
<packages>
org.onosproject.impl:org.onosproject.core.impl:org.onosproject.cluster.impl:org.onosproject.net.device.impl:org.onosproject.net.link.impl:org.onosproject.net.host.impl:org.onosproject.net.topology.impl:org.onosproject.net.packet.impl:org.onosproject.net.flow.impl:org.onosproject.net.*.impl:org.onosproject.event.impl:org.onosproject.net.intent.impl:org.onosproject.net.proxyarp.impl:org.onosproject.mastership.impl:org.onosproject.net.resource.impl:org.onosproject.json:org.onosproject.json.*:org.onosproject.provider.host.impl:org.onosproject.provider.lldp.impl:org.onosproject.net.statistic.impl
org.onosproject.impl:org.onosproject.core.impl:org.onosproject.cluster.impl:org.onosproject.net.device.impl:org.onosproject.net.link.impl:org.onosproject.net.host.impl:org.onosproject.net.topology.impl:org.onosproject.net.packet.impl:org.onosproject.net.flow.impl:org.onosproject.net.*.impl:org.onosproject.event.impl:org.onosproject.net.intent.impl:org.onosproject.net.proxyarp.impl:org.onosproject.mastership.impl:org.onosproject.net.resource.impl:org.onosproject.json:org.onosproject.json.*:org.onosproject.provider.host.impl:org.onosproject.provider.lldp.impl:org.onosproject.net.statistic.impl:org.onosproject.app.impl:org.onosproject.common.*
</packages>
</group>
<group>
......
......@@ -22,6 +22,7 @@
description="ONOS 3rd party dependencies">
<bundle>mvn:commons-lang/commons-lang/2.6</bundle>
<bundle>mvn:org.apache.commons/commons-lang3/3.3.2</bundle>
<bundle>mvn:commons-configuration/commons-configuration/1.10</bundle>
<bundle>mvn:com.google.guava/guava/18.0</bundle>
<bundle>mvn:io.netty/netty/3.9.2.Final</bundle>
<bundle>mvn:io.netty/netty-common/4.0.23.Final</bundle>
......@@ -86,6 +87,7 @@
description="ONOS core components">
<feature>onos-api</feature>
<bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onos-core-dist/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onos-core-serializers/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onlab-netty/@ONOS-VERSION</bundle>
......@@ -95,6 +97,7 @@
description="ONOS core components">
<feature>onos-api</feature>
<bundle>mvn:org.onosproject/onos-core-net/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onos-core-common/@ONOS-VERSION</bundle>
<bundle>mvn:org.onosproject/onos-core-trivial/@ONOS-VERSION</bundle>
</feature>
......
......@@ -161,6 +161,12 @@
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
......@@ -315,6 +321,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-core-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-of-api</artifactId>
......
......@@ -133,8 +133,8 @@ public class HostLocationProviderTest {
private CoreService coreService;
private TestHostProviderService providerService;
private ApplicationId appId = new DefaultApplicationId((short) 100,
"org.onosproject.provider.host");
private ApplicationId appId =
new DefaultApplicationId(100, "org.onosproject.provider.host");
@Before
public void setUp() {
......
......@@ -97,8 +97,8 @@ public class LLDPLinkProviderTest {
private PacketProcessor testProcessor;
private DeviceListener deviceListener;
private ApplicationId appId = new DefaultApplicationId((short) 100,
"org.onosproject.provider.lldp");
private ApplicationId appId =
new DefaultApplicationId(100, "org.onosproject.provider.lldp");
@Before
public void setUp() {
......
#!/bin/bash
# -----------------------------------------------------------------------------
# Tool to manage ONOS applications using REST API.
# -----------------------------------------------------------------------------
node=${1:-$OCI}
cmd=${2:-list}
app=${3}
export URL=http://$node:8181/onos/v1/applications
export HDR="-HContent-Type:application/octet-stream"
export curl="curl -sS"
case $cmd in
list) $curl -X GET $URL;;
install) $curl -X POST $HDR $URL --data-binary @$app;;
uninstall) $curl -X DELETE $URL/$app;;
activate) $curl -X POST $URL/$app/active;;
deactivate) $curl -X DELETE $URL/$app/active;;
esac
This diff is collapsed. Click to expand it.
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onlab.junit;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
/**
* Base for exception tests.
*/
public abstract class ExceptionTest {
protected static final Throwable CAUSE = new RuntimeException("boom");
protected static final String MESSAGE = "Uh oh.... boom";
protected abstract Exception getDefault();
protected abstract Exception getWithMessage();
protected abstract Exception getWithMessageAndCause();
@Test
public void noMessageNoCause() {
Exception e = getDefault();
assertEquals("incorrect message", null, e.getMessage());
assertEquals("incorrect cause", null, e.getCause());
}
@Test
public void withMessage() {
Exception e = getWithMessage();
assertEquals("incorrect message", MESSAGE, e.getMessage());
assertEquals("incorrect cause", null, e.getCause());
}
@Test
public void withCause() {
Exception e = getWithMessageAndCause();
assertEquals("incorrect message", MESSAGE, e.getMessage());
assertSame("incorrect cause", CAUSE, e.getCause());
}
}
......@@ -15,6 +15,14 @@
*/
package org.onlab.junit;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Random;
import static com.google.common.base.Preconditions.checkArgument;
import static org.junit.Assert.fail;
......@@ -23,6 +31,8 @@ import static org.junit.Assert.fail;
*/
public final class TestTools {
private static final Random RANDOM = new Random();
// Prohibit construction
private TestTools() {
}
......@@ -109,4 +119,92 @@ public final class TestTools {
assertAfter(0, duration, assertions);
}
/**
* Creates a directory tree of test files. To signify creating a directory
* file path should end with '/'.
*
* @param paths list of file paths
* @return list of created files
* @throws java.io.IOException if there is an issue
*/
public static List<File> createTestFiles(List<String> paths) throws IOException {
return createTestFiles(paths, 32, 1024);
}
/**
* Creates a directory tree of test files. To signify creating a directory
* file path should end with '/'.
*
* @param paths list of file paths
* @param minSize minimum file size in bytes
* @param maxSize maximum file size in bytes
* @return list of created files
* @throws java.io.IOException if there is an issue
*/
public static List<File> createTestFiles(List<String> paths,
int minSize, int maxSize) throws IOException {
ImmutableList.Builder<File> files = ImmutableList.builder();
for (String p : paths) {
File f = new File(p);
if (p.endsWith("/")) {
if (f.mkdirs()) {
files.add(f);
}
} else {
Files.createParentDirs(f);
if (f.createNewFile()) {
writeRandomFile(f, minSize, maxSize);
files.add(f);
}
}
}
return files.build();
}
/**
* Writes random binary content into the specified file. The number of
* bytes will be random between the given minimum and maximum.
*
* @param file file to write data to
* @param minSize minimum number of bytes to write
* @param maxSize maximum number of bytes to write
* @throws IOException if there is an issue
*/
public static void writeRandomFile(File file, int minSize, int maxSize) throws IOException {
int size = minSize + (minSize == maxSize ? 0 : RANDOM.nextInt(maxSize - minSize));
byte[] data = new byte[size];
tweakBytes(RANDOM, data, size / 4);
Files.write(data, file);
}
/**
* Tweaks the given number of bytes in a byte array.
*
* @param random random number generator
* @param data byte array to be tweaked
* @param count number of bytes to tweak
*/
public static void tweakBytes(Random random, byte[] data, int count) {
tweakBytes(random, data, count, 0, data.length);
}
/**
* Tweaks the given number of bytes in the specified range of a byte array.
*
* @param random random number generator
* @param data byte array to be tweaked
* @param count number of bytes to tweak
* @param start index at beginning of range (inclusive)
* @param end index at end of range (exclusive)
*/
public static void tweakBytes(Random random, byte[] data, int count,
int start, int end) {
int len = end - start;
for (int i = 0; i < count; i++) {
data[start + random.nextInt(len)] = (byte) random.nextInt();
}
}
}
......
......@@ -15,6 +15,8 @@
*/
package org.onlab.util;
import static java.nio.file.Files.delete;
import static java.nio.file.Files.walkFileTree;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.BufferedReader;
......@@ -24,6 +26,11 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.Thread.UncaughtExceptionHandler;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadFactory;
......@@ -39,7 +46,7 @@ public abstract class Tools {
private Tools() {
}
private static final Logger TOOLS_LOG = getLogger(Tools.class);
private static final Logger log = getLogger(Tools.class);
/**
* Returns a thread factory that produces threads named according to the
......@@ -56,7 +63,7 @@ public abstract class Tools {
@Override
public void uncaughtException(Thread t, Throwable e) {
TOOLS_LOG.error("Uncaught exception on {}", t.getName(), e);
log.error("Uncaught exception on {}", t.getName(), e);
}
}).build();
}
......@@ -141,4 +148,56 @@ public abstract class Tools {
}
}
/**
* Purges the specified directory path.&nbsp;Use with great caution since
* no attempt is made to check for symbolic links, which could result in
* deletion of unintended files.
*
* @param path directory to be removed
* @throws java.io.IOException if unable to remove contents
*/
public static void removeDirectory(String path) throws IOException {
walkFileTree(Paths.get(path), new DirectoryDeleter());
}
/**
* Purges the specified directory path.&nbsp;Use with great caution since
* no attempt is made to check for symbolic links, which could result in
* deletion of unintended files.
*
* @param dir directory to be removed
* @throws java.io.IOException if unable to remove contents
*/
public static void removeDirectory(File dir) throws IOException {
walkFileTree(Paths.get(dir.getAbsolutePath()), new DirectoryDeleter());
}
private static class DirectoryDeleter extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes)
throws IOException {
if (attributes.isRegularFile()) {
delete(file);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path directory, IOException ioe)
throws IOException {
delete(directory);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException ioe)
throws IOException {
log.warn("Unable to delete file {}", file);
log.warn("Boom", ioe);
return FileVisitResult.CONTINUE;
}
}
}
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.impl;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.app.ApplicationService;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.Application;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Application JSON codec.
*/
public class ApplicationCodec extends JsonCodec<Application> {
@Override
public ObjectNode encode(Application app, CodecContext context) {
checkNotNull(app, "Application cannot be null");
ApplicationService service = context.get(ApplicationService.class);
ObjectNode result = context.mapper().createObjectNode()
.put("name", app.id().name())
.put("id", app.id().id())
.put("version", app.version().toString())
.put("description", app.description())
.put("origin", app.origin())
.put("permissions", app.permissions().toString())
.put("featuresRepo", app.featuresRepo().isPresent() ?
app.featuresRepo().toString() : "")
.put("features", app.features().toString())
.put("state", service.getState(app.id()).toString());
return result;
}
}
......@@ -26,6 +26,7 @@ import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.JsonCodec;
import org.onosproject.core.Application;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
......@@ -64,6 +65,7 @@ public class CodecManager implements CodecService {
@Activate
public void activate() {
codecs.clear();
registerCodec(Application.class, new ApplicationCodec());
registerCodec(Annotations.class, new AnnotationsCodec());
registerCodec(Device.class, new DeviceCodec());
registerCodec(Port.class, new PortCodec());
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS 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.onosproject.app.ApplicationAdminService;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.Set;
/**
* REST resource for interacting with the inventory of applications.
*/
@Path("applications")
public class ApplicationsWebResource extends AbstractWebResource {
@GET
public Response getApplications() {
ApplicationAdminService service = get(ApplicationAdminService.class);
Set<Application> apps = service.getApplications();
return ok(encodeArray(Application.class, "applications", apps)).build();
}
@GET
@Path("{name}")
public Response getApplication(@PathParam("id") String name) {
ApplicationAdminService service = get(ApplicationAdminService.class);
ApplicationId appId = service.getId(name);
return response(service, appId);
}
@POST
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
@Produces(MediaType.APPLICATION_JSON)
public Response installApplication(InputStream stream) {
ApplicationAdminService service = get(ApplicationAdminService.class);
Application app = service.install(stream);
return ok(codec(Application.class).encode(app, this)).build();
}
@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Path("{name}")
public Response uninstallApplication(@PathParam("name") String name) {
ApplicationAdminService service = get(ApplicationAdminService.class);
ApplicationId appId = service.getId(name);
service.uninstall(appId);
return Response.ok().build();
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("{name}/active")
public Response activateApplication(@PathParam("name") String name) {
ApplicationAdminService service = get(ApplicationAdminService.class);
ApplicationId appId = service.getId(name);
service.activate(appId);
return response(service, appId);
}
@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Path("{name}/active")
public Response deactivateApplication(@PathParam("name") String name) {
ApplicationAdminService service = get(ApplicationAdminService.class);
ApplicationId appId = service.getId(name);
service.deactivate(appId);
return response(service, appId);
}
private Response response(ApplicationAdminService service, ApplicationId appId) {
Application app = service.getApplication(appId);
return ok(codec(Application.class).encode(app, this)).build();
}
}
......@@ -35,6 +35,7 @@
org.onosproject.rest.exceptions.ServerErrorMapper,
org.onosproject.rest.JsonBodyWriter,
org.onosproject.rest.ApplicationsWebResource,
org.onosproject.rest.DevicesWebResource,
org.onosproject.rest.LinksWebResource,
org.onosproject.rest.HostsWebResource,
......
......@@ -66,8 +66,7 @@ public class IntentCodecTest extends AbstractIntentTest {
private final HostId id1 = hid("12:34:56:78:91:ab/1");
private final HostId id2 = hid("12:34:56:78:92:ab/1");
private final ApplicationId appId =
new DefaultApplicationId((short) 3, "test");
private final ApplicationId appId = new DefaultApplicationId(3, "test");
final TrafficSelector emptySelector =
DefaultTrafficSelector.builder().build();
final TrafficTreatment emptyTreatment =
......
......@@ -62,8 +62,7 @@ import static org.junit.Assert.fail;
public class IntentsResourceTest extends ResourceTest {
final IntentService mockIntentService = createMock(IntentService.class);
final HashSet<Intent> intents = new HashSet<>();
private static final ApplicationId APP_ID =
new DefaultApplicationId((short) 1, "test");
private static final ApplicationId APP_ID = new DefaultApplicationId(1, "test");
private IdGenerator mockGenerator;
/**
......