<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
<version>7.0.42</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<!-- yang model dependencies -->
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<module>yang-store-impl</module>
<module>yang-test</module>
<module>logback-config</module>
+ <module>threadpool-config-api</module>
+ <module>threadpool-config-impl</module>
</modules>
<profiles>
--- /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">
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-subsystem</artifactId>
+ <version>0.2.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>threadpool-config-api</artifactId>
+ <name>${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.opendaylight.controller.config.api.*,
+ com.google.common.eventbus,
+ </Import-Package>
+ <Export-Package>
+ org.opendaylight.controller.config.threadpool,
+ org.opendaylight.controller.config.yang.threadpool
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
--- /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.config.threadpool;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Interface representing scheduled {@link ThreadPool}.
+ */
+public interface ScheduledThreadPool extends ThreadPool {
+
+ @Override
+ public ScheduledExecutorService getExecutor();
+}
\ No newline at end of file
--- /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.config.threadpool;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Interface representing thread pool.
+ */
+public interface ThreadPool {
+
+ public ExecutorService getExecutor();
+
+ public int getMaxThreadCount();
+}
\ No newline at end of file
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module threadpool {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:threadpool";
+ prefix "th";
+
+ import config { prefix config; revision-date 2013-04-05; }
+
+ organization "Cisco Systems, Inc.";
+
+ contact "Robert Varga <rovarga@cisco.com>";
+
+ description
+ "This module contains the base YANG definitions for
+ thread-related services.
+
+ Copyright (c)2013 Cisco Systems, Inc. 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";
+
+ revision "2013-04-09" {
+ description
+ "Added eventbus service.";
+ }
+
+ revision "2013-04-05" {
+ description
+ "Updated with YANG extension for Java class specification.";
+ }
+
+ revision "2013-04-03" {
+ description
+ "Initial revision by Anton Tkacik, Tomas Olvecky and
+ Robert Varga.";
+ }
+
+ identity eventbus {
+ description
+ "Service representing an event bus. The service acts as message
+ router between event producers and event consumers";
+
+ base "config:service-type";
+ config:java-class "com.google.common.eventbus.EventBus";
+ }
+
+ identity threadfactory {
+ description
+ "Service representing a ThreadFactory instance. It is directly
+ useful in Java world, where various library pieces need to create
+ threads and you may want to inject a customized thread
+ implementation.";
+
+ base "config:service-type";
+ config:java-class "java.util.concurrent.ThreadFactory";
+ }
+
+ identity threadpool {
+ description
+ "A simple pool of threads able to execute work.";
+
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.config.threadpool.ThreadPool";
+ }
+
+ identity scheduled-threadpool {
+ description
+ "An extension of the simple pool of threads able to schedule
+ work to be executed at some point in time.";
+
+ base "threadpool";
+ config:java-class "org.opendaylight.controller.config.threadpool.ScheduledThreadPool";
+ }
+
+}
--- /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">
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-subsystem</artifactId>
+ <version>0.2.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>threadpool-config-impl</artifactId>
+ <name>${project.artifactId}</name>
+ <packaging>bundle</packaging>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>threadpool-config-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Private-Package>
+ org.opendaylight.controller.config.threadpool.util,
+ javax.annotation.*,
+ org.opendaylight.controller.config.yang.threadpool.impl,
+ </Private-Package>
+ <Import-Package>
+ org.opendaylight.controller.config.api.*,
+ org.opendaylight.controller.config.spi.*,
+ org.opendaylight.controller.config.threadpool,
+ org.opendaylight.controller.config.yang.threadpool,
+ javax.management,
+ org.osgi.framework,
+ org.slf4j,
+ com.google.common.*
+ </Import-Package>
+ <Export-Package>
+ org.opendaylight.controller.config.threadpool.util
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
--- /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.config.threadpool.util;
+
+import com.google.common.eventbus.AsyncEventBus;
+import com.google.common.eventbus.DeadEvent;
+import com.google.common.eventbus.Subscribe;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+import org.opendaylight.controller.config.yang.threadpool.impl.AsyncEventBusRuntimeMXBean;
+import org.opendaylight.controller.config.yang.threadpool.impl.AsyncEventBusRuntimeRegistration;
+import org.opendaylight.controller.config.yang.threadpool.impl.AsyncEventBusRuntimeRegistrator;
+
+/**
+ * Closeable version of {@link AsyncEventBus}.
+ */
+public class CloseableAsyncEventBus extends AsyncEventBus implements Closeable {
+ private final ThreadPool threadPool;
+ private final AsyncEventBusRuntimeRegistration rootRegistration;
+
+ public CloseableAsyncEventBus(String identifier, ThreadPool threadPool,
+ AsyncEventBusRuntimeRegistrator rootRegistrator) {
+ super(identifier, threadPool.getExecutor());
+ this.threadPool = threadPool;
+ rootRegistration = rootRegistrator.register(new AsyncEventBusRuntimeMXBean() {
+ private long deadEventsCounter = 0;
+
+ @Subscribe
+ public void increaseDeadEvents(DeadEvent deadEvent) {
+ deadEventsCounter++;
+ }
+
+ @Override
+ public Long countDeadEvents() {
+ return deadEventsCounter;
+ }
+
+ });
+ }
+
+ public ThreadPool getThreadPool() {
+ return threadPool;
+ }
+
+ @Override
+ public void close() throws IOException {
+ rootRegistration.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.config.threadpool.util;
+
+import java.io.Closeable;
+
+import org.opendaylight.controller.config.yang.threadpool.impl.EventBusRuntimeMXBean;
+import org.opendaylight.controller.config.yang.threadpool.impl.EventBusRuntimeRegistration;
+import org.opendaylight.controller.config.yang.threadpool.impl.EventBusRuntimeRegistrator;
+
+import com.google.common.eventbus.DeadEvent;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+
+/**
+ * Closeable {@link EventBus}.
+ */
+public class CloseableEventBus extends EventBus implements Closeable {
+
+ private final EventBusRuntimeRegistration rootRegistration;
+
+ public CloseableEventBus(String identifier, EventBusRuntimeRegistrator rootRegistrator) {
+ super(identifier);
+ rootRegistration = rootRegistrator.register(new EventBusRuntimeMXBean() {
+ private long deadEventsCounter = 0;
+
+ @Subscribe
+ public void increaseDeadEvents(DeadEvent deadEvent) {
+ deadEventsCounter++;
+ }
+
+ @Override
+ public Long countDeadEvents() {
+ return deadEventsCounter;
+ }
+ });
+
+ }
+
+ @Override
+ public void close() {
+ rootRegistration.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.config.threadpool.util;
+
+import java.io.Closeable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+
+/**
+ * Implementation of {@link ThreadPool} using fixed number of threads wraps
+ * {@link ExecutorService}.
+ */
+public class FixedThreadPoolWrapper implements ThreadPool, Closeable {
+
+ private final ThreadPoolExecutor executor;
+
+ public FixedThreadPoolWrapper(int threadCount, ThreadFactory factory) {
+ this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount, factory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ExecutorService getExecutor() {
+ return Executors.unconfigurableExecutorService(executor);
+ }
+
+ @Override
+ public void close() {
+ executor.shutdown();
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return executor.getMaximumPoolSize();
+ }
+
+ public void setMaxThreadCount(int maxThreadCount) {
+ executor.setCorePoolSize(maxThreadCount);
+ executor.setMaximumPoolSize(maxThreadCount);
+ }
+}
--- /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.config.threadpool.util;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.config.threadpool.ThreadPool;
+
+/**
+ * Implementation of {@link ThreadPool} using flexible number of threads wraps
+ * {@link ExecutorService}.
+ */
+public class FlexibleThreadPoolWrapper implements ThreadPool, Closeable {
+ private final ThreadPoolExecutor executor;
+
+ public FlexibleThreadPoolWrapper(int minThreadCount, int maxThreadCount, long keepAlive, TimeUnit timeUnit,
+ ThreadFactory threadFactory) {
+
+ executor = new ThreadPoolExecutor(minThreadCount, maxThreadCount, keepAlive, timeUnit,
+ new SynchronousQueue<Runnable>(), threadFactory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ExecutorService getExecutor() {
+ return Executors.unconfigurableExecutorService(executor);
+ }
+
+ public int getMinThreadCount() {
+ return executor.getCorePoolSize();
+ }
+
+ public void setMinThreadCount(int minThreadCount) {
+ executor.setCorePoolSize(minThreadCount);
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return executor.getMaximumPoolSize();
+ }
+
+ public void setMaxThreadCount(int maxThreadCount) {
+ executor.setMaximumPoolSize(maxThreadCount);
+ }
+
+ public long getKeepAliveMillis() {
+ return executor.getKeepAliveTime(TimeUnit.MILLISECONDS);
+ }
+
+ public void setKeepAliveMillis(long keepAliveMillis) {
+ executor.setKeepAliveTime(keepAliveMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public void setThreadFactory(ThreadFactory threadFactory) {
+ executor.setThreadFactory(threadFactory);
+ }
+
+ public void prestartAllCoreThreads() {
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public void close() throws IOException {
+ executor.shutdown();
+ }
+
+}
--- /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.config.threadpool.util;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Implementation of {@link ThreadFactory}.
+ */
+@ThreadSafe
+public class NamingThreadPoolFactory implements ThreadFactory, Closeable {
+
+ private final ThreadGroup group;
+ private final String namePrefix;
+ private final AtomicLong threadName = new AtomicLong();
+
+ public NamingThreadPoolFactory(String namePrefix) {
+ Preconditions.checkNotNull(namePrefix);
+ this.group = new ThreadGroup(namePrefix);
+ this.namePrefix = namePrefix;
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(group, r, String.format("%s-%d", group.getName(), threadName.incrementAndGet()));
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ public String getNamePrefix() {
+ return namePrefix;
+ }
+
+}
--- /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.config.threadpool.util;
+
+import java.io.Closeable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
+
+/**
+ * Implementation of {@link ScheduledThreadPool} wraps
+ * {@link ScheduledExecutorService}.
+ */
+public class ScheduledThreadPoolWrapper implements ScheduledThreadPool, Closeable {
+
+ private final ScheduledThreadPoolExecutor executor;
+ private final int threadCount;
+
+ public ScheduledThreadPoolWrapper(int threadCount, ThreadFactory factory) {
+ this.threadCount = threadCount;
+ this.executor = new ScheduledThreadPoolExecutor(threadCount, factory);
+ executor.prestartAllCoreThreads();
+ }
+
+ @Override
+ public ScheduledExecutorService getExecutor() {
+ return Executors.unconfigurableScheduledExecutorService(executor);
+ }
+
+ @Override
+ public void close() {
+ executor.shutdown();
+ }
+
+ @Override
+ public int getMaxThreadCount() {
+ return threadCount;
+ }
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: async-eventbus
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Tue Nov 05 15:40:46 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.threadpool.util.CloseableAsyncEventBus;
+
+/**
+*
+*/
+public final class AsyncEventBusModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractAsyncEventBusModule {
+
+ public AsyncEventBusModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public AsyncEventBusModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ AsyncEventBusModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new CloseableAsyncEventBus(getIdentifier().toString(), getThreadpoolDependency(),
+ getRootRuntimeBeanRegistratorWrapper());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: async-eventbus
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Tue Nov 05 15:40:46 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class AsyncEventBusModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractAsyncEventBusModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: eventbus
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Tue Nov 05 15:40:46 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.threadpool.util.CloseableEventBus;
+
+/**
+*
+*/
+public final class EventBusModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractEventBusModule {
+
+ public EventBusModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public EventBusModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, EventBusModule oldModule,
+ java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new CloseableEventBus(getIdentifier().toString(), getRootRuntimeBeanRegistratorWrapper());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: eventbus
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Tue Nov 05 15:40:46 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class EventBusModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractEventBusModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-fixed
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.FixedThreadPoolWrapper;
+
+/**
+*
+*/
+public final class FixedThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFixedThreadPoolModule {
+
+ public FixedThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public FixedThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ FixedThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new FixedThreadPoolWrapper(getMaxThreadCount(), getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-fixed
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class FixedThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFixedThreadPoolModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-flexible
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import java.util.concurrent.TimeUnit;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.FlexibleThreadPoolWrapper;
+
+/**
+*
+*/
+public final class FlexibleThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFlexibleThreadPoolModule {
+
+ public FlexibleThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public FlexibleThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ FlexibleThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getKeepAliveMillis(), keepAliveMillisJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getKeepAliveMillis() > 0, "must be greater than zero",
+ keepAliveMillisJmxAttribute);
+
+ JmxAttributeValidationException.checkNotNull(getMinThreadCount(), minThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMinThreadCount() > 0, "must be greater than zero",
+ minThreadCountJmxAttribute);
+
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new FlexibleThreadPoolWrapper(getMinThreadCount(), getMaxThreadCount(), getKeepAliveMillis(),
+ TimeUnit.MILLISECONDS, getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-flexible
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class FlexibleThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractFlexibleThreadPoolModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadfactory-naming
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory;
+
+/**
+*
+*/
+public final class NamingThreadFactoryModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractNamingThreadFactoryModule {
+
+ public NamingThreadFactoryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public NamingThreadFactoryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ NamingThreadFactoryModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getNamePrefix(), namePrefixJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new NamingThreadPoolFactory(getNamePrefix());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadfactory-naming
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class NamingThreadFactoryModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractNamingThreadFactoryModuleFactory {
+
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-scheduled
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.threadpool.util.ScheduledThreadPoolWrapper;
+
+/**
+*
+*/
+public final class ScheduledThreadPoolModule extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractScheduledThreadPoolModule {
+
+ public ScheduledThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public ScheduledThreadPoolModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ ScheduledThreadPoolModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ JmxAttributeValidationException.checkNotNull(getMaxThreadCount(), maxThreadCountJmxAttribute);
+ JmxAttributeValidationException.checkCondition(getMaxThreadCount() > 0, "must be greater than zero",
+ maxThreadCountJmxAttribute);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new ScheduledThreadPoolWrapper(getMaxThreadCount(), getThreadFactoryDependency());
+ }
+}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: threadpool-impl yang module local name: threadpool-scheduled
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 06 16:19:33 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.threadpool.impl;
+
+/**
+*
+*/
+public class ScheduledThreadPoolModuleFactory extends
+ org.opendaylight.controller.config.yang.threadpool.impl.AbstractScheduledThreadPoolModuleFactory {
+
+}
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module threadpool-impl {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl";
+ prefix "th-java";
+
+ import threadpool { prefix th; revision-date 2013-04-09; }
+ import config { prefix config; revision-date 2013-04-05; }
+ import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+
+ organization "Cisco Systems, Inc.";
+
+ contact "Robert Varga <rovarga@cisco.com>";
+
+ description
+ "This module contains the base YANG definitions for
+ thread services pure Java implementation.
+
+ Copyright (c)2013 Cisco Systems, Inc. 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";
+
+ revision "2013-04-05" {
+ description
+ "Updated to work with new anchors.";
+ }
+
+ revision "2013-04-03" {
+ description
+ "Initial revision by Anton Tkacik, Tomas Olvecky and
+ Robert Varga.";
+ }
+
+ identity eventbus {
+ base config:module-type;
+ config:provided-service th:eventbus;
+ config:java-name-prefix EventBus;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case eventbus {
+ when "/config:modules/config:module/config:type = 'eventbus'";
+ // No real configuration
+ }
+ }
+
+ augment "/config:modules/config:module/config:state" {
+ case eventbus {
+ when "/config:modules/config:module/config:type = 'eventbus'";
+ rpcx:rpc-context-instance "event-bus-rpc";
+ }
+ }
+
+ identity event-bus-rpc;
+
+ identity async-eventbus {
+ base config:module-type;
+ config:provided-service th:eventbus;
+ config:java-name-prefix AsyncEventBus;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case async-eventbus {
+ when "/config:modules/config:module/config:type = 'async-eventbus'";
+ container threadpool {
+ uses config:service-ref {
+ refine type {
+ //mandatory true;
+ config:required-identity th:threadpool;
+ }
+ }
+ }
+ }
+ }
+
+ augment "/config:modules/config:module/config:state" {
+ case async-eventbus {
+ when "/config:modules/config:module/config:type = 'async-eventbus'";
+ rpcx:rpc-context-instance "event-bus-rpc";
+ }
+ }
+
+ rpc get-dead-events-count {
+ config:java-name-prefix countDeadEvents;
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance event-bus-rpc;
+ }
+ }
+ }
+ output {
+ leaf result {
+ type uint32;
+ }
+ }
+ }
+
+ identity threadfactory-naming {
+ base config:module-type;
+ config:provided-service th:threadfactory;
+ config:java-name-prefix NamingThreadFactory;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadfactory-naming {
+ when "/config:modules/config:module/config:type = 'threadfactory-naming'";
+ leaf name-prefix {
+ type string;
+ }
+ }
+ }
+
+ identity threadpool-fixed {
+ base config:module-type;
+ config:provided-service th:threadpool;
+ config:java-name-prefix FixedThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-fixed {
+ when "/config:modules/config:module/config:type = 'threadpool-fixed'";
+ leaf max-thread-count {
+ type uint16;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ //mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
+
+ identity threadpool-flexible {
+ base config:module-type;
+ config:provided-service th:threadpool;
+ config:java-name-prefix FlexibleThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-flexible {
+ when "/config:modules/config:module/config:type = 'threadpool-flexible'";
+ leaf max-thread-count {
+ type uint16;
+ }
+ leaf minThreadCount {
+ type uint16;
+ }
+ leaf keepAliveMillis {
+ type uint32;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ // mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
+
+ identity threadpool-scheduled {
+ base config:module-type;
+ config:provided-service th:scheduled-threadpool;
+ config:java-name-prefix ScheduledThreadPool;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case threadpool-scheduled {
+ when "/config:modules/config:module/config:type = 'threadpool-scheduled'";
+ leaf max-thread-count {
+ type uint16;
+ }
+
+ container threadFactory {
+ uses config:service-ref {
+ refine type {
+ // mandatory true;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
+ }
+ }
+}
+
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-compability</artifactId>
+ <artifactId>sal-compatibility</artifactId>
<version>${mdsal.version}</version>
</dependency>
<dependency>
<version>2.4</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.yangtools.thirdparty</groupId>
<artifactId>antlr4-runtime-osgi-nohead</artifactId>
<version>4.0</version>
<artifactId>yang-model-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>yang-ext</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>yang-ext</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
</profile>
</profiles>
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>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>compatibility-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>flow-management-compatibility</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-compability</artifactId>
+ <artifactId>sal-compatibility</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager
import static com.google.common.base.Preconditions.*;
import static extension org.opendaylight.controller.md.frm.compatibility.FlowConfigMapping.*;
-import static extension org.opendaylight.controller.sal.compability.NodeMapping.*;
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*;
import org.opendaylight.controller.sal.common.util.Arguments
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
import org.opendaylight.yangtools.yang.common.RpcResult
import org.opendaylight.controller.forwardingrulesmanager.FlowConfig
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder
-import static extension org.opendaylight.controller.sal.compability.NodeMapping.*
-import static org.opendaylight.controller.sal.compability.MDFlowMapping.*
-import static org.opendaylight.controller.sal.compability.ToSalConversionsUtils.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import static org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow
--- /dev/null
+package org.opendaylight.controller.md.frm.compatibility;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SampleConsumer {
+
+ ConsumerContext context;
+
+ void addFlowExample() {
+
+ DataBrokerService dataService = context.getSALService(DataBrokerService.class);
+
+ DataModificationTransaction transaction = dataService.beginTransaction();
+ Flow flow = createSampleFlow("foo", null);
+ InstanceIdentifier<Flow> path = InstanceIdentifier.builder().node(Flows.class).node(Flow.class, flow.getKey())
+ .toInstance();
+ transaction.putConfigurationData(path, flow);
+
+ transaction.commit();
+
+ dataService.readConfigurationData(path);
+ }
+
+ Flow createSampleFlow(String name, NodeRef node) {
+ FlowBuilder ret = new FlowBuilder();
+ FlowKey key = new FlowKey(name, node);
+ ret.setKey(key);
+ return ret.build();
+ }
+}
--- /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>compatibility-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>inventory-topology-compatibility</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>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>Forwarding Rules Manager Adapter
+ for MD-SAL</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <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-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager</artifactId>
+ <version>0.6.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topologymanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-management</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-topology</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwardingrulesmanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-compatibility</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.opendaylight.controller.md.compatibility.inventory
+
+import org.opendaylight.controller.switchmanager.ISwitchManager
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
+import java.util.ArrayList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import static extension org.opendaylight.controller.sal.compatibility.InventoryMapping.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder
+
+class InventoryReader implements RuntimeDataProvider {
+
+ @Property
+ var ISwitchManager switchManager;
+
+ override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+
+ // Topology and Inventory are operational only
+ return null;
+ }
+
+ override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ val type = path.targetType;
+ var DataObject data = null;
+ switch (type) {
+ case Nodes:
+ data = readNodes(path as InstanceIdentifier<Nodes>)
+ case Node:
+ data = readNode(path as InstanceIdentifier<Node>)
+ case NodeConnector:
+ data = readNodeConnector(path as InstanceIdentifier<NodeConnector>)
+ }
+ return data;
+ }
+
+ def DataObject readNodeConnector(InstanceIdentifier<NodeConnector> identifier) {
+ val nodeConnector = identifier.toAdNodeConnector();
+ return constructNodeConnector(nodeConnector)
+ }
+
+ def DataObject readNode(InstanceIdentifier<Node> identifier) {
+ val node = identifier.toAdNode();
+ return constructNode(node);
+ }
+
+
+ def Node constructNode(org.opendaylight.controller.sal.core.Node node) {
+ val connectors = switchManager.getNodeConnectors(node)
+
+ val tpList = new ArrayList<NodeConnector>(connectors.size)
+ for (connector : connectors) {
+ tpList.add(constructNodeConnector(connector));
+ }
+
+ val it = new NodeBuilder()
+ key = node.toNodeKey();
+ nodeConnector = tpList
+ return build();
+ }
+
+ def NodeConnector constructNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector) {
+ val it = new NodeConnectorBuilder()
+ key = connector.toNodeConnectorKey()
+ return build();
+ }
+
+ def readNodes(InstanceIdentifier<Nodes> identifier) {
+ val nodes = switchManager.nodes
+ val nodeList = new ArrayList<Node>(nodes.size)
+ for (node : nodes) {
+ nodeList.add(constructNode(node))
+ }
+ val it = new NodesBuilder();
+ node = nodeList
+ return build()
+
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.switchmanager
+
+import org.opendaylight.controller.switchmanager.ISwitchManager
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.core.Property
+import java.util.List
+import org.opendaylight.controller.sal.core.Node
+import java.net.InetAddress
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.core.Description
+import org.opendaylight.controller.sal.core.Tier
+import org.opendaylight.controller.sal.core.Bandwidth
+import org.opendaylight.controller.sal.core.ForwardingMode
+import org.opendaylight.controller.sal.core.MacAddress
+
+import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import java.net.NetworkInterface
+import java.net.SocketException
+import java.util.Collections
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import java.util.ArrayList
+import org.opendaylight.controller.switchmanager.Switch
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import java.util.Map
+import java.util.HashSet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState
+
+class CompatibleSwitchManager extends ConfigurableSwitchManager implements ISwitchManager {
+
+ private static val log = LoggerFactory.getLogger(CompatibleSwitchManager)
+
+ @org.eclipse.xtend.lib.Property
+ var DataBrokerService dataService;
+
+ override addNodeConnectorProp(NodeConnector nodeConnector, Property prop) {
+ val it = dataService.beginTransaction
+ val path = nodeConnector.toNodeConnectorRef
+
+ // TODO: Update FlowCapableNode
+ return null;
+ }
+
+ override createProperty(String propName, String propValue) {
+ try {
+ if (propName.equalsIgnoreCase(Description.propertyName)) {
+ return new Description(propValue);
+ } else if (propName.equalsIgnoreCase(Tier.TierPropName)) {
+ val tier = Integer.parseInt(propValue);
+ return new Tier(tier);
+ } else if (propName.equalsIgnoreCase(Bandwidth.BandwidthPropName)) {
+ val bw = Long.parseLong(propValue);
+ return new Bandwidth(bw);
+ } else if (propName.equalsIgnoreCase(ForwardingMode.name)) {
+ val mode = Integer.parseInt(propValue);
+ return new ForwardingMode(mode);
+ } else if (propName.equalsIgnoreCase(MacAddress.name)) {
+ return new MacAddress(propValue);
+ } else {
+ log.debug("Not able to create {} property", propName);
+ }
+ } catch (Exception e) {
+ log.debug("createProperty caught exception {}", e.getMessage());
+ }
+ return null;
+ }
+
+ override doesNodeConnectorExist(NodeConnector nc) {
+ val ref = nc.toNodeConnectorRef
+ return dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>) !== null
+ }
+
+ override getControllerMAC() {
+ var byte[] macAddress = null;
+
+ try {
+ val nis = NetworkInterface.getNetworkInterfaces();
+ while (nis.hasMoreElements()) {
+ val ni = nis.nextElement();
+ try {
+ macAddress = ni.getHardwareAddress();
+ return macAddress;
+ } catch (SocketException e) {
+ log.error("Failed to acquire controller MAC: ", e);
+ }
+ }
+ } catch (SocketException e) {
+ log.error("Failed to acquire controller MAC: ", e);
+ return macAddress;
+ }
+
+ if (macAddress == null) {
+ log.warn("Failed to acquire controller MAC: No physical interface found");
+
+ // This happens when running controller on windows VM, for example
+ // Try parsing the OS command output
+ }
+ return macAddress;
+ }
+
+ override getControllerProperties() {
+ return Collections.emptyMap()
+ }
+
+ override getControllerProperty(String propertyName) {
+ return null;
+ }
+
+ override getNetworkDevices() {
+ val path = InstanceIdentifier.builder().node(Nodes).toInstance;
+ val data = dataService.readOperationalData(path) as Nodes;
+ val ret = new ArrayList<Switch>();
+ for (node : data.node) {
+ ret.add(node.toSwitch());
+ }
+ return ret;
+ }
+
+ override getNodeConnector(Node node, String nodeConnectorName) {
+ val key = new NodeConnectorKey(new NodeConnectorId(nodeConnectorName));
+ return new NodeConnector(MD_SAL_TYPE, key, node);
+ }
+
+ override getNodeConnectorProp(NodeConnector nodeConnector, String propName) {
+ getNodeConnectorProps(nodeConnector).get(propName);
+ }
+
+ override getNodeConnectorProps(NodeConnector nodeConnector) {
+ val ref = nodeConnector.toNodeConnectorRef
+ val data = readNodeConnector(ref.value);
+ return data.toAdProperties();
+ }
+
+ override getNodeConnectors(Node node) {
+ val ref = node.toNodeRef;
+ val data = readNode(ref.value);
+ val ret = new HashSet();
+ for (nc : data.nodeConnector) {
+
+ val adConnector = new NodeConnector(MD_SAL_TYPE, nc.key, node);
+ ret.add(adConnector);
+ }
+ return ret;
+ }
+
+ override getNodeDescription(Node node) {
+ (getNodeProps(node).get(Description.propertyName) as Description).value;
+ }
+
+ override getNodeMAC(Node node) {
+ (getNodeProps(node).get(MacAddress.name) as MacAddress).macAddress;
+ }
+
+ override getNodeProp(Node node, String propName) {
+ getNodeProps(node).get(propName)
+ }
+
+ override getNodeProps(Node node) {
+ val ref = node.toNodeRef;
+ val data = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+ return data.toAdProperties();
+ }
+
+ override getNodes() {
+ val path = InstanceIdentifier.builder().node(Nodes).toInstance;
+ val data = dataService.readOperationalData(path) as Nodes;
+ val ret = new HashSet<Node>();
+ for (node : data.node) {
+ ret.add(new Node(MD_SAL_TYPE, node.key));
+ }
+ return ret;
+ }
+
+ def Switch toSwitch(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
+ val adNode = new Node(MD_SAL_TYPE, node.key);
+ val sw = new Switch(adNode)
+ return sw;
+ }
+
+ override getPhysicalNodeConnectors(Node node) {
+ val ref = node.toNodeRef;
+ val data = readNode(ref.value);
+ val ret = new HashSet();
+ for (nc : data.nodeConnector) {
+ val flowConnector = nc.getAugmentation(FlowCapableNodeConnector)
+ val adConnector = new NodeConnector(MD_SAL_TYPE, nc.key, node);
+ ret.add(adConnector);
+ }
+ return ret;
+ }
+
+ def Map<String, Property> toAdProperties(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector connector) {
+ return Collections.emptyMap
+ }
+
+ def Map<String, Property> toAdProperties(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node connector) {
+ return Collections.emptyMap
+ }
+
+ def readNode(InstanceIdentifier<?> ref) {
+ dataService.readOperationalData(ref as InstanceIdentifier<? extends DataObject>) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+ }
+
+ def readNodeConnector(InstanceIdentifier<?> ref) {
+ dataService.readOperationalData(ref as InstanceIdentifier<? extends DataObject>) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+ }
+
+ override getSpanPorts(Node node) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override getSubnetByNetworkAddress(InetAddress networkAddress) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override getUpNodeConnectors(Node node) {
+ val ref = node.toNodeRef
+ val data = readNode(ref.value);
+ val ret = new HashSet<NodeConnector>();
+ for (nc : data.nodeConnector) {
+ val flowConn = nc.getAugmentation(FlowCapableNodeConnector);
+ if (flowConn != null && flowConn.state == PortState.Live) {
+ ret.add(new NodeConnector(MD_SAL_TYPE, nc.key, node));
+ }
+ }
+ return ret;
+ }
+
+ override isNodeConnectorEnabled(NodeConnector nodeConnector) {
+ val ref = nodeConnector.toNodeConnectorRef
+ val data = readNodeConnector(ref.value);
+
+ return true;
+ }
+
+ override isSpecial(NodeConnector p) {
+ val ref = p.toNodeConnectorRef
+ val data = readNodeConnector(ref.value);
+
+ return true;
+ }
+
+ override removeControllerProperty(String propertyName) {
+ // NOOP
+ }
+
+ override removeNodeAllProps(Node node) {
+ // NOOP: not supported node has more properties than AD-SAL is capable to see
+ }
+
+ override removeNodeConnectorAllProps(NodeConnector nodeConnector) {
+ // NOOP: not supported node has more properties than AD-SAL is capable to see
+ }
+
+ override removeNodeConnectorProp(NodeConnector nc, String propName) {
+ // NOOP: not supported node has more properties than AD-SAL is capable to see
+ }
+
+ override removeNodeProp(Node node, String propName) {
+ // NOOP: not supported node has more properties than AD-SAL is capable to see
+ }
+
+ override removePortsFromSubnet(String name, List<String> nodeConnectors) {
+ // NOOP
+ }
+
+ override removeSubnet(String name) {
+ // NOOP
+ }
+
+ override setControllerProperty(Property property) {
+ // NOOP
+ }
+
+ override setNodeProp(Node node, Property prop) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override addPortsToSubnet(String name, List<String> nodeConnectors) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ }
--- /dev/null
+package org.opendaylight.controller.md.compatibility.switchmanager
+
+import org.opendaylight.controller.switchmanager.ISwitchManager
+import org.opendaylight.controller.switchmanager.SpanConfig
+import org.opendaylight.controller.switchmanager.SwitchConfig
+import org.opendaylight.controller.switchmanager.SubnetConfig
+
+/**
+ *
+ * THis methods should be backed by config subsystem.
+ *
+ */
+abstract class ConfigurableSwitchManager implements ISwitchManager {
+
+ override saveSwitchConfig() {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override removeSpanConfig(SpanConfig cfgObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override addSubnet(SubnetConfig configObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ final override addSpanConfig(SpanConfig configObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ final override getSpanConfigList() {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ final override updateSwitchConfig(SwitchConfig cfgObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ final override updateNodeConfig(SwitchConfig switchConfig) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ final override getSubnetConfig(String subnet) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ final override removeNodeConfig(String nodeId) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ final override removeSubnet(SubnetConfig configObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ final override getSubnetsConfigList() {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ final override getSwitchConfig(String nodeId) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override modifySubnet(SubnetConfig configObject) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.topology
+
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.controller.sal.core.Edge
+import java.util.Set
+import org.opendaylight.controller.sal.core.Property
+import org.opendaylight.controller.sal.core.NodeConnector
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+import org.opendaylight.controller.sal.compatibility.InventoryMapping
+class TopologyMapping {
+
+ new(TopologyKey path, InstanceIdentifier<Topology> key) {
+ // NOOP
+ }
+
+ def Edge toAdTopologyEdge(InstanceIdentifier<Link> identifier) {
+ val linkKey = (identifier.path.last as IdentifiableItem<Link,LinkKey>).key;
+ val components = linkKey.linkId.value.split("::::");
+ val tail = InventoryMapping.nodeConnectorFromId(components.get(0));
+ val head = InventoryMapping.nodeConnectorFromId(components.get(1));
+ return new Edge(tail, head);
+ }
+
+ def NodeConnector toAdTopologyNodeConnector(InstanceIdentifier<TerminationPoint> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<TerminationPoint,TerminationPointKey>).key;
+ return InventoryMapping.nodeConnectorFromId(tpKey.tpId.value);
+ }
+
+ def org.opendaylight.controller.sal.core.Node toAdTopologyNode(
+ InstanceIdentifier<Node> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<Node,NodeKey>).key;
+ return InventoryMapping.nodeFromNodeId(tpKey.nodeId.value);
+ }
+
+
+
+ def NodeKey toTopologyNodeKey(org.opendaylight.controller.sal.core.Node node) {
+ val nodeId = new NodeId(InventoryMapping.toNodeId(node));
+ return new NodeKey(nodeId);
+ }
+
+ def TerminationPointKey toTopologyTerminationPointKey(NodeConnector nc) {
+ val node = nc.node;
+ val nodeId = new TpId(InventoryMapping.toNodeConnectorId(nc))
+ return new TerminationPointKey(nodeId);
+ }
+
+ def LinkKey toTopologyLinkKey(Edge edge) {
+ val sourceTp = edge.tailNodeConnector.toTopologyTerminationPointKey;
+ val destTp = edge.headNodeConnector.toTopologyTerminationPointKey;
+ val linkId = new LinkId('''«sourceTp.tpId»::::«destTp.tpId»''')
+ return new LinkKey(linkId);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.topology
+
+import org.opendaylight.controller.switchmanager.ISwitchManager
+import org.opendaylight.controller.topologymanager.ITopologyManager
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import org.opendaylight.controller.md.compatibility.topology.TopologyMapping
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyBuilder
+import java.util.ArrayList
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointBuilder
+import org.opendaylight.controller.sal.core.Edge
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder
+
+class TopologyReader implements RuntimeDataProvider {
+
+ @Property
+ var ISwitchManager switchManager;
+
+ @Property
+ var ITopologyManager topologyManager;
+
+ @Property
+ val TopologyKey topologyKey;
+
+ @Property
+ val InstanceIdentifier<Topology> topologyPath;
+
+ @Property
+ val extension TopologyMapping mapping;
+
+ new() {
+ _topologyKey = new TopologyKey(new TopologyId("compatibility:ad-sal"));
+ _topologyPath = InstanceIdentifier.builder().node(NetworkTopology).child(Topology, topologyKey).toInstance;
+ _mapping = new TopologyMapping(topologyKey, topologyPath);
+ }
+
+ override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+
+ // Topology and Inventory are operational only
+ return null;
+ }
+
+ override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ val type = path.targetType;
+ var DataObject data = null;
+ if (false == topologyPath.contains(path)) {
+ return null;
+ }
+ switch (type) {
+ case Topology:
+ data = readTopology(path as InstanceIdentifier<Topology>)
+ case Node:
+ data = readNode(path as InstanceIdentifier<Node>)
+ case TerminationPoint:
+ data = readTerminationPoint(path as InstanceIdentifier<TerminationPoint>)
+ case Link:
+ data = readLink(path as InstanceIdentifier<Link>)
+ }
+ return data;
+ }
+
+ def DataObject readLink(InstanceIdentifier<Link> identifier) {
+ val edge = identifier.toAdTopologyEdge();
+ val properties = topologyManager?.edges?.get(edge);
+
+ return constructLink(edge);
+ }
+
+ def DataObject readTerminationPoint(InstanceIdentifier<TerminationPoint> identifier) {
+ val nodeConnector = identifier.toAdTopologyNodeConnector();
+ return constructTerminationPoint(nodeConnector)
+ }
+
+ def DataObject readNode(InstanceIdentifier<Node> identifier) {
+ val node = identifier.toAdTopologyNode();
+ return constructNode(node);
+ }
+
+ def DataObject readTopology(InstanceIdentifier<Topology> identifier) {
+
+ //val nodeConnectors = switchManager.
+ val nodes = switchManager.nodes
+ val edges = topologyManager.edges
+
+ val nodeList = new ArrayList<Node>(nodes.size)
+ for (node : nodes) {
+ nodeList.add(constructNode(node))
+ }
+
+ val linkList = new ArrayList<Link>(edges.size)
+ for (edge : edges.keySet) {
+ linkList.add(constructLink(edge))
+ }
+
+ val it = new TopologyBuilder();
+ key = topologyKey
+ node = nodeList
+ link = linkList
+ return build()
+ }
+
+ def constructLink(Edge edge) {
+ val sourceNc = edge.tailNodeConnector
+ val destNc = edge.headNodeConnector
+
+ val it = new LinkBuilder()
+ key = edge.toTopologyLinkKey();
+ source = new SourceBuilder().setSourceNode(sourceNc.node.toTopologyNodeKey.nodeId).setSourceTp(
+ sourceNc.toTopologyTerminationPointKey.tpId).build()
+ destination = new DestinationBuilder().setDestNode(destNc.node.toTopologyNodeKey.nodeId).setDestTp(
+ destNc.toTopologyTerminationPointKey.tpId).build
+ return build()
+ }
+
+ def Node constructNode(org.opendaylight.controller.sal.core.Node node) {
+ val connectors = switchManager.getNodeConnectors(node)
+
+ val tpList = new ArrayList<TerminationPoint>(connectors.size)
+ for (connector : connectors) {
+ tpList.add(constructTerminationPoint(connector));
+ }
+
+ val it = new NodeBuilder()
+ key = node.toTopologyNodeKey();
+ terminationPoint = tpList
+ return build();
+ }
+
+ def TerminationPoint constructTerminationPoint(NodeConnector connector) {
+ val it = new TerminationPointBuilder()
+ key = connector.toTopologyTerminationPointKey
+ return build();
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.topologymanager
+
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+import java.util.Map
+import org.opendaylight.controller.sal.core.Edge
+import java.util.Set
+import java.util.List
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+import java.util.Collections
+import com.google.common.collect.FluentIterable
+import java.util.HashSet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.controller.sal.compatibility.NodeMapping
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.Source
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.Destination
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import java.util.HashMap
+
+class AdSalTopologyMapping {
+
+ val TopologyKey topologyMapping;
+ @Property
+ val InstanceIdentifier<Topology> topologyPath;
+
+ new(TopologyKey topology) {
+ topologyMapping = topology;
+ _topologyPath = InstanceIdentifier.builder.node(NetworkTopology).child(Topology, topology).toInstance;
+ }
+
+ def InstanceIdentifier<TerminationPoint> toTerminationPoint(NodeConnector connector) {
+ InstanceIdentifier.builder(topologyPath).node(Node).child(TerminationPoint, connector.toTerminationPointKey()).toInstance;
+ }
+
+ def Map<Edge, Set<org.opendaylight.controller.sal.core.Property>> toEdgePropertiesMap(Iterable<Link> links) {
+ val ret = new HashMap<Edge, Set<org.opendaylight.controller.sal.core.Property>>
+ for (link : links) {
+ ret.put(link.toEdge(), link.toProperties())
+ }
+ return ret;
+ }
+
+ def Set<Edge> toEdges(Iterable<Link> links) {
+ val ret = new HashSet<Edge>
+ for (link : links) {
+ ret.add(link.toEdge)
+ }
+ return ret;
+ }
+
+ def Edge toEdge(Link link) {
+ val tail = link.source.toNodeConnector();
+ val head = link.destination.toNodeConnector();
+ return new Edge(tail, head);
+ }
+
+ def org.opendaylight.controller.sal.core.Node toAdNode(Node node) {
+ return node.nodeId.toAdNode;
+ }
+
+ def org.opendaylight.controller.sal.core.Node toAdNode(
+ org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId node) {
+ val key = new NodeKey(new NodeId(node))
+ return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, key);
+ }
+
+ def NodeConnector toNodeConnector(Source ref) {
+ val adNode = ref.sourceNode.toAdNode();
+ val key = new NodeConnectorKey(new NodeConnectorId(ref.sourceTp))
+ return new NodeConnector(NodeMapping.MD_SAL_TYPE, key, adNode);
+ }
+
+ def NodeConnector toNodeConnector(Destination ref) {
+ val adNode = ref.destNode.toAdNode();
+ val key = new NodeConnectorKey(new NodeConnectorId(ref.destTp))
+ return new NodeConnector(NodeMapping.MD_SAL_TYPE, key, adNode);
+ }
+
+ def TerminationPointKey toTerminationPointKey(NodeConnector connector) {
+ }
+
+ def Set<org.opendaylight.controller.sal.core.Property> toProperties(Link link) {
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.topologymanager
+
+import org.opendaylight.controller.topologymanager.ITopologyManager
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.core.Host
+import org.opendaylight.controller.sal.core.UpdateType
+import java.util.Set
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import java.util.HashMap
+import org.opendaylight.controller.sal.core.Edge
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import com.google.common.collect.FluentIterable
+
+class CompatibleTopologyManager extends ConfigurableLinkManager implements ITopologyManager {
+
+ @Property
+ var TypeSafeDataReader dataReader;
+
+ @Property
+ var extension AdSalTopologyMapping topologyMapping;
+
+ override getEdges() {
+ val topology = dataReader.readOperationalData(topologyPath);
+ return topology.link.toEdgePropertiesMap();
+ }
+
+ override getNodeEdges() {
+ val topology = dataReader.readOperationalData(topologyPath);
+ val ret = new HashMap<org.opendaylight.controller.sal.core.Node, Set<Edge>>;
+ for (node : topology.node) {
+ val adNode = node.toAdNode();
+ val adEdges = FluentIterable.from(topology.link).filter[
+ source.sourceNode == node.nodeId || destination.destNode == node.nodeId].toEdges();
+ ret.put(adNode, adEdges)
+ }
+ return ret;
+ }
+
+ /**
+ * Returns true if point is connected to link
+ */
+ def isInternal(TerminationPoint point) {
+ val topology = dataReader.readConfigurationData(topologyPath);
+ val tpId = point.key.tpId;
+ return FluentIterable.from(topology.link).anyMatch(
+ [
+ source.sourceTp == tpId || destination.destTp == tpId
+ ])
+ }
+
+ override getNodeConnectorWithHost() {
+ }
+
+ override getHostAttachedToNodeConnector(NodeConnector p) {
+ val tpPath = p.toTerminationPoint();
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ override getHostsAttachedToNodeConnector(NodeConnector p) {
+ val topology = dataReader.readOperationalData(topologyPath);
+
+ throw new UnsupportedOperationException("Hosts not mapped yet")
+ }
+
+ override getNodesWithNodeConnectorHost() {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+ override isInternal(NodeConnector p) {
+ val tpPath = p.toTerminationPoint();
+ val connector = dataReader.readConfigurationData(tpPath);
+ return connector.isInternal();
+ }
+
+ override updateHostLink(NodeConnector p, Host h, UpdateType t,
+ Set<org.opendaylight.controller.sal.core.Property> props) {
+ // Update app defined topology
+ }
+
+ override saveConfig() {
+ // FIXME: commit configuration
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.md.compatibility.topologymanager
+
+import org.opendaylight.controller.topologymanager.ITopologyManager
+import org.opendaylight.controller.topologymanager.TopologyUserLinkConfig
+
+abstract class ConfigurableLinkManager implements ITopologyManager {
+
+ final override addUserLink(TopologyUserLinkConfig link) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+
+ final override deleteUserLink(String linkName) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+
+
+ final override getUserLinks() {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+
+ }
+}
\ 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>
+ </parent>
+ <artifactId>compatibility-parent</artifactId>
+ <packaging>pom</packaging>
+ <name>MD-SAL to AD-SAL Adaptation</name>
+ <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>sal-compatibility</module>
+ <module>inventory-topology-compatibility</module>
+ <module>flow-management-compatibility</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-service</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-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.name}</Bundle-Name>
+ <Bundle-Activator>org.opendaylight.controller.sal.compability.ComponentActivator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <configuration>
+ <includes>org.opendaylight.controller.*</includes>
+ </configuration>
+ <executions>
+ <execution>
+ <id>pre-test</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>post-test</id>
+ <phase>test</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
+ <artifactId>compatibility-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
- <artifactId>sal-compability</artifactId>
+ <artifactId>sal-compatibility</artifactId>
<name>MD-SAL to AD-SAL Adaptation</name>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
</scm>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-service</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-statistics</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-binding-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<packaging>bundle</packaging>
<configuration>
<instructions>
<Bundle-Name>${project.name}</Bundle-Name>
- <Bundle-Activator>org.opendaylight.controller.sal.compability.ComponentActivator</Bundle-Activator>
+ <Bundle-Activator>org.opendaylight.controller.sal.compatibility.ComponentActivator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
-package org.opendaylight.controller.sal.compability
+package org.opendaylight.controller.sal.compatibility
import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
import org.opendaylight.controller.sal.core.Node
import org.opendaylight.controller.sal.core.NodeConnector
-import static org.opendaylight.controller.sal.compability.NodeMapping.*
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
import org.apache.felix.dm.Component
import java.util.Arrays
-package org.opendaylight.controller.sal.compability
+package org.opendaylight.controller.sal.compatibility
import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener
-package org.opendaylight.controller.sal.compability
+package org.opendaylight.controller.sal.compatibility
import java.util.concurrent.ExecutionException
import org.opendaylight.controller.sal.core.Node
import org.opendaylight.yangtools.yang.common.RpcResult
import org.slf4j.LoggerFactory
-import static org.opendaylight.controller.sal.compability.MDFlowMapping.*
+import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
-import static extension org.opendaylight.controller.sal.compability.NodeMapping.*
-import static extension org.opendaylight.controller.sal.compability.ToSalConversionsUtils.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener {
-package org.opendaylight.controller.sal.compability;
+package org.opendaylight.controller.sal.compatibility;
import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
import java.util.Arrays;
import java.util.List;
+import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-
import com.google.common.net.InetAddresses;
-
-
-
-
-
-
-
-
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.*;
-import static org.opendaylight.controller.sal.compability.NodeMapping.*;
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.*;
public class FromSalConversionsUtils {
-package org.opendaylight.controller.sal.compability
+package org.opendaylight.controller.sal.compatibility
import org.opendaylight.controller.sal.reader.IPluginInReadService
import org.opendaylight.controller.sal.core.NodeConnector
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
import static extension org.opendaylight.controller.sal.common.util.Arguments.*
-import static extension org.opendaylight.controller.sal.compability.NodeMapping.*
-import static org.opendaylight.controller.sal.compability.MDFlowMapping.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
--- /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.compatibility
+
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
+
+class InventoryMapping {
+
+ static def org.opendaylight.controller.sal.core.NodeConnector toAdNodeConnector(
+ InstanceIdentifier<NodeConnector> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<NodeConnector,NodeConnectorKey>).key;
+ return nodeConnectorFromId(tpKey.id.value);
+ }
+
+ static def org.opendaylight.controller.sal.core.Node toAdNode(InstanceIdentifier<Node> identifier) {
+ val tpKey = (identifier.path.last as IdentifiableItem<Node,NodeKey>).key;
+ return nodeFromNodeId(tpKey.id.value);
+ }
+
+
+ static def NodeRef toNodeRef(org.opendaylight.controller.sal.core.Node node) {
+ val nodeId = new NodeKey(new NodeId(node.toNodeId))
+ val path = InstanceIdentifier.builder().node(Nodes).child(Node,nodeId).toInstance;
+ return new NodeRef(path);
+ }
+
+ static def NodeKey toNodeKey(org.opendaylight.controller.sal.core.Node node) {
+ val nodeId = new NodeId(node.toNodeId)
+ return new NodeKey(nodeId);
+ }
+
+ static def NodeConnectorKey toNodeConnectorKey(org.opendaylight.controller.sal.core.NodeConnector nc) {
+ val nodeId = new NodeConnectorId(nc.toNodeConnectorId)
+ return new NodeConnectorKey(nodeId);
+ }
+
+ static def String toNodeId(org.opendaylight.controller.sal.core.Node node) {
+ '''ad-sal:«node.type»::«node.nodeIDString»'''
+ }
+
+ static def String toNodeConnectorId(org.opendaylight.controller.sal.core.NodeConnector nc) {
+ '''«nc.node.toNodeId»::«nc.nodeConnectorIDString»'''
+ }
+
+ static def org.opendaylight.controller.sal.core.Node nodeFromNodeId(String nodeId) {
+ return nodeFromString(nodeId.split("::"))
+ }
+
+ static def nodeConnectorFromId(String invId) {
+ return nodeConnectorFromString(invId.split("::"));
+ }
+
+ private static def org.opendaylight.controller.sal.core.NodeConnector nodeConnectorFromString(String[] string) {
+ val node = nodeFromString(string.subList(0, 1));
+ return org.opendaylight.controller.sal.core.NodeConnector.fromStringNoNode(string.get(2), node);
+ }
+
+ private static def org.opendaylight.controller.sal.core.Node nodeFromString(String[] strings) {
+ val type = strings.get(0).substring(6);
+ org.opendaylight.controller.sal.core.Node.fromString(type, strings.get(1))
+ }
+
+}
-package org.opendaylight.controller.sal.compability;
+package org.opendaylight.controller.sal.compatibility;
import com.google.common.net.InetAddresses
import java.math.BigInteger
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp
-import static extension org.opendaylight.controller.sal.compability.FromSalConversionsUtils.*
-import static extension org.opendaylight.controller.sal.compability.NodeMapping.*
+import static extension org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions
-package org.opendaylight.controller.sal.compability
+package org.opendaylight.controller.sal.compatibility
import org.opendaylight.controller.sal.core.Node
import org.opendaylight.controller.sal.core.NodeConnector
-package org.opendaylight.controller.sal.compability;
+package org.opendaylight.controller.sal.compatibility;
public class ProtocolConstants {
// source: http://en.wikipedia.org/wiki/Ethertype
-package org.opendaylight.controller.sal.compability;
+package org.opendaylight.controller.sal.compatibility;
import com.google.common.net.InetAddresses;
+
import org.opendaylight.controller.sal.action.Controller;
import org.opendaylight.controller.sal.action.Drop;
import org.opendaylight.controller.sal.action.Flood;
import java.util.Collections;
import java.util.List;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.ETHERNET_ARP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.SCTP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.TCP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.UDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.SCTP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
-package org.opendaylight.controller.sal.compability.adsal;
+package org.opendaylight.controller.sal.compatibility.adsal;
-import org.opendaylight.controller.sal.compability.NodeMapping;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
import org.opendaylight.controller.sal.packet.IPluginInDataPacketService;
import org.opendaylight.controller.sal.packet.RawPacket;
import org.opendaylight.controller.sal.packet.RawPacket;
--- /dev/null
+package org.opendaylight.controller.sal.compatibility.adsal;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.common.util.Futures;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.compatibility.InventoryMapping;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
+import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FlowServiceAdapter.class);
+
+ private IFlowProgrammerService delegate;
+
+ private NotificationProviderService publish;
+
+ @Override
+ public void flowRemoved(org.opendaylight.controller.sal.core.Node node, Flow flow) {
+ FlowRemovedBuilder flowRemovedBuilder = new FlowRemovedBuilder();
+ flowRemovedBuilder.setNode(InventoryMapping.toNodeRef(node));
+ publish.publish(flowRemovedBuilder.build());
+ }
+
+ @Override
+ public void flowErrorReported(org.opendaylight.controller.sal.core.Node node, long rid, Object err) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
+
+ Flow flow = ToSalConversionsUtils.toFlow(input);
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Status status = delegate.addFlowAsync(node, flow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+ }
+
+ @Override
+ public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
+
+ Flow flow = ToSalConversionsUtils.toFlow(input);
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Status status = delegate.removeFlowAsync(node, flow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+
+ }
+
+ @Override
+ public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
+ @SuppressWarnings("unchecked")
+ org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
+ .getNode().getValue());
+ Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
+ Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
+ Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
+ Void rpcResultType = null;
+ return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+ }
+}
-package org.opendaylight.controller.sal.compability.adsal;
+package org.opendaylight.controller.sal.compatibility.adsal;
import java.math.BigInteger;
import java.util.ArrayList;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.common.util.Futures;
import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.compability.NodeMapping;
-import org.opendaylight.controller.sal.compability.ToSalConversionsUtils;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
+import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
-package org.opendaylight.controller.sal.compability;
+/*
+ * 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.compatibility.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.ETHERNET_ARP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.SCTP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.TCP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.UDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.SCTP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
-import org.opendaylight.controller.sal.action.Action;
-import org.opendaylight.controller.sal.action.Flood;
-import org.opendaylight.controller.sal.action.FloodAll;
-import org.opendaylight.controller.sal.action.HwPath;
-import org.opendaylight.controller.sal.action.Loopback;
-import org.opendaylight.controller.sal.action.PopVlan;
-import org.opendaylight.controller.sal.action.PushVlan;
-import org.opendaylight.controller.sal.action.SetDlDst;
-import org.opendaylight.controller.sal.action.SetDlSrc;
-import org.opendaylight.controller.sal.action.SetDlType;
-import org.opendaylight.controller.sal.action.SetNextHop;
-import org.opendaylight.controller.sal.action.SetNwDst;
-import org.opendaylight.controller.sal.action.SetNwSrc;
-import org.opendaylight.controller.sal.action.SetNwTos;
-import org.opendaylight.controller.sal.action.SetTpDst;
-import org.opendaylight.controller.sal.action.SetTpSrc;
-import org.opendaylight.controller.sal.action.SetVlanCfi;
-import org.opendaylight.controller.sal.action.SetVlanId;
-import org.opendaylight.controller.sal.action.SetVlanPcp;
-import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.action.*;
+import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
+import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-package org.opendaylight.controller.sal.compability;
+/*
+ * 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.compatibility.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
-import com.google.common.net.InetAddresses;
import org.junit.Test;
-import org.opendaylight.controller.sal.action.Flood;
-import org.opendaylight.controller.sal.action.FloodAll;
-import org.opendaylight.controller.sal.action.HwPath;
-import org.opendaylight.controller.sal.action.Loopback;
-import org.opendaylight.controller.sal.action.Output;
-import org.opendaylight.controller.sal.action.PopVlan;
-import org.opendaylight.controller.sal.action.PushVlan;
-import org.opendaylight.controller.sal.action.SetDlDst;
-import org.opendaylight.controller.sal.action.SetDlSrc;
-import org.opendaylight.controller.sal.action.SetDlType;
-import org.opendaylight.controller.sal.action.SetNextHop;
-import org.opendaylight.controller.sal.action.SetNwDst;
-import org.opendaylight.controller.sal.action.SetNwSrc;
-import org.opendaylight.controller.sal.action.SetNwTos;
-import org.opendaylight.controller.sal.action.SetTpDst;
-import org.opendaylight.controller.sal.action.SetTpSrc;
-import org.opendaylight.controller.sal.action.SetVlanCfi;
-import org.opendaylight.controller.sal.action.SetVlanId;
-import org.opendaylight.controller.sal.action.SetVlanPcp;
-import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.action.*;
+import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.ControllerActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.DropActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.OutputActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopMplsActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushMplsActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushPbbActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetMplsTtlActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTtlActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetQueueActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSource;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
-import java.math.BigInteger;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import com.google.common.net.InetAddresses;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.ETHERNET_ARP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.SCTP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.TCP;
-import static org.opendaylight.controller.sal.compability.ProtocolConstants.UDP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.SCTP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
+import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
public class TestToSalConversionsUtils {
// prefix:
--- /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">
+
+ <parent>
+ <artifactId>model-parent</artifactId>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <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>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>model-topology</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ <version>2013.07.12.2-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+module opendaylight-topology-inventory {
+ yang-version 1;
+ namespace "urn:opendaylight:model:topology:inventory";
+ // replace with IANA namespace when assigned
+ prefix "nt";
+
+ import yang-ext { prefix "ext"; }
+ import ietf-inet-types { prefix "inet"; }
+ import opendaylight-inventory {prefix "inv";}
+ import opendaylight-topology {prefix "odt";}
+ import network-topology {prefix "topo";}
+
+ organization "TBD";
+
+ contact "WILL-BE-DEFINED-LATER";
+
+ revision 2013-10-30 {
+ description
+ "Initial revision.";
+ }
+
+ augment "/topo:network-topology/topo:topology/topo:node" {
+ ext:augment-identifier "inventory-node";
+ uses inv:node-context-ref;
+ }
+
+ augment "/topo:network-topology/topo:topology/topo:node/topo:termination-point" {
+ ext:augment-identifier "inventory-node-connector";
+ leaf node-connector {
+ ext:context-reference "inv:node-connector-context";
+ type inv:node-connector-ref;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+module opendaylight-topology {
+ yang-version 1;
+ namespace "urn:opendaylight:model:topology:general";
+ // replace with IANA namespace when assigned
+ prefix "nt";
+
+ import yang-ext { prefix "ext"; }
+ import ietf-inet-types { prefix "inet"; }
+ import opendaylight-inventory {prefix "inv";}
+ import network-topology {prefix "topo";}
+
+ organization "TBD";
+
+ contact "WILL-BE-DEFINED-LATER";
+
+ revision 2013-10-30 {
+ description
+ "Initial revision.";
+ }
+
+ identity node-type {
+
+ }
+
+ typedef node-type-ref {
+ type identityref {
+ base node-type;
+ }
+ }
+
+ identity topology-context {
+
+ }
+
+ identity topology-node-context {
+
+ }
+
+ grouping node-identifiers {
+ list node-identifier {
+ key "type identifier";
+ leaf type {
+ type node-type-ref;
+ }
+ leaf identifier {
+ type inet:uri;
+ }
+ }
+ }
+
+ augment "/topo:network-topology/topo:topology" {
+ ext:context-instance "topology-context";
+ }
+
+ /* Inventory Augmentations */
+ augment "/topo:network-topology/topo:topology/topo:node" {
+ ext:context-instance "topology-node-context";
+ }
+
+ augment "/topo:network-topology/topo:topology/topo:node" {
+ ext:augment-identifier "identifiable-node";
+ uses node-identifiers;
+ }
+}
--- /dev/null
+module opendaylight-topology-view {
+ yang-version 1;
+ namespace "urn:opendaylight:model:topology:view";
+ // replace with IANA namespace when assigned
+ prefix "nt";
+
+ import yang-ext { prefix "ext"; }
+ import ietf-inet-types { prefix "inet"; }
+ import network-topology {prefix "topo";}
+ import opendaylight-topology {prefix "odl";}
+
+ organization "TBD";
+
+ contact "WILL-BE-DEFINED-LATER";
+
+ revision 2013-10-30 {
+ description
+ "Initial revision.";
+ }
+
+
+ grouping aggregate-topology {
+ leaf-list original-topology {
+ type topo:topology-ref;
+ }
+ }
+
+ grouping aggregate-node {
+ list original-node {
+ leaf topology {
+ type topo:topology-ref;
+ }
+ leaf node {
+ type topo:node-ref;
+ }
+ }
+ }
+
+ augment "/topo:network-topology/topo:topology" {
+ ext:augment-identifier "aggregated-topology";
+ uses aggregate-topology;
+ }
+
+ augment "/topo:network-topology/topo:topology/topo:node" {
+ ext:augment-identifier "aggregated-node";
+ uses aggregate-node;
+ }
+}
\ No newline at end of file
<module>model-flow-service</module>
<module>model-flow-statistics</module>
<module>model-flow-management</module>
+ <module>model-topology</module>
</modules>
<build>
<module>sal-binding-config</module>
<module>sal-binding-broker</module>
+ <module>sal-binding-util</module>
+
<!-- Samples -->
<module>samples</module>
<!-- Base Models -->
<module>model</module>
- <!-- Compability Packages -->
- <module>sal-compability</module>
<!-- Connectors -->
<module>sal-connector-api</module>
<module>sal-rest-connector</module>
- <module>flow-management-compatibility</module>
<!-- Clustered Data Store -->
<module>clustered-data-store/implementation</module>
+ <module>inventory-manager</module>
+ <!-- Compability Packages -->
+ <module>compatibility</module>
+
<module>sal-zeromq-connector</module>
<module>test</module>
</modules>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.core.version}</version>
+ <scope>provided</scope>
</dependency>
</dependencies>
</project>
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-package>
+ org.opendaylight.controller.sal.binding.spi.*,
+ </Export-package>
<Private-Package>
org.opendaylight.controller.config.yang.md.sal.binding.impl,
- org.opendaylight.controller.sal.binding.spi,
- org.opendaylight.controller.sal.binding.spi.*,
org.opendaylight.controller.sal.binding.impl,
org.opendaylight.controller.sal.binding.impl.*,
+ org.opendaylight.controller.sal.binding.codegen,
org.opendaylight.controller.sal.binding.codegen.*,
</Private-Package>
</instructions>
import org.opendaylight.controller.sal.binding.api.data.DataProviderService
import org.opendaylight.yangtools.yang.binding.DataObject
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener
import org.opendaylight.controller.md.sal.common.api.TransactionStatus
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification
import org.opendaylight.controller.md.sal.common.api.data.DataReader
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
import org.opendaylight.yangtools.concepts.ListenerRegistration
-import static extension org.opendaylight.controller.sal.binding.impl.util.MapUtils.*;
-import java.util.Collection
-import java.util.Map.Entry
-import java.util.HashSet
-import java.util.Set
import com.google.common.collect.Multimap
import static com.google.common.base.Preconditions.*;
import java.util.List
-import java.util.LinkedList
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
import com.google.common.collect.HashMultimap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Callable
import java.util.Collections
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
import java.util.ArrayList
-import org.opendaylight.controller.sal.common.util.RpcErrors
+import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import java.util.Arrays
class DataBrokerImpl extends DeprecatedDataAPISupport implements DataProviderService {
@Property
var ExecutorService executor;
- Multimap<InstanceIdentifier, DataReaderRegistration> configReaders = HashMultimap.create();
- Multimap<InstanceIdentifier, DataReaderRegistration> operationalReaders = HashMultimap.create();
+ val dataReadRouter = new BindingAwareDataReaderRouter;
+
Multimap<InstanceIdentifier, DataChangeListenerRegistration> listeners = HashMultimap.create();
Multimap<InstanceIdentifier, DataCommitHandlerRegistration> commitHandlers = HashMultimap.create();
}
override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
- val readers = configReaders.getAllChildren(path);
- return readers.readConfiguration(path);
+ return dataReadRouter.readConfigurationData(path);
}
override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- val readers = operationalReaders.getAllChildren(path);
- return readers.readOperational(path);
+ return dataReadRouter.readOperationalData(path);
}
override registerCommitHandler(InstanceIdentifier<? extends DataObject> path,
return reg;
}
- override registerDataReader(InstanceIdentifier<? extends DataObject> path,
- DataReader<InstanceIdentifier<? extends DataObject>, DataObject> provider) {
- val ret = new DataReaderRegistration(provider, this);
- ret.paths.add(path);
- configReaders.put(path, ret);
- operationalReaders.put(path, ret);
- return ret;
- }
-
- protected def removeReader(DataReaderRegistration reader) {
- for (path : reader.paths) {
- operationalReaders.remove(path, reader);
- configReaders.remove(path, reader);
- }
+ override registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader) {
+
+ val confReg = dataReadRouter.registerConfigurationReader(path,reader);
+ val dataReg = dataReadRouter.registerOperationalReader(path,reader);
+
+ return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
}
protected def removeListener(DataChangeListenerRegistration registration) {
protected def removeCommitHandler(DataCommitHandlerRegistration registration) {
commitHandlers.remove(registration.path, registration);
}
-
- protected def DataObject readConfiguration(
- Collection<Entry<? extends InstanceIdentifier, ? extends DataReaderRegistration>> entries,
- InstanceIdentifier<? extends DataObject> path) {
-
- val List<DataObject> partialResults = new LinkedList();
- for (entry : entries) {
- partialResults.add(entry.value.instance.readConfigurationData(path))
- }
- return merge(path, partialResults);
- }
-
- protected def DataObject readOperational(
- Collection<Entry<? extends InstanceIdentifier, ? extends DataReaderRegistration>> entries,
- InstanceIdentifier<? extends DataObject> path) {
-
- val List<DataObject> partialResults = new LinkedList();
- for (entry : entries) {
- partialResults.add(entry.value.instance.readOperationalData(path))
- }
- return merge(path, partialResults);
- }
-
- protected def DataObject merge(InstanceIdentifier<? extends DataObject> identifier, List<DataObject> objects) {
-
- // FIXME: implement real merge
- if (objects.size > 0) {
- return objects.get(0);
- }
- }
protected def getActiveCommitHandlers() {
-
return commitHandlers.entries.map[ value.instance].toSet
}
}
-package class DataReaderRegistration extends //
-AbstractObjectRegistration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> {
-
- DataBrokerImpl dataBroker;
-
- @Property
- val Set<InstanceIdentifier<? extends DataObject>> paths;
-
- new(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> instance, DataBrokerImpl broker) {
- super(instance)
- dataBroker = broker;
- _paths = new HashSet();
- }
-
- override protected removeRegistration() {
- dataBroker.removeReader(this);
- }
-
-}
-
package class DataChangeListenerRegistration extends AbstractObjectRegistration<DataChangeListener> implements ListenerRegistration<DataChangeListener> {
DataBrokerImpl dataBroker;
+++ /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.binding.impl
-
-import org.opendaylight.controller.sal.common.DataStoreIdentifier
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
-
-class DataProviderContext {
-
- @Property
- var DataStoreIdentifier identifier;
- @Property
- var RuntimeDataProvider provider;
-}
final DataBrokerImpl broker;
public DataTransactionImpl(DataBrokerImpl dataBroker) {
+ super(dataBroker);
identifier = new Object();
broker = dataBroker;
status = TransactionStatus.NEW;
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.util
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+
+class BindingAwareDataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ override protected merge(InstanceIdentifier<? extends DataObject> path, Iterable<DataObject> data) {
+ return data.iterator.next;
+ }
+
+}
\ 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>
+ </parent>
+ <artifactId>sal-binding-util</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>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ <version>3.1.0</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public final class TypeSafeDataReader {
+
+
+ private final DataReader<InstanceIdentifier<?>,DataObject> delegate;
+
+
+
+ public DataReader<InstanceIdentifier<?>, DataObject> getDelegate() {
+ return delegate;
+ }
+
+
+ public TypeSafeDataReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+ this.delegate = delegate;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public <D extends DataObject> D readConfigurationData(InstanceIdentifier<D> path) {
+ return (D) delegate.readConfigurationData(path);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
+ return (D) delegate.readOperationalData(path);
+ }
+
+ public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<?>, DataObject> delegate) {
+ return new TypeSafeDataReader(delegate);
+ }
+}
// FIXME: After 0.6 Release of YANGTools refactor to use Path marker interface for arguments.
// import org.opendaylight.yangtools.concepts.Path;
+public interface DataChange<P/* extends Path<P> */, D> {
-public interface DataChange<P/* extends Path<P> */,D> {
+ /**
+ * Returns a map of paths and newly created objects
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getCreatedOperationalData();
- Map<P,D> getCreatedOperationalData();
+ /**
+ * Returns a map of paths and newly created objects
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getCreatedConfigurationData();
- Map<P,D> getUpdatedOperationalData();
+ /**
+ * Returns a map of paths and respective updated objects after update.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalOperationalData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getUpdatedOperationalData();
- Set<P> getRemovedOperationalData();
+ /**
+ * Returns a map of paths and respective updated objects after update.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalConfigurationData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Map<P, D> getUpdatedConfigurationData();
- Map<P,D> getCreatedConfigurationData();
- Map<P,D> getUpdatedConfigurationData();
+ /**
+ * Returns a set of paths of removed objects.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalConfigurationData()}
+ *
+ * @return map of paths and newly created objects
+ */
Set<P> getRemovedConfigurationData();
+ /**
+ * Returns a set of paths of removed objects.
+ *
+ * Original state of the object is in
+ * {@link #getOriginalOperationalData()}
+ *
+ * @return map of paths and newly created objects
+ */
+ Set<P> getRemovedOperationalData();
+
+ /**
+ * Return a map of paths and original state of updated and removed objectd.
+ *
+ * @return map of paths and original state of updated and removed objectd.
+ */
+ Map<P, D> getOriginalConfigurationData();
+
+ /**
+ * Return a map of paths and original state of updated and removed objectd.
+ *
+ * @return map of paths and original state of updated and removed objectd.
+ */
+ Map<P, D> getOriginalOperationalData();
}
public interface DataChangeEvent<P,D> extends DataChange<P, D>, Immutable {
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedConfigurationSubtree();
+
+ /**
+ * Returns a new subtree of data, which starts at the path
+ * where listener was registered.
+ *
+ */
+ D getUpdatedOperationalSubtree();
}
*/
public interface DataCommitHandler<P/* extends Path<P> */,D> {
-
+
DataCommitTransaction<P, D> requestCommit(DataModification<P,D> modification);
public interface DataCommitTransaction<P/* extends Path<P> */,D> {
// import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public interface DataModification<P/* extends Path<P> */, D> extends DataReader<P, D> {
+public interface DataModification<P/* extends Path<P> */, D> extends DataChange<P, D>, DataReader<P, D> {
/**
* Returns transaction identifier
TransactionStatus getStatus();
+ /**
+ *
+ * Use {@link #putOperationalData(Object, Object)} instead.
+ *
+ * @param path
+ * @param data
+ */
void putRuntimeData(P path, D data);
+ void putOperationalData(P path, D data);
+
void putConfigurationData(P path, D data);
+ /**
+ * Use {@link #removeOperationalData(Object)}
+ *
+ * @param path
+ */
void removeRuntimeData(P path);
- void removeConfigurationData(P path);
-
- public Map<P, D> getUpdatedConfigurationData();
+ void removeOperationalData(P path);
- public Map<P, D> getUpdatedOperationalData();
-
- public Set<P> getRemovedConfigurationData();
-
- public Set<P> getRemovedOperationalData();
+ void removeConfigurationData(P path);
/**
* Initiates a two-phase commit of modification.
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.data;
+
+public interface DataStore<P, D> extends //
+ DataReader<P, D>, //
+ DataModificationTransactionFactory<P, D> {
+
+ @Override
+ public DataModification<P, D> beginTransaction();
+
+ @Override
+ public D readConfigurationData(P path);
+
+ @Override
+ public D readOperationalData(P path);
+
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+
+public interface Route<C,P> extends Immutable {
+
+ C getType();
+
+ P getPath();
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import java.util.EventListener;
+
+public interface RouteChangeListener<C,P> extends EventListener {
+
+ void onRouteChange(RouteChange<C, P> change);
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+public interface RouteChangePublisher<C,P> {
+
+ ListenerRegistration<RouteChangeListener<C,P>> registerRouteChangeListener(RouteChangeListener<C,P> listener);
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.api.routing;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface Router<C,P,D> extends //
+ RouteChangePublisher<C, P> {
+
+ Map<C, Set<P>> getAnnouncedPaths();
+}
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
- <Export-Package>org.opendaylight.controller.md.sal.common.impl</Export-Package>
+ <Export-Package>
+ org.opendaylight.controller.md.sal.common.impl,
+ org.opendaylight.controller.md.sal.common.impl.*
+ </Export-Package>
</instructions>
</configuration>
</plugin>
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.yangtools.concepts.Path;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.NEW;
-public abstract class AbstractDataModification<P /*extends Path<P>*/, D> implements DataModification<P, D> {
+public abstract class AbstractDataModification<P /* extends Path<P> */, D> implements DataModification<P, D> {
- private final Map<P, D> configurationUpdate;
- private final Map<P, D> operationalUpdate;
+ private final ConcurrentMap<P, D> operationalOriginal;
+ private final ConcurrentMap<P, D> configurationOriginal;
- private final Set<P> configurationRemove;
- private final Set<P> operationalRemove;
+ private final ConcurrentMap<P, D> operationalCreated;
+ private final ConcurrentMap<P, D> configurationCreated;
+ private final ConcurrentMap<P, D> configurationUpdate;
+ private final ConcurrentMap<P, D> operationalUpdate;
+
+ private final ConcurrentMap<P, P> configurationRemove;
+ private final ConcurrentMap<P, P> operationalRemove;
+
+ private final Map<P, D> unmodifiable_configurationOriginal;
+ private final Map<P, D> unmodifiable_operationalOriginal;
+ private final Map<P, D> unmodifiable_configurationCreated;
+ private final Map<P, D> unmodifiable_operationalCreated;
private final Map<P, D> unmodifiable_configurationUpdate;
private final Map<P, D> unmodifiable_operationalUpdate;
private final Set<P> unmodifiable_configurationRemove;
private final Set<P> unmodifiable_OperationalRemove;
+ private DataReader<P, D> reader;
+
+ public AbstractDataModification(DataReader<P, D> reader) {
+ this.reader = reader;
+ this.configurationUpdate = new ConcurrentHashMap<>();
+ this.operationalUpdate = new ConcurrentHashMap<>();
+ this.configurationRemove = new ConcurrentHashMap<>();
+ this.operationalRemove = new ConcurrentHashMap<>();
- public AbstractDataModification(Map<P, D> configurationUpdate, Map<P, D> operationalUpdate,
- Set<P> configurationRemove, Set<P> operationalRemove) {
- this.configurationUpdate = configurationUpdate;
- this.operationalUpdate = operationalUpdate;
- this.configurationRemove = configurationRemove;
- this.operationalRemove = operationalRemove;
+ this.configurationOriginal = new ConcurrentHashMap<>();
+ this.operationalOriginal = new ConcurrentHashMap<>();
+ this.configurationCreated = new ConcurrentHashMap<>();
+ this.operationalCreated = new ConcurrentHashMap<>();
+
+ unmodifiable_configurationOriginal = Collections.unmodifiableMap(configurationOriginal);
+ unmodifiable_operationalOriginal = Collections.unmodifiableMap(operationalOriginal);
+ unmodifiable_configurationCreated = Collections.unmodifiableMap(configurationCreated);
+ unmodifiable_operationalCreated = Collections.unmodifiableMap(operationalCreated);
unmodifiable_configurationUpdate = Collections.unmodifiableMap(configurationUpdate);
unmodifiable_operationalUpdate = Collections.unmodifiableMap(operationalUpdate);
- unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove);
- unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove);
- }
+ unmodifiable_configurationRemove = Collections.unmodifiableSet(configurationRemove.keySet());
+ unmodifiable_OperationalRemove = Collections.unmodifiableSet(operationalRemove.keySet());
- public AbstractDataModification() {
- this(new HashMap<P, D>(), new HashMap<P, D>(), new HashSet<P>(), new HashSet<P>());
}
@Override
public final void putConfigurationData(P path, D data) {
checkMutable();
+
+ if (!hasConfigurationOriginal(path)) {
+ configurationCreated.put(path, data);
+ }
+
configurationUpdate.put(path, data);
configurationRemove.remove(path);
}
@Override
- public final void putRuntimeData(P path, D data) {
+ public final void putOperationalData(P path, D data) {
checkMutable();
+ if (!hasOperationalOriginal(path)) {
+ operationalCreated.put(path, data);
+ }
operationalUpdate.put(path, data);
operationalRemove.remove(path);
}
@Override
- public final void removeRuntimeData(P path) {
+ public final void putRuntimeData(P path, D data) {
+ putRuntimeData(path, data);
+ }
+
+ @Override
+ public final void removeOperationalData(P path) {
checkMutable();
+ hasOperationalOriginal(path);
operationalUpdate.remove(path);
- operationalRemove.add(path);
+ operationalRemove.put(path, path);
+ }
+
+ @Override
+ public final void removeRuntimeData(P path) {
+ removeOperationalData(path);
}
@Override
public final void removeConfigurationData(P path) {
checkMutable();
+ hasConfigurationOriginal(path);
configurationUpdate.remove(path);
- configurationRemove.add(path);
+ configurationRemove.put(path, path);
}
private final void checkMutable() {
}
@Override
- public Map<P, D> getUpdatedConfigurationData() {
+ public final Map<P, D> getUpdatedConfigurationData() {
return unmodifiable_configurationUpdate;
}
@Override
- public Map<P, D> getUpdatedOperationalData() {
+ public final Map<P, D> getUpdatedOperationalData() {
return unmodifiable_operationalUpdate;
}
@Override
- public Set<P> getRemovedConfigurationData() {
+ public final Set<P> getRemovedConfigurationData() {
return unmodifiable_configurationRemove;
}
@Override
- public Set<P> getRemovedOperationalData() {
+ public final Set<P> getRemovedOperationalData() {
return unmodifiable_OperationalRemove;
}
+ @Override
+ public Map<P, D> getCreatedConfigurationData() {
+ return unmodifiable_configurationCreated;
+ }
+
+ @Override
+ public Map<P, D> getCreatedOperationalData() {
+ return unmodifiable_operationalCreated;
+ }
+
+ @Override
+ public Map<P, D> getOriginalConfigurationData() {
+ return unmodifiable_configurationOriginal;
+ }
+
+ @Override
+ public Map<P, D> getOriginalOperationalData() {
+ return unmodifiable_operationalOriginal;
+ }
+
+ @Override
+ public D readOperationalData(P path) {
+ return reader.readOperationalData(path);
+ }
+
+ @Override
+ public D readConfigurationData(P path) {
+ return reader.readConfigurationData(path);
+ }
+
+ private boolean hasConfigurationOriginal(P path) {
+ if (configurationOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ configurationOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean hasOperationalOriginal(P path) {
+ if (operationalOriginal.containsKey(path)) {
+ return true;
+ }
+ D data = reader.readConfigurationData(path);
+ if (data != null) {
+ operationalOriginal.putIfAbsent(path, data);
+ return true;
+ }
+ return false;
+ }
}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.impl.routing;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.concepts.Registration;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Base abstract implementation of DataReadRouter, which performs
+ * a read operation on multiple data readers and then merges result.
+ *
+ * @param <P>
+ * @param <D>
+ */
+public abstract class AbstractDataReadRouter<P extends Path<?>, D> implements DataReader<P, D> {
+
+ Multimap<P, DataReaderRegistration<P, D>> configReaders = HashMultimap.create();
+ Multimap<P, DataReaderRegistration<P, D>> operationalReaders = HashMultimap.create();
+
+ @Override
+ public D readConfigurationData(P path) {
+ FluentIterable<D> dataBits = FluentIterable //
+ .from(getReaders(configReaders, path)).transform(configurationRead(path));
+ return merge(path,dataBits);
+ }
+
+ @Override
+ public D readOperationalData(P path) {
+ FluentIterable<D> dataBits = FluentIterable //
+ .from(getReaders(configReaders, path)).transform(operationalRead(path));
+ return merge(path,dataBits);
+
+ }
+
+ /**
+ * Merges data readed by reader instances from specified path
+ *
+ * @param path Path on which read was performed
+ * @param data Data which was returned by read operation.
+ * @return Merged result.
+ */
+ protected abstract D merge(P path,Iterable<D> data);
+
+ /**
+ * Returns a function which performs configuration read for supplied path
+ *
+ * @param path
+ * @return function which performs configuration read for supplied path
+ */
+
+ private Function<DataReader<P, D>, D> configurationRead(final P path) {
+ return new Function<DataReader<P, D>, D>() {
+ @Override
+ public D apply(DataReader<P, D> input) {
+ return input.readConfigurationData(path);
+ }
+ };
+ }
+
+ /**
+ * Returns a function which performs operational read for supplied path
+ *
+ * @param path
+ * @return function which performs operational read for supplied path
+ */
+ private Function<DataReader<P, D>, D> operationalRead(final P path) {
+ return new Function<DataReader<P, D>, D>() {
+ @Override
+ public D apply(DataReader<P, D> input) {
+ return input.readConfigurationData(path);
+ }
+ };
+ }
+
+ // Registrations
+
+ /**
+ * Register's a reader for operational data.
+ *
+ * @param path Path which is served by this reader
+ * @param reader Reader instance which is responsible for reading particular subpath.
+ * @return
+ */
+ public Registration<DataReader<P, D>> registerOperationalReader(P path, DataReader<P, D> reader) {
+ OperationalDataReaderRegistration<P, D> ret = new OperationalDataReaderRegistration<>(path, reader);
+ operationalReaders.put(path, ret);
+ return ret;
+ }
+
+ public Registration<DataReader<P, D>> registerConfigurationReader(P path, DataReader<P, D> reader) {
+ ConfigurationDataReaderRegistration<P, D> ret = new ConfigurationDataReaderRegistration<>(path, reader);
+ configReaders.put(path, ret);
+ return ret;
+ }
+
+ Iterable<DataReader<P, D>> getOperationalReaders(P path) {
+ return getReaders(operationalReaders, path);
+ }
+
+ Iterable<DataReader<P, D>> getConfigurationReaders(P path) {
+ return getReaders(configReaders, path);
+ }
+
+ private Iterable<DataReader<P, D>> getReaders(Multimap<P, DataReaderRegistration<P, D>> readerMap, P path) {
+ return FluentIterable
+ .from(readerMap.entries()) //
+ .filter(affects(path)) //
+ .transform(retrieveInstance());
+ }
+
+ private void removeRegistration(OperationalDataReaderRegistration<?, ?> registration) {
+ operationalReaders.remove(registration.getKey(), registration);
+ }
+
+ private void removeRegistration(ConfigurationDataReaderRegistration<?, ?> registration) {
+ configReaders.remove(registration.getKey(), registration);
+ }
+
+ private Function<? super Entry<P, DataReaderRegistration<P, D>>, DataReader<P, D>> retrieveInstance() {
+ return new Function<Entry<P, DataReaderRegistration<P, D>>, DataReader<P,D>>() {
+ @Override
+ public DataReader<P, D> apply(Entry<P, DataReaderRegistration<P, D>> input) {
+ return input.getValue().getInstance();
+ }
+ };
+ }
+
+ private Predicate<? super Entry<P, DataReaderRegistration<P, D>>> affects(final P path) {
+
+ return new Predicate<Entry<P, DataReaderRegistration<P, D>>>() {
+
+ @Override
+ public boolean apply(Entry<P, DataReaderRegistration<P, D>> input) {
+ final Path key = input.getKey();
+ return key.contains(path) || ((Path) path).contains(key);
+ }
+
+ };
+ }
+
+ private class ConfigurationDataReaderRegistration<P extends Path<?>, D> extends DataReaderRegistration<P, D> {
+
+ public ConfigurationDataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(key, instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ AbstractDataReadRouter.this.removeRegistration(this);
+ }
+ }
+
+ private class OperationalDataReaderRegistration<P extends Path<?>, D> extends DataReaderRegistration<P, D> {
+
+ public OperationalDataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(key, instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ AbstractDataReadRouter.this.removeRegistration(this);
+ }
+ }
+
+ private abstract static class DataReaderRegistration<P extends Path<?>, D> extends
+ AbstractObjectRegistration<DataReader<P, D>> {
+
+ private final P key;
+
+ public P getKey() {
+ return this.key;
+ }
+
+ public DataReaderRegistration(P key, DataReader<P, D> instance) {
+ super(instance);
+ this.key = key;
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.compability;
+
+import org.opendaylight.controller.sal.core.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+
+public class ToSalPropertyClassUtils {
+ public static Bandwidth salAdvertisedBandwidthFrom(NodeConnector nodeConnector) {
+ FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ PortFeatures portFeatures = flowCapNodeConn.getAdvertisedFeatures();
+ return new AdvertisedBandwidth(resolveBandwidth(portFeatures));
+ }
+
+ public static Bandwidth salPeerBandwidthFrom(NodeConnector nodeConnector) {
+ FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ PortFeatures portFeatures = flowCapNodeConn.getPeerFeatures();
+ return new PeerBandwidth(resolveBandwidth(portFeatures));
+ }
+
+ public static Bandwidth salSupportedBandwidthFrom(NodeConnector nodeConnector) {
+ FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ PortFeatures portFeatures = flowCapNodeConn.getSupported();
+ return new SupportedBandwidth(resolveBandwidth(portFeatures));
+ }
+
+ public static MacAddress salMacAddressFrom(NodeConnector nodeConnector) {
+ FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ String hwAddress = flowCapNodeConn.getHardwareAddress().getValue();
+ return new MacAddress(bytesFrom(hwAddress));
+ }
+
+
+ public static Name salNameFrom(NodeConnector nodeConnector) {
+ FlowCapableNodeConnector flowCapNodeConn = nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+ return new Name(flowCapNodeConn.getName());
+ }
+
+
+
+ private static byte[] bytesFrom(String hwAddress) {
+ String[] mac = hwAddress.split(":");
+ byte[] macAddress = new byte[6]; // mac.length == 6 bytes
+ for (int i = 0; i < mac.length; i++) {
+ macAddress[i] = Integer.decode("0x" + mac[i]).byteValue();
+ }
+ return macAddress;
+ }
+
+ private static long resolveBandwidth(PortFeatures portFeatures) {
+ if (portFeatures.is_1tbFd()) {
+ return Bandwidth.BW1Tbps;
+ } else if (portFeatures.is_100gbFd()) {
+ return Bandwidth.BW100Gbps;
+ } else if (portFeatures.is_40gbFd()) {
+ return Bandwidth.BW40Gbps;
+ } else if (portFeatures.is_10gbFd()) {
+ return Bandwidth.BW10Gbps;
+ } else if (portFeatures.is_1gbHd() || portFeatures.is_1gbFd()) {
+ return Bandwidth.BW1Gbps;
+ } else if (portFeatures.is_100mbHd() || portFeatures.is_100mbFd()) {
+ return Bandwidth.BW100Mbps;
+ } else if (portFeatures.is_10mbHd() || portFeatures.is_10mbFd()) {
+ return Bandwidth.BW10Mbps;
+ } else {
+ return Bandwidth.BWUNK;
+ }
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.compability.adsal;
-
-import java.util.concurrent.Future;
-
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Futures;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.compability.NodeMapping;
-import org.opendaylight.controller.sal.compability.ToSalConversionsUtils;
-import org.opendaylight.controller.sal.core.ConstructionException;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.flowprogrammer.Flow;
-import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
-import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlowServiceAdapter.class);
-
- private IFlowProgrammerService delegate;
-
- private NotificationProviderService publish;
-
- @Override
- public void flowRemoved(Node node, Flow flow) {
- FlowRemovedBuilder flowRemovedBuilder = new FlowRemovedBuilder();
- flowRemovedBuilder.setNode(NodeMapping.toNodeRef(node));
- publish.publish(flowRemovedBuilder.build());
- }
-
- @Override
- public void flowErrorReported(Node node, long rid, Object err) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
- try {
- Flow flow = ToSalConversionsUtils.toFlow(input);
- Node node = NodeMapping.toADNode(input.getNode());
- Status status = delegate.addFlowAsync(node, flow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
- }
-
- @Override
- public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
- try {
- Flow flow = ToSalConversionsUtils.toFlow(input);
- Node node = NodeMapping.toADNode(input.getNode());
- Status status = delegate.removeFlowAsync(node, flow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
- }
-
- @Override
- public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
- try {
- Node node = NodeMapping.toADNode(input.getNode());
- Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
- Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
- Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
- Void rpcResultType = null;
- return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
- } catch (ConstructionException e) {
- LOG.error(e.getMessage());
- }
- return null;
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.core.api;
+
+import java.util.concurrent.Future;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RpcConsumptionRegistry {
+ /**
+ * Sends an RPC to other components registered to the broker.
+ *
+ * @see RpcImplementation
+ * @param rpc
+ * Name of RPC
+ * @param input
+ * Input data to the RPC
+ * @return Result of the RPC call
+ */
+ Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input);
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.core.api;
+
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface RpcProvisionRegistry {
+
+ /**
+ * Registers an implementation of the rpc.
+ *
+ * <p>
+ * The registered rpc functionality will be available to all other
+ * consumers and providers registered to the broker, which are aware of
+ * the {@link QName} assigned to the rpc.
+ *
+ * <p>
+ * There is no assumption that rpc type is in the set returned by
+ * invoking {@link RpcImplementation#getSupportedRpcs()}. This allows
+ * for dynamic rpc implementations.
+ *
+ * @param rpcType
+ * Name of Rpc
+ * @param implementation
+ * Provider's Implementation of the RPC functionality
+ * @throws IllegalArgumentException
+ * If the name of RPC is invalid
+ */
+ RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException;
+
+ RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+}
import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService;
import org.opendaylight.controller.sal.common.DataStoreIdentifier;
import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;;
public interface DataProviderService extends
DataBrokerService, //
*/
void removeRefresher(DataStoreIdentifier store, DataRefresher refresher);
+
+ Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+
+ Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader);
+
public interface DataRefresher extends Provider.ProviderFunctionality {
/**
--- /dev/null
+package org.opendaylight.controller.sal.core.api.mount;
+
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+
+public interface MountProvisionInstance extends MountInstance, NotificationPublishService, RpcProvisionRegistry {
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.core.api.mount;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public interface MountProvisionService extends MountService {
+
+ @Override
+ public MountProvisionInstance getMountPoint(InstanceIdentifier path);
+
+ MountProvisionInstance createMountPoint(InstanceIdentifier path);
+
+ MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+}
<groupId>org.opendaylight.controller</groupId>\r
<artifactId>sal-common-util</artifactId>\r
<version>1.0-SNAPSHOT</version>\r
+ </dependency>\r
+ <dependency>\r
+ <groupId>org.opendaylight.controller</groupId>\r
+ <artifactId>sal-common-impl</artifactId>\r
+ <version>1.0-SNAPSHOT</version>\r
</dependency>\r
<dependency>\r
<groupId>org.opendaylight.controller</groupId>\r
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>\r
<Bundle-Activator>org.opendaylight.controller.sal.dom.broker.BrokerActivator</Bundle-Activator>\r
<Private-Package>\r
- org.opendaylight.controller.sal.dom.broker,\r
+ org.opendaylight.controller.sal.dom.broker.*\r
</Private-Package>\r
</instructions>\r
</configuration>\r
*/
package org.opendaylight.controller.sal.dom.broker;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.BrokerService;
-import org.opendaylight.controller.sal.core.api.Consumer;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.spi.BrokerModule;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.osgi.framework.BundleContext;
-import org.slf4j.LoggerFactory;
+import java.util.Collections
+import java.util.HashMap
+import java.util.HashSet
+import java.util.Map
+import java.util.Set
+import java.util.concurrent.Callable
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import org.opendaylight.controller.sal.core.api.Broker
+import org.opendaylight.controller.sal.core.api.BrokerService
+import org.opendaylight.controller.sal.core.api.Consumer
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.spi.BrokerModule
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.osgi.framework.BundleContext
+import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
import org.opendaylight.yangtools.concepts.ListenerRegistration
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
-import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry
public class BrokerImpl implements Broker {
private static val log = LoggerFactory.getLogger(BrokerImpl);
private val Map<Class<? extends BrokerService>, BrokerModule> serviceProviders = Collections.
synchronizedMap(new HashMap<Class<? extends BrokerService>, BrokerModule>());
-
- private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
- // RPC Context
- private val Map<QName, RpcImplementation> rpcImpls = Collections.synchronizedMap(
- new HashMap<QName, RpcImplementation>());
-
// Implementation specific
@Property
private var ExecutorService executor = Executors.newFixedThreadPool(5);
@Property
private var BundleContext bundleContext;
+
+ @Property
+ private var RpcRouter router;
override registerConsumer(Consumer consumer, BundleContext ctx) {
checkPredicates(consumer);
return prov.getServiceForSession(service, session);
}
- // RPC Functionality
- protected def void addRpcImplementation(QName rpcType, RpcImplementation implementation) {
- if(rpcImpls.get(rpcType) != null) {
- throw new IllegalStateException("Implementation for rpc " + rpcType + " is already registered.");
- }
-
-
- rpcImpls.put(rpcType, implementation);
-
-
- for(listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e){
- log.error("Unhandled exception during invoking listener",e);
- }
- }
- }
-
- protected def void removeRpcImplementation(QName rpcType, RpcImplementation implToRemove) {
- if(implToRemove == rpcImpls.get(rpcType)) {
- rpcImpls.remove(rpcType);
- }
-
- for(listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationRemoved(rpcType);
- } catch (Exception e){
- log.error("Unhandled exception during invoking listener",e);
- }
- }
- }
-
protected def Future<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- val impl = rpcImpls.get(rpc);
- val result = executor.submit([|impl.invokeRpc(rpc, input)] as Callable<RpcResult<CompositeNode>>);
+ val result = executor.submit([|router.invokeRpc(rpc, input)] as Callable<RpcResult<CompositeNode>>);
return result;
}
sessions.remove(consumerContextImpl);
providerSessions.remove(consumerContextImpl);
}
-
- protected def getSupportedRpcs() {
- rpcImpls.keySet;
- }
-
- def ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
- rpcRegistrationListeners.register(listener);
- }
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
+import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+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;
+
+public class MountPointImpl implements MountProvisionInstance {
+
+ final RpcRouter rpcs;
+ final DataReaderRouter dataReader;
+ final NotificationRouter notificationRouter;
+
+ public MountPointImpl(InstanceIdentifier path) {
+ rpcs = new RpcRouterImpl("");
+ dataReader = new DataReaderRouter();
+ notificationRouter = new NotificationRouterImpl();
+ }
+
+ @Override
+ public void publish(CompositeNode notification) {
+ notificationRouter.publish(notification);
+ }
+
+ @Override
+ public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+ return notificationRouter.addNotificationListener(notification, listener);
+ }
+
+ @Override
+ public CompositeNode readConfigurationData(InstanceIdentifier path) {
+ return dataReader.readConfigurationData(path);
+ }
+
+ @Override
+ public CompositeNode readOperationalData(InstanceIdentifier path) {
+ return dataReader.readOperationalData(path);
+ }
+
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return dataReader.registerOperationalReader(path, reader);
+ }
+
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return dataReader.registerConfigurationReader(path, reader);
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return rpcs.addRoutedRpcImplementation(rpcType, implementation);
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ return rpcs.addRpcImplementation(rpcType, implementation);
+ }
+
+ public Set<QName> getSupportedRpcs() {
+ return rpcs.getSupportedRpcs();
+ }
+
+
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ return rpcs.invokeRpc(rpc, input);
+ }
+
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return rpcs.addRpcRegistrationListener(listener);
+ }
+
+
+ @Override
+ public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataModificationTransaction beginTransaction() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
+ DataChangeListener listener) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void sendNotification(CompositeNode notification) {
+ publish(notification);
+
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker
+
+
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import java.util.concurrent.ConcurrentMap
+import java.util.concurrent.ConcurrentHashMap
+import static com.google.common.base.Preconditions.*;
+
+class MountPointManagerImpl implements MountProvisionService {
+
+ ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
+
+ override createMountPoint(InstanceIdentifier path) {
+ checkState(!mounts.containsKey(path),"Mount already created");
+ val mount = new MountPointImpl(path);
+ mounts.put(path,mount);
+ }
+
+
+ override createOrGetMountPoint(InstanceIdentifier path) {
+ val mount = mounts.get(path);
+ if(mount === null) {
+ return createMountPoint(path)
+ }
+ return mount;
+ }
+
+
+ override getMountPoint(InstanceIdentifier path) {
+ mounts.get(path);
+ }
+
+
+}
package org.opendaylight.controller.sal.dom.broker
-import java.util.Collections
-import java.util.HashMap
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
import org.opendaylight.controller.sal.core.api.Provider
import org.opendaylight.controller.sal.core.api.RpcImplementation
import org.opendaylight.yangtools.yang.common.QName
import org.osgi.framework.BundleContext
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
-import static java.util.Collections.*
-import java.util.Collections
-import java.util.HashMap
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
+import org.opendaylight.yangtools.concepts.Registration
+
+import java.util.Set
+import java.util.HashSet
class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession {
@Property
private val Provider provider;
- private val rpcImpls = Collections.synchronizedMap(new HashMap<QName, RpcImplementation>());
+ private val Set<Registration<?>> registrations = new HashSet();
new(Provider provider, BundleContext ctx) {
super(null, ctx);
}
override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
- if (rpcType == null) {
- throw new IllegalArgumentException("rpcType must not be null");
- }
- if (implementation == null) {
- throw new IllegalArgumentException("Implementation must not be null");
- }
- broker.addRpcImplementation(rpcType, implementation);
- rpcImpls.put(rpcType, implementation);
-
- return new RpcRegistrationImpl(rpcType, implementation, this);
+ val origReg = broker.router.addRpcImplementation(rpcType, implementation);
+ val newReg = new RpcRegistrationWrapper(origReg);
+ registrations.add(newReg);
+ return newReg;
}
- def removeRpcImplementation(RpcRegistrationImpl implToRemove) throws IllegalArgumentException {
- val localImpl = rpcImpls.get(implToRemove.type);
- if (localImpl !== implToRemove.instance) {
- throw new IllegalStateException("Implementation was not registered in this session");
- }
- broker.removeRpcImplementation(implToRemove.type, localImpl);
- rpcImpls.remove(implToRemove.type);
+ protected def removeRpcImplementation(RpcRegistrationWrapper implToRemove) throws IllegalArgumentException {
+ registrations.remove(implToRemove);
}
-
+
override close() {
- removeAllRpcImlementations
- super.close
- }
-
- private def removeAllRpcImlementations() {
- if (!rpcImpls.empty) {
- for (entry : rpcImpls.entrySet) {
- broker.removeRpcImplementation(entry.key, entry.value);
- }
- rpcImpls.clear
+
+ for (reg : registrations) {
+ reg.close()
}
+ super.close
}
override addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
}
override getSupportedRpcs() {
- broker.getSupportedRpcs();
+ broker.router.supportedRpcs;
}
override addRpcRegistrationListener(RpcRegistrationListener listener) {
- broker.addRpcRegistrationListener(listener);
+ broker.router.addRpcRegistrationListener(listener);
}
}
-class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
+class RpcRegistrationWrapper implements RpcRegistration {
+
@Property
- val QName type
+ val RpcRegistration delegate
- private var ProviderContextImpl context
+ new(RpcRegistration delegate) {
+ _delegate = delegate
+ }
- new(QName type, RpcImplementation instance, ProviderContextImpl ctx) {
- super(instance)
- _type = type
- context = ctx
+ override getInstance() {
+ delegate.instance
}
- override protected removeRegistration() {
- context.removeRpcImplementation(this)
- context = null
+ override close() {
+ delegate.close
}
+ override getType() {
+ delegate.type
+ }
}
+
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+
+class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
+
+ override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
+ return data.iterator.next
+ }
+
+}
--- /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.dom.broker.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.BrokerService;
+import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Consumer.ConsumerFunctionality;
+import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationService;
+import org.opendaylight.controller.sal.core.spi.BrokerModule;
+import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+
+public class NotificationRouterImpl implements NotificationRouter {
+ private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class);
+
+ private Multimap<QName, Registration<NotificationListener>> listeners = HashMultimap.create();
+
+ private void sendNotification(CompositeNode notification) {
+ QName type = notification.getNodeType();
+ Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
+ log.info("Publishing notification " + type);
+
+ if (toNotify == null) {
+ // No listeners were registered - returns.
+ return;
+ }
+
+ for (Registration<NotificationListener> listener : toNotify) {
+ try {
+ // FIXME: ensure that notification is immutable
+ listener.getInstance().onNotification(notification);
+ } catch (Exception e) {
+ log.error("Uncaught exception in NotificationListener", e);
+ }
+ }
+
+ }
+
+ @Override
+ public void publish(CompositeNode notification) {
+ sendNotification(notification);
+ }
+
+ @Override
+ public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
+ ListenerRegistration ret = new ListenerRegistration(notification, listener);
+ return ret;
+ }
+
+ private class ListenerRegistration extends AbstractObjectRegistration<NotificationListener> {
+
+ final QName type;
+
+ public ListenerRegistration(QName type, NotificationListener instance) {
+ super(instance);
+ this.type = type;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ listeners.remove(type, this);
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
+import org.opendaylight.yangtools.concepts.Identifiable
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.controller.sal.core.api.RpcImplementation
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import static com.google.common.base.Preconditions.*;
+import java.util.Map
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Set
+import java.util.Collections
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
+import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
+import org.slf4j.LoggerFactory
+
+class RpcRouterImpl implements RpcRouter, Identifiable<String> {
+
+ static val log = LoggerFactory.getLogger(RpcRouterImpl)
+
+ Map<QName, RpcRegistration> implementations = new ConcurrentHashMap();
+
+ @Property
+ val Set<QName> supportedRpcs = Collections.unmodifiableSet(implementations.keySet);
+
+ private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
+
+ @Property
+ val String identifier;
+
+ new(String name) {
+ _identifier = name;
+ }
+
+ override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ }
+
+ override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
+ checkNotNull(rpcType, "Rpc Type should not be null");
+ checkNotNull(implementation, "Implementation should not be null.");
+ checkState(!implementations.containsKey(rpcType), "Provider for supplied rpc is already registered.");
+ val reg = new RpcRegistrationImpl(rpcType, implementation, this);
+ implementations.put(rpcType, reg)
+
+ for (listener : rpcRegistrationListeners.listeners) {
+ try {
+ listener.instance.onRpcImplementationAdded(rpcType);
+ } catch (Exception e) {
+ log.error("Unhandled exception during invoking listener", e);
+ }
+ }
+
+ return reg;
+
+ }
+
+ override invokeRpc(QName rpc, CompositeNode input) {
+ checkNotNull(rpc, "Rpc Type should not be null");
+
+ val impl = implementations.get(rpc);
+ checkState(impl !== null, "Provider for supplied rpc is not registered.");
+
+ return impl.instance.invokeRpc(rpc, input);
+ }
+
+ def remove(RpcRegistrationImpl impl) {
+ val existing = implementations.get(impl.type);
+ if (existing == impl) {
+ implementations.remove(impl.type);
+ }
+ for (listener : rpcRegistrationListeners.listeners) {
+ try {
+ listener.instance.onRpcImplementationRemoved(impl.type);
+ } catch (Exception e) {
+ log.error("Unhandled exception during invoking listener", e);
+ }
+ }
+ }
+
+ override addRpcRegistrationListener(RpcRegistrationListener listener) {
+ rpcRegistrationListeners.register(listener);
+ }
+
+}
+
+class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
+
+ @Property
+ val QName type;
+
+ @Property
+ var RpcRouterImpl router;
+
+ new(QName type, RpcImplementation instance, RpcRouterImpl router) {
+ super(instance)
+ _type = type
+ _router = router
+ }
+
+ override protected removeRegistration() {
+ router.remove(this);
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface NotificationRouter {
+
+ void publish(CompositeNode notification);
+
+ /**
+ * Registers a notification listener for supplied notification type.
+ *
+ * @param notification
+ * @param listener
+ */
+ Registration<NotificationListener> addNotificationListener(QName notification,
+ NotificationListener listener);
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+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;
+
+public interface RoutedRpcProcessor extends RpcImplementation {
+
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+
+ public Set<QName> getSupportedRpcs();
+
+ public QName getRpcType();
+
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
+
+ Map<InstanceIdentifier,RpcImplementation> getRoutes();
+
+ RpcImplementation getDefaultRoute();
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.spi;
+
+import java.util.Set;
+
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RpcRouter extends RpcProvisionRegistry, RpcImplementation {
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException;
+
+ @Override
+ public Set<QName> getSupportedRpcs();
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
+
+ ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
+}
<artifactId>sal-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
+ <properties>
+ <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+ </properties>
<artifactId>sal-netconf-connector</artifactId>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<groupId>${project.groupId}</groupId>
<artifactId>sal-connector-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>0.2.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-test</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-util</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-api</artifactId>
+ <version>${netconf.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>util</artifactId>
+ <scope>test</scope>
+ <version>0.3.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-client</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-netconf-connector</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-test</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-manager</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-mapping-api</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-util</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-impl</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-store-impl</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>logback-config</artifactId>
+ <scope>test</scope>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
<packaging>bundle</packaging>
}
for (int i = 0; i < fileList.length; i++) {
String fileName = fileList[i];
- testFiles.add(new File(testDir, fileName));
+ if (new File(testDir, fileName).isDirectory() == false) {
+ testFiles.add(new File(testDir, fileName));
+ }
}
return parser.parseYangModels(testFiles);
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.Set;
+import java.util.regex.*;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.*;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class YangAndXmlToJsonConversion {
+
+ @Ignore
+ @Test
+ /**
+ * Test for simple yang types (leaf, list, leaf-list, container and various combination of them)
+ *
+ */
+ public void simpleYangTypesTest() {
+ String jsonOutput = null;
+
+ jsonOutput = convertXmlDataAndYangToJson("/yang-to-json-conversion/simple-yang-types/xml/data.xml",
+ "/yang-to-json-conversion/simple-yang-types");
+
+// jsonOutput =
+// readJsonFromFile("/yang-to-json-conversion/simple-yang-types/xml/output.json");
+
+ verifyJsonOutputForSimpleYangTypes(jsonOutput);
+
+ }
+
+ private void verifyJsonOutputForSimpleYangTypes(String jsonOutput) {
+
+ assertTrue("First and last character has to be '{' and '}'", Pattern.compile("\\A\\{.*\\}\\z", Pattern.DOTALL)
+ .matcher(jsonOutput).matches());
+
+ String prefix = "\"(smptp:|)";
+
+ // subnodes of cont1
+ String cont1 = prefix + "cont1\":\\{";
+ testLeaf(cont1, "lf11", new String("lf"), jsonOutput, prefix);
+ testLeafList(cont1, "lflst11", jsonOutput, prefix, new Integer(55), new Integer(56), new Integer(57));
+ testLeafList(cont1, "lflst12", jsonOutput, prefix, new String("lflst12 str1"), new String("lflst12 str2"),
+ new String("lflst12 str1"));
+
+ // subnodes of lst111
+ // first object of lst111
+ String lst11 = cont1 + ".*" + prefix + "lst11\":\\[\\{";
+ testLeaf(lst11, "lf111", new Integer(140), jsonOutput, prefix);
+ testLeaf(lst11, "lf112", new String("lf112 str"), jsonOutput, prefix);
+
+ // subnodes of cont111
+ String cont111 = lst11 + ".*" + prefix + "cont111\":\\{";
+ testLeaf(cont111, "lf1111", new String("lf1111 str"), jsonOutput, prefix);
+ testLeafList(cont1, "lflst1111", jsonOutput, prefix, new Integer(2048), new Integer(1024), new Integer(4096));
+
+ // subnodes of lst1111
+ String lst1111 = cont111 + ".*" + prefix + "lst1111\":\\[\\{";
+ testLeaf(lst1111, "lf1111A", new String("lf1111A str11"), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111B", new Integer(4), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111A", new String("lf1111A str12"), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111B", new Integer(7), jsonOutput, prefix);
+ // :subnodes of lst1111
+ // :subnodes of cont111
+ // :first object of lst111
+
+ // second object of lst111
+ testLeaf(lst11, "lf111", new Integer(141), jsonOutput, prefix);
+ testLeaf(lst11, "lf112", new String("lf112 str2"), jsonOutput, prefix);
+
+ // subnodes of cont111
+ testLeaf(cont111, "lf1111", new String("lf1111 str2"), jsonOutput, prefix);
+ testLeafList(cont1, "lflst1111", jsonOutput, prefix, new Integer(2049), new Integer(1025), new Integer(4097));
+
+ // subnodes of lst1111
+ testLeaf(lst1111, "lf1111A", new String("lf1111A str21"), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111B", new Integer(5), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111A", new String("lf1111A str22"), jsonOutput, prefix);
+ testLeaf(lst1111, "lf1111B", new Integer(8), jsonOutput, prefix);
+ // :subnodes of lst111
+ // :subnodes of cont111
+ // :second object of lst111
+ // :second object of lst111
+ // :subnodes of cont1
+ }
+
+ private void testLeaf(String prevRegEx, String lstName, Object value, String jsonFile, String elementPrefix) {
+ String newValue = null;
+ if (value instanceof Integer) {
+ newValue = value.toString();
+ } else if (value instanceof String) {
+ newValue = "\"" + value.toString() + "\"";
+ }
+ String lf = elementPrefix + lstName + "\":" + newValue;
+ assertTrue(">>\"" + lstName + "\":" + newValue + "<< is missing",
+ Pattern.compile(".*" + prevRegEx + ".*" + lf + ".*", Pattern.DOTALL).matcher(jsonFile).matches());
+
+ }
+
+ private void testLeafList(String prevRegEx, String lflstName, String jsonFile, String elementPrefix,
+ Object... dataInList) {
+ // order of element in the list isn't defined :(
+ String lflstBegin = elementPrefix + lflstName + "\":\\[";
+ String lflstEnd = ".*\\],";
+ assertTrue(
+ ">>\"" + lflstName + "\": [],<< is missing",
+ Pattern.compile(".*" + prevRegEx + ".*" + lflstBegin + lflstEnd + ".*", Pattern.DOTALL)
+ .matcher(jsonFile).matches());
+
+ for (Object obj : dataInList) {
+ testValueOfLeafList(prevRegEx, lflstBegin, obj, jsonFile);
+ }
+ }
+
+ private void testValueOfLeafList(String prevRegEx, String lflstPrevRegEx, Object value, String jsonFile) {
+ String lflstData = null;
+ lflstData = regExForDataValueInList(value);
+ assertNotNull(lflstPrevRegEx + ": value doesn't have correct type.", lflstData);
+ assertTrue(
+ prevRegEx + ": data value >" + value + "< is missing.",
+ Pattern.compile(".*" + prevRegEx + ".*" + lflstPrevRegEx + lflstData + ".*", Pattern.DOTALL)
+ .matcher(jsonFile).matches());
+
+ }
+
+ /**
+ * Data value can be first, inner, last or only one member of list
+ *
+ * @param dataValue
+ * @return
+ */
+ private String regExForDataValueInList(Object dataValue) {
+ String newDataValue;
+ if (dataValue instanceof Integer) {
+ newDataValue = dataValue.toString();
+ return "(" + newDataValue + "(,[0-9]+)+|([0-9]+,)+" + newDataValue + "(,[0-9]+)+|([0-9]+,)+" + newDataValue
+ + "|" + newDataValue + ")\\]";
+ } else if (dataValue instanceof String) {
+ newDataValue = "\"" + dataValue.toString() + "\"";
+ return "(" + newDataValue + "(,\".+\")+|(\".+\",)+" + newDataValue + "(,\".+\")+|(\".+\",)+" + newDataValue
+ + "|" + newDataValue + ")\\]";
+ }
+ return null;
+ }
+
+ private String readJsonFromFile(String path) {
+ String fullPath = YangAndXmlToJsonConversion.class.getResource(path).getPath();
+ assertNotNull("Path to file can't be null.", fullPath);
+ File file = new File(fullPath);
+ assertNotNull("File can't be null", file);
+ FileReader fileReader = null;
+ try {
+ fileReader = new FileReader(file);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ assertNotNull("File reader can't be null.", fileReader);
+
+ StringBuilder strBuilder = new StringBuilder();
+ char[] buffer = new char[1000];
+
+ while (true) {
+ int loadedCharNum;
+ try {
+ loadedCharNum = fileReader.read(buffer);
+ } catch (IOException e) {
+ break;
+ }
+ if (loadedCharNum == -1) {
+ break;
+ }
+ strBuilder.append(buffer, 0, loadedCharNum);
+ }
+ try {
+ fileReader.close();
+ } catch (IOException e) {
+ System.out.println("The file wasn't closed");
+ ;
+ }
+ String rawStr = strBuilder.toString();
+ rawStr = rawStr.replace("\n", "");
+ rawStr = rawStr.replace("\r", "");
+ rawStr = rawStr.replace("\t", "");
+ rawStr = removeSpaces(rawStr);
+
+ return rawStr;
+ }
+
+ private String removeSpaces(String rawStr) {
+ StringBuilder strBuilder = new StringBuilder();
+ int i = 0;
+ int quoteCount = 0;
+ while (i < rawStr.length()) {
+ if (rawStr.substring(i, i + 1).equals("\"")) {
+ quoteCount++;
+ }
+
+ if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) {
+ strBuilder.append(rawStr.charAt(i));
+ }
+ i++;
+ }
+
+ return strBuilder.toString();
+ }
+
+ private String convertXmlDataAndYangToJson(String xmlDataPath, String yangPath) {
+ String jsonResult = null;
+ Set<Module> modules = null;
+
+ try {
+ modules = TestUtils.loadModules(YangAndXmlToJsonConversion.class.getResource(yangPath).getPath());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ assertNotNull("modules can't be null.", modules);
+
+ InputStream xmlStream = YangAndXmlToJsonConversion.class.getResourceAsStream(xmlDataPath);
+ CompositeNode compositeNode = null;
+ try {
+ compositeNode = TestUtils.loadCompositeNode(xmlStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ assertNotNull("Composite node can't be null", compositeNode);
+
+ StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
+ for (Module module : modules) {
+ for (DataSchemaNode dataSchemaNode : module.getChildNodes()) {
+ StructuredData structuredData = new StructuredData(compositeNode, dataSchemaNode);
+ ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+ try {
+ structuredDataToJsonProvider.writeTo(structuredData, null, null, null, null, null, byteArrayOS);
+ } catch (WebApplicationException | IOException e) {
+ e.printStackTrace();
+ }
+ assertFalse(
+ "Returning JSON string can't be empty for node " + dataSchemaNode.getQName().getLocalName(),
+ byteArrayOS.toString().isEmpty());
+ jsonResult = byteArrayOS.toString();
+ try {
+ outputToFile(byteArrayOS);
+ } catch (IOException e) {
+ System.out.println("Output file wasn't cloased sucessfuly.");
+ }
+ }
+ }
+ return jsonResult;
+ }
+
+ private void outputToFile(ByteArrayOutputStream outputStream) throws IOException {
+ FileOutputStream fileOS = null;
+ try {
+ String path = YangAndXmlToJsonConversion.class.getResource("/yang-to-json-conversion/xml").getPath();
+ File outFile = new File(path + "/data.json");
+ fileOS = new FileOutputStream(outFile);
+ try {
+ fileOS.write(outputStream.toByteArray());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ fileOS.close();
+ } catch (FileNotFoundException e1) {
+ e1.printStackTrace();
+ }
+ }
+}
--- /dev/null
+module simple-yang-types {
+ namespace "simple:yang:types";
+
+ prefix "smptp";
+ revision 2013-11-5 {
+ description "Initial revision.";
+ }
+
+ container cont1 {
+ leaf lf11 {
+ type string;
+ }
+ leaf-list lflst11 {
+ type int32;
+ }
+ leaf-list lflst12 {
+ type string;
+ }
+ list lst11 {
+ key lf111;
+ leaf lf111 {
+ type uint8;
+ }
+ leaf lf112 {
+ type string;
+ }
+ container cont111 {
+ leaf lf1111 {
+ type string;
+ }
+ leaf-list lflst1111 {
+ type int32;
+ }
+ list lst1111 {
+ leaf lf1111A {
+ type string;
+ }
+ leaf lf1111B {
+ type uint8;
+ }
+ }
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+{
+ "smptp:cont1": {
+ "lf11":"lf",
+ "lflst11": [55,56,57],
+ "lflst12": ["lflst12 str1", "lflst12 str2", "lflst12 str3"],
+ "lst11": [
+ {
+ "lf111":140,
+ "lf112":"lf112 str",
+ "cont111": {
+ "lf1111":"lf1111 str",
+ "lflst1111": [2048, 1024, 4096],
+ "lst1111": [
+ {
+ "lf1111A": "lf1111A str11",
+ "lf1111B": 4
+ },
+ {
+ "lf1111A": "lf1111A str12",
+ "lf1111B": 7
+ }
+ ]
+ }
+ },
+ {
+ "lf111":141,
+ "lf112":"lf112 str2",
+ "cont111": {
+ "lf1111":"lf1111 str2",
+ "lflst1111": [2049, 1025, 4097],
+ "lst1111": [
+ {
+ "lf1111A": "lf1111A str21",
+ "lf1111B": 5
+ },
+ {
+ "lf1111A": "lf1111A str22",
+ "lf1111B": 8
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
--- /dev/null
+<cont1>
+ <lf11>lf</lf11>
+ <lflst11>55</lflst11>
+ <lflst11>56</lflst11>
+ <lflst11>57</lflst11>
+ <lflst12>lflst12 str1</lflst12>
+ <lflst12>lflst12 str2</lflst12>
+ <lflst12>lflst12 str3</lflst12>
+ <lst11>
+ <lf111>140</lf111>
+ <lf112>lf112 str</lf112>
+ <cont111>
+ <lf1111>lf1111 str</lf1111>
+ <lflst1111>2048</lflst1111>
+ <lflst1111>1024</lflst1111>
+ <lflst1111>4096</lflst1111>
+ <lst1111>
+ <lf1111A>lf1111A str11</lf1111A>
+ <lf1111B>4</lf1111B>
+ </lst1111>
+ <lst1111>
+ <lf1111A>lf1111A str12</lf1111A>
+ <lf1111B>7</lf1111B>
+ </lst1111>
+ </cont111>
+ </lst11>
+ <lst11>
+ <lf111>141</lf111>
+ <lf112>lf112 str2</lf112>
+ <cont111>
+ <lf1111>lf1111 str2</lf1111>
+ <lflst1111>2049</lflst1111>
+ <lflst1111>1025</lflst1111>
+ <lflst1111>4097</lflst1111>
+ <lst1111>
+ <lf1111A>lf1111A str21</lf1111A>
+ <lf1111B>5</lf1111B>
+ </lst1111>
+ <lst1111>
+ <lf1111A>lf1111A str22</lf1111A>
+ <lf1111B>8</lf1111B>
+ </lst1111>
+ </cont111>
+ </lst11>
+</cont1>
doNothing().when(provider).abortTestTransaction(any(ObjectName.class));
doReturn(mockOn).when(provider).getOrCreateTransaction();
+ doNothing().when(provider).wipeTestTransaction(any(ObjectName.class));
+
doReturn(configTransactionClient).when(configRegistry).getConfigTransactionClient(any(ObjectName.class));
doReturn("mockConfigTransactionClient").when(configTransactionClient).toString();
<target>
<candidate/>
</target>
- <default-operation>replace</default-operation>
+ <default-operation>merge</default-operation>
<config>
</config>
<artifactId>netty-handler</artifactId>
<version>${netconf.netty.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>ganymed</artifactId>
+ </dependency>
</dependencies>
<build>
org.opendaylight.controller.config.stat,
com.google.common.base,
com.google.common.collect,
+ ch.ethz.ssh2,
io.netty.buffer,
io.netty.channel,
io.netty.channel.socket,
--- /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.netconf.util.handler.ssh;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import java.io.IOException;
+import java.net.SocketAddress;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.AuthenticationHandler;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.Invoker;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClient;
+import org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter;
+import org.opendaylight.controller.netconf.util.handler.ssh.virtualsocket.VirtualSocket;
+
+/**
+ * Netty SSH handler class. Acts as interface between Netty and SSH library. All standard Netty message handling
+ * stops at instance of this class. All downstream events are handed of to wrapped {@link org.opendaylight.controller.netconf.util.handler.ssh.client.SshClientAdapter};
+ */
+public class SshHandler extends ChannelOutboundHandlerAdapter {
+ private final VirtualSocket virtualSocket = new VirtualSocket();
+ private final SshClientAdapter sshClientAdapter;
+
+ public SshHandler(AuthenticationHandler authenticationHandler, Invoker invoker) throws IOException {
+ SshClient sshClient = new SshClient(virtualSocket, authenticationHandler);
+ this.sshClientAdapter = new SshClientAdapter(sshClient, invoker);
+ }
+
+ @Override
+ public void handlerAdded(ChannelHandlerContext ctx){
+ if (ctx.channel().pipeline().get("socket") == null) {
+ ctx.channel().pipeline().addFirst("socket", virtualSocket);
+ }
+ }
+
+ @Override
+ public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
+ if (ctx.channel().pipeline().get("socket") != null) {
+ ctx.channel().pipeline().remove("socket");
+ }
+ }
+
+ @Override
+ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
+ this.sshClientAdapter.write((String) msg);
+ }
+
+ @Override
+ public void connect(final ChannelHandlerContext ctx,
+ SocketAddress remoteAddress,
+ SocketAddress localAddress,
+ ChannelPromise promise) throws Exception {
+ ctx.connect(remoteAddress, localAddress, promise);
+
+ promise.addListener(new ChannelFutureListener() {
+ public void operationComplete(ChannelFuture channelFuture) throws Exception {
+ sshClientAdapter.start(ctx);
+ }}
+ );
+ }
+
+ @Override
+ public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
+ sshClientAdapter.stop(promise);
+ }
+}
--- /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.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class providing authentication facility to SSH handler.
+ */
+public abstract class AuthenticationHandler {
+ public abstract void authenticate(Connection connection) throws IOException;
+}
--- /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.netconf.util.handler.ssh.authentication;
+
+import ch.ethz.ssh2.Connection;
+
+import java.io.IOException;
+
+/**
+ * Class Providing username/password authentication option to {@link org.opendaylight.controller.netconf.util.handler.ssh.SshHandler}
+ */
+public class LoginPassword extends AuthenticationHandler {
+ private final String username;
+ private final String password;
+
+ public LoginPassword(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ @Override
+ public void authenticate(Connection connection) throws IOException {
+ boolean isAuthenticated = connection.authenticateWithPassword(username, password);
+
+ if (isAuthenticated == false) throw new IOException("Authentication failed.");
+ }
+}
--- /dev/null
+package org.opendaylight.controller.netconf.util.handler.ssh.client;
+
+import java.io.IOException;
+
+/**
+ * Abstract class providing mechanism of invoking various SSH level services.
+ * Class is not allowed to be extended, as it provides its own implementations via instance initiators.
+ */
+public abstract class Invoker {
+ private boolean invoked = false;
+
+ private Invoker(){}
+
+ protected boolean isInvoked() {
+ return invoked;
+ }
+
+ abstract void invoke(SshSession session) throws IOException;
+
+ /**
+ * Invoker implementation to invokes subsystem SSH service.
+ *
+ * @param subsystem
+ * @return
+ */
+ public static Invoker subsystem(final String subsystem) {
+ return new Invoker() {
+ @Override
+