<!-- Compability Packages -->
<module>compatibility</module>
- <!-- Clustering
- <module>sal-remoterpc-connector/implementation</module>
- -->
</modules>
<build>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<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>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
-
- <artifactId>sal-remoterpc-connector</artifactId>
- <packaging>bundle</packaging>
-
- <properties>
- <stax.version>1.0.1</stax.version>
- <zeromq.version>0.3.1</zeromq.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-connector-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <!-- MD Sal interdependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-core-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
-
- <!-- Tests -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- AD Sal -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
-
- <!-- Yang tools -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
-
- <!-- Third Party -->
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>${zeromq.version}</version>
- </dependency>
-
- <dependency>
- <groupId>stax</groupId>
- <artifactId>stax-api</artifactId>
- <version>${stax.version}</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>*,
- !org.codehaus.enunciate.jaxrs</Import-Package>
- <Export-Package>org.opendaylight.controller.config.yang.md.sal.remote.rpc,
- org.opendaylight.controller.sal.connector.remoterpc.util,
- org.opendaylight.controller.sal.connector.remoterpc.dto,
- org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient,
- org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcServer,
- org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcProvider</Export-Package>
- <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- </instructions>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>target/site/models</outputBaseDir>
- </generator>
-
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>target/site/models</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.remote.rpc;
-
-import org.opendaylight.controller.sal.connector.remoterpc.*;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.osgi.framework.BundleContext;
-
-/**
-*
-*/
-public final class ZeroMQServerModule extends org.opendaylight.controller.config.yang.md.sal.remote.rpc.AbstractZeroMQServerModule
- {
-
- private static final Integer ZEROMQ_ROUTER_PORT = 5554;
- private BundleContext bundleContext;
-
- public ZeroMQServerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public ZeroMQServerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
- ZeroMQServerModule oldModule, java.lang.AutoCloseable oldInstance) {
-
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- protected void customValidation(){
- // Add custom validation for module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
-
- Broker broker = getDomBrokerDependency();
-
- final int port = getPort() != null ? getPort() : ZEROMQ_ROUTER_PORT;
-
- ServerImpl serverImpl = new ServerImpl(port);
-
- ClientImpl clientImpl = new ClientImpl();
-
- RoutingTableProvider provider = new RoutingTableProvider(bundleContext);//,serverImpl);
-
-
- facade.setRoutingTableProvider(provider );
- facade.setContext(bundleContext);
- facade.setRpcProvisionRegistry((RpcProvisionRegistry) broker);
-
- broker.registerProvider(facade, bundleContext);
- return facade;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.remote.rpc;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-
-/**
-*
-*/
-public class ZeroMQServerModuleFactory extends org.opendaylight.controller.config.yang.md.sal.remote.rpc.AbstractZeroMQServerModuleFactory
-{
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
- ZeroMQServerModule module = (ZeroMQServerModule) super.createModule(instanceName, dependencyResolver, bundleContext);
- module.setBundleContext(bundleContext);
- return module;
- }
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver,
- DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
- ZeroMQServerModule module = (ZeroMQServerModule) super.createModule(instanceName, dependencyResolver, old,bundleContext);
- module.setBundleContext(bundleContext);
- return module;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-public class CapturedMessageHandler implements Runnable {
-
- private Logger _logger = LoggerFactory.getLogger(CapturedMessageHandler.class);
-
- private ZMQ.Socket socket;
-
- public CapturedMessageHandler(ZMQ.Socket socket){
- this.socket = socket;
- }
-
- @Override
- public void run(){
-
- try {
- while (!Thread.currentThread().isInterrupted()){
- String message = socket.recvStr();
- _logger.debug("Captured [{}]", message);
- }
- } catch (Exception e) {
- _logger.error("Exception raised [{}]", e.getMessage());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * An implementation of {@link RpcImplementation} that makes
- * remote RPC calls
- */
-public class ClientImpl implements RemoteRpcClient {
-
- private final Logger _logger = LoggerFactory.getLogger(ClientImpl.class);
-
- private final ZMQ.Context context = ZMQ.context(1);
- private final ClientRequestHandler handler;
- private RoutingTableProvider routingTableProvider;
-
- public ClientImpl(){
- handler = new ClientRequestHandler(context);
- start();
- }
-
- public ClientImpl(ClientRequestHandler handler){
- this.handler = handler;
- start();
- }
-
- public RoutingTableProvider getRoutingTableProvider() {
- return routingTableProvider;
- }
-
- @Override
- public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
- this.routingTableProvider = routingTableProvider;
- }
-
- @Override
- public void start() {/*NOOPS*/}
-
- @Override
- public void stop() {
- closeZmqContext();
- handler.close();
- _logger.info("Stopped");
- }
-
- @Override
- public void close(){
- stop();
- }
-
- /**
- * Finds remote server that can execute this rpc and sends a message to it
- * requesting execution.
- * The call blocks until a response from remote server is received. Its upto
- * the client of this API to implement a timeout functionality.
- *
- * @param rpc remote service to be executed
- * @param input payload for the remote service
- * @return
- */
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- String address = lookupRemoteAddressForGlobalRpc(routeId);
- return sendMessage(input, routeId, address);
- }
-
- /**
- * Finds remote server that can execute this routed rpc and sends a message to it
- * requesting execution.
- * The call blocks until a response from remote server is received. Its upto
- * the client of this API to implement a timeout functionality.
- *
- * @param rpc
- * rpc to be called
- * @param identifier
- * instance identifier on which rpc is to be executed
- * @param input
- * payload
- * @return
- */
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
-
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
- routeId.setRoute(identifier);
-
- String address = lookupRemoteAddressForRpc(routeId);
-
- return sendMessage(input, routeId, address);
- }
-
- private ListenableFuture<RpcResult<CompositeNode>> sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) {
- Message request = new Message.MessageBuilder()
- .type(Message.MessageType.REQUEST)
- .sender(Context.getInstance().getLocalUri())
- .recipient(address)
- .route(routeId)
- .payload(XmlUtils.compositeNodeToXml(input))
- .build();
-
- List<RpcError> errors = new ArrayList<RpcError>();
-
- try{
- Message response = handler.handle(request);
- CompositeNode payload = null;
-
- if ( response != null ) {
-
- _logger.info("Received response [{}]", response);
-
- Object rawPayload = response.getPayload();
- switch (response.getType()) {
- case ERROR:
- if ( rawPayload instanceof List )
- errors = (List) rawPayload;
- break;
-
- case RESPONSE:
- payload = XmlUtils.xmlToCompositeNode((String) rawPayload);
- break;
-
- default:
- errors.add(
- RpcErrors.getRpcError(null, null,null,null,"Unable to get response from remote controller", null, null)
- );
- break;
-
- }
- }
- return Futures.immediateFuture(Rpcs.getRpcResult(true, payload, errors));
-
- } catch (Exception e){
- collectErrors(e, errors);
- return Futures.immediateFuture(Rpcs.<CompositeNode>getRpcResult(false, null, errors));
- }
- }
-
- /**
- * Find address for the given route identifier in routing table
- * @param routeId route identifier
- * @return remote network address
- */
- private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier routeId){
- checkNotNull(routeId, "route must not be null");
-
- Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable = routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
-
- String address = null;
- try {
- address = routingTable.get().getGlobalRoute(routeId);
- } catch (RoutingTableException|SystemException e) {
- _logger.error("Exception caught while looking up remote address " + e);
- }
- checkState(address != null, "Address not found for route [%s]", routeId);
-
- return address;
- }
-
- /**
- * Find address for the given route identifier in routing table
- * @param routeId route identifier
- * @return remote network address
- */
- private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier routeId){
- checkNotNull(routeId, "route must not be null");
-
- Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable = routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
-
- String address = routingTable.get().getLastAddedRoute(routeId);
- checkState(address != null, "Address not found for route [%s]", routeId);
-
- return address;
- }
-
- private void collectErrors(Exception e, List<RpcError> errors){
- if (e == null) return;
- if (errors == null) errors = new ArrayList<RpcError>();
-
- errors.add(RpcErrors.getRpcError(null, null, null, null, e.getMessage(), null, e.getCause()));
- for (Throwable t : e.getSuppressed()) {
- errors.add(RpcErrors.getRpcError(null, null, null, null, t.getMessage(), null, t));
- }
- }
-
- /**
- * Closes ZMQ Context. It tries to gracefully terminate the context. If
- * termination takes more than a second, its forcefully shutdown.
- */
- private void closeZmqContext() {
- ExecutorService exec = Executors.newSingleThreadExecutor();
- FutureTask zmqTermination = new FutureTask(new Runnable() {
-
- @Override
- public void run() {
- try {
- if (context != null)
- context.term();
- _logger.debug("ZMQ Context terminated");
- } catch (Exception e) {
- _logger.debug("ZMQ Context termination threw exception [{}]. Continuing shutdown...", e);
- }
- }
- }, null);
-
- exec.execute(zmqTermination);
-
- try {
- zmqTermination.get(1L, TimeUnit.SECONDS);
- } catch (Exception e) {/*ignore and continue with shutdown*/}
-
- exec.shutdownNow();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- *
- */
-class ClientRequestHandler implements AutoCloseable{
-
- private Logger _logger = LoggerFactory.getLogger(ClientRequestHandler.class);
- private final String DEFAULT_NAME = "remoterpc-client-worker";
- private final String INPROC_PROTOCOL_PREFIX = "inproc://";
- private final String TCP_PROTOCOL_PREFIX = "tcp://";
-
- private ZMQ.Context context;
-
- /*
- * Worker thread pool. Each thread runs a ROUTER-DEALER pair
- */
- private ExecutorService workerPool;
-
- /*
- * Set of remote servers this client is currently connected to
- */
- private Map<String, String> connectedServers;
-
- protected ClientRequestHandler(ZMQ.Context context) {
- this.context = context;
- connectedServers = new ConcurrentHashMap<String, String>();
- start();
- }
-
- /**
- * Starts a pool of worker as needed. A worker thread that has not been used for 5 min
- * is terminated and removed from the pool. If thread dies due to an exception, its
- * restarted.
- */
- private void start(){
-
- workerPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
- 5L, TimeUnit.MINUTES,
- new SynchronousQueue<Runnable>()){
-
- @Override
- protected void afterExecute(Runnable r, Throwable t) {
- if (isTerminating() || isTerminated() || isShutdown())
- return;
-
- Worker worker = (Worker) r;
- Preconditions.checkState( worker != null );
- String remoteServerAddress = worker.getRemoteServerAddress();
- connectedServers.remove(remoteServerAddress);
-
- if ( t != null ){
- _logger.debug("Exception caught while terminating worker [{},{}]. " +
- "Restarting worker...", t.getClass(), t.getMessage());
-
- connectedServers.put(remoteServerAddress, remoteServerAddress);
- this.execute(r);
- }
- super.afterExecute(r, null);
- }
- };
- }
-
- public Message handle(Message request) throws IOException, ClassNotFoundException, InterruptedException {
-
- String remoteServerAddress = request.getRecipient();
- //if we already have router-dealer bridge setup for this address the send request
- //otherwise first create the bridge and then send request
- if ( connectedServers.containsKey(remoteServerAddress) )
- return sendMessage(request, remoteServerAddress);
-
- else{
- workerPool.execute(new Worker(remoteServerAddress));
- connectedServers.put(remoteServerAddress, remoteServerAddress);
- //give little time for sockets to get initialized
- //TODO: Add socket ping-pong message to ensure socket init rather than thread.sleep.
- Thread.sleep(1000);
- return sendMessage(request, remoteServerAddress);
- }
- }
-
- private Message sendMessage(Message request, String address) throws IOException, ClassNotFoundException {
- Message response = null;
- ZMQ.Socket socket = context.socket(ZMQ.REQ);
-
- try {
- String inProcessSocketAddress = INPROC_PROTOCOL_PREFIX + address;
- socket.connect( inProcessSocketAddress );
- _logger.debug("Sending request [{}]", request);
- socket.send(Message.serialize(request));
- _logger.info("Request sent. Waiting for reply...");
- byte[] reply = socket.recv(0);
- _logger.info("Response received");
- response = (Message) Message.deserialize(reply);
- _logger.debug("Response [{}]", response);
- } finally {
- socket.close();
- }
- return response;
- }
-
- /**
- * This gets called automatically if used with try-with-resources
- */
- @Override
- public void close(){
- workerPool.shutdown();
- _logger.info("Request Handler closed");
- }
-
- /**
- * Total number of workers in the pool. Number of workers represent
- * number of remote servers {@link org.opendaylight.controller.sal.connector.remoterpc.ClientImpl} is connected to.
- *
- * @return worker count
- */
- public int getWorkerCount(){
-
- if (workerPool == null) return 0;
-
- return ((ThreadPoolExecutor)workerPool).getActiveCount();
- }
- /**
- * Handles RPC request
- */
- private class Worker implements Runnable {
- private String name;
- private String remoteServer; //<serverip:rpc-port>
-
- public Worker(String address){
- this.name = DEFAULT_NAME + "[" + address + "]";
- this.remoteServer = address;
- }
-
- public String getRemoteServerAddress(){
- return this.remoteServer;
- }
-
- @Override
- public void run() {
- Thread.currentThread().setName(name);
- _logger.debug("Starting ... ");
-
- ZMQ.Socket router = context.socket(ZMQ.ROUTER);
- ZMQ.Socket dealer = context.socket(ZMQ.DEALER);
-
- try {
- int success = router.bind(INPROC_PROTOCOL_PREFIX + remoteServer);
- Preconditions.checkState(-1 != success, "Could not bind to " + remoteServer);
-
- dealer.connect(TCP_PROTOCOL_PREFIX + remoteServer);
-
- _logger.info("Worker started for [{}]", remoteServer);
-
- //TODO: Add capture handler
- //This code will block until the zmq context is terminated.
- ZMQ.proxy(router, dealer, null);
-
- } catch (Exception e) {
- _logger.debug("Ignoring exception [{}, {}]", e.getClass(), e.getMessage());
- } finally {
- try {
- router.close();
- dealer.close();
- } catch (Exception x) {
- _logger.debug("Exception while closing socket [{}]", x);
- }
- _logger.debug("Closing...");
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.zeromq.ZMQ;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Enumeration;
-
-/**
- * Provides a ZeroMQ Context object
- */
-public class Context {
- private ZMQ.Context zmqContext = ZMQ.context(1);
- private String uri;
- private final String DEFAULT_RPC_PORT = "5554";
-
- private static Context _instance = new Context();
-
- private Context() {}
-
- public static Context getInstance(){
- return _instance;
- }
-
- public ZMQ.Context getZmqContext(){
- return this.zmqContext;
- }
-
- public String getLocalUri(){
- uri = (uri != null) ? uri
- : new StringBuilder().append(getIpAddress()).append(":")
- .append(getRpcPort()).toString();
-
- return uri;
- }
-
- public String getRpcPort(){
- String rpcPort = (System.getProperty("rpc.port") != null)
- ? System.getProperty("rpc.port")
- : DEFAULT_RPC_PORT;
-
- return rpcPort;
- }
-
- private String getIpAddress(){
- String ipAddress = (System.getProperty("local.ip") != null)
- ? System.getProperty("local.ip")
- : findIpAddress();
-
- return ipAddress;
- }
-
- /**
- * Finds IPv4 address of the local VM
- * TODO: This method is non-deterministic. There may be more than one IPv4 address. Cant say which
- * address will be returned. Read IP from a property file or enhance the code to make it deterministic.
- * Should we use IP or hostname?
- *
- * @return
- */
- private String findIpAddress() {
- String hostAddress = null;
- Enumeration e = null;
- try {
- e = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e1) {
- e1.printStackTrace();
- }
- while (e.hasMoreElements()) {
-
- NetworkInterface n = (NetworkInterface) e.nextElement();
-
- Enumeration ee = n.getInetAddresses();
- while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
- if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
- hostAddress = i.getHostAddress();
- }
- }
- return hostAddress;
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
-
-public interface RemoteRpcClient extends AutoCloseable{
-
- void setRoutingTableProvider(RoutingTableProvider provider);
-
- void stop();
-
- void start();
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class RemoteRpcProvider implements
- RpcImplementation,
- RoutedRpcDefaultImplementation,
- AutoCloseable,
- Provider {
-
- private final Logger _logger = LoggerFactory.getLogger(RemoteRpcProvider.class);
-
- private final ServerImpl server;
- private final ClientImpl client;
- private RoutingTableProvider routingTableProvider;
- private final RpcListener listener = new RpcListener();
- private final RoutedRpcListener routeChangeListener = new RoutedRpcListener();
- private ProviderSession brokerSession;
- private RpcProvisionRegistry rpcProvisionRegistry;
- private BundleContext context;
- private ServiceTracker clusterTracker;
-
- public RemoteRpcProvider(ServerImpl server, ClientImpl client) {
- this.server = server;
- this.client = client;
- }
-
- public void setRoutingTableProvider(RoutingTableProvider provider) {
- this.routingTableProvider = provider;
- client.setRoutingTableProvider(provider);
- }
-
- public void setContext(BundleContext context){
- this.context = context;
- }
-
- public void setRpcProvisionRegistry(RpcProvisionRegistry rpcProvisionRegistry){
- this.rpcProvisionRegistry = rpcProvisionRegistry;
- }
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
- brokerSession = session;
- server.setBrokerSession(session);
- start();
- }
-
- @Override
- public Set<QName> getSupportedRpcs() {
- //TODO: Ask Tony if we need to get this from routing table
- return Collections.emptySet();
- }
-
- @Override
- public Collection<ProviderFunctionality> getProviderFunctionality() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- return client.invokeRpc(rpc, input);
- }
-
- @Override
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
- return client.invokeRpc(rpc, identifier, input);
- }
-
- public void start() {
- server.start();
- client.start();
- brokerSession.addRpcRegistrationListener(listener);
- rpcProvisionRegistry.setRoutedRpcDefaultDelegate(this);
- rpcProvisionRegistry.registerRouteChangeListener(routeChangeListener);
-
- announceSupportedRpcs();
- announceSupportedRoutedRpcs();
- }
-
- @Override
- public void close() throws Exception {
- unregisterSupportedRpcs();
- unregisterSupportedRoutedRpcs();
- server.close();
- client.close();
- }
-
- public void stop() {
- server.stop();
- client.stop();
- }
-
- /**
- * Add all the locally registered RPCs in the clustered routing table
- */
- private void announceSupportedRpcs(){
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- for (QName rpc : currentlySupported) {
- listener.onRpcImplementationAdded(rpc);
- }
- }
-
- /**
- * Add all the locally registered Routed RPCs in the clustered routing table
- */
- private void announceSupportedRoutedRpcs(){
-
- //TODO: announce all routed RPCs as well
-
- }
-
- /**
- * Un-Register all the supported RPCs from clustered routing table
- */
- private void unregisterSupportedRpcs(){
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- //TODO: remove all routed RPCs as well
- for (QName rpc : currentlySupported) {
- listener.onRpcImplementationRemoved(rpc);
- }
- }
-
- /**
- * Un-Register all the locally supported Routed RPCs from clustered routing table
- */
- private void unregisterSupportedRoutedRpcs(){
-
- //TODO: remove all routed RPCs as well
-
- }
-
- private RoutingTable<RpcRouter.RouteIdentifier, String> getRoutingTable(){
- Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> routingTable =
- routingTableProvider.getRoutingTable();
-
- checkState(routingTable.isPresent(), "Routing table is null");
-
- return routingTable.get();
- }
-
- /**
- * Listener for rpc registrations in broker
- */
- private class RpcListener implements RpcRegistrationListener {
-
- @Override
- public void onRpcImplementationAdded(QName rpc) {
-
- _logger.debug("Adding registration for [{}]", rpc);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
-
- try {
- routingTable.addGlobalRoute(routeId, server.getServerAddress());
- _logger.debug("Route added [{}-{}]", routeId, server.getServerAddress());
-
- } catch (RoutingTableException | SystemException e) {
- //TODO: This can be thrown when route already exists in the table. Broker
- //needs to handle this.
- _logger.error("Unhandled exception while adding global route to routing table [{}]", e);
-
- }
- }
-
- @Override
- public void onRpcImplementationRemoved(QName rpc) {
-
- _logger.debug("Removing registration for [{}]", rpc);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
-
- try {
- routingTable.removeGlobalRoute(routeId);
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route delete failed {}", e);
- }
- }
- }
-
- /**
- * Listener for Routed Rpc registrations in broker
- */
- private class RoutedRpcListener
- implements RouteChangeListener<RpcRoutingContext, InstanceIdentifier> {
-
- /**
- *
- * @param routeChange
- */
- @Override
- public void onRouteChange(RouteChange<RpcRoutingContext, InstanceIdentifier> routeChange) {
- Map<RpcRoutingContext, Set<InstanceIdentifier>> announcements = routeChange.getAnnouncements();
- announce(getRouteIdentifiers(announcements));
-
- Map<RpcRoutingContext, Set<InstanceIdentifier>> removals = routeChange.getRemovals();
- remove(getRouteIdentifiers(removals));
- }
-
- /**
- *
- * @param announcements
- */
- private void announce(Set<RpcRouter.RouteIdentifier> announcements) {
- _logger.debug("Announcing [{}]", announcements);
- RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
- try {
- routingTable.addRoutes(announcements, server.getServerAddress());
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route announcement failed {}", e);
- }
- }
-
- /**
- *
- * @param removals
- */
- private void remove(Set<RpcRouter.RouteIdentifier> removals){
- _logger.debug("Removing [{}]", removals);
- RoutingTable<RpcRouter.RouteIdentifier, String> routingTable = getRoutingTable();
- try {
- routingTable.removeRoutes(removals, server.getServerAddress());
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route removal failed {}", e);
- }
- }
-
- /**
- *
- * @param changes
- * @return
- */
- private Set<RpcRouter.RouteIdentifier> getRouteIdentifiers(Map<RpcRoutingContext, Set<InstanceIdentifier>> changes) {
- RouteIdentifierImpl routeId = null;
- Set<RpcRouter.RouteIdentifier> routeIdSet = new HashSet<RpcRouter.RouteIdentifier>();
-
- for (RpcRoutingContext context : changes.keySet()){
- routeId = new RouteIdentifierImpl();
- routeId.setType(context.getRpc());
- //routeId.setContext(context.getContext());
-
- for (InstanceIdentifier instanceId : changes.get(context)){
- routeId.setRoute(instanceId);
- routeIdSet.add(routeId);
- }
- }
- return routeIdSet;
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-public interface RemoteRpcServer extends AutoCloseable {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
-import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class RoutingTableProvider implements AutoCloseable {
-
- @SuppressWarnings("rawtypes")
- final ServiceTracker<RoutingTable,RoutingTable> tracker;
-
- private RoutingTableImpl routingTableImpl = null;
-
- //final private RouteChangeListener routeChangeListener;
-
-
- public RoutingTableProvider(BundleContext ctx){//,RouteChangeListener rcl) {
- @SuppressWarnings("rawtypes")
- ServiceTracker<RoutingTable, RoutingTable> rawTracker = new ServiceTracker<>(ctx, RoutingTable.class, null);
- tracker = rawTracker;
- tracker.open();
-
- //routeChangeListener = rcl;
- }
-
- public Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> getRoutingTable() {
- @SuppressWarnings("unchecked")
- RoutingTable<RpcRouter.RouteIdentifier,String> tracked = tracker.getService();
-
- if(tracked instanceof RoutingTableImpl){
- if(routingTableImpl != tracked){
- routingTableImpl= (RoutingTableImpl)tracked;
- //routingTableImpl.setRouteChangeListener(routeChangeListener);
- }
- }
-
- return Optional.fromNullable(tracked);
- }
-
- @Override
- public void close() throws Exception {
- tracker.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * ZeroMq based implementation of RpcRouter.
- */
-public class ServerImpl implements RemoteRpcServer {
-
- private Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
-
- private ExecutorService serverPool;
- protected ServerRequestHandler handler;
-
- private Set<QName> remoteServices;
- private ProviderSession brokerSession;
- private ZMQ.Context context;
-
- private final String HANDLER_INPROC_ADDRESS = "inproc://rpc-request-handler";
- private final int HANDLER_WORKER_COUNT = 2;
- private final int HWM = 200;//high water mark on sockets
- private volatile State status = State.STOPPED;
-
- private String serverAddress;
- private int port;
-
- public static enum State {
- STARTING, STARTED, STOPPED;
- }
-
- public ServerImpl(int port) {
- this.port = port;
- }
-
- public State getStatus() {
- return this.status;
- }
-
- public Optional<ServerRequestHandler> getHandler() {
- return Optional.fromNullable(this.handler);
- }
-
- public void setBrokerSession(ProviderSession session) {
- this.brokerSession = session;
- }
-
- public Optional<ProviderSession> getBrokerSession() {
- return Optional.fromNullable(this.brokerSession);
- }
-
- public Optional<ZMQ.Context> getZmqContext() {
- return Optional.fromNullable(this.context);
- }
-
- public String getServerAddress() {
- return serverAddress;
- }
-
- public String getHandlerAddress() {
- return HANDLER_INPROC_ADDRESS;
- }
-
- /**
- *
- */
- public void start() {
- Preconditions.checkState(State.STOPPED == this.getStatus(),
- "Remote RPC Server is already running");
-
- status = State.STARTING;
- _logger.debug("Remote RPC Server is starting...");
-
- String hostIpAddress = findIpAddress();
-
- //Log and silently die as per discussion in the bug (bug-362)
- //https://bugs.opendaylight.org/show_bug.cgi?id=362
- //
- // A tracking enhancement defect (bug-366) is created to properly fix this issue
- //https://bugs.opendaylight.org/show_bug.cgi?id=366
- //checkState(hostIpAddress != null, "Remote RPC Server could not acquire host ip address");
-
- if (hostIpAddress == null) {
- _logger.error("Remote RPC Server could not acquire host ip address. Stopping...");
- stop();
- return;
- }
-
- this.serverAddress = new StringBuilder(hostIpAddress).
- append(":").
- append(port).
- toString();
-
- context = ZMQ.context(1);
- remoteServices = new HashSet<QName>();//
- serverPool = Executors.newSingleThreadExecutor();//main server thread
- serverPool.execute(receive()); // Start listening rpc requests
-
- status = State.STARTED;
- _logger.info("Remote RPC Server started [{}]", getServerAddress());
- }
-
- public void stop(){
- close();
- }
-
- /**
- *
- */
- @Override
- public void close() {
-
- if (State.STOPPED == this.getStatus()) return; //do nothing
-
- if (serverPool != null)
- serverPool.shutdown();
-
- closeZmqContext();
-
- status = State.STOPPED;
- _logger.info("Remote RPC Server stopped");
- }
-
- /**
- * Closes ZMQ Context. It tries to gracefully terminate the context. If
- * termination takes more than 5 seconds, its forcefully shutdown.
- */
- private void closeZmqContext() {
- ExecutorService exec = Executors.newSingleThreadExecutor();
- FutureTask zmqTermination = new FutureTask(new Runnable() {
-
- @Override
- public void run() {
- try {
- if (context != null)
- context.term();
- _logger.debug("ZMQ Context terminated gracefully!");
- } catch (Exception e) {
- _logger.debug("ZMQ Context termination threw exception [{}]. Continuing shutdown...", e);
- }
- }
- }, null);
-
- exec.execute(zmqTermination);
-
- try {
- zmqTermination.get(5L, TimeUnit.SECONDS);
- } catch (Exception e) {/*ignore and continue with shutdown*/}
-
- exec.shutdownNow();
- }
-
- /**
- * Main listener thread that spawns {@link ServerRequestHandler} as workers.
- *
- * @return
- */
- private Runnable receive() {
- return new Runnable() {
-
- @Override
- public void run() {
- Thread.currentThread().setName("remote-rpc-server");
- _logger.debug("Remote RPC Server main thread starting...");
-
- //socket clients connect to (frontend)
- ZMQ.Socket clients = context.socket(ZMQ.ROUTER);
-
- //socket RequestHandlers connect to (backend)
- ZMQ.Socket workers = context.socket(ZMQ.DEALER);
-
- try (SocketPair capturePair = new SocketPair();
- ServerRequestHandler requestHandler = new ServerRequestHandler(context,
- brokerSession,
- HANDLER_WORKER_COUNT,
- HANDLER_INPROC_ADDRESS,
- getServerAddress());) {
-
- handler = requestHandler;
- clients.setHWM(HWM);
- clients.bind("tcp://*:" + port);
- workers.setHWM(HWM);
- workers.bind(HANDLER_INPROC_ADDRESS);
- //start worker threads
- _logger.debug("Remote RPC Server worker threads starting...");
- requestHandler.start();
- //start capture thread
- // handlerPool.execute(new CaptureHandler(capturePair.getReceiver()));
- // Connect work threads to client threads via a queue
- ZMQ.proxy(clients, workers, null);//capturePair.getSender());
-
- } catch (Exception e) {
- _logger.debug("Unhandled exception [{}, {}]", e.getClass(), e.getMessage());
- } finally {
- if (clients != null) clients.close();
- if (workers != null) workers.close();
- _logger.info("Remote RPC Server stopped");
- }
- }
- };
- }
-
- /**
- * Finds IPv4 address of the local VM
- * TODO: This method is non-deterministic. There may be more than one IPv4 address. Cant say which
- * address will be returned. Read IP from a property file or enhance the code to make it deterministic.
- * Should we use IP or hostname?
- *
- * @return
- */
- private String findIpAddress() {
- Enumeration e = null;
- try {
- e = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e1) {
- _logger.error("Failed to get list of interfaces", e1);
- return null;
- }
- while (e.hasMoreElements()) {
-
- NetworkInterface n = (NetworkInterface) e.nextElement();
-
- Enumeration ee = n.getInetAddresses();
- while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
- _logger.debug("Trying address {}", i);
- if ((i instanceof Inet4Address) && (!i.isLoopbackAddress())) {
- String hostAddress = i.getHostAddress();
- _logger.debug("Settled on host address {}", hostAddress);
- return hostAddress;
- }
- }
- }
-
- _logger.error("Failed to find a suitable host address");
- return null;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Collection;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- *
- */
-public class ServerRequestHandler implements AutoCloseable{
-
- private Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class);
- private final String DEFAULT_NAME = "remote-rpc-worker";
- private String dealerAddress;
- private String serverAddress;
- private int workerCount;
- private ZMQ.Context context;
- private Broker.ProviderSession broker;
-
- private RequestHandlerThreadPool workerPool;
- private final AtomicInteger threadId = new AtomicInteger();
-
- public ServerRequestHandler(ZMQ.Context context,
- Broker.ProviderSession session,
- int workerCount,
- String dealerAddress,
- String serverAddress) {
- this.context = context;
- this.dealerAddress = dealerAddress;
- this.serverAddress = serverAddress;
- this.broker = session;
- this.workerCount = workerCount;
- }
-
- public ThreadPoolExecutor getWorkerPool(){
- return workerPool;
- }
-
- public void start(){
- workerPool = new RequestHandlerThreadPool(
- workerCount, workerCount,
- 0L, TimeUnit.MILLISECONDS,
- new LinkedBlockingQueue<Runnable>());
- //unbound is ok. Task will never be submitted
-
- for (int i=0;i<workerCount;i++){
- workerPool.execute(new Worker(threadId.incrementAndGet()));
- }
- }
-
- /**
- * This gets called automatically if used with try-with-resources
- * @throws Exception
- */
- @Override
- public void close() throws Exception {
- if (workerPool != null)
- workerPool.shutdown();
- _logger.info("Request Handler closed");
- }
-
- /**
- * Worker to handles RPC request
- */
- private class Worker implements Runnable {
- private String name;
-
- public Worker(int id){
- this.name = DEFAULT_NAME + "-" + id;
- }
-
- @Override
- public void run() {
- Thread.currentThread().setName(name);
- _logger.debug("Starting... ");
- ZMQ.Socket socket = null;
-
- try {
- socket = context.socket(ZMQ.REP);
- socket.connect(dealerAddress);
-
- while (!Thread.currentThread().isInterrupted()) {
-
- MessageHandler handler = new MessageHandler(socket);
- handler.receiveMessage();
-
- if (handler.hasMessageForBroker()) {
-
- Message request = handler.getMessage();
- Future<RpcResult<CompositeNode>> rpc = null;
- RpcResult<CompositeNode> result = null;
-
- //TODO Call this in a new thread with timeout
- try {
- rpc = broker.rpc(
- (QName) request.getRoute().getType(),
- XmlUtils.xmlToCompositeNode((String) request.getPayload()));
-
- result = (rpc != null) ? rpc.get() : null;
-
- handler.sendResponse(result);
-
- } catch (Exception e) {
- _logger.debug("Broker threw [{}]", e);
- handler.sendError(e.getMessage());
- }
- }
-
- }
- } catch (Exception e) {
- printException(e);
- } finally {
- closeSocket(socket);
- }
- }
-
- private void printException(Exception e) {
- try (StringWriter s = new StringWriter();
- PrintWriter p = new PrintWriter(s)) {
- e.printStackTrace(p);
- _logger.debug(s.toString());
- } catch (IOException e1) {/*Ignore and continue*/ }
- }
-
- private void closeSocket(ZMQ.Socket socket) {
- try {
- if (socket != null) socket.close();
- } catch (Exception x) {
- _logger.debug("Exception while closing socket [{}]", x);
- } finally {
- if (socket != null) socket.close();
- }
- _logger.debug("Closing...");
- }
- }
-
-
- /**
- *
- */
- public class RequestHandlerThreadPool extends ThreadPoolExecutor{
-
- public RequestHandlerThreadPool(int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue) {
- super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
- }
-
- @Override
- protected void afterExecute(Runnable r, Throwable t) {
- if (isTerminating() || isTerminated() || isShutdown())
- return;
-
- if ( t != null ){
- _logger.debug("Exception caught while terminating worker [{},{}]", t.getClass(), t.getMessage());
- }
-
- this.execute(new Worker(threadId.incrementAndGet()));
- super.afterExecute(r, null);
- }
- }
-
- class MessageHandler{
- private ZMQ.Socket socket;
- private Message message; //parsed message received on zmq server port
- private boolean messageForBroker = false; //if the message is valid and not a "ping" message
-
- public MessageHandler(ZMQ.Socket socket){
- this.socket = socket;
- }
-
- void receiveMessage(){
- byte[] bytes = socket.recv(); //this blocks
- _logger.debug("Received bytes:[{}]", bytes.length);
-
- Object objectRecvd = null;
- try{
- objectRecvd = Message.deserialize(bytes);
- }catch (Exception e){
- sendError(e.getMessage());
- return;
- }
-
- if (!(objectRecvd instanceof Message)) {
- sendError("Invalid message received");
- return;
- }
-
- message = (Message) objectRecvd;
-
- _logger.info("Received request [{}]", message);
-
- if (Message.MessageType.PING == message.getType()){
- sendPong();
- return;
- }
-
- messageForBroker = true;
- }
-
- boolean hasMessageForBroker(){
- return messageForBroker;
- }
-
- Message getMessage(){
- return message;
- }
-
- void sendResponse(RpcResult<CompositeNode> result){
- CompositeNode payload = (result != null) ? result.getResult() : null;
-
- String recipient = null;
- RpcRouter.RouteIdentifier routeId = null;
-
- if (message != null) {
- recipient = message.getSender();
- routeId = message.getRoute();
- }
-
- Message response = new Message.MessageBuilder()
- .type(Message.MessageType.RESPONSE)
- .sender(serverAddress)
- .recipient(recipient)
- .route(routeId)
- .payload(XmlUtils.compositeNodeToXml(payload))
- .build();
-
- send(response);
- }
-
- private void sendError(String msg){
- Message errorResponse = new Message.MessageBuilder()
- .type(Message.MessageType.ERROR)
- .sender(serverAddress)
- .payload(msg)
- .build();
-
- send(errorResponse);
- }
-
- private void sendPong(){
- Message pong = new Message.MessageBuilder()
- .type(Message.MessageType.PONG)
- .sender(serverAddress)
- .build();
-
- send(pong);
- }
-
- private void send(Message msg){
- byte[] serializedMessage = null;
- try {
- serializedMessage = Message.serialize(msg);
- } catch (Exception e) {
- _logger.debug("Unexpected error during serialization of response [{}]", msg);
- return;
- }
-
- if (serializedMessage != null)
- if (socket.send(serializedMessage))
- _logger.info("Response sent [{}]", msg);
- else _logger.debug("Failed to send serialized message");
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.zeromq.ZMQ;
-
-import java.util.UUID;
-
-/**
- *
- */
-public class SocketPair implements AutoCloseable{
- private ZMQ.Socket sender;
- private ZMQ.Socket receiver;
-
- private static final String INPROC_PREFIX = "inproc://";
-
- public SocketPair(){
- String address = new StringBuilder(INPROC_PREFIX)
- .append(UUID.randomUUID())
- .toString();
-
- receiver = Context.getInstance().getZmqContext().socket(ZMQ.PAIR);
- receiver.bind(address);
-
- sender = Context.getInstance().getZmqContext().socket(ZMQ.PAIR);
- sender.connect(address);
- }
-
- public ZMQ.Socket getSender(){
- return this.sender;
- }
-
- public ZMQ.Socket getReceiver(){
- return this.receiver;
- }
-
- @Override
- public void close() throws Exception {
- sender.close();
- receiver.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc.dto;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-
-import java.io.*;
-
-public class Message implements Serializable {
-
- public static enum MessageType {
- PING((byte) 0),
- PONG((byte) 1),
- REQUEST((byte) 2),
- RESPONSE((byte) 3),
- ERROR((byte)4);
-
- private final byte type;
-
- MessageType(byte type) {
- this.type = type;
- }
-
- public byte getType(){
- return this.type;
- }
- }
-
- private MessageType type;
- private String sender;
- private String recipient;
- private RpcRouter.RouteIdentifier route;
- private Object payload;
-
- public MessageType getType() {
- return type;
- }
-
- public void setType(MessageType type) {
- this.type = type;
- }
-
- public String getSender() {
- return sender;
- }
-
- public void setSender(String sender) {
- this.sender = sender;
- }
-
- public RpcRouter.RouteIdentifier getRoute() {
- return route;
- }
-
- public void setRoute(RpcRouter.RouteIdentifier route) {
- this.route = route;
- }
-
- public Object getPayload() {
- return payload;
- }
-
- public void setPayload(Object payload) {
- this.payload = payload;
- }
-
- public String getRecipient() {
- return recipient;
- }
-
- public void setRecipient(String recipient) {
- this.recipient = recipient;
- }
-
- @Override
- public String toString() {
- return "Message{" +
- "type=" + type +
- ", sender='" + sender + '\'' +
- ", recipient='" + recipient + '\'' +
- ", route=" + route +
- ", payload=" + payload +
- '}';
- }
-
- /**
- * Converts any {@link Serializable} object to byte[]
- *
- * @param obj
- * @return
- * @throws IOException
- */
- public static byte[] serialize(Object obj) throws IOException {
- ByteArrayOutputStream b = new ByteArrayOutputStream();
- ObjectOutputStream o = new ObjectOutputStream(b);
- o.writeObject(obj);
- return b.toByteArray();
- }
-
- /**
- * Converts byte[] to a java object
- *
- * @param bytes
- * @return
- * @throws IOException
- * @throws ClassNotFoundException
- */
- public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
- ByteArrayInputStream b = new ByteArrayInputStream(bytes);
- ObjectInputStream o = new ObjectInputStream(b);
- return o.readObject();
- }
-
- public static class Response extends Message implements RpcRouter.RpcReply {
- private ResponseCode code; // response code
-
- public static enum ResponseCode {
- SUCCESS(200), BADREQUEST(400), TIMEOUT(408), GONE(410), SERVERERROR(500), SERVICEUNAVAILABLE(503);
-
- private int code;
-
- ResponseCode(int code) {
- this.code = code;
- }
- }
-
- public ResponseCode getCode() {
- return code;
- }
-
- public void setCode(ResponseCode code) {
- this.code = code;
- }
- }
-
- /**
- * Builds a {@link Message} object
- */
- public static class MessageBuilder{
-
- private Message message;
-
- public MessageBuilder(){
- message = new Message();
- }
-
-
- public MessageBuilder type(MessageType type){
- message.setType(type);
- return this;
- }
-
- public MessageBuilder sender(String sender){
- message.setSender(sender);
- return this;
- }
-
- public MessageBuilder recipient(String recipient){
- message.setRecipient(recipient);
- return this;
- }
-
- public MessageBuilder route(RpcRouter.RouteIdentifier route){
- message.setRoute(route);
- return this;
- }
-
- public MessageBuilder payload(Object obj){
- message.setPayload(obj);
- return this;
- }
-
- public Message build(){
- return message;
- }
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc.dto;
-
-import org.zeromq.ZMQ;
-
-/**
- * A class encapsulating {@link Message} and the {@link ZMQ.Socket} over which it is transmitted
- */
-public class MessageWrapper {
-
- private Message _message;
- private ZMQ.Socket _receiveSocket;
-
- public MessageWrapper(Message message, ZMQ.Socket receiveSocket) {
- this._message = message;
- this._receiveSocket = receiveSocket;
- }
-
- public Message getMessage() {
- return _message;
- }
-
- public ZMQ.Socket getReceiveSocket() {
- return _receiveSocket;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc.dto;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-import java.io.Serializable;
-
-public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>,Serializable {
-
- private QName context;
- private QName type;
- private InstanceIdentifier route;
-
- @Override
- public QName getContext() {
- return this.context;
- }
-
- @Override
- public QName getType() {
- return this.type;
- }
-
- @Override
- public InstanceIdentifier getRoute() {
- return this.route;
- }
-
- public void setContext(QName context) {
- this.context = context;
- }
-
- public void setType(QName type) {
- this.type = type;
- }
-
- public void setRoute(InstanceIdentifier route) {
- this.route = route;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- RouteIdentifierImpl that = (RouteIdentifierImpl) o;
-
- if (context == null){
- if (that.getContext() != null) return false;
- }else
- if (!context.equals(that.context)) return false;
-
- if (route == null){
- if (that.getRoute() != null) return false;
- }else
- if (!route.equals(that.route)) return false;
-
- if (type == null){
- if (that.getType() != null) return false;
- }else
- if (!type.equals(that.type)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int prime = 31;
- int result = 0;
- result = prime * result + (context == null ? 0:context.hashCode());
- result = prime * result + (type == null ? 0:type.hashCode());
- result = prime * result + (route == null ? 0:route.hashCode());
- return result;
- }
-
- @Override
- public String toString() {
- return "RouteIdentifierImpl{" +
- "context=" + context +
- ", type=" + type +
- ", route=" + route +
- '}';
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc.util;
-
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.ByteArrayInputStream;
-import java.io.StringWriter;
-
-public class XmlUtils {
-
- private static final Logger _logger = LoggerFactory.getLogger(XmlUtils.class);
-
- public static String compositeNodeToXml(CompositeNode cNode){
- if (cNode == null) return new String();
-
- Document domTree = NodeUtils.buildShadowDomTree(cNode);
- StringWriter writer = new StringWriter();
- try {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- transformer.transform(new DOMSource(domTree), new StreamResult(writer));
- } catch (TransformerException e) {
- _logger.error("Error during translation of Document to OutputStream", e);
- }
-
- return writer.toString();
- }
-
- public static CompositeNode xmlToCompositeNode(String xml){
- if (xml==null || xml.length()==0) return null;
-
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(new ByteArrayInputStream(xml.getBytes()));
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /dev/null
-module odl-sal-dom-rpc-remote-cfg {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc";
- prefix "rpc-cluster";
-
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-dom {prefix dom;}
-
- description
- "Service definition for Binding Aware MD-SAL.";
-
- revision "2013-10-28" {
- description
- "Initial revision";
- }
-
- identity remote-rpc-server {
- base config:service-type;
- config:java-class "org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcServer";
- }
-
- identity remote-rpc-client {
- base config:service-type;
- config:java-class "org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient";
- }
-
- identity remote-zeromq-rpc-server {
- base config:module-type;
- config:java-name-prefix ZeroMQServer;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case remote-zeromq-rpc-server {
- when "/config:modules/config:module/config:type = 'remote-zeromq-rpc-server'";
-
- container dom-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dom:dom-broker-osgi-registry;
- }
- }
- }
-
- leaf port {
- type uint16;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.base.Optional;
-
-/**
- *
- */
-public class ClientImplTest {
- RoutingTableProvider routingTableProvider;
- ClientImpl client;
- ClientRequestHandler mockHandler;
-
- @Before
- public void setUp() throws Exception {
-
- //mock routing table
- routingTableProvider = mock(RoutingTableProvider.class);
- RoutingTable<RpcRouter.RouteIdentifier, String> mockRoutingTable = new MockRoutingTable<String, String>();
- Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
- when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
-
- //mock ClientRequestHandler
- mockHandler = mock(ClientRequestHandler.class);
-
- client = new ClientImpl(mockHandler);
- client.setRoutingTableProvider(routingTableProvider);
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void getRoutingTableProvider_Call_ShouldReturnMockProvider() throws Exception {
- Assert.assertEquals(routingTableProvider, client.getRoutingTableProvider());
-
- }
-
- @Test
- public void testStart() throws Exception {
-
- }
-
- @Test
- public void testStop() throws Exception {
-
- }
-
- @Test
- public void testClose() throws Exception {
-
- }
-
- //@Test
- public void invokeRpc_NormalCall_ShouldReturnSuccess() throws Exception {
-
- when(mockHandler.handle(any(Message.class))).
- thenReturn(MessagingUtil.createEmptyMessage());
-
- RpcResult<CompositeNode> result = client.invokeRpc(null, null).get();
-
- Assert.assertTrue(result.isSuccessful());
- Assert.assertTrue(result.getErrors().isEmpty());
- Assert.assertNull(result.getResult());
- }
-
- //@Test
- public void invokeRpc_HandlerThrowsException_ShouldReturnError() throws Exception {
-
- when(mockHandler.handle(any(Message.class))).
- thenThrow(new IOException());
-
- RpcResult<CompositeNode> result = client.invokeRpc(null, null).get();
-
- Assert.assertFalse(result.isSuccessful());
- Assert.assertFalse(result.getErrors().isEmpty());
- Assert.assertNull(result.getResult());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import junit.framework.Assert;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.util.concurrent.*;
-
-/**
- *
- */
-public class ClientRequestHandlerTest {
-
- private final Logger _logger = LoggerFactory.getLogger(ClientRequestHandlerTest.class);
-
- ZMQ.Context context;
- ExecutorService serverThread;
- final String SERVER_ADDRESS = "localhost:5553";
-
- ClientRequestHandler handler;
-
- @Before
- public void setUp() throws Exception {
- context = ZMQ.context(1);
- serverThread = Executors.newCachedThreadPool();
- handler = new ClientRequestHandler(context);
- }
-
- @After
- public void tearDown() throws Exception {
- serverThread.shutdown();
- MessagingUtil.closeZmqContext(context);
- handler.close();
- }
-
- @Test
- public void handle_SingleRemote_ShouldReturnResponse() throws Exception {
- serverThread.execute(MessagingUtil.startReplyServer(context, SERVER_ADDRESS, 1));
- Message request = new Message();
- request.setRecipient(SERVER_ADDRESS);
- Message response = handleMessageWithTimeout(request);
- Assert.assertNotNull(response);
- //should be connected to only 1 remote server
- Assert.assertEquals(1, handler.getWorkerCount());
- Assert.assertEquals(response.getRecipient(), SERVER_ADDRESS);
- }
-
- // @Test
- public void handle_MultiRemote_ShouldReturnResponses() throws Exception {
- ExecutorService threadPool = Executors.newCachedThreadPool();
- final int port = 5555;
- String serverAddress = null;
- for (int i = 0; i < 5; i++) {
- serverAddress = "localhost:" + (port + i);
- serverThread.execute(MessagingUtil.startReplyServer(context, serverAddress, 1));
- threadPool.execute(createEmptyMessageTaskAndHandle(handler, serverAddress));
- }
- Thread.currentThread().sleep(5000);//wait for all messages to get processed
- //should be connected to 5 remote server
- Assert.assertEquals(5, handler.getWorkerCount());
- }
-
- private Runnable createEmptyMessageTaskAndHandle(final ClientRequestHandler handler, final String serverAddress) {
-
- return new Runnable() {
- @Override
- public void run() {
- Message request = new Message();
- request.setRecipient(serverAddress);
- try {
- Message response = handleMessageWithTimeout(request);
- Assert.assertNotNull(response);
- Assert.assertEquals(response.getRecipient(), serverAddress);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- };
- }
-
- private Message handleMessageWithTimeout(final Message request) {
- Message response = null;
-
- FutureTask task = new FutureTask(new Callable<Message>() {
-
- @Override
- public Message call() {
- try {
- return handler.handle(request);
- } catch (Exception e) {
- _logger.debug("Client handler failed to handle request. Exception is [{}]", e);
- }
- return null;
- }
- });
-
- serverThread.execute(task);
-
- try {
- response = (Message) task.get(5L, TimeUnit.SECONDS); //wait for max 5 sec for server to respond
- } catch (Exception e) {/*ignore and continue*/}
-
- return response;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Mock implementation of routing table
- */
-public class MockRoutingTable<K, V> implements RoutingTable {
-
-
- @Override
- public void addRoute(Object o, Object o2) throws RoutingTableException, SystemException {
-
- }
-
- @Override
- public void addGlobalRoute(Object o, Object o2) throws RoutingTableException, SystemException {
-
- }
-
- @Override
- public void removeRoute(Object o, Object o2) {
-
- }
-
- @Override
- public void addRoutes(Set set, Object o) throws RoutingTableException, SystemException {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void removeRoutes(Set set, Object o) throws RoutingTableException, SystemException {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void removeGlobalRoute(Object o) throws RoutingTableException, SystemException {
-
- }
-
- @Override
- public Object getGlobalRoute(Object o) throws RoutingTableException, SystemException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public Set getRoutes(Object o) {
- Set<String> routes = new HashSet<String>();
- routes.add("localhost:5554");
- return routes;
- }
-
- @Override
- public Object getLastAddedRoute(Object o) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
-// @Override
-// public Set<Map.Entry> getAllRoutes() {
-// return Collections.emptySet();
-// }
-
-// @Override
-// public Object getARoute(Object o) {
-// return null;
-// }
-}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RemoteRpcProviderTest {
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testSetRoutingTableProvider() throws Exception {
-
- }
-
- @Test
- public void testOnSessionInitiated() throws Exception {
-
- }
-
- @Test
- public void testGetSupportedRpcs() throws Exception {
-
- }
-
- @Test
- public void testGetProviderFunctionality() throws Exception {
-
- }
-
- @Test
- public void testInvokeRpc() throws Exception {
-
- }
-
- @Test
- public void testInvokeRoutedRpc() throws Exception {
-
- }
-
- @Test
- public void testStart() throws Exception {
-
- }
-
- @Test
- public void testClose() throws Exception {
-
- }
-
- @Test
- public void testStop() throws Exception {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.StringWriter;
-
-public class SerilizationTest {
-
- private static final Logger _logger = LoggerFactory.getLogger(SerilizationTest.class);
-
- public void fromXml() {
- }
-
- @Test
- public void toXml() throws FileNotFoundException {
-
- //InputStream xmlStream = SerilizationTest.class.getResourceAsStream("/FourSimpleChildren.xml");
- InputStream xmlStream = SerilizationTest.class.getResourceAsStream("/AddFlow.xml");
- StringWriter writer = new StringWriter();
-
- CompositeNode data = loadCompositeNode(xmlStream);
- Document domTree = NodeUtils.buildShadowDomTree(data);
- try {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- //transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- //transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- //transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
- //transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- transformer.transform(new DOMSource(domTree), new StreamResult(writer));
- } catch (TransformerException e) {
- _logger.error("Error during translation of Document to OutputStream", e);
- }
-
- _logger.info("Parsed xml [{}]", writer.toString());
- }
-
- // Figure out how to include TestUtils through pom ...was getting errors
- private CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-
-import com.google.common.base.Optional;
-import junit.framework.Assert;
-import org.junit.*;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.zeromq.ZMQ;
-import zmq.Ctx;
-import zmq.SocketBase;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ThreadPoolExecutor;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ServerImplTest {
-
- private static ZMQ.Context context;
- private ServerImpl server;
- private Broker.ProviderSession brokerSession;
- private RoutingTableProvider routingTableProvider;
- private RpcRegistrationListener listener;
-
- ExecutorService pool;
-
- //Server configuration
- private final int HANDLER_COUNT = 2;
- private final int HWM = 200;
- private final int port = 5554;
- //server address
- private final String SERVER_ADDRESS = "tcp://localhost:5554";
-
- //@BeforeClass
- public static void init() {
- context = ZMQ.context(1);
- }
-
- //@AfterClass
- public static void destroy() {
- MessagingUtil.closeZmqContext(context);
- }
-
- @Before
- public void setup() throws InterruptedException {
- context = ZMQ.context(1);
- brokerSession = mock(Broker.ProviderSession.class);
- routingTableProvider = mock(RoutingTableProvider.class);
- listener = mock(RpcRegistrationListener.class);
-
- server = new ServerImpl(port);
- server.setBrokerSession(brokerSession);
-
- RoutingTable<RpcRouter.RouteIdentifier, String> mockRoutingTable = new MockRoutingTable<String, String>();
- Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
- when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
-
- when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
- when(brokerSession.getSupportedRpcs()).thenReturn(Collections.EMPTY_SET);
- when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null);
- server.start();
- Thread.sleep(5000);//wait for server to start
- }
-
- @After
- public void tearDown() throws InterruptedException {
-
- if (pool != null)
- pool.shutdown();
-
- if (server != null)
- server.stop();
-
- MessagingUtil.closeZmqContext(context);
-
- Thread.sleep(5000);//wait for server to stop
- Assert.assertEquals(ServerImpl.State.STOPPED, server.getStatus());
- }
-
- @Test
- public void getBrokerSession_Call_ShouldReturnBrokerSession() throws Exception {
- Optional<Broker.ProviderSession> mayBeBroker = server.getBrokerSession();
-
- if (mayBeBroker.isPresent())
- Assert.assertEquals(brokerSession, mayBeBroker.get());
- else
- Assert.fail("Broker does not exist in Remote RPC Server");
-
- }
-
- @Test
- public void start_Call_ShouldSetServerStatusToStarted() throws Exception {
- Assert.assertEquals(ServerImpl.State.STARTED, server.getStatus());
-
- }
-
- @Test
- public void start_Call_ShouldCreateNZmqSockets() throws Exception {
- final int EXPECTED_COUNT = 2 + HANDLER_COUNT; //1 ROUTER + 1 DEALER + HANDLER_COUNT
-
- Optional<ZMQ.Context> mayBeContext = server.getZmqContext();
- if (mayBeContext.isPresent())
- Assert.assertEquals(EXPECTED_COUNT, findSocketCount(mayBeContext.get()));
- else
- Assert.fail("ZMQ Context does not exist in Remote RPC Server");
- }
-
- @Test
- public void start_Call_ShouldCreate1ServerThread() {
- final String SERVER_THREAD_NAME = "remote-rpc-server";
- final int EXPECTED_COUNT = 1;
- List<Thread> serverThreads = findThreadsWithName(SERVER_THREAD_NAME);
- Assert.assertEquals(EXPECTED_COUNT, serverThreads.size());
- }
-
- @Test
- public void start_Call_ShouldCreateNHandlerThreads() {
- //final String WORKER_THREAD_NAME = "remote-rpc-worker";
- final int EXPECTED_COUNT = HANDLER_COUNT;
-
- Optional<ServerRequestHandler> serverRequestHandlerOptional = server.getHandler();
- if (serverRequestHandlerOptional.isPresent()){
- ServerRequestHandler handler = serverRequestHandlerOptional.get();
- ThreadPoolExecutor workerPool = handler.getWorkerPool();
- Assert.assertEquals(EXPECTED_COUNT, workerPool.getPoolSize());
- } else {
- Assert.fail("Server is in illegal state. ServerHandler does not exist");
- }
-
- }
-
- @Test
- public void testStop() throws Exception {
-
- }
-
- @Test
- public void testOnRouteUpdated() throws Exception {
-
- }
-
- @Test
- public void testOnRouteDeleted() throws Exception {
-
- }
-
- private int findSocketCount(ZMQ.Context context)
- throws NoSuchFieldException, IllegalAccessException {
- Field ctxField = context.getClass().getDeclaredField("ctx");
- ctxField.setAccessible(true);
- Ctx ctx = Ctx.class.cast(ctxField.get(context));
-
- Field socketListField = ctx.getClass().getDeclaredField("sockets");
- socketListField.setAccessible(true);
- List<SocketBase> sockets = List.class.cast(socketListField.get(ctx));
-
- return sockets.size();
- }
-
- private List<Thread> findThreadsWithName(String name) {
- Thread[] threads = new Thread[Thread.activeCount()];
- Thread.enumerate(threads);
-
- List<Thread> foundThreads = new ArrayList();
- for (Thread t : threads) {
- if (t.getName().startsWith(name))
- foundThreads.add(t);
- }
-
- return foundThreads;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import junit.framework.Assert;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.zeromq.ZMQ;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static org.mockito.Mockito.mock;
-
-public class ServerRequestHandlerTest {
-
- ServerRequestHandler handler;
- ZMQ.Context context;
- ExecutorService executorService = Executors.newCachedThreadPool();
- private int workerCount = 2;
- private String mockDealerAddress = "inproc://rpc-request-handler";
- private String mockServerIp = "localhost";
- private int mockServerPort = 5554;
-
- @Before
- public void setUp() throws Exception {
- context = ZMQ.context(1);
- String mockServerAddress = mockServerIp + ":" + mockServerPort;
- Broker.ProviderSession mockSession = mock(Broker.ProviderSession.class);
- handler = new ServerRequestHandler(context, mockSession, workerCount, mockDealerAddress, mockServerAddress);
- handler.start();
- }
-
- @After
- public void tearDown() throws Exception {
- executorService.shutdown();
- MessagingUtil.closeZmqContext(context);
- handler.close();
- }
-
- @Test
- public void testStart() throws Exception {
- //should start workers == workerCount
- Assert.assertEquals(workerCount, handler.getWorkerPool().getPoolSize());
-
- //killing a thread should recreate another one
-
- //start router-dealer bridge
- executorService.execute(MessagingUtil.createRouterDealerBridge(context, mockDealerAddress, mockServerPort));
- Thread.sleep(1000); //give sometime for socket initialization
-
- //this will kill the thread
- final String WORKER_THREAD_NAME = "remote-rpc-worker";
- interruptAThreadWithName(WORKER_THREAD_NAME);
-
- //send 4 message to router
- for (int i = 0; i < 4; i++)
- executorService.execute(MessagingUtil.sendAnEmptyMessage(context, "tcp://" + mockServerIp + ":" + mockServerPort));
-
- //worker pool size should not change.
- Assert.assertEquals(workerCount, handler.getWorkerPool().getPoolSize());
-
- Thread.sleep(10000); //wait for processing to complete
- }
-
- @Test
- public void testClose() throws Exception {
-
- }
-
- /**
- * Interrupts the first thread found whose name starts with the provided name
- *
- * @param name
- */
- private void interruptAThreadWithName(String name) {
- List<Thread> workerThreads = findThreadsWithName(name);
- if (workerThreads.size() > 0) workerThreads.get(0).interrupt();
- }
-
- /**
- * Find all threads that start with the given name
- *
- * @param name
- * @return
- */
- private List<Thread> findThreadsWithName(String name) {
- Thread[] threads = new Thread[Thread.activeCount()];
- Thread.enumerate(threads);
-
- List<Thread> foundThreads = new ArrayList();
- for (Thread t : threads) {
- if (t.getName().startsWith(name))
- foundThreads.add(t);
- }
-
- return foundThreads;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc.utils;
-
-import junit.framework.Assert;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-public class MessagingUtil {
-
- private static final Logger _logger = LoggerFactory.getLogger(MessagingUtil.class);
-
- public static Runnable startReplyServer(final ZMQ.Context context,
- final String serverAddress,
- final int numRequests /*number of requests after which server shuts down*/) {
- return new Runnable() {
-
- @Override
- public void run() {
- final ZMQ.Socket socket = context.socket(ZMQ.REP);
- try {
- int returnCode = socket.bind("tcp://" + serverAddress);
- Assert.assertNotSame(-1, returnCode);
- _logger.info(" Starting reply server[{}] for test...", serverAddress);
-
- //for (int i=0;i<numRequests;i++) {
- while (!Thread.currentThread().isInterrupted()) {
- byte[] bytes = socket.recv();
- _logger.debug(" Got request ");
- socket.send(bytes);
- _logger.debug(" Sent response ");
- }
- } catch (Exception x) {
- StringWriter w = new StringWriter();
- PrintWriter p = new PrintWriter(w);
- x.printStackTrace(p);
- _logger.debug(w.toString());
- } finally {
- socket.close();
- _logger.info("Shutting down reply server");
- }
- }
- };
- }
-
- public static Runnable createRouterDealerBridge(final ZMQ.Context context, final String dealerAddress, final int routerPort) {
- return new Runnable() {
- @Override
- public void run() {
- ZMQ.Socket router = null;
- ZMQ.Socket dealer = null;
- try {
- router = context.socket(ZMQ.ROUTER);
- dealer = context.socket(ZMQ.DEALER);
- router.bind("tcp://*:" + routerPort);
- dealer.bind(dealerAddress);
- ZMQ.proxy(router, dealer, null);
- } catch (Exception e) {/*Ignore*/} finally {
- if (router != null) router.close();
- if (dealer != null) dealer.close();
- }
- }
- };
- }
-
- public static Runnable sendAMessage(final ZMQ.Context context, final String serverAddress, final Message msg)
- throws IOException, ClassNotFoundException, InterruptedException {
-
- return new Runnable() {
- @Override
- public void run() {
- final ZMQ.Socket socket = context.socket(ZMQ.REQ);
- try {
-
- socket.connect(serverAddress);
- System.out.println(Thread.currentThread().getName() + " Sending message");
- try {
- socket.send(Message.serialize(msg));
- } catch (IOException e) {
- e.printStackTrace();
- }
- byte[] bytes = socket.recv();
- Message response = null;
- try {
- response = (Message) Message.deserialize(bytes);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + " Got response " + response);
- } catch (Exception x) {
- x.printStackTrace();
- } finally {
- socket.close();
- }
- }
- };
- }
-
- public static Runnable sendAnEmptyMessage(final ZMQ.Context context, final String serverAddress)
- throws IOException, ClassNotFoundException, InterruptedException {
-
- return new Runnable() {
- @Override
- public void run() {
- final ZMQ.Socket socket = context.socket(ZMQ.REQ);
- try {
-
- socket.connect(serverAddress);
- System.out.println(Thread.currentThread().getName() + " Sending message");
- try {
- socket.send(Message.serialize(new Message()));
- } catch (IOException e) {
- e.printStackTrace();
- }
- byte[] bytes = socket.recv();
- Message response = null;
- try {
- response = (Message) Message.deserialize(bytes);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + " Got response " + response);
- } catch (Exception x) {
- x.printStackTrace();
- } finally {
- socket.close();
- }
- }
- };
- }
-
- public static Message createEmptyMessage() {
- return new Message();
- }
-
- /**
- * Closes ZMQ Context. It tries to gracefully terminate the context. If
- * termination takes more than a second, its forcefully shutdown.
- */
- public static void closeZmqContext(final ZMQ.Context context) {
- if (context == null) return;
-
- ExecutorService exec = Executors.newSingleThreadExecutor();
- FutureTask zmqTermination = new FutureTask(new Runnable() {
-
- @Override
- public void run() {
- try {
- if (context != null)
- context.term();
- _logger.debug("ZMQ Context terminated gracefully!");
- } catch (Exception e) {/*Ignore and continue shutdown*/}
- }
- }, null);
-
- exec.execute(zmqTermination);
-
- try {
- zmqTermination.get(1L, TimeUnit.SECONDS);
- } catch (Exception e) {
- _logger.debug("ZMQ Context terminated forcefully!");
- }
-
- exec.shutdownNow();
- }
-}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.remoterpc.utils;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.zeromq.ZMQ;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class RemoteServerTestClient {
-
-
-
- public static void main(String args[]) throws Exception{
- String serverAddress = "tcp://10.195.128.108:5666";
- ZMQ.Context ctx = ZMQ.context(1);
- ExecutorService executor = Executors.newSingleThreadExecutor();
- RemoteServerTestClient client = new RemoteServerTestClient();
- executor.execute(
- MessagingUtil.sendAMessage(ctx, serverAddress, client.createPingMessage(serverAddress))
- );
- MessagingUtil.sendAMessage(ctx, serverAddress, client.createPingMessage(serverAddress));
-
- Thread.sleep(5000);
- MessagingUtil.closeZmqContext(ctx);
- executor.shutdown();
- }
-
- public Message createPingMessage(String serverAddress){
- Message ping = new Message.MessageBuilder()
- .type(Message.MessageType.PING)
- .sender("localhost:5444")
- .recipient(serverAddress)
- .build();
-
- return ping;
- }
- public Message createAddFlowMessage(String serverAddress ){
-
- RpcRouter.RouteIdentifier routeIdentifier = getAddFlowRpcIdentifier();
-
- Message addFlow = new Message.MessageBuilder()
- .type(Message.MessageType.REQUEST)
- .sender("localhost:5444")
- .recipient(serverAddress)
- .route(routeIdentifier)
- .payload(getAddFlowPayload(1,1))
- .build();
-
- return addFlow;
- }
-
- private RpcRouter.RouteIdentifier getAddFlowRpcIdentifier(){
- throw new UnsupportedOperationException();
- }
-
- private CompositeNode getAddFlowPayload(int flowId, int tableId){
- final String xml =
- "<flow xmlns=\"urn:opendaylight:flow:inventory\">"
- + "<priority>5</priority>"
- + "<flow-name>Foo</flow-name>"
- + "<match>"
- + "<ethernet-match>"
- + "<ethernet-type>"
- + "<type>2048</type>"
- + "</ethernet-type>"
- + "</ethernet-match>"
- + "<ipv4-destination>10.0.10.2/24</ipv4-destination>"
- + "</match>"
- + "<id>" + flowId + "</id>"
- + "<table_id>" + tableId + "</table_id>"
- + "<instructions>"
- + "<instruction>"
- + "<order>0</order>"
- + "<apply-actions>"
- + "<action>"
- + "<order>0</order>"
- + "<dec-nw-ttl/>"
- + "</action>"
- + "</apply-actions>"
- + "</instruction>"
- + "</instructions>"
- + "</flow>";
-
- return XmlUtils.xmlToCompositeNode(xml);
- }
-}
+++ /dev/null
-<add-flow xmlns="urn:opendaylight:flow:service">
- <input>
- <transaction-uri>BA-7</transaction-uri>
- <table_id>4</table_id>
- <priority>5</priority>
- <node>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]
- </node>
- <match>
- <ipv4-destination>10.0.10.2/24</ipv4-destination>
- <ethernet-match>
- <ethernet-type>
- <type>2048</type>
- </ethernet-type>
- </ethernet-match>
- </match>
- <instructions>
- <instruction>
- <order>0</order>
- <apply-actions>
- <action>
- <order>0</order>
- <dec-nw-ttl/>
- </action>
- </apply-actions>
- </instruction>
- </instructions>
- <flow-table>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]
- </flow-table>
- <flow-ref>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)flow[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]
- </flow-ref>
- <flow-name>Foo</flow-name>
- </input>
-</add-flow>
\ No newline at end of file
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</rpc>
+++ /dev/null
-<configuration scan="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <root level="DEBUG">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
+++ /dev/null
-<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>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- <packaging>bundle</packaging>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sample.zeromq.consumer;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Hashtable;
-import java.util.concurrent.*;
-
-import org.opendaylight.controller.sal.core.api.AbstractConsumer;
-import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-
-import javax.xml.stream.XMLStreamException;
-
-public class ExampleConsumer extends AbstractConsumer {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
- private ConsumerSession session;
-
- private ServiceRegistration<ExampleConsumer> thisReg;
- private Logger _logger = LoggerFactory.getLogger(ExampleConsumer.class);
-
- @Override
- public void onSessionInitiated(ConsumerSession session) {
- this.session = session;
- }
-
- public RpcResult<CompositeNode> invokeRpc(QName qname, CompositeNode input) {
- _logger.info("Invoking RPC:[{}] with Input:[{}]", qname.getLocalName(), input);
- RpcResult<CompositeNode> result = null;
- Future<RpcResult<CompositeNode>> future = ExampleConsumer.this.session.rpc(qname, input);
- try {
- result = future.get();
- } catch (Exception e) {
- e.printStackTrace();
- }
- _logger.info("Returning Result:[{}]", result);
- return result;
- }
-
- @Override
- protected void startImpl(BundleContext context){
- thisReg = context.registerService(ExampleConsumer.class, this, new Hashtable<String,String>());
- }
- @Override
- protected void stopImpl(BundleContext context) {
- super.stopImpl(context);
- thisReg.unregister();
- }
-
- public CompositeNode getValidCompositeNodeWithOneSimpleChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/OneSimpleChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithTwoSimpleChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/TwoSimpleChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithFourSimpleChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/FourSimpleChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithOneSimpleOneCompositeChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/OneSimpleOneCompositeChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithTwoCompositeChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/TwoCompositeChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getInvalidCompositeNodeSimpleChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/InvalidSimpleChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getInvalidCompositeNodeCompositeChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/InvalidCompositeChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- //Note to self: Stolen from TestUtils
- ///Users/alefan/odl/controller4/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
- // Figure out how to include TestUtils through pom ...was getting errors
- private CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</rpc>
+++ /dev/null
-<rpc>
- <innerinterface1>
- <name>eth1</name>
- <type>ethernet</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface1>
- <innerinterface2>
- <name>error</name>
- <type>ethernet</type>
- <enabled>true</enabled>
- <description>some interface</description>
- </innerinterface2>
-</rpc>
+++ /dev/null
-<rpc>
- <name>error</name>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <innerinterface>
- <name>eth1</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface>
-</rpc>
+++ /dev/null
-<rpc>
- <innerinterface1>
- <name>eth1</name>
- <type>ethernet</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface1>
- <innerinterface2>
- <name>eth2</name>
- <type>ethernet</type>
- <enabled>true</enabled>
- <description>some interface</description>
- </innerinterface2>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
- <packaging>pom</packaging>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
- <modules>
- <module>consumer-service</module>
- <module>provider-service</module>
- <module>test-it</module>
- <module>test-nb</module>
- </modules>
-
-</project>
+++ /dev/null
-<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>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- <packaging>bundle</packaging>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.sample.zeromq.provider.ExampleProvider</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sample.zeromq.provider;
-
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.URI;
-import java.util.*;
-
-public class ExampleProvider extends AbstractProvider implements RpcImplementation {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
- private RpcRegistration reg;
-
- private ServiceRegistration thisReg;
-
- private ProviderSession session;
- private Logger _logger = LoggerFactory.getLogger(ExampleProvider.class);
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
- this.session = session;
- }
-
- @Override
- public Set<QName> getSupportedRpcs() {
- Set<QName> supportedRpcs = new HashSet<QName>();
- supportedRpcs.add(QNAME);
- return supportedRpcs;
- }
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(final QName rpc, CompositeNode input) {
- boolean success = false;
- CompositeNode output = null;
- Collection<RpcError> errors = new ArrayList<>();
-
- // Only handle supported RPC calls
- if (getSupportedRpcs().contains(rpc)) {
- if (input == null) {
- errors.add(RpcErrors.getRpcError("app", "tag", "info", RpcError.ErrorSeverity.WARNING, "message:null input", RpcError.ErrorType.RPC, null));
- }
- else {
- if (isErroneousInput(input)) {
- errors.add(RpcErrors.getRpcError("app", "tag", "info", RpcError.ErrorSeverity.ERROR, "message:error", RpcError.ErrorType.RPC, null));
- }
- else {
- success = true;
- output = addSuccessNode(input);
- }
- }
- }
- return Rpcs.getRpcResult(success, output, errors);
- }
-
- // Examines input -- dives into CompositeNodes and finds any value equal to "error"
- private boolean isErroneousInput(CompositeNode input) {
- for (Node<?> n : input.getChildren()) {
- if (n instanceof CompositeNode) {
- if (isErroneousInput((CompositeNode)n)) {
- return true;
- }
- }
- else { //SimpleNode
- if ((input.getChildren().get(0).getValue()).equals("error")) {
- return true;
- }
- }
- }
- return false;
- }
-
- // Adds a child SimpleNode containing the value "success" to the input CompositeNode
- private CompositeNode addSuccessNode(CompositeNode input) {
- List<Node<?>> list = new ArrayList<Node<?>>(input.getChildren());
- SimpleNodeTOImpl<String> simpleNode = new SimpleNodeTOImpl<String>(QNAME, input, "success");
- list.add(simpleNode);
- return new CompositeNodeTOImpl(QNAME, null, list);
- }
-
- @Override
- protected void startImpl(BundleContext context) {
- thisReg = context.registerService(ExampleProvider.class, this, new Hashtable<String, String>());
- }
-
- @Override
- protected void stopImpl(BundleContext context) {
- if (reg != null) {
- try {
- reg.close();
- thisReg.unregister();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
- public void announce(QName name) {
- _logger.debug("Announcing [{}]\n\n\n", name);
- reg = this.session.addRpcImplementation(name, this);
- }
-
-}
+++ /dev/null
-<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>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-it</artifactId>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
- <properties>
- <jackson.version>2.3.0</jackson.version>
- <exam.version>3.0.0</exam.version>
- <url.version>1.5.0</url.version>
- </properties>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>1.7</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>maven-paxexam-plugin</artifactId>
- <version>1.2.4</version>
- <executions>
- <execution>
- <id>generate-config</id>
- <goals>
- <goal>generate-depends-file</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- <pluginManagement>
- <plugins>
- <!--This plugin's configuration is used to store Eclipse
- m2e settings only. It has no influence on the Maven build itself. -->
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>1.0.0</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>
- org.ops4j.pax.exam
- </groupId>
- <artifactId>
- maven-paxexam-plugin
- </artifactId>
- <versionRange>
- [1.2.4,)
- </versionRange>
- <goals>
- <goal>
- generate-depends-file
- </goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <ignore></ignore>
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>xtend-lib-osgi</artifactId>
- <version>2.4.3</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-native</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-link-mvn</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- <version>1.5.2</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <version>3.8.1.v20120830-144521</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <version>1.7.2</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>1.0.9</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.0.9</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <!--dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-data-impl</artifactId>
- <version>${yangtools.version}</version> </dependency -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-parser-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>antlr4-runtime-osgi-nohead</artifactId>
- <version>4.0</version>
- </dependency>
-
- <!-- routing table dependencies -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>zeromq-routingtable.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.stub</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- <version>3.0.1</version>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>eclipselink</groupId>
- <artifactId>javax.resource</artifactId>
- <version>1.5.0.v200906010428</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>yang-ext</artifactId>
- <version>2013.09.07.3</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.3</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-it</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-config</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-connector-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <version>3.8.1.v20120830-144521</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>0.3.1</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>xtend-lib-osgi</artifactId>
- <version>2.4.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-native</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-netconf-connector</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>logback-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-persister-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-persister-file-xml-adapter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <version>${exam.version}</version>
- <!-- Compile scope here is intentional, it is used in TestHelper
- class which could be downloaded via nexus and reused in other integration
- tests. -->
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-link-mvn</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <version>3.8.1.v20120830-144521</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <version>1.7.2</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>1.0.9</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.0.9</version>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-service</artifactId>
- <version>1.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager</artifactId>
- <version>0.2.3-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-management</artifactId>
- <version>1.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>antlr4-runtime-osgi-nohead</artifactId>
- <version>4.0</version>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sample.zeromq.test.it;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient;
-
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer;
-import org.opendaylight.controller.sample.zeromq.provider.ExampleProvider;
-
-import org.opendaylight.controller.test.sal.binding.it.TestHelper;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.util.Filter;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import javax.inject.Inject;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Hashtable;
-
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
-
-import static org.ops4j.pax.exam.CoreOptions.*;
-
-@RunWith(PaxExam.class)
-public class RouterTest {
-
- private Logger _logger = LoggerFactory.getLogger(RouterTest.class);
-
- public static final String ODL = "org.opendaylight.controller";
- public static final String YANG = "org.opendaylight.yangtools";
- public static final String SAMPLE = "org.opendaylight.controller.tests";
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
-
- @Inject
- org.osgi.framework.BundleContext ctx;
-
- @Inject
- @Filter(timeout=60*1000)
- Broker broker;
-
- private ZMQ.Context zmqCtx = ZMQ.context(1);
- //private Server router;
- //private ExampleProvider provider;
-
- //@Test
- public void testInvokeRpc() throws Exception{
- //Thread.sleep(1000);
- //Send announcement
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
-
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
-
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
-
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- ServiceReference routerRef = ctx.getServiceReference(RemoteRpcClient.class);
- RemoteRpcClient router = (RemoteRpcClient) ctx.getService(routerRef);
- _logger.debug("Found router[{}]", router);
- _logger.debug("Invoking RPC [{}]", QNAME);
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = router.invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertNotNull(result);
- }
- }
-
- @Test
- public void testInvokeRpcWithValidSimpleNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithOneSimpleChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithValidSimpleNodes() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithFourSimpleChildren();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithValidCompositeNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithTwoCompositeChildren();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithNullInput() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, null);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.WARNING, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- @Test
- public void testInvokeRpcWithInvalidSimpleNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getInvalidCompositeNodeSimpleChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.ERROR, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- @Test
- public void testInvokeRpcWithInvalidCompositeNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getInvalidCompositeNodeCompositeChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.ERROR, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- //@Test
- // This method is UNTESTED -- need to get around the bundling issues before I know if this even work
-// public void testInvokeRpcWithValidCompositeNode() throws Exception{
-// Thread.sleep(10000);
-// //Send announcement
-// ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
-// Assert.assertNotNull(providerRef);
-//
-// ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
-// Assert.assertNotNull(provider);
-//
-// ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
-// Assert.assertNotNull(consumerRef);
-//
-// ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
-// Assert.assertNotNull(consumer);
-//
-// _logger.debug("Provider sends announcement [{}]", "heartbeat");
-// provider.announce(QNAME);
-// ServiceReference routerRef = ctx.getServiceReference(Client.class);
-// Client router = (Client) ctx.getService(routerRef);
-// _logger.debug("Found router[{}]", router);
-// _logger.debug("Invoking RPC [{}]", QNAME);
-// for (int i = 0; i < 3; i++) {
-// RpcResult<CompositeNode> result = router.getInstance().invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
-// _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
-// Assert.assertNotNull(result);
-// }
-// }
-
- private Message send(Message msg) throws IOException {
- ZMQ.Socket reqSocket = zmqCtx.socket(ZMQ.REQ);
- reqSocket.connect("tcp://localhost:5555");
- reqSocket.send(Message.serialize(msg));
- Message response = parseMessage(reqSocket);
-
- return response;
- }
-
- /**
- * @param socket
- * @return
- */
- private Message parseMessage(ZMQ.Socket socket) {
-
- Message msg = null;
- try {
- byte[] bytes = socket.recv();
- _logger.debug("Received bytes:[{}]", bytes.length);
- msg = (Message) Message.deserialize(bytes);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- return msg;
- }
-
-
- private void printState(){
- Bundle[] b = ctx.getBundles();
- _logger.debug("\n\nNumber of bundles [{}]\n\n]", b.length);
- for (int i=0;i<b.length;i++){
- _logger.debug("Bundle States {}-{} ",b[i].getSymbolicName(), stateToString(b[i].getState()));
-
- if ( Bundle.INSTALLED == b[i].getState() || (Bundle.RESOLVED == b[i].getState())){
- try {
- b[i].start();
- } catch (BundleException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- private String stateToString(int state) {
- switch (state) {
- case Bundle.ACTIVE:
- return "ACTIVE";
- case Bundle.INSTALLED:
- return "INSTALLED";
- case Bundle.RESOLVED:
- return "RESOLVED";
- case Bundle.UNINSTALLED:
- return "UNINSTALLED";
- default:
- return "Not CONVERTED";
- }
- }
-
- @Configuration
- public Option[] config() {
- return options(systemProperty("osgi.console").value("2401"),
- systemProperty("rpc.port").value("5555"),
- mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), //
- mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
- mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
- mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
-
- //mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-common").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
- mavenBundle(ODL, "sal-common-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-util").versionAsInProject(), //
- mavenBundle(ODL, "sal-core-api").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-broker-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-core-spi").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-connector-api").versionAsInProject(), //
-
-
- baseModelBundles(),
- bindingAwareSalBundles(),
- TestHelper.bindingIndependentSalBundles(),
- TestHelper.configMinumumBundles(),
- TestHelper.mdSalCoreBundles(),
-
- //Added the consumer
- mavenBundle(SAMPLE, "sal-remoterpc-connector-test-consumer").versionAsInProject(), //
- //**** These two bundles below are NOT successfully resolved -- some of their dependencies must be missing
- //**** This causes the "Message" error to occur, the class cannot be found
- mavenBundle(SAMPLE, "sal-remoterpc-connector-test-provider").versionAsInProject(), //
- mavenBundle(ODL, "sal-remoterpc-connector").versionAsInProject(), //
-
- mavenBundle(ODL, "zeromq-routingtable.implementation").versionAsInProject(),
- mavenBundle(YANG, "concepts").versionAsInProject(),
- mavenBundle(YANG, "yang-binding").versionAsInProject(), //
- mavenBundle(YANG, "yang-common").versionAsInProject(), //
- mavenBundle(YANG, "yang-data-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-data-impl").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-parser-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-parser-impl").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
- mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), //
- mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
- mavenBundle("com.google.guava", "guava").versionAsInProject(), //
- mavenBundle("org.zeromq", "jeromq").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
- mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
- //routingtable dependencies
- systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
- // List framework bundles
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.console").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.util").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.osgi.services").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell").versionAsInProject(),
- // List logger bundles
-
- mavenBundle("org.opendaylight.controller", "clustering.services")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.controller", "clustering.stub")
- .versionAsInProject(),
-
-
- // List all the bundles on which the test case depends
- mavenBundle("org.opendaylight.controller", "sal")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.controller", "sal.implementation")
- .versionAsInProject(),
- mavenBundle("org.jboss.spec.javax.transaction",
- "jboss-transaction-api_1.1_spec").versionAsInProject(),
- mavenBundle("org.apache.commons", "commons-lang3")
- .versionAsInProject(),
- mavenBundle("org.apache.felix",
- "org.apache.felix.dependencymanager")
- .versionAsInProject(),
-
- junitBundles()
- );
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<persisted-snapshots>
- <snapshots>
- <snapshot>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
- </capability>
- <capability>
- urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
- </capability>
- <capability>
- urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
- </capability>
- <capability>
- urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
- </capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28</capability>
- <capability>
- urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28
- </capability>
- </required-capabilities>
- <configuration>
-
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:schema-service-singleton
- </type>
- <name>yang-schema-service</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:hash-map-data-store
- </type>
- <name>hash-map-data-store</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:dom-broker-impl
- </type>
- <name>dom-broker</name>
- <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-data-store
- </type>
- <name>ref_hash-map-data-store</name>
- </data-store>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-broker-impl
- </type>
- <name>binding-broker-impl</name>
- <notification-service
- xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
- </type>
- <name>ref_binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-data-broker
- </type>
- <name>ref_binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:runtime-generated-mapping
- </type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-notification-broker
- </type>
- <name>binding-notification-broker</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-data-broker
- </type>
- <name>binding-data-broker</name>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-broker-osgi-registry
- </type>
- <name>ref_dom-broker</name>
- </dom-broker>
- <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- binding:binding-dom-mapping-service
- </type>
- <name>ref_runtime-mapping-singleton</name>
- </mapping-service>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- prefix:remote-zeromq-rpc-server
- </type>
- <name>remoter</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- prefix:dom-broker-osgi-registry
- </type>
- <name>ref_dom-broker</name>
- </dom-broker>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:schema-service
- </type>
- <instance>
- <name>ref_yang-schema-service</name>
- <provider>
- /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
- </type>
- <instance>
- <name>ref_binding-notification-broker</name>
- <provider>
- /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-data-store
- </type>
- <instance>
- <name>ref_hash-map-data-store</name>
- <provider>
- /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-broker-osgi-registry
- </type>
- <instance>
- <name>ref_binding-broker-impl</name>
- <provider>
- /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- binding-impl:binding-dom-mapping-service
- </type>
- <instance>
- <name>ref_runtime-mapping-singleton</name>
- <provider>
- /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-broker-osgi-registry
- </type>
- <instance>
- <name>ref_dom-broker</name>
- <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-data-broker
- </type>
- <instance>
- <name>ref_binding-data-broker</name>
- <provider>
- /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']
- </provider>
- </instance>
- </service>
- </services>
- </data>
-
- </configuration>
- </snapshot>
- </snapshots>
-</persisted-snapshots>
+++ /dev/null
-<configuration scan="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
-
- <logger name="org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort" level="ERROR"/>
-
- <root level="info">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<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>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>sal-remoterpc-connector-test-nb</artifactId>
- <packaging>bundle</packaging>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- </Export-Package>
- <Import-Package>
- com.sun.jersey.spi.container.servlet,
- !org.codehaus.jackson.annotate,
- javax.ws.rs,
- javax.ws.rs.core,
- javax.xml.bind,
- javax.xml.bind.annotation,
- org.slf4j,
- org.apache.catalina.filters,
- !org.codehaus.jackson.jaxrs,
- org.opendaylight.controller.sample.zeromq.provider,
- org.opendaylight.controller.sample.zeromq.consumer,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.yangtools.yang.common,
- org.opendaylight.controller.sal.connector.api,
- org.opendaylight.controller.sal.connector.remoterpc.api;version="[0.4,1)",
- org.opendaylight.controller.sal.connector.remoterpc.impl;version="[0.4,1)",
- org.opendaylight.controller.sal.connector.remoterpc.dto,
- org.opendaylight.controller.sal.connector.remoterpc.util,
- org.osgi.framework,
- com.google.common.base,
- org.opendaylight.yangtools.yang.data.api,
- !org.codehaus.enunciate.jaxrs
-
- </Import-Package>
- <Web-ContextPath>/controller/nb/v2/zmqnb</Web-ContextPath>
- <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
- </instructions>
- <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>5.0.0</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- </dependencies>
-
- </project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.tests.zmqrouter.rest;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
-import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer;
-import org.opendaylight.controller.sample.zeromq.provider.ExampleProvider;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.osgi.framework.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.io.Serializable;
-import java.net.URI;
-import java.util.Set;
-
-@Path("router")
-public class Router {
- private Logger _logger = LoggerFactory.getLogger(Router.class);
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
-
- @GET
- @Path("/hello")
- @Produces(MediaType.TEXT_PLAIN)
- public String hello() {
- return "Hello";
- }
-
- @GET
- @Path("/announce")
- @Produces(MediaType.TEXT_PLAIN)
- public String announce() {
- _logger.info("Announce request received");
-
- BundleContext ctx = getBundleContext();
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- if (providerRef == null) {
- _logger.debug("Could not get provider reference");
- return "Could not get provider reference";
- }
-
- ExampleProvider provider = (ExampleProvider) ctx.getService(providerRef);
- if (provider == null) {
- _logger.info("Could not get provider service");
- return "Could not get provider service";
- }
-
- provider.announce(QNAME);
- return "Announcement sent ";
-
- }
-
- @GET
- @Path("/rpc")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpc() throws Exception {
- _logger.info("Invoking RPC");
-
- ExampleConsumer consumer = getConsumer();
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/rpc-success")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpcSuccess() throws Exception {
- ExampleConsumer consumer = getConsumer();
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getValidCompositeNodeWithFourSimpleChildren()); //TODO: Change this
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/rpc-failure")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpcFailure() throws Exception {
- ExampleConsumer consumer = getConsumer();
- //RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getInvalidCompositeNodeCompositeChild()); //TODO: Change this
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, null); //TODO: Change this
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/routingtable")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRoutingTable() {
- _logger.info("Invoking adding an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RoutingIdentifierImpl rii = new RoutingIdentifierImpl();
- try {
- routingTable.addGlobalRoute(rii.toString(), "172.27.12.1:5000");
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
- String result = routingTable.dumpRoutingTableCache();
-
-
-
-
- _logger.info("Result [{}] routes added for route" + rii + result);
-
- return result;
- }
-
- @GET
- @Path("/routingtabledelete")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeDeleteRoutingTable() {
- _logger.info("Invoking adding an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTable routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RoutingIdentifierImpl rii = new RoutingIdentifierImpl();
- try {
- routingTable.removeGlobalRoute(rii.toString());
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
- Set<String> routes = routingTable.getRoutes(rii.toString());
-
- StringBuilder stringBuilder = new StringBuilder();
- if (routes != null) {
- for (String route : routes) {
- stringBuilder.append(route);
- }
- } else {
- stringBuilder.append(" successfully");
- }
-
- _logger.info("Result [{}] routes removed for route" + rii + stringBuilder.toString());
-
- return stringBuilder.toString();
- }
-
- private String stringify(RpcResult<CompositeNode> result) {
- CompositeNode node = result.getResult();
- StringBuilder builder = new StringBuilder("result:").append(XmlUtils.compositeNodeToXml(node)).append("\n")
- .append("error:").append(result.getErrors()).append("\n");
-
- return builder.toString();
- }
-
- private BundleContext getBundleContext() {
- ClassLoader tlcl = Thread.currentThread().getContextClassLoader();
- Bundle bundle = null;
-
- if (tlcl instanceof BundleReference) {
- bundle = ((BundleReference) tlcl).getBundle();
- } else {
- _logger.info("Unable to determine the bundle context based on " +
- "thread context classloader.");
- bundle = FrameworkUtil.getBundle(this.getClass());
- }
- return (bundle == null ? null : bundle.getBundleContext());
- }
-
- private ExampleConsumer getConsumer() {
- BundleContext ctx = getBundleContext();
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- if (consumerRef == null) {
- _logger.debug("Could not get consumer reference");
- throw new NullPointerException("Could not get consumer reference");
- }
- ExampleConsumer consumer = (ExampleConsumer) ctx.getService(consumerRef);
- if (consumer == null) {
- _logger.info("Could not get consumer service");
- throw new NullPointerException("Could not get consumer service");
- }
- return consumer;
- }
-
- class RoutingIdentifierImpl implements RpcRouter.RouteIdentifier, Serializable {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "global");
- private final QName instance = new QName(URI.create("127.0.0.1"), "local");
-
- @Override
- public QName getContext() {
- return QNAME;
- }
-
- @Override
- public QName getType() {
- return QNAME;
- }
-
- @Override
- public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier getRoute() {
- return InstanceIdentifier.of(instance);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- RoutingIdentifierImpl that = (RoutingIdentifierImpl) o;
-
- if (!QNAME.equals(that.QNAME)) return false;
- if (!instance.equals(that.instance)) return false;
- if (!namespace.equals(that.namespace)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = namespace.hashCode();
- result = 31 * result + QNAME.hashCode();
- result = 31 * result + instance.hashCode();
- return result;
- }
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- version="3.0">
- <servlet>
- <servlet-name>JAXRSZmq</servlet-name>
- <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
- <init-param>
- <param-name>javax.ws.rs.Application</param-name>
- <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>JAXRSZmq</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
-
-
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>NB api</web-resource-name>
- <url-pattern>/*</url-pattern>
- <http-method>POST</http-method>
- <http-method>GET</http-method>
- <http-method>PUT</http-method>
- <http-method>PATCH</http-method>
- <http-method>DELETE</http-method>
- <http-method>HEAD</http-method>
- </web-resource-collection>
- <auth-constraint>
- <role-name>System-Admin</role-name>
- <role-name>Network-Admin</role-name>
- <role-name>Network-Operator</role-name>
- <role-name>Container-User</role-name>
- </auth-constraint>
- </security-constraint>
-
- <security-role>
- <role-name>System-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Operator</role-name>
- </security-role>
- <security-role>
- <role-name>Container-User</role-name>
- </security-role>
-
- <login-config>
- <auth-method>BASIC</auth-method>
- <realm-name>opendaylight</realm-name>
- </login-config>
-</web-app>