HIGUCHI Yuta
Committed by Yuta HIGUCHI

ONOS-3322 Sketch of Remote Service

Change-Id: I9c16b56b8d02d7f3995eafb1bb96211089774ca7
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc;
import com.google.common.annotations.Beta;
// Implementation is expected to be a handler for RPC channel
// and shim-layer to convert Java Service interface calls to/from RPC call
/**
* Context for Remote service.
*/
@Beta
public interface RemoteServiceContext {
// we may need a method to check connection state?
/**
* Returns implementation of the specified service class.
*
* @param serviceClass service class
* @param <T> type of service
* @return implementation class
* @throws UnsupportedOperationException if this context does not support it.
*/
<T> T get(Class<T> serviceClass);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc;
import java.net.URI;
import org.onosproject.net.provider.Provider;
import com.google.common.annotations.Beta;
//Factory to create RemoteServiceContext
/**
* Abstraction of a remote service implementation provider.
*/
@Beta
public interface RemoteServiceContextProvider extends Provider {
/**
* Returns {@link RemoteServiceContext} for given URI.
*
* @param uri URI for remote end point.
* @return {@link RemoteServiceContext}
*/
RemoteServiceContext get(URI uri);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc;
import org.onosproject.net.provider.ProviderService;
import com.google.common.annotations.Beta;
// Not completely sure if we will make use of this at the moment
// added to follow existing {@link ProviderRegistry} pattern
@Beta
public interface RemoteServiceContextProviderService
extends ProviderService<RemoteServiceContextProvider> {
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc;
import java.net.URI;
import com.google.common.annotations.Beta;
// This is actually the RPC Service, where consumers get
// RemoteSericeContext (~= RPC Session) for given URI
// expected to be implemented by some Manager class on Lower-side ONOS
/**
* Service for retrieving RPC session handler ({@link RemoteServiceContext}).
*/
@Beta
public interface RemoteServiceDirectory {
/**
* Returns remote service context.
*
* @param uri URI representing remote end point. e.g., (grpc://hostname:port)
* @return remote service context
* @throws UnsupportedOperationException if URI scheme was not supported.
*/
RemoteServiceContext get(URI uri);
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc;
import org.onosproject.net.provider.ProviderRegistry;
import com.google.common.annotations.Beta;
/**
* Abstraction of a remote service provider registry.
*/
@Beta
public interface RemoteServiceProviderRegistry
extends ProviderRegistry<RemoteServiceContextProvider,
RemoteServiceContextProviderService> {
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Incubating inter-cluster RPC APIs.
*/
package org.onosproject.incubator.rpc;
......@@ -35,6 +35,7 @@
<module>api</module>
<module>net</module>
<module>store</module>
<module>rpc</module>
</modules>
<dependencies>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2015 Open Networking Laboratory
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>onos-incubator</artifactId>
<groupId>org.onosproject</groupId>
<version>1.4.0-SNAPSHOT</version>
</parent>
<artifactId>onos-incubator-rpc</artifactId>
<packaging>bundle</packaging>
<description>ONOS inter-cluster RPC service</description>
<url>http://onosproject.org</url>
<properties>
<onos.app.name>org.onosproject.incubator.rpc</onos.app.name>
</properties>
<dependencies>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onlab-osgi</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-incubator-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<executions>
<execution>
<id>generate-scr-srcdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
</configuration>
</plugin>
<plugin>
<groupId>org.onosproject</groupId>
<artifactId>onos-maven-plugin</artifactId>
<executions>
<execution>
<id>cfg</id>
<phase>generate-resources</phase>
<goals>
<goal>cfg</goal>
</goals>
</execution>
<execution>
<id>swagger</id>
<phase>generate-sources</phase>
<goals>
<goal>swagger</goal>
</goals>
</execution>
<execution>
<id>app</id>
<phase>package</phase>
<goals>
<goal>app</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc.impl;
import java.util.Map;
import java.util.Set;
import org.onosproject.incubator.rpc.RemoteServiceContextProvider;
import org.onosproject.incubator.rpc.RemoteServiceContextProviderService;
import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry;
import org.onosproject.net.provider.ProviderId;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
// Probably should change name or add missing feature (provider from scheme) to
// org.onosproject.net.provider.AbstractProviderRegistry<P, S>
@Beta
abstract class AbstractProviderRegistry
implements RemoteServiceProviderRegistry {
private final Map<ProviderId, RemoteServiceContextProvider> pidToProvider = Maps.newConcurrentMap();
private final Map<String, RemoteServiceContextProvider> schemeToProvider = Maps.newConcurrentMap();
public AbstractProviderRegistry() {
super();
}
protected abstract RemoteServiceContextProviderService createProviderService(RemoteServiceContextProvider provider);
@Override
public synchronized RemoteServiceContextProviderService register(RemoteServiceContextProvider provider) {
// TODO check if it already exists
pidToProvider.put(provider.id(), provider);
schemeToProvider.put(provider.id().scheme(), provider);
return createProviderService(provider);
}
@Override
public synchronized void unregister(RemoteServiceContextProvider provider) {
pidToProvider.remove(provider.id(), provider);
schemeToProvider.remove(provider.id().scheme(), provider);
}
@Override
public Set<ProviderId> getProviders() {
return ImmutableSet.copyOf(pidToProvider.keySet());
}
protected RemoteServiceContextProvider getProvider(ProviderId pid) {
return pidToProvider.get(pid);
}
protected RemoteServiceContextProvider getProvider(String scheme) {
return schemeToProvider.get(scheme);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc.impl;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.URI;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
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.onlab.osgi.DefaultServiceDirectory;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.incubator.rpc.RemoteServiceContext;
import org.onosproject.incubator.rpc.RemoteServiceContextProvider;
import org.onosproject.incubator.rpc.RemoteServiceContextProviderService;
import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
/**
* Sample implementation of RemoteServiceContextProvider.
*
* Scheme: "local", calling corresponding local service on request.
* Only expected for testing until real RPC implementation is ready.
*
* Note: This is expected to be removed or separated out as separate bundle
* once other RPC implementaion became available.
*/
@Beta
@Component(immediate = true)
public class LocalRemoteServiceProvider implements RemoteServiceContextProvider {
private final Logger log = LoggerFactory.getLogger(getClass());
private RemoteServiceContext theOne = new LocalServiceContext();
private static final ProviderId PID = new ProviderId("local", "org.onosproject.rpc.provider.local");
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RemoteServiceProviderRegistry rpcRegistry;
private final Map<Class<? extends Object>, Object> services = new ConcurrentHashMap<>();
private RemoteServiceContextProviderService providerService;
@Activate
protected void activate() {
services.put(SomeOtherService.class, new SomeOtherServiceImpl());
providerService = rpcRegistry.register(this);
log.info("Started");
}
@Deactivate
protected void deactivate() {
rpcRegistry.unregister(this);
log.info("Stopped");
}
@Override
public ProviderId id() {
return PID;
}
@Override
public RemoteServiceContext get(URI uri) {
checkArgument(Objects.equals(uri.getScheme(), "local"));
return theOne;
}
private final class LocalServiceContext implements RemoteServiceContext {
private final ServiceDirectory directory = new DefaultServiceDirectory();
@Override
public <T> T get(Class<T> serviceClass) {
@SuppressWarnings("unchecked")
T service = (T) services.get(serviceClass);
if (service != null) {
return service;
}
// look up OSGi services on this host.
// provided to unblock development depending on RPC.
return directory.get(serviceClass);
}
}
// Service provided by RPC can be non-OSGi Service
public static interface SomeOtherService {
String hello();
}
public static class SomeOtherServiceImpl implements SomeOtherService {
@Override
public String hello() {
return "Goodbye";
}
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc.impl;
import java.net.URI;
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.Service;
import org.onosproject.incubator.rpc.RemoteServiceContext;
import org.onosproject.incubator.rpc.RemoteServiceDirectory;
import org.onosproject.incubator.rpc.RemoteServiceContextProvider;
import org.onosproject.incubator.rpc.RemoteServiceContextProviderService;
import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
/**
* Provides RemoteService related APIs.
*/
@Beta
@Component(immediate = true)
@Service
public class RemoteServiceManager extends AbstractProviderRegistry
implements RemoteServiceDirectory, RemoteServiceProviderRegistry {
private final Logger log = LoggerFactory.getLogger(getClass());
@Activate
protected void activate() {
log.info("Started");
}
@Deactivate
protected void deactivate() {
log.info("Stopped");
}
@Override
public RemoteServiceContext get(URI uri) {
RemoteServiceContextProvider factory = getProvider(uri.getScheme());
if (factory != null) {
return factory.get(uri);
}
throw new UnsupportedOperationException(uri.getScheme() + " not supported");
}
private final class InternalRemoteServiceContextProviderService
extends AbstractProviderService<RemoteServiceContextProvider>
implements RemoteServiceContextProviderService {
public InternalRemoteServiceContextProviderService(RemoteServiceContextProvider provider) {
super(provider);
}
}
// make this abstract method if slicing out
@Override
protected RemoteServiceContextProviderService createProviderService(RemoteServiceContextProvider provider) {
return new InternalRemoteServiceContextProviderService(provider);
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Implementation of the inter-cluster RPC service.
*/
package org.onosproject.incubator.rpc.impl;
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.incubator.rpc.impl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Set of tests of the ONOS application component.
*/
public class RemoteServiceManagerTest {
private RemoteServiceManager component;
@Before
public void setUp() {
component = new RemoteServiceManager();
component.activate();
}
@After
public void tearDown() {
component.deactivate();
}
@Test
public void basics() {
}
}