<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.6.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossts.jta</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
@Override
public String toString() {
- return "ExceptionMessageWithStackTrace [message=" + message
- + ", stackTrace=" + stackTrace + "]";
+ return message;
}
}
return null;
}
- private synchronized void blankTransaction() {
+ synchronized void blankTransaction() {
// race condition check: config-persister might push new configuration while server is starting up.
ConflictingVersionException lastException = null;
for (int i = 0; i < 10; i++) {
configRegistryJMXRegistrator.registerToJMX(configRegistry);
// track bundles containing factories
- extenderBundleTracker = new ExtenderBundleTracker(context);
+ BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(configRegistry);
+ extenderBundleTracker = new ExtenderBundleTracker(context, blankTransactionServiceTracker);
extenderBundleTracker.open();
- BlankTransactionServiceTracker customizer = new BlankTransactionServiceTracker(configRegistry);
- ServiceTracker<?, ?> serviceTracker = new ServiceTracker(context, ModuleFactory.class, customizer);
+ ServiceTracker<?, ?> serviceTracker = new ServiceTracker(context, ModuleFactory.class, blankTransactionServiceTracker);
serviceTracker.open();
}
* Code based on http://www.toedter.com/blog/?p=236
*/
public class ExtenderBundleTracker extends BundleTracker<Object> {
-
+ private final BlankTransactionServiceTracker blankTransactionServiceTracker;
private static final Logger logger = LoggerFactory.getLogger(ExtenderBundleTracker.class);
- public ExtenderBundleTracker(BundleContext context) {
+ public ExtenderBundleTracker(BundleContext context, BlankTransactionServiceTracker blankTransactionServiceTracker) {
super(context, Bundle.ACTIVE, null);
+ this.blankTransactionServiceTracker = blankTransactionServiceTracker;
logger.trace("Registered as extender with context {}", context);
}
@Override
public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
super.removedBundle(bundle,event,object);
+ // workaround for service tracker not getting removed service event
+ blankTransactionServiceTracker.blankTransaction();
}
// TODO:test
plaintext, xml;
public static final String XML_STORAGE_FIRST_LINE = "<" + ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME + ">";
+ private static final String XML_FILE_DEFINITION_LINE = "<?xml";
static FileType getFileType(File file) {
String firstLine = readFirstLine(file);
}
private static boolean isXmlStorage(String firstLine) {
- return firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+ boolean isXml = false;
+ isXml |= firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+ isXml |= firstLine.startsWith(XML_FILE_DEFINITION_LINE);
+ return isXml;
}
private static boolean isPlaintextStorage(String firstLine) {
import java.util.SortedSet;
import org.junit.Test;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class DirectoryStorageAdapterTest {
-
- Persister tested;
+ XmlDirectoryPersister tested;
+ Logger logger = LoggerFactory.getLogger(DirectoryStorageAdapterTest.class.toString());
@Test
public void testEmptyDirectory() throws Exception {
@Test
public void testOneFile() throws Exception {
File folder = getFolder("oneFile");
-
- PropertiesProviderTest pp = new PropertiesProviderTest();
- pp.addProperty("directoryStorage",folder.getPath());
- XmlDirectoryStorageAdapter xmlDsa = new XmlDirectoryStorageAdapter();
- tested = xmlDsa.instantiate(pp);
-
+ tested = new XmlDirectoryPersister(folder);
+ logger.info("Testing : "+tested.toString());
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(1, results.size());
ConfigSnapshotHolder result = results.get(0);
@Test
public void testTwoFiles() throws Exception {
File folder = getFolder("twoFiles");
-
- PropertiesProviderTest pp = new PropertiesProviderTest();
- pp.addProperty("directoryStorage",folder.getPath());
- XmlDirectoryStorageAdapter xmlDsa = new XmlDirectoryStorageAdapter();
- tested = xmlDsa.instantiate(pp);
-
+ tested = new XmlDirectoryPersister((folder));
+ logger.info("Testing : "+tested.toString());
List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
assertEquals(2, results.size());
<artifactId>mockito-configuration</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
package org.opendaylight.controller.config.persist.storage.file.xml;
import com.google.common.base.Charsets;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
import java.io.File;
import java.nio.file.Files;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
-
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
import static junit.framework.Assert.assertFalse;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
@Test
public void testFileAdapter() throws Exception {
XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
- storage.setFileStorage(file);
- storage.setNumberOfBackups(Integer.MAX_VALUE);
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",file.getPath());
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+ storage.instantiate(pp);
+
final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
@Override
public String getConfigSnapshot() {
@Test
public void testFileAdapterOneBackup() throws Exception {
XmlFileStorageAdapter storage = new XmlFileStorageAdapter();
- storage.setFileStorage(file);
- storage.setNumberOfBackups(1);
+
+ PropertiesProviderTest pp = new PropertiesProviderTest();
+ pp.addProperty("fileStorage",file.getPath());
+ pp.addProperty("numberOfBackups",Integer.toString(Integer.MAX_VALUE));
+ storage.instantiate(pp);
+
final ConfigSnapshotHolder holder = new ConfigSnapshotHolder() {
@Override
public String getConfigSnapshot() {
storage.persistConfig(holder);
- assertEquals(16, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
+ assertEquals(27, com.google.common.io.Files.readLines(file, Charsets.UTF_8).size());
List<ConfigSnapshotHolder> lastConf = storage.loadLastConfigs();
assertEquals(1, lastConf.size());
-/**
- * Generated file
-
- * Generated from: yang module name: config-test yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * Do not modify this file unless it is present under src/main directory
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.controller.config.yang.logback.config;
-/**
- * Generated file
-
- * Generated from: yang module name: config-test yang module local name: testing
- * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- * Generated at: Fri Sep 27 14:06:33 CEST 2013
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * Do not modify this file unless it is present under src/main directory
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.controller.config.yang.logback.config;
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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.yang.netty.eventexecutor;
import javax.management.InstanceAlreadyExistsException;
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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.yang.netty.timer;
import javax.management.InstanceAlreadyExistsException;
* @param inputSecret must match configured secret of the implementation
* @param reason Optional string to be logged while shutting down
*/
- void shutdown(String inputSecret, Optional<String> reason);
+ void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason);
}
public final class ShutdownModule extends AbstractShutdownModule {
private final Bundle systemBundle;
- private final ShutdownModule nullableOldModule;
public ShutdownModule(ModuleIdentifier identifier, Bundle systemBundle) {
super(identifier, null);
singletonCheck(identifier);
this.systemBundle = systemBundle;
- this.nullableOldModule = null;
}
public ShutdownModule(ModuleIdentifier identifier, ShutdownModule oldModule, java.lang.AutoCloseable oldInstance,
super(identifier, null, oldModule, oldInstance);
singletonCheck(identifier);
this.systemBundle = systemBundle;
- this.nullableOldModule = oldModule;
}
private static void singletonCheck(ModuleIdentifier identifier) {
throw new UnsupportedOperationException();
}
- @Override
- public String getSecret() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getOldSecret() {
- throw new UnsupportedOperationException();
- }
-
- String getActualSecret() {
- return super.getSecret();
- }
-
- String getActualOldSecret() {
- return super.getOldSecret();
- }
-
@Override
protected void customValidation() {
- JmxAttributeValidationException.checkNotNull(super.getOldSecret(), oldSecretJmxAttribute);
JmxAttributeValidationException.checkNotNull(super.getSecret(), secretJmxAttribute);
- if (nullableOldModule != null) {
- // if nothing changed, remain valid
- boolean sameAsOldModule = isSame(nullableOldModule);
- if (sameAsOldModule == false) {
- boolean valid = getActualOldSecret().equals(nullableOldModule.getActualSecret());
- JmxAttributeValidationException.checkCondition(valid, "Invalid old secret", oldSecretJmxAttribute);
- }
- }
}
@Override
public java.lang.AutoCloseable createInstance() {
- return new ShutdownServiceImpl(getActualSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
+ return new ShutdownServiceImpl(getSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
}
}
package org.opendaylight.controller.config.yang.shutdown.impl;
import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
-
- @Override
- public org.opendaylight.controller.config.spi.Module createModule(String instanceName, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.api.DynamicMBeanWithInstance old, org.osgi.framework.BundleContext bundleContext) throws Exception {
- org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule oldModule = null;
- try {
- oldModule = (org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule) old.getModule();
- } catch(Exception e) {
- return handleChangedClass(old);
- }
- org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
-
- module.setOldSecret(oldModule.getActualOldSecret());
- module.setSecret(oldModule.getActualSecret());
-
- return module;
- }
+import java.util.Arrays;
+import java.util.Set;
+public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
ShutdownModule oldModule, AutoCloseable oldInstance,
Bundle systemBundle = bundleContext.getBundle(0);
return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), systemBundle);
}
+
+ @Override
+ public Set<ShutdownModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
+ ModuleIdentifier id = new ModuleIdentifier(NAME, NAME);
+ DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(id);
+ ShutdownModule shutdownModule = instantiateModule(NAME, dependencyResolver, bundleContext);
+ return new java.util.HashSet<>(Arrays.asList(shutdownModule));
+ }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+
public class ShutdownServiceImpl implements ShutdownService, AutoCloseable {
private final ShutdownService impl;
private final ShutdownRuntimeRegistration registration;
}
@Override
- public void shutdown(String inputSecret, Optional<String> reason) {
- impl.shutdown(inputSecret, reason);
+ public void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason) {
+ impl.shutdown(inputSecret, maxWaitTime, reason);
}
@Override
}
@Override
- public void shutdown(String inputSecret, Optional<String> reason) {
+ public void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason) {
logger.warn("Shutdown issued with secret {} and reason {}", inputSecret, reason);
try {
Thread.sleep(1000); // prevent brute force attack
if (this.secret.equals(inputSecret)) {
logger.info("Server is shutting down");
- Thread stopSystemBundle = new Thread() {
- @Override
- public void run() {
- try {
- // wait so that JMX response is received
- Thread.sleep(1000);
- systemBundle.stop();
- } catch (BundleException e) {
- logger.warn("Can not stop OSGi server", e);
- } catch (InterruptedException e) {
- logger.warn("Shutdown process interrupted", e);
- }
- }
- };
- stopSystemBundle.start();
-
+ // actual work:
+ Thread stopSystemBundleThread = new StopSystemBundleThread(systemBundle);
+ stopSystemBundleThread.start();
+ if (maxWaitTime != null && maxWaitTime > 0) {
+ Thread systemExitThread = new CallSystemExitThread(maxWaitTime);
+ logger.debug("Scheduling {}", systemExitThread);
+ systemExitThread.start();
+ }
+ // end
} else {
logger.warn("Unauthorized attempt to shut down server");
throw new IllegalArgumentException("Invalid secret");
}
+class StopSystemBundleThread extends Thread {
+ private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class);
+ private final Bundle systemBundle;
+
+ StopSystemBundleThread(Bundle systemBundle) {
+ super("stop-system-bundle");
+ this.systemBundle = systemBundle;
+ }
+
+ @Override
+ public void run() {
+ try {
+ // wait so that JMX response is received
+ Thread.sleep(1000);
+ systemBundle.stop();
+ } catch (BundleException e) {
+ logger.warn("Can not stop OSGi server", e);
+ } catch (InterruptedException e) {
+ logger.warn("Shutdown process interrupted", e);
+ }
+ }
+}
+
+class CallSystemExitThread extends Thread {
+ private static final Logger logger = LoggerFactory.getLogger(CallSystemExitThread.class);
+ private final long maxWaitTime;
+ CallSystemExitThread(long maxWaitTime) {
+ super("call-system-exit-daemon");
+ setDaemon(true);
+ if (maxWaitTime <= 0){
+ throw new IllegalArgumentException("Cannot schedule to zero or negative time:" + maxWaitTime);
+ }
+ this.maxWaitTime = maxWaitTime;
+ }
+
+ @Override
+ public String toString() {
+ return "CallSystemExitThread{" +
+ "maxWaitTime=" + maxWaitTime +
+ '}';
+ }
+
+ @Override
+ public void run() {
+ try {
+ // wait specified time
+ Thread.sleep(maxWaitTime);
+ logger.error("Since some threads are still running, server is going to shut down via System.exit(1) !");
+ // do a thread dump
+ ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
+ StringBuffer sb = new StringBuffer();
+ for(ThreadInfo info : threads) {
+ sb.append(info);
+ sb.append("\n");
+ }
+ logger.warn("Thread dump:{}", sb);
+ System.exit(1);
+ } catch (InterruptedException e) {
+ logger.info("Interrupted, not going to call System.exit(1)");
+ }
+ }
+}
+
+
class MXBeanImpl implements ShutdownRuntimeMXBean {
private final ShutdownService impl;
}
@Override
- public void shutdown(String inputSecret, String nullableReason) {
+ public void shutdown(String inputSecret, Long maxWaitTime, String nullableReason) {
Optional<String> optionalReason;
if (nullableReason == null) {
optionalReason = Optional.absent();
} else {
optionalReason = Optional.of(nullableReason);
}
- impl.shutdown(inputSecret, optionalReason);
+ impl.shutdown(inputSecret, maxWaitTime, optionalReason);
}
}
type string;
default "";
}
- leaf old-secret {
- type string;
- default "";
- }
}
}
leaf input-secret {
type string;
}
+ leaf max-wait-time {
+ type uint32;
+ description "Maximum time in milliseconds before process is forcibly exited. Zero or null cancels this functionality.";
+ }
leaf reason {
type string;
}
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.ValidationException.ExceptionMessageWithStackTrace;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import javax.management.JMX;
import javax.management.ObjectName;
import java.util.Collections;
-import java.util.Map;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
mockedContext.getBundle(0);
doNothing().when(mockedSysBundle).stop();
+ ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+ // initialize default instance
+ transaction.commit();
}
@Test
}
}
+ private static final ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+
@Test
public void testWithoutSecret() throws Exception {
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
- transaction.createModule(NAME, NAME);
- transaction.commit();
// test JMX rpc
- ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+
ShutdownRuntimeMXBean runtime = configRegistryClient.newMXBeanProxy(runtimeON, ShutdownRuntimeMXBean.class);
try {
- runtime.shutdown("foo", null);
+ runtime.shutdown("foo", 60000L, null);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Invalid secret", e.getMessage());
}
- runtime.shutdown("", null);
+ runtime.shutdown("", 60000L, null);
assertStopped();
}
@Test
public void testWithSecret() throws Exception {
ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
- ObjectName on = transaction.createModule(NAME, NAME);
+ ObjectName on = transaction.lookupConfigBean(NAME, NAME);
ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
String secret = "secret";
proxy.setSecret(secret);
transaction.commit();
shutdownViaRuntimeJMX(secret);
-
- // test old secret
- transaction = configRegistryClient.createTransaction();
- on = transaction.lookupConfigBean(NAME, NAME);
- proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
- try {
- rethrowCause(proxy).getOldSecret();
- fail();
- } catch (UnsupportedOperationException e) {
- }
try {
- rethrowCause(proxy).getSecret();
+ ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
+ runtime.shutdown("foo", 60000L, null);
fail();
- } catch (UnsupportedOperationException e) {
- }
- // set secret to nothing
- String newSecret = "newSecret";
- proxy.setSecret(newSecret);
- try {
- transaction.commit();
- fail("Old secret not provided - should fail validation");
- } catch (ValidationException e) {
- Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations = e.getFailedValidations();
- assertTrue(failedValidations.containsKey(NAME));
- ExceptionMessageWithStackTrace exceptionMessageWithStackTrace = failedValidations.get(NAME).get(NAME);
- assertNotNull(exceptionMessageWithStackTrace);
- assertEquals("OldSecret Invalid old secret", exceptionMessageWithStackTrace.getMessage());
-
+ } catch (IllegalArgumentException e) {
+ assertEquals("Invalid secret", e.getMessage());
}
- proxy.setOldSecret(secret);
- transaction.commit();
- shutdownViaRuntimeJMX(newSecret);
}
private void shutdownViaRuntimeJMX(String secret) throws Exception {
// test JMX rpc
- ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
try {
- runtime.shutdown("", null);
+ runtime.shutdown("", 60000L, null);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Invalid secret", e.getMessage());
}
- runtime.shutdown(secret, null);
+ runtime.shutdown(secret, 60000L, null);
assertStopped();
}
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*
+ * 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
+ */
+
/**
* Generated file
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.async;\r
\r
import static org.junit.Assert.assertThat;\r
+/*
+ * 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.eventbus;
import static org.junit.Assert.assertEquals;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.eventbus;\r
\r
import static org.mockito.Mockito.doNothing;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.fixed;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.fixed;\r
\r
import static org.mockito.Mockito.doNothing;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.flexible;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.naming;\r
\r
import static org.junit.Assert.assertEquals;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.naming;\r
\r
import static org.mockito.Matchers.any;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.scheduled;\r
\r
import org.junit.Before;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.config.threadpool.scheduled;\r
\r
import com.google.common.util.concurrent.ListenableFutureTask;\r
+/*
+ * 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.yangjmxgenerator.attribute;
import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml
netconf.config.persister.2.properties.numberOfBackups=1
-
yangstore.blacklist=.*controller.model.*
# Set Default start level for framework
fi
elif [[ $platform == 'osx' ]]; then
TARGET_FILE=$0
- cd `dirname $TARGET_FILE`
+ cd `dirname "$TARGET_FILE"`
TARGET_FILE=`basename $TARGET_FILE`
# Iterate down a (possible) chain of symlinks
while [ -L "$TARGET_FILE" ]
do
- TARGET_FILE=`readlink $TARGET_FILE`
- cd `dirname $TARGET_FILE`
- TARGET_FILE=`basename $TARGET_FILE`
+ TARGET_FILE=`readlink "$TARGET_FILE"`
+ cd `dirname "$TARGET_FILE"`
+ TARGET_FILE=`basename "$TARGET_FILE"`
done
# Compute the canonicalized name by finding the physical path
JVM at path ${JAVA_HOME}/bin/java check your JAVA_HOME" && exit -1;
if [ -z ${ODL_BASEDIR} ]; then
- basedir=`dirname ${fullpath}`
+ basedir=`dirname "${fullpath}"`
else
basedir=${ODL_BASEDIR}
fi
if [ -z ${ODL_DATADIR} ]; then
- datadir=`dirname ${fullpath}`
+ datadir=`dirname "${fullpath}"`
else
datadir=${ODL_DATADIR}
fi
########################################
# Now add to classpath the OSGi JAR
########################################
-CLASSPATH=${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
-FWCLASSPATH=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+CLASSPATH="${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+FWCLASSPATH=file:"${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
########################################
# Now add the extensions
fi
fi
+iotmpdir=`echo "${datadir}" | sed 's/ /\\ /g'`
+bdir=`echo "${basedir}" | sed 's/ /\\ /g'`
+confarea=`echo "${datadir}" | sed 's/ /\\ /g'`
+fwclasspath=`echo "${FWCLASSPATH}" | sed 's/ /\\ /g'`
+
if [ "${startdaemon}" -eq 1 ]; then
if [ -e "${pidfile}" ]; then
echo "Another instance of controller running, check with $0 -status"
exit -1
fi
$JAVA_HOME/bin/java ${extraJVMOpts} \
- -Djava.io.tmpdir=${datadir}/work/tmp \
- -Dosgi.install.area=${basedir} \
- -Dosgi.configuration.area=${datadir}/configuration \
- -Dosgi.frameworkClassPath=${FWCLASSPATH} \
- -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \
+ -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
+ -Dosgi.install.area="${bdir}" \
+ -Dosgi.configuration.area="${confarea}/configuration" \
+ -Dosgi.frameworkClassPath="${fwclasspath}" \
+ -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \
-Djava.awt.headless=true \
- -classpath ${CLASSPATH} \
+ -classpath "${CLASSPATH}" \
org.eclipse.equinox.launcher.Main \
-console ${daemonport} \
-consoleLog &
exit -1
fi
$JAVA_HOME/bin/java ${extraJVMOpts} \
- -Djava.io.tmpdir=${datadir}/work/tmp \
- -Dosgi.install.area=${basedir} \
- -Dosgi.configuration.area=${datadir}/configuration \
- -Dosgi.frameworkClassPath=${FWCLASSPATH} \
- -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \
+ -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
+ -Dosgi.install.area="${bdir}" \
+ -Dosgi.configuration.area="${confarea}/configuration" \
+ -Dosgi.frameworkClassPath="${fwclasspath}" \
+ -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \
-Djava.awt.headless=true \
- -classpath ${CLASSPATH} \
+ -classpath "${CLASSPATH}" \
org.eclipse.equinox.launcher.Main \
-console \
-consoleLog
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
// staticFlowEntry should never be null.
// the null check is just an extra defensive check.
if(staticFlowEntry != null) {
- staticFlows.remove(staticFlowEntry.getKey());
+ // Modify status and update cluster cache
+ log.debug("Updating static flow configuration on async error event");
+ String status = String.format("Cannot be installed on node. reason: %s", errorString);
+ staticFlowEntry.getValue().setStatus(status);
+ refreshClusterStaticFlowsStatus(node);
}
}
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.6.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
throw new UnsupportedOperationException("TODO: auto-generated method stub")
}
+ override getConfiguredNotConnectedSwitches() {
+ return null;
}
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
import org.opendaylight.controller.sal.utils.INodeConnectorFactory
import org.opendaylight.controller.sal.utils.INodeFactory
import org.opendaylight.controller.clustering.services.IClusterGlobalServices
+import org.opendaylight.controller.sal.packet.IPluginInDataPacketService
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
+import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
+class ComponentActivator extends ComponentActivatorAbstractBase {
private BundleContext context;
@Property
TopologyProvider tpProvider = new TopologyProvider()
+ @Property
+ DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter()
+
+
override protected init() {
Node.NodeIDType.registerIDType(MD_SAL_TYPE, String);
}
def setBroker(BindingAwareBroker broker) {
- broker.registerConsumer(this, context)
+ broker.registerProvider(new SalCompatibilityProvider(this), context)
}
- override onSessionInitialized(ConsumerContext session) {
- val subscribe = session.getSALService(NotificationService)
-
- // Registration of Flow Service
- flow.delegate = session.getRpcService(SalFlowService)
- flow.dataBrokerService = session.getSALService(DataBrokerService);
- subscribe.registerNotificationListener(flow);
-
- // Data Packet Service
- subscribe.registerNotificationListener(inventory);
-
- // Inventory Service
- inventory.dataService = session.getSALService(DataBrokerService);
- inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
- inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService);
- inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
- inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
- inventory.dataProviderService = session.getSALService(DataProviderService)
- topology.dataService = session.getSALService(DataProviderService)
- tpProvider.dataService = session.getSALService(DataProviderService)
- tpProvider.start();
-
- subscribe.registerNotificationListener(dataPacket)
-
- }
override protected getGlobalImplementations() {
return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider)
configure(imp, c);
}
+ override protected getImplementations() {
+ return Arrays.asList(dataPacketService)
+ }
+
+ override protected configureInstance(Component c, Object imp, String containerName) {
+ instanceConfigure(imp, c, containerName);
+ }
+
private def dispatch configure(MDSalNodeFactory imp, Component it) {
setInterface(INodeFactory.name, properties);
}
}
+ private def dispatch instanceConfigure(DataPacketServiceAdapter imp, Component it, String containerName) {
+ setInterface(IPluginInDataPacketService.name, properties)
+ }
+
+ private def dispatch instanceConfigure(ComponentActivator imp, Component it, String containerName) {
+ }
+
+
private def dispatch configure(InventoryAndReadAdapter imp, Component it) {
setInterface(Arrays.asList(IPluginInInventoryService.name, IPluginInReadService.name), properties)
add(
add(
createServiceDependency() //
.setService(IPluginOutInventoryService) //
- .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
+ .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") //
.setRequired(false))
add(
createServiceDependency() //
return props;
}
}
+package class SalCompatibilityProvider implements BindingAwareProvider {
+
+ private val ComponentActivator activator;
+
+ new(ComponentActivator cmpAct) {
+ activator = cmpAct;
+ }
+
+ override getFunctionality() {
+ // Noop
+ }
+
+ override getImplementations() {
+ // Noop
+ }
+
+
+ override onSessionInitialized(ConsumerContext session) {
+ // Noop
+ }
+
+
+ override onSessionInitiated(ProviderContext session) {
+ val it = activator
+ val subscribe = session.getSALService(NotificationService)
+
+ // Registration of Flow Service
+ flow.delegate = session.getRpcService(SalFlowService)
+ flow.dataBrokerService = session.getSALService(DataBrokerService);
+ subscribe.registerNotificationListener(flow);
+
+ // Data Packet Service
+ subscribe.registerNotificationListener(inventory);
+ dataPacketService.delegate = session.getRpcService(PacketProcessingService)
+
+ // Inventory Service
+ inventory.dataService = session.getSALService(DataBrokerService);
+ inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService);
+ inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService);
+ inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
+ inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
+ inventory.dataProviderService = session.getSALService(DataProviderService)
+ topology.dataService = session.getSALService(DataProviderService)
+ tpProvider.dataService = session.getSALService(DataProviderService)
+
+
+ tpProvider.start();
+
+ subscribe.registerNotificationListener(dataPacket)
+ }
+}
import java.util.ArrayList
import java.util.Collections
import java.util.List
+import java.util.Set
+import java.util.concurrent.CopyOnWriteArrayList;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
import org.opendaylight.controller.sal.binding.api.data.DataProviderService
import org.opendaylight.controller.sal.core.Edge
@Property
OpendaylightFlowTableStatisticsService flowTableStatisticsService;
- @Property
- IPluginOutInventoryService inventoryPublisher;
-
@Property
FlowTopologyDiscoveryService topologyDiscovery;
@Property
- List<IPluginOutReadService> statisticsPublisher = new ArrayList<IPluginOutReadService>();
-
+ List<IPluginOutReadService> statisticsPublisher = new CopyOnWriteArrayList<IPluginOutReadService>();
+
+ @Property
+ List<IPluginOutInventoryService> inventoryPublisher = new CopyOnWriteArrayList<IPluginOutInventoryService>();
+
+ def setInventoryPublisher(IPluginOutInventoryService listener){
+ inventoryPublisher.add(listener);
+ }
+
+ def unsetInventoryPublisher(IPluginOutInventoryService listener){
+ inventoryPublisher.remove(listener);
+ }
+
def setReadPublisher(IPluginOutReadService listener) {
statisticsPublisher.add(listener);
}
override onNodeRemoved(NodeRemoved notification) {
val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
- inventoryPublisher.updateNode(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
+ publishNodeUpdate(notification.nodeRef.toADNode, UpdateType.REMOVED, properties);
}
override onNodeConnectorUpdated(NodeConnectorUpdated update) {
var nodeConnector = update.nodeConnectorRef.toADNodeConnector
- inventoryPublisher.updateNodeConnector(nodeConnector , updateType , update.toADNodeConnectorProperties);
+ publishNodeConnectorUpdate(nodeConnector , updateType , update.toADNodeConnectorProperties);
}
override onNodeUpdated(NodeUpdated notification) {
if ( this._dataService.readOperationalData(identifier) == null ){
updateType = UpdateType.ADDED;
}
- inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
+ publishNodeUpdate(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
//Notify the listeners of IPluginOutReadService
override getConfiguredNotConnectedNodes() {
return Collections.emptySet();
}
+
+
+ private def publishNodeUpdate(Node node, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+ for( publisher : inventoryPublisher){
+ publisher.updateNode(node, updateType, properties);
+ }
+ }
+
+ private def publishNodeConnectorUpdate(org.opendaylight.controller.sal.core.NodeConnector nodeConnector, UpdateType updateType, Set<org.opendaylight.controller.sal.core.Property> properties){
+ for( publisher : inventoryPublisher){
+ publisher.updateNodeConnector(nodeConnector, updateType, properties);
+ }
+ }
}
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
private TransmitPacketInput toTransmitPacketInput(RawPacket rawPacket) {
TransmitPacketInputBuilder builderTPIB = new TransmitPacketInputBuilder();
- NodeConnectorRef egress = NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
- NodeConnectorRef ingress = NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
+ builderTPIB.setNode(NodeMapping.toNodeRef(rawPacket.getOutgoingNodeConnector().getNode()));
+
+ NodeConnectorRef egress = rawPacket.getOutgoingNodeConnector() == null ? null :
+ NodeMapping.toNodeConnectorRef(rawPacket.getOutgoingNodeConnector());
+ NodeConnectorRef ingress = rawPacket.getIncomingNodeConnector() == null ? null :
+ NodeMapping.toNodeConnectorRef(rawPacket.getIncomingNodeConnector());
byte[] payload = rawPacket.getPacketData();
builderTPIB.setEgress(egress);
return builderTPIB.build();
}
+ public PacketProcessingService getDelegate() {
+ return delegate;
+ }
+
+ public void setDelegate(PacketProcessingService delegate) {
+ this.delegate = delegate;
+ }
+
+
+
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Ericsson , 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.forwardingrulesmanager.consumer.impl;
-
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FRMConsumerImpl extends AbstractBindingAwareProvider implements CommandProvider {
- protected static final Logger logger = LoggerFactory.getLogger(FRMConsumerImpl.class);
- private static ProviderContext p_session;
- private static DataBrokerService dataBrokerService;
- private static NotificationService notificationService;
- private FlowConsumerImpl flowImplRef;
- private GroupConsumerImpl groupImplRef;
- private MeterConsumerImpl meterImplRef;
- private static DataProviderService dataProviderService;
- private static IClusterContainerServices clusterContainerService = null;
- private static IContainer container;
-
- @Override
- public void onSessionInitiated(ProviderContext session) {
- FRMConsumerImpl.p_session = session;
-
- if (!getDependentModule()) {
- logger.error("Unable to fetch handlers for dependent modules");
- System.out.println("Unable to fetch handlers for dependent modules");
- return;
- }
-
- if (null != session) {
- notificationService = session.getSALService(NotificationService.class);
-
- if (null != notificationService) {
- dataBrokerService = session.getSALService(DataBrokerService.class);
-
- if (null != dataBrokerService) {
- dataProviderService = session.getSALService(DataProviderService.class);
-
- if (null != dataProviderService) {
- flowImplRef = new FlowConsumerImpl();
- groupImplRef = new GroupConsumerImpl();
- meterImplRef = new MeterConsumerImpl();
- registerWithOSGIConsole();
- } else {
- logger.error("Data Provider Service is down or NULL. "
- + "Accessing data from configuration data store will not be possible");
- System.out.println("Data Broker Service is down or NULL.");
- }
-
- } else {
- logger.error("Data Broker Service is down or NULL.");
- System.out.println("Data Broker Service is down or NULL.");
- }
- } else {
- logger.error("Notification Service is down or NULL.");
- System.out.println("Notification Service is down or NULL.");
- }
- } else {
- logger.error("Consumer session is NULL. Please check if provider is registered");
- System.out.println("Consumer session is NULL. Please check if provider is registered");
- }
-
- }
-
- public static IClusterContainerServices getClusterContainerService() {
- return clusterContainerService;
- }
-
- public static void setClusterContainerService(IClusterContainerServices clusterContainerService) {
- FRMConsumerImpl.clusterContainerService = clusterContainerService;
- }
-
- public static IContainer getContainer() {
- return container;
- }
-
- public static void setContainer(IContainer container) {
- FRMConsumerImpl.container = container;
- }
-
- private void registerWithOSGIConsole() {
- BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
- bundleContext.registerService(CommandProvider.class.getName(), this, null);
- }
-
- private boolean getDependentModule() {
- do {
- clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(
- IClusterContainerServices.class, this);
- try {
- Thread.sleep(4);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- } while (clusterContainerService == null);
-
- do {
-
- container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
- try {
- Thread.sleep(5);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- } while (container == null);
-
- return true;
- }
-
- public static DataProviderService getDataProviderService() {
- return dataProviderService;
- }
-
- public FlowConsumerImpl getFlowImplRef() {
- return flowImplRef;
- }
-
- public GroupConsumerImpl getGroupImplRef() {
- return groupImplRef;
- }
-
- public static ProviderContext getProviderSession() {
- return p_session;
- }
-
- public static NotificationService getNotificationService() {
- return notificationService;
- }
-
- public static DataBrokerService getDataBrokerService() {
- return dataBrokerService;
- }
-
- /*
- * OSGI COMMANDS
- */
- @Override
- public String getHelp() {
- StringBuffer help = new StringBuffer();
- return help.toString();
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
-import org.opendaylight.controller.sal.utils.IPProtocols;
-import org.opendaylight.controller.sal.utils.NetUtils;
-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.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
-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 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
-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.EthernetMatch;
-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.Layer3Match;
-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.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-
-public class FRMUtil {
- protected static final Logger logger = LoggerFactory.getLogger(FRMUtil.class);
- private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
-
- public static enum operation {
- ADD, DELETE, UPDATE, GET
- };
-
- private enum EtherIPType {
- ANY, V4, V6;
- };
-
- public static boolean isNameValid(String name) {
-
- // Name validation
- if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) {
- return false;
- }
- return true;
-
- }
-
- public static boolean validateMatch(Flow flow) {
- EtherIPType etype = EtherIPType.ANY;
- EtherIPType ipsrctype = EtherIPType.ANY;
- EtherIPType ipdsttype = EtherIPType.ANY;
-
- Match match = flow.getMatch();
- if (match != null) {
- EthernetMatch ethernetmatch = match.getEthernetMatch();
- IpMatch ipmatch = match.getIpMatch();
- Layer3Match layer3match = match.getLayer3Match();
- VlanMatch vlanmatch = match.getVlanMatch();
- match.getIcmpv4Match();
-
- if (ethernetmatch != null) {
- if ((ethernetmatch.getEthernetSource() != null)
- && !isL2AddressValid(ethernetmatch.getEthernetSource().getAddress().getValue())) {
-
- logger.error("Ethernet source address is not valid. Example: 00:05:b9:7c:81:5f",
- ethernetmatch.getEthernetSource());
- return false;
- }
-
- if ((ethernetmatch.getEthernetDestination() != null)
- && !isL2AddressValid(ethernetmatch.getEthernetDestination().getAddress().getValue())) {
- logger.error("Ethernet destination address is not valid. Example: 00:05:b9:7c:81:5f",
- ethernetmatch.getEthernetDestination());
- return false;
- }
-
- if (ethernetmatch.getEthernetType() != null) {
- long type = ethernetmatch.getEthernetType().getType().getValue().longValue();
- if ((type < 0) || (type > 0xffff)) {
- logger.error("Ethernet type is not valid");
- return false;
- } else {
- if (type == 0x0800) {
- etype = EtherIPType.V4;
- } else if (type == 0x86dd) {
- etype = EtherIPType.V6;
- }
- }
-
- }
- }
-
- if (layer3match != null) {
- if (layer3match instanceof Ipv4Match) {
- if (((Ipv4Match) layer3match).getIpv4Source() != null) {
- if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Source().getValue())) {
- ipsrctype = EtherIPType.V4;
- } else {
- logger.error("IP source address is not valid");
- return false;
- }
-
- } else if (((Ipv4Match) layer3match).getIpv4Destination() != null) {
- if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Destination().getValue())) {
- ipdsttype = EtherIPType.V4;
- } else {
- logger.error("IP Destination address is not valid");
- return false;
- }
-
- }
- } else if (layer3match instanceof Ipv6Match) {
- if (((Ipv6Match) layer3match).getIpv6Source() != null) {
- if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Source().getValue())) {
- ipsrctype = EtherIPType.V6;
- } else {
- logger.error("IPv6 source address is not valid");
- return false;
- }
-
- } else if (((Ipv6Match) layer3match).getIpv6Destination() != null) {
- if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Destination().getValue())) {
- ipdsttype = EtherIPType.V6;
- } else {
- logger.error("IPv6 Destination address is not valid");
- return false;
- }
-
- }
-
- }
-
- if (etype != EtherIPType.ANY) {
- if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
- logger.error("Type mismatch between Ethernet & Src IP");
- return false;
- }
- if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
- logger.error("Type mismatch between Ethernet & Dst IP");
- return false;
- }
- }
- if (ipsrctype != ipdsttype) {
- if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
- logger.error("IP Src Dest Type mismatch");
- return false;
- }
- }
- }
-
- if (ipmatch != null) {
- if (ipmatch.getIpProtocol() != null && !(isProtocolValid(ipmatch.getIpProtocol().toString()))) {
- logger.error("Protocol is not valid");
- return false;
- }
-
- }
-
- if (vlanmatch != null) {
- if (vlanmatch.getVlanId() != null
- && !(isVlanIdValid(vlanmatch.getVlanId().getVlanId().getValue().toString()))) {
- logger.error("Vlan ID is not in the range 0 - 4095");
- return false;
- }
-
- if (vlanmatch.getVlanPcp() != null
- && !(isVlanPriorityValid(vlanmatch.getVlanPcp().getValue().toString()))) {
- logger.error("Vlan priority is not in the range 0 - 7");
- return false;
- }
- }
-
- }
-
- return true;
-
- }
-
- public static boolean validateActions(List<Action> actions) {
-
- if (actions == null || actions.isEmpty()) {
- logger.error("Actions value is null or empty");
- return false;
- }
-
- for (Action curaction : actions) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = curaction
- .getAction();
- if (action instanceof ControllerActionCase) {
- Integer length = ((ControllerActionCase) action).getControllerAction().getMaxLength();
- if (length < 0 || length > 65294) {
- logger.error("Controller: MaxLength is not valid");
- return false;
- }
- } else if (action instanceof OutputActionCase) {
- Integer length = ((OutputActionCase) action).getOutputAction().getMaxLength();
- Uri outputnodeconnector = ((OutputActionCase) action).getOutputAction().getOutputNodeConnector();
- if (length < 0 || length > 65294) {
- logger.error("OutputAction: MaxLength is not valid");
- return false;
- }
- if (outputnodeconnector != null) {
- if (!outputnodeconnector.getValue().equals(NodeConnectorIDType.ALL)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.CONTROLLER)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.HWPATH)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2OPENFLOW)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2PCEP)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2ONEPK)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2PCEP)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2ONEPK)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2OPENFLOW)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PRODUCTION)
- || !outputnodeconnector.getValue().equals(NodeConnectorIDType.SWSTACK)) {
- logger.error("Output Action: NodeConnector Type is not valid");
- return false;
- }
-
- }
- } else if (action instanceof PushMplsActionCase) {
- Integer ethertype = ((PushMplsActionCase) action).getPushMplsAction().getEthernetType();
- if (ethertype != null && ethertype != 0x8847 && ethertype != 0x8848) {
- logger.error("Ether Type is not valid for PushMplsAction");
- return false;
- }
- } else if (action instanceof PushPbbActionCase) {
- Integer ethertype = ((PushPbbActionCase) action).getPushPbbAction().getEthernetType();
- if (ethertype != null && ethertype != 0x88E7) {
- logger.error("Ether type is not valid for PushPbbAction");
- return false;
- }
- } else if (action instanceof PushVlanActionCase) {
- Integer ethertype = ((PushVlanActionCase) action).getPushVlanAction().getEthernetType();
- if (ethertype != null && ethertype != 0x8100 && ethertype != 0x88a8) {
- logger.error("Ether Type is not valid for PushVlanAction");
- return false;
- }
- } else if (action instanceof SetDlDstActionCase || action instanceof SetDlSrcActionCase) {
- MacAddress address = ((SetDlDstActionCase) action).getSetDlDstAction().getAddress();
- if (address != null && !isL2AddressValid(address.getValue())) {
- logger.error("SetDlDstAction: Address not valid");
- return false;
- }
- } else if (action instanceof SetDlSrcActionCase) {
- MacAddress address = ((SetDlSrcActionCase) action).getSetDlSrcAction().getAddress();
- if (address != null && !isL2AddressValid(address.getValue())) {
- logger.error("SetDlSrcAction: Address not valid");
- return false;
- }
- } else if (action instanceof SetQueueActionCase) {
- String queue = ((SetQueueActionCase) action).getSetQueueAction().getQueue();
- if (queue != null && !isQueueValid(queue)) {
- logger.error("Queue Id not valid");
- return false;
- }
- } else if (action instanceof SetTpDstActionCase) {
- PortNumber port = ((SetTpDstActionCase) action).getSetTpDstAction().getPort();
- if (port != null && !isPortValid(port)) {
- logger.error("Port not valid");
- }
- } else if (action instanceof SetTpSrcActionCase) {
- PortNumber port = ((SetTpSrcActionCase) action).getSetTpSrcAction().getPort();
- if (port != null && !isPortValid(port)) {
- logger.error("Port not valid");
- }
- } else if (action instanceof SetVlanIdActionCase) {
- VlanId vlanid = ((SetVlanIdActionCase) action).getSetVlanIdAction().getVlanId();
- if (vlanid != null && !isVlanIdValid(vlanid.toString())) {
- logger.error("Vlan ID %s is not in the range 0 - 4095");
- return false;
- }
- } else if (action instanceof SetVlanPcpActionCase) {
- VlanPcp vlanpcp = ((SetVlanPcpActionCase) action).getSetVlanPcpAction().getVlanPcp();
- if (vlanpcp != null && !isVlanPriorityValid(vlanpcp.toString())) {
- logger.error("Vlan priority %s is not in the range 0 - 7");
- return false;
- }
- }
- }
- return true;
-
- }
-
- public static boolean validateInstructions(Flow flow) {
- List<Instruction> instructionsList = new ArrayList<>();
- Instructions instructions = flow.getInstructions();
- if (instructions == null) {
- return false;
- }
- instructionsList = instructions.getInstruction();
-
- for (Instruction instruction : instructionsList) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
- .getInstruction();
- if (curInstruction instanceof GoToTableCase) {
-
- Short tableid = ((GoToTableCase) curInstruction).getGoToTable().getTableId();
- if (tableid < 0) {
- logger.error("table id is not valid");
- return false;
- }
- }
-
- else if (curInstruction instanceof WriteActionsCase) {
-
- List<Action> action = ((WriteActionsCase) curInstruction).getWriteActions().getAction();
- validateActions(action);
-
- }
-
- else if (curInstruction instanceof ApplyActionsCase) {
- List<Action> action = ((ApplyActionsCase) curInstruction).getApplyActions().getAction();
- validateActions(action);
- }
-
- else if (curInstruction instanceof ClearActionsCase) {
- List<Action> action = ((ClearActionsCase) curInstruction).getClearActions().getAction();
- validateActions(action);
- }
-
- else if (curInstruction instanceof MeterCase) {
-
- MeterId meter = ((MeterCase) curInstruction).getMeter().getMeterId();
- if (meter != null && !isValidMeter(meter)) {
- logger.error("Meter Id is not valid");
- return false;
- }
- }
-
- }
-
- return true;
- }
-
- public static boolean isValidMeter(MeterId meter) {
- // TODO
- return true;
- }
-
- public static boolean isQueueValid(String queue) {
- // TODO
- return true;
- }
-
- public static boolean isPortValid(PortNumber port) {
- // TODO
- return true;
- }
-
- public static boolean isL2AddressValid(String mac) {
- if (mac == null) {
- return false;
- }
-
- Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
- Matcher mm = macPattern.matcher(mac);
- if (!mm.matches()) {
- logger.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
- return false;
- }
- return true;
- }
-
- public static boolean isProtocolValid(String protocol) {
- IPProtocols proto = IPProtocols.fromString(protocol);
- return (proto != null);
- }
-
- public static boolean isVlanIdValid(String vlanId) {
- int vlan = Integer.decode(vlanId);
- return ((vlan >= 0) && (vlan < 4096));
- }
-
- public static boolean isVlanPriorityValid(String vlanPriority) {
- int pri = Integer.decode(vlanPriority);
- return ((pri >= 0) && (pri < 8));
- }
-}
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-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.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
-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.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableRef;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FlowConsumerImpl {
- protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class);
- private final FlowEventListener flowEventListener = new FlowEventListener();
- private Registration<NotificationListener> listener1Reg;
- private SalFlowService flowService;
- // private FlowDataListener listener;
- private FlowDataCommitHandler commitHandler;
-
- public FlowConsumerImpl() {
- InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Flows.class).toInstance();
- flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class);
-
- if (null == flowService) {
- logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
- return;
- }
-
- // For switch events
- listener1Reg = FRMConsumerImpl.getNotificationService().registerNotificationListener(flowEventListener);
-
- if (null == listener1Reg) {
- logger.error("Listener to listen on flow data modifcation events");
- return;
- }
- // addFlowTest();
- commitHandler = new FlowDataCommitHandler();
- FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
- }
-
- /**
- * Adds flow to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void addFlow(InstanceIdentifier<?> path, Flow dataObject) {
-
- AddFlowInputBuilder input = new AddFlowInputBuilder();
- input.fieldsFrom(dataObject);
- input.setNode((dataObject).getNode());
- input.setFlowTable(new FlowTableRef(createTableInstance(dataObject.getId(), dataObject.getNode())));
- // We send flow to the sounthbound plugin
- flowService.addFlow(input.build());
- }
-
- /**
- * Removes flow to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void removeFlow(InstanceIdentifier<?> path, Flow dataObject) {
-
- RemoveFlowInputBuilder input = new RemoveFlowInputBuilder();
- input.fieldsFrom(dataObject);
- input.setNode((dataObject).getNode());
- input.setTableId(dataObject.getTableId());
- input.setFlowTable(new FlowTableRef(createTableInstance((long)dataObject.getTableId(), (dataObject).getNode())));
- // We send flow to the sounthbound plugin
- flowService.removeFlow(input.build());
- }
-
- /**
- * Update flow to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void updateFlow(InstanceIdentifier<?> path, Flow updatedFlow, Flow originalFlow) {
-
- UpdateFlowInputBuilder input = new UpdateFlowInputBuilder();
- UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder();
- updatedflowbuilder.fieldsFrom(updatedFlow);
- input.setNode(updatedFlow.getNode());
- input.setUpdatedFlow(updatedflowbuilder.build());
- OriginalFlowBuilder ofb = new OriginalFlowBuilder(originalFlow);
- input.setOriginalFlow(ofb.build());
- // We send flow to the sounthbound plugin
- flowService.updateFlow(input.build());
- }
-
- private void commitToPlugin(internalTransaction transaction) {
- Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = transaction.getModification()
- .getCreatedConfigurationData().entrySet();
-
- /*
- * This little dance is because updatedEntries contains both created and
- * modified entries The reason I created a new HashSet is because the
- * collections we are returned are immutable.
- */
- Set<Entry<InstanceIdentifier<?>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<?>, DataObject>>();
- updatedEntries.addAll(transaction.getModification().getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- Set<InstanceIdentifier<?>> removeEntriesInstanceIdentifiers = transaction.getModification()
- .getRemovedConfigurationData();
- transaction.getModification().getOriginalConfigurationData();
- for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
- if (entry.getValue() instanceof Flow) {
- logger.debug("Coming add cc in FlowDatacommitHandler");
- Flow flow = (Flow) entry.getValue();
- boolean status = validate(flow);
- if (!status) {
- return;
- }
- addFlow(entry.getKey(), (Flow) entry.getValue());
- }
- }
-
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- if (entry.getValue() instanceof Flow) {
- logger.debug("Coming update cc in FlowDatacommitHandler");
- Flow updatedFlow = (Flow) entry.getValue();
- Flow originalFlow = (Flow) transaction.modification.getOriginalConfigurationData().get(entry.getKey());
- boolean status = validate(updatedFlow);
- if (!status) {
- return;
- }
- updateFlow(entry.getKey(), updatedFlow, originalFlow);
- }
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
- DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(instanceId);
- if (removeValue instanceof Flow) {
- logger.debug("Coming remove cc in FlowDatacommitHandler");
- Flow flow = (Flow) removeValue;
- boolean status = validate(flow);
-
- if (!status) {
- return;
- }
-
- removeFlow(instanceId, (Flow) removeValue);
- }
- }
- }
-
- private final class FlowDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-
- @SuppressWarnings("unchecked")
- public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- // We should verify transaction
- logger.debug("Coming in FlowDatacommitHandler");
- internalTransaction transaction = new internalTransaction(modification);
- transaction.prepareUpdate();
- return transaction;
- }
- }
-
- private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
- private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
- @Override
- public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
- return modification;
- }
-
- public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- this.modification = modification;
- }
-
- /**
- * We create a plan which flows will be added, which will be updated and
- * which will be removed based on our internal state.
- *
- */
- void prepareUpdate() {
-
- }
-
- /**
- * We are OK to go with execution of plan
- *
- */
- @Override
- public RpcResult<Void> finish() throws IllegalStateException {
- commitToPlugin(this);
- return Rpcs.getRpcResult(true, null, Collections.<RpcError> emptySet());
- }
-
- /**
- *
- * We should rollback our preparation
- *
- */
- @Override
- public RpcResult<Void> rollback() throws IllegalStateException {
- rollBackFlows(modification);
- return Rpcs.getRpcResult(true, null, Collections.<RpcError> emptySet());
-
- }
- }
-
- private void rollBackFlows(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet();
-
- /*
- * This little dance is because updatedEntries contains both created and modified entries
- * The reason I created a new HashSet is because the collections we are returned are immutable.
- */
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
- updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- Set<InstanceIdentifier<? >> removeEntriesInstanceIdentifiers = modification.getRemovedConfigurationData();
- for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
- if(entry.getValue() instanceof Flow) {
- removeFlow(entry.getKey(),(Flow) entry.getValue()); // because we are rolling back, remove what we would have added.
- }
- }
-
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- if(entry.getValue() instanceof Flow) {
- Flow updatedFlow = (Flow) entry.getValue();
- Flow originalFlow = (Flow) modification.getOriginalConfigurationData().get(entry.getKey());
- updateFlow(entry.getKey(), updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original
- }
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
- DataObject removeValue = (Flow) modification.getOriginalConfigurationData().get(instanceId);
- if(removeValue instanceof Flow) {
- addFlow(instanceId,(Flow) removeValue);// because we are rolling back, add what we would have removed.
-
- }
- }
-}
- final class FlowEventListener implements SalFlowListener {
-
- List<FlowAdded> addedFlows = new ArrayList<>();
- List<FlowRemoved> removedFlows = new ArrayList<>();
- List<FlowUpdated> updatedFlows = new ArrayList<>();
-
- @Override
- public void onFlowAdded(FlowAdded notification) {
- addedFlows.add(notification);
- }
-
- @Override
- public void onFlowRemoved(FlowRemoved notification) {
- removedFlows.add(notification);
- }
-
- @Override
- public void onFlowUpdated(FlowUpdated notification) {
- updatedFlows.add(notification);
- }
-
- @Override
- public void onNodeErrorNotification(NodeErrorNotification notification) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification notification) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
- // TODO Auto-generated method stub
-
- }
- }
-
- public boolean validate(Flow flow) {
- String msg = ""; // Specific part of warn/error log
-
- boolean result = true;
- // flow Name validation
- if (!FRMUtil.isNameValid(flow.getFlowName())) {
- msg = "Invalid Flow name";
- result = false;
- }
-
- // Node Validation
- if (result == true && flow.getNode() == null) {
- msg = "Node is null";
- result = false;
- }
-
- // TODO: Validate we are seeking to program a flow against a valid
- // Node
-
- if (result == true && flow.getPriority() != null) {
- if (flow.getPriority() < 0 || flow.getPriority() > 65535) {
- msg = String.format("priority %s is not in the range 0 - 65535", flow.getPriority());
- result = false;
- }
- }
-
- if (!FRMUtil.validateMatch(flow)) {
- logger.error("Not a valid Match");
- result = false;
- }
- if (!FRMUtil.validateInstructions(flow)) {
- logger.error("Not a valid Instruction");
- result = false;
- }
- if (result == false) {
- logger.warn("Invalid Configuration for flow {}. The failure is {}", flow, msg);
- logger.error("Invalid Configuration ({})", msg);
- }
- return result;
- }
-
- private InstanceIdentifier<?> createTableInstance(Long tableId, NodeRef nodeRef) {
- Table table;
- InstanceIdentifier<Table> tableInstance;
- TableBuilder builder = new TableBuilder();
- builder.setId(tableId);
- builder.setKey(new TableKey(tableId, nodeRef));
- table = builder.build();
- tableInstance = InstanceIdentifier.builder(Tables.class).child(Table.class, table.getKey()).toInstance();
- return tableInstance;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.Groups;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("unused")
-public class GroupConsumerImpl {
-
- protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
- private final GroupEventListener groupEventListener = new GroupEventListener();
- private Registration<NotificationListener> groupListener;
- private SalGroupService groupService;
- private GroupDataCommitHandler groupCommitHandler;
-
- private IContainer container;
-
- public GroupConsumerImpl() {
-
- InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Groups.class).toInstance();
- groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
-
- if (null == groupService) {
- logger.error("Consumer SAL Group Service is down or NULL. FRM may not function as intended");
- System.out.println("Consumer SAL Group Service is down or NULL.");
- return;
- }
-
- // For switch events
- groupListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(groupEventListener);
-
- if (null == groupListener) {
- logger.error("Listener to listen on group data modifcation events");
- System.out.println("Listener to listen on group data modifcation events.");
- return;
- }
-
- groupCommitHandler = new GroupDataCommitHandler();
- FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, groupCommitHandler);
- }
-
- public Status validateGroup(Group group) {
- String groupName;
- Iterator<Bucket> bucketIterator;
- boolean returnResult;
- Buckets groupBuckets;
-
- if (null != group) {
- groupName = group.getGroupName();
- if (!FRMUtil.isNameValid(groupName)) {
- logger.error("Group Name is invalid %s" + groupName);
- return new Status(StatusCode.BADREQUEST, "Group Name is invalid");
- }
-
- if (!(group.getGroupType().getIntValue() >= GroupTypes.GroupAll.getIntValue() && group.getGroupType()
- .getIntValue() <= GroupTypes.GroupFf.getIntValue())) {
- logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
- return new Status(StatusCode.BADREQUEST, "Invalid Group type");
- }
-
- groupBuckets = group.getBuckets();
-
- if (null != groupBuckets && null != groupBuckets.getBucket()) {
- bucketIterator = groupBuckets.getBucket().iterator();
-
- while (bucketIterator.hasNext()) {
- if (!(FRMUtil.validateActions(bucketIterator.next().getAction()))) {
- logger.error("Error in action bucket");
- return new Status(StatusCode.BADREQUEST, "Invalid Group bucket contents");
- }
- }
- }
- }
-
- return new Status(StatusCode.SUCCESS);
- }
-
- /**
- * Update Group entries to the southbound plugin/inventory and our internal
- * database
- *
- * @param path
- * @param dataObject
- */
- private void updateGroup(InstanceIdentifier<?> path,
- Group updatedGroupDataObject, Group originalGroupDataObject) {
- UpdatedGroupBuilder updateGroupBuilder = null;
- Status groupOperationStatus = validateGroup(updatedGroupDataObject);
-
- if (!groupOperationStatus.isSuccess()) {
- logger.error("Group data object validation failed %s" + updatedGroupDataObject.getGroupName());
- return;
- }
-
- UpdateGroupInputBuilder groupInputBuilder = new UpdateGroupInputBuilder();
- updateGroupBuilder = new UpdatedGroupBuilder(updatedGroupDataObject);
- updateGroupBuilder.setGroupId(new GroupId(updatedGroupDataObject.getId()));
- groupInputBuilder.setNode(updatedGroupDataObject.getNode());
- groupInputBuilder.setUpdatedGroup(updateGroupBuilder.build());
- OriginalGroupBuilder originalGroupBuilder = new OriginalGroupBuilder(originalGroupDataObject);
- groupInputBuilder.setOriginalGroup(originalGroupBuilder.build());
- groupService.updateGroup(groupInputBuilder.build());
- return;
- }
-
- /**
- * Adds Group to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void addGroup(InstanceIdentifier<?> path, Group groupAddDataObject) {
- GroupKey groupKey = groupAddDataObject.getKey();
- Status groupOperationStatus = validateGroup(groupAddDataObject);
-
- if (!groupOperationStatus.isSuccess()) {
- logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
- return;
- }
-
- AddGroupInputBuilder groupData = new AddGroupInputBuilder();
- groupData.fieldsFrom(groupAddDataObject);
- groupData.setGroupId(new GroupId(groupAddDataObject.getId()));
- groupData.setNode(groupAddDataObject.getNode());
- groupService.addGroup(groupData.build());
- return;
- }
-
- /**
- * Remove Group to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void removeGroup(InstanceIdentifier<?> path, Group groupRemoveDataObject) {
- GroupKey groupKey = groupRemoveDataObject.getKey();
- Status groupOperationStatus = validateGroup(groupRemoveDataObject);
-
- if (!groupOperationStatus.isSuccess()) {
- logger.error("Group data object validation failed %s" + groupRemoveDataObject.getGroupName());
- return;
- }
-
- RemoveGroupInputBuilder groupData = new RemoveGroupInputBuilder();
- groupData.fieldsFrom(groupRemoveDataObject);
- groupData.setGroupId(new GroupId(groupRemoveDataObject.getId()));
- groupData.setNode(groupRemoveDataObject.getNode());
- groupService.removeGroup(groupData.build());
- return;
- }
-
- private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
- DataModification<InstanceIdentifier<?>, DataObject> modification = transaction.modification;
- //get created entries
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
- modification.getCreatedConfigurationData().entrySet();
-
- //get updated entries
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries =
- new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-
- updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- //get removed entries
- Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
- modification.getRemovedConfigurationData();
-
- for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) {
- if(entry.getValue() instanceof Group) {
- addGroup(entry.getKey(), (Group)entry.getValue());
- }
- }
-
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- if(entry.getValue() instanceof Group) {
- Group originalGroup = (Group) modification.getOriginalConfigurationData().get(entry.getKey());
- Group updatedGroup = (Group) entry.getValue();
- updateGroup(entry.getKey(), originalGroup, updatedGroup);
- }
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
- DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId);
- if(removeValue instanceof Group) {
- removeGroup(instanceId, (Group)removeValue);
- }
- }
-
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
- }
-
- private final class GroupDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-
- @Override
- public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
- DataModification<InstanceIdentifier<?>, DataObject> modification) {
- InternalTransaction transaction = new InternalTransaction(modification);
- transaction.prepareUpdate();
- return transaction;
- }
- }
-
- private final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
- private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
- public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- this.modification = modification;
- }
-
- /**
- * We create a plan which flows will be added, which will be updated and
- * which will be removed based on our internal state.
- *
- */
- void prepareUpdate() {
-
- }
-
- /**
- * We are OK to go with execution of plan
- *
- */
- @Override
- public RpcResult<Void> finish() throws IllegalStateException {
-
- RpcResult<Void> rpcStatus = commitToPlugin(this);
- return rpcStatus;
- }
-
- /**
- *
- * We should rollback our preparation
- *
- */
- @Override
- public RpcResult<Void> rollback() throws IllegalStateException {
-
- ///needs to be implemented as per gerrit 3314
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
- }
-
- @Override
- public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
- return modification;
- }
-
- }
-
- final class GroupEventListener implements SalGroupListener {
-
- List<GroupAdded> addedGroups = new ArrayList<>();
- List<GroupRemoved> removedGroups = new ArrayList<>();
- List<GroupUpdated> updatedGroups = new ArrayList<>();
-
- @Override
- public void onGroupAdded(GroupAdded notification) {
- addedGroups.add(notification);
- }
-
- @Override
- public void onGroupRemoved(GroupRemoved notification) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onGroupUpdated(GroupUpdated notification) {
- // TODO Auto-generated method stub
-
- }
- }
- }
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Interface that describes methods for accessing the flows database.
- */
-public interface IForwardingRulesManager {
-
- /**
- * Returns the specifications of all the flows configured for all the
- * switches on the current container
- *
- * @return the list of flow configurations present in the database
- */
- public List<DataObject> get();
-
- /**
- * Returns the specification of the flow configured for the given network
- * node on the current container
- *
- * @param name
- * the flow name
- * @param n
- * the network node identifier
- * @return the {@code FlowConfig} object
- */
- public DataObject getWithName(String name, Node n);
-
-}
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
-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.group.service.rev130918.UpdateGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MeterConsumerImpl {
- protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
- private final MeterEventListener meterEventListener = new MeterEventListener();
- private Registration<NotificationListener> meterListener;
- private SalMeterService meterService;
- private MeterDataCommitHandler commitHandler;
-
- public MeterConsumerImpl() {
- InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Meters.class).toInstance();
- meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
-
- if (null == meterService) {
- logger.error("Consumer SAL Meter Service is down or NULL. FRM may not function as intended");
- System.out.println("Consumer SAL Meter Service is down or NULL.");
- return;
- }
-
- // For switch/plugin events
- meterListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(meterEventListener);
-
- if (null == meterListener) {
- logger.error("Listener to listen on meter data modifcation events");
- System.out.println("Listener to listen on meter data modifcation events.");
- return;
- }
-
- commitHandler = new MeterDataCommitHandler();
- FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
- }
-
- /**
- * Adds Meter to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private Status addMeter(InstanceIdentifier<?> path, Meter meterAddDataObject) {
- MeterKey meterKey = meterAddDataObject.getKey();
-
- if (null != meterKey && validateMeter(meterAddDataObject).isSuccess()) {
- AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder();
- meterBuilder.fieldsFrom(meterAddDataObject);
- meterBuilder.setMeterId(new MeterId(meterAddDataObject.getId()));
- meterBuilder.setNode(meterAddDataObject.getNode());
- meterService.addMeter(meterBuilder.build());
- } else {
- return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
- }
-
- return new Status(StatusCode.SUCCESS);
- }
-
- /*
- * Update Meter to the southbound plugin and our internal database
- *
- * @param path
- *
- * @param dataObject
- */
- private Status updateMeter(InstanceIdentifier<?> path,
- Meter updatedMeter, Meter originalMeter) {
- UpdatedMeterBuilder updateMeterBuilder = null;
-
- if (validateMeter(updatedMeter).isSuccess()) {
- UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder();
- updateMeterInputBuilder.setNode(updatedMeter.getNode());
- updateMeterBuilder = new UpdatedMeterBuilder();
- updateMeterBuilder.fieldsFrom(updatedMeter);
- updateMeterBuilder.setMeterId(new MeterId(updatedMeter.getId()));
- updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build());
- OriginalMeterBuilder originalMeterBuilder = new OriginalMeterBuilder(originalMeter);
- updateMeterInputBuilder.setOriginalMeter(originalMeterBuilder.build());
- meterService.updateMeter(updateMeterInputBuilder.build());
- } else {
- return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
- }
-
- return new Status(StatusCode.SUCCESS);
- }
-
- /*
- * Remove Meter to the southbound plugin and our internal database
- *
- * @param path
- *
- * @param dataObject
- */
- private Status removeMeter(InstanceIdentifier<?> path, Meter meterRemoveDataObject) {
- MeterKey meterKey = meterRemoveDataObject.getKey();
-
- if (null != meterKey && validateMeter(meterRemoveDataObject).isSuccess()) {
- RemoveMeterInputBuilder meterBuilder = new RemoveMeterInputBuilder();
- meterBuilder.fieldsFrom(meterRemoveDataObject);
- meterBuilder.setNode(meterRemoveDataObject.getNode());
- meterBuilder.setMeterId(new MeterId(meterRemoveDataObject.getId()));
- meterService.removeMeter(meterBuilder.build());
- } else {
- return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
- }
-
- return new Status(StatusCode.SUCCESS);
- }
-
- public Status validateMeter(Meter meter) {
- String meterName;
- Status returnStatus = null;
-
- if (null != meter) {
- meterName = meter.getMeterName();
- if (!FRMUtil.isNameValid(meterName)) {
- logger.error("Meter Name is invalid %s" + meterName);
- returnStatus = new Status(StatusCode.BADREQUEST, "Meter Name is invalid");
- return returnStatus;
- }
-
- for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
- if (null != meter.getFlags() && !meter.getFlags().isMeterBurst()) {
- if (0 < meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBurstSize()) {
- logger.error("Burst size should only be associated when Burst FLAG is set");
- returnStatus = new Status(StatusCode.BADREQUEST,
- "Burst size should only be associated when Burst FLAG is set");
- break;
- }
- }
- }
-
- if (null != returnStatus && !returnStatus.isSuccess()) {
- return returnStatus;
- } else if (null != meter.getMeterBandHeaders()) {
- BandType setBandType = null;
- DscpRemark dscpRemark = null;
- for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
- setBandType = meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBandType();
- if (setBandType instanceof DscpRemark) {
- dscpRemark = (DscpRemark) setBandType;
- if (0 > dscpRemark.getRate()) {
-
- }
- } else if (setBandType instanceof Drop) {
- if (0 < dscpRemark.getPercLevel()) {
- logger.error("Number of drop Precedence level");
- }
- } else if (setBandType instanceof Experimenter) {
-
- }
- }
- }
- }
- return new Status(StatusCode.SUCCESS);
- }
-
- private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
- DataModification<InstanceIdentifier<?>, DataObject> modification = transaction.modification;
- //get created entries
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
- modification.getCreatedConfigurationData().entrySet();
-
- //get updated entries
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries =
- new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-
- updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
- updatedEntries.removeAll(createdEntries);
-
- //get removed entries
- Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
- modification.getRemovedConfigurationData();
-
- for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) {
- if(entry.getValue() instanceof Meter) {
- addMeter(entry.getKey(), (Meter)entry.getValue());
- }
- }
-
- for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
- if(entry.getValue() instanceof Meter) {
- Meter originalMeter = (Meter) modification.getOriginalConfigurationData().get(entry.getKey());
- Meter updatedMeter = (Meter) entry.getValue();
- updateMeter(entry.getKey(), originalMeter, updatedMeter);
- }
- }
-
- for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
- DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId);
- if(removeValue instanceof Meter) {
- removeMeter(instanceId, (Meter)removeValue);
- }
- }
-
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
- }
-
- final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
- private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
- @Override
- public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
- return modification;
- }
-
- public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- this.modification = modification;
- }
-
- /**
- * We create a plan which flows will be added, which will be updated and
- * which will be removed based on our internal state.
- *
- */
- void prepareUpdate() {
-
- }
-
- /**
- * We are OK to go with execution of plan
- *
- */
- @Override
- public RpcResult<Void> finish() throws IllegalStateException {
-
- RpcResult<Void> rpcStatus = commitToPlugin(this);
- return rpcStatus;
- }
-
- /**
- *
- * We should rollback our preparation
- *
- */
- @Override
- public RpcResult<Void> rollback() throws IllegalStateException {
- return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-
- }
-
- }
-
- private final class MeterDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
- @Override
- public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
- DataModification<InstanceIdentifier<?>, DataObject> modification) {
- // We should verify transaction
- InternalTransaction transaction = new InternalTransaction(modification);
- transaction.prepareUpdate();
- return transaction;
- }
- }
-
- final class MeterEventListener implements SalMeterListener {
-
- List<MeterAdded> addedMeter = new ArrayList<>();
- List<MeterRemoved> removeMeter = new ArrayList<>();
- List<MeterUpdated> updatedMeter = new ArrayList<>();
-
- @Override
- public void onMeterAdded(MeterAdded notification) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onMeterRemoved(MeterRemoved notification) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onMeterUpdated(MeterUpdated notification) {
- // TODO Auto-generated method stub
-
- }
- }
-}
+++ /dev/null
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TableFeaturesConsumerImpl {
- protected static final Logger logger = LoggerFactory.getLogger(TableFeaturesConsumerImpl.class);
- private SalTableService tableService;
- private TableDataCommitHandler commitHandler;
- private final IClusterContainerServices clusterContainerService = null;
- private IContainer container;
- private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
- private boolean inContainerMode; // being used by global instance only
-
- public TableFeaturesConsumerImpl() {
- InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Tables.class).toInstance();
- tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class);
-
- if (null == tableService) {
- logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
- System.out.println("Consumer SAL Service is down or NULL.");
- return;
- }
-
- System.out.println("-------------------------------------------------------------------");
- commitHandler = new TableDataCommitHandler();
- FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
- container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
- }
-
- /**
- * Updates TableFeatures to the southbound plugin and our internal database
- *
- * @param path
- * @param dataObject
- */
- private void updateTableFeatures(InstanceIdentifier<?> path, TableFeatures dataObject) {
-
- UpdateTableInputBuilder input = new UpdateTableInputBuilder();
- UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder();
- updatedtablebuilder.fieldsFrom(dataObject);
- List<TableFeatures> features = updatedtablebuilder.build().getTableFeatures();
- for (TableFeatures feature : features) {
- if (feature != null && feature.getMaxEntries() != null) {
- logger.error("Max Entries field is read-only, cannot be changed");
- return;
- }
- }
- input.setUpdatedTable(updatedtablebuilder.build());
-
- // We send table feature update request to the sounthbound plugin
- tableService.updateTable(input.build());
- }
-
- @SuppressWarnings("unchecked")
- private void commitToPlugin(internalTransaction transaction) {
-
- for (@SuppressWarnings("unused")
- Entry<InstanceIdentifier<?>, TableFeatures> entry : transaction.updates.entrySet()) {
- System.out.println("Coming update cc in TableDatacommitHandler");
- updateTableFeatures(entry.getKey(), entry.getValue());
- }
-
- }
-
- private final class TableDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-
- @SuppressWarnings("unchecked")
- @Override
- public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- // We should verify transaction
- System.out.println("Coming in TableFeaturesDatacommitHandler");
- internalTransaction transaction = new internalTransaction(modification);
- transaction.prepareUpdate();
- return transaction;
- }
- }
-
- private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
- private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
- @Override
- public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
- return modification;
- }
-
- public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
- this.modification = modification;
- }
-
- Map<InstanceIdentifier<?>, TableFeatures> updates = new HashMap<>();
- Map<InstanceIdentifier<?>, TableFeatures> createdEntries = new HashMap<>();
-
- /**
- * We create a plan which table features will be updated.
- *
- */
- void prepareUpdate() {
- Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet();
-
- Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
- for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
-
- // validating the DataObject
-
- Status status = validate(container, (TableFeatures) entry);
- if (!status.isSuccess()) {
- logger.warn("Invalid Configuration for table features The failure is {}", entry,
- status.getDescription());
- String error = "Invalid Configuration (" + status.getDescription() + ")";
- logger.error(error);
- return;
- }
- if (entry.getValue() instanceof TableFeatures) {
- TableFeatures tablefeatures = (TableFeatures) entry.getValue();
- preparePutEntry(entry.getKey(), tablefeatures);
- }
-
- }
- }
-
- private void preparePutEntry(InstanceIdentifier<?> key, TableFeatures tablefeatures) {
- if (tablefeatures != null) {
- // Updating the Map
- System.out.println("Coming update in TableFeaturesDatacommitHandler");
- updates.put(key, tablefeatures);
- }
- }
-
- /**
- * We are OK to go with execution of plan
- *
- */
- @Override
- public RpcResult<Void> finish() throws IllegalStateException {
-
- commitToPlugin(this);
- // We return true if internal transaction is successful.
- // return Rpcs.getRpcResult(true, null, Collections.emptySet());
- return Rpcs.getRpcResult(true, null, null);
- }
-
- /**
- *
- * We should rollback our preparation
- *
- */
- @Override
- public RpcResult<Void> rollback() throws IllegalStateException {
- // NOOP - we did not modified any internal state during
- // requestCommit phase
- // return Rpcs.getRpcResult(true, null, Collections.emptySet());
- return Rpcs.getRpcResult(true, null, null);
-
- }
-
- public Status validate(IContainer container, TableFeatures dataObject) {
-
- String tablename = dataObject.getName();
- if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX)
- || tablename.length() != 32) {
- return new Status(StatusCode.BADREQUEST, "Invalid table name");
- }
-
- return new Status(StatusCode.SUCCESS);
- }
- }
-}
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.0</version>
+ <version>2013.08.27.1</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27-SNAPSHOT</version>
+ <version>2013.08.27.1-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
* version of RpcServices
*
*/
-public interface RpcConsumerRegistry {
+public interface RpcConsumerRegistry extends BindingAwareService {
/**
* Returns a session specific instance (implementation) of requested
* YANG module implentation / service provided by consumer.
package org.opendaylight.controller.sal.binding.api;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
/**
- * Interface defining provider's access to the Rpc Registry
- * which could be used to register their implementations of service to the MD-SAL.
+ * Interface defining provider's access to the Rpc Registry which could be used
+ * to register their implementations of service to the MD-SAL.
*
* @author ttkacik
- *
+ *
*/
-public interface RpcProviderRegistry extends RpcConsumerRegistry {
+public interface RpcProviderRegistry extends //
+ RpcConsumerRegistry, //
+ RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
/**
* Registers an global RpcService implementation.
*
/**
*
- * Register an Routed RpcService where routing is determined on annotated (in YANG model)
- * context-reference and value of annotated leaf.
+ * Register an Routed RpcService where routing is determined on annotated
+ * (in YANG model) context-reference and value of annotated leaf.
*
- * @param type Type of RpcService, use generated interface class, not your implementation clas
- * @param implementation Implementation of RpcService
- * @return Registration object for routed Rpc which could be used to close an
+ * @param type
+ * Type of RpcService, use generated interface class, not your
+ * implementation clas
+ * @param implementation
+ * Implementation of RpcService
+ * @return Registration object for routed Rpc which could be used to close
+ * an
*
* @throws IllegalStateException
*/
package org.opendaylight.controller.sal.binding.api.mount;
+import java.util.EventListener;
+
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
- * Provider MountProviderService, this version allows access to MD-SAL
- * services specific for this mountpoint and registration / provision of
- * interfaces for mount point.
+ * Provider MountProviderService, this version allows access to MD-SAL services
+ * specific for this mountpoint and registration / provision of interfaces for
+ * mount point.
*
* @author ttkacik
*
*/
-public interface MountProviderService extends MountInstance {
+public interface MountProviderService extends MountService {
+
+ @Override
+ public MountProviderInstance getMountPoint(InstanceIdentifier<?> path);
MountProviderInstance createMountPoint(InstanceIdentifier<?> path);
+
+ MountProviderInstance createOrGetMountPoint(InstanceIdentifier<?> path);
+
+ ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+ public interface MountProvisionListener extends EventListener {
+
+ void onMountPointCreated(InstanceIdentifier<?> path);
+
+ void onMountPointRemoved(InstanceIdentifier<?> path);
+
+ }
}
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
* 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.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import java.util.Set;
-package org.opendaylight.controller.sal.binding.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.RpcService;
* 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.spi;
+package org.opendaylight.controller.sal.binding.api.rpc;
import java.util.Map;
<artifactId>sal-binding-api</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.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
/**\r
-* Generated file\r
+ * Generated file\r
\r
-* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl\r
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
-* Generated at: Wed Nov 20 17:33:01 CET 2013\r
-*\r
-* Do not modify this file unless it is present under src/main directory\r
-*/\r
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl\r
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator\r
+ * Generated at: Wed Nov 20 17:33:01 CET 2013\r
+ *\r
+ * Do not modify this file unless it is present under src/main directory\r
+ */\r
package org.opendaylight.controller.config.yang.md.sal.binding.impl;\r
\r
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardingUtils;\r
import org.osgi.framework.BundleContext;\r
\r
-import com.google.common.base.Preconditions;\r
+import com.google.common.util.concurrent.MoreExecutors;\r
\r
/**\r
*\r
*/\r
-public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
+public final class BindingBrokerImplModule extends\r
+ org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule {\r
\r
private BundleContext bundleContext;\r
\r
- public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {\r
super(identifier, dependencyResolver);\r
}\r
\r
- public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,\r
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,\r
+ BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {\r
super(identifier, dependencyResolver, oldModule, oldInstance);\r
}\r
\r
@Override\r
- public void validate(){\r
+ public void validate() {\r
super.validate();\r
}\r
\r
@Override\r
public java.lang.AutoCloseable createInstance() {\r
- BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getIdentifier().getInstanceName(),getBundleContext());\r
- broker.setDataBroker(getDataBrokerDependency());\r
- broker.setNotifyBroker(getNotificationServiceDependency());\r
+\r
+ RootBindingAwareBroker broker;\r
+ if (DomForwardingUtils.isDomForwardedBroker(getDataBrokerDependency())) {\r
+ broker = createForwardedBroker();\r
+ } else {\r
+ broker = createStandaloneBroker();\r
+ }\r
broker.start();\r
return broker;\r
}\r
\r
+ private RootBindingAwareBroker createStandaloneBroker() {\r
+ RootBindingAwareBroker broker = new RootBindingAwareBroker(getIdentifier().getInstanceName());\r
+\r
+ broker.setDataBroker(getDataBrokerDependency());\r
+ broker.setNotificationBroker(getNotificationServiceDependency());\r
+ broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+ return broker;\r
+ }\r
+\r
+ private RootBindingAwareBroker createForwardedBroker() {\r
+ DomForwardedBindingBrokerImpl broker = new DomForwardedBindingBrokerImpl(getIdentifier().getInstanceName());\r
+\r
+ broker.setDataBroker(getDataBrokerDependency());\r
+ broker.setNotificationBroker(getNotificationServiceDependency());\r
+ broker.setRpcBroker(new RpcProviderRegistryImpl(broker.getIdentifier()));\r
+\r
+ broker.getMountManager().setDataCommitExecutor(SingletonHolder.getDefaultCommitExecutor());\r
+ broker.getMountManager().setNotificationExecutor(SingletonHolder.getDefaultNotificationExecutor());\r
+\r
+\r
+ DomForwardingUtils.reuseForwardingFrom(broker, broker.getDataBroker());\r
+ broker.startForwarding();\r
+ return broker;\r
+ }\r
+\r
public BundleContext getBundleContext() {\r
return bundleContext;\r
}\r
import java.util.concurrent.Executors;\r
import java.util.concurrent.ScheduledExecutorService;\r
\r
-import org.opendaylight.controller.config.yang.md.sal.binding.statistics.DataBrokerRuntimeMXBeanImpl;\r
import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;\r
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;\r
import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;\r
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;\r
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedDataBrokerImpl;\r
import org.opendaylight.controller.sal.core.api.Broker;\r
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;\r
import org.opendaylight.controller.sal.core.api.data.DataProviderService;\r
import org.opendaylight.yangtools.yang.binding.DataObject;\r
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
\r
@Override\r
public java.lang.AutoCloseable createInstance() {\r
- DataBrokerRuntimeMXBeanImpl dataBindingBroker = new DataBrokerRuntimeMXBeanImpl();\r
+ RootDataBrokerImpl dataBindingBroker;\r
\r
- // FIXME: obtain via dependency management\r
- ExecutorService executor = Executors.newCachedThreadPool();\r
- ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);\r
- dataBindingBroker.setExecutor(listeningExecutor);\r
-\r
- Broker domBroker = getDomBrokerDependency();\r
- BindingIndependentMappingService mappingService = getMappingServiceDependency();\r
\r
- if (domBroker != null && mappingService != null) {\r
- BindingIndependentConnector runtimeMapping = new BindingIndependentConnector();\r
- runtimeMapping.setMappingService(mappingService);\r
- runtimeMapping.setBaDataService(dataBindingBroker);\r
- domBroker.registerProvider(runtimeMapping, getBundleContext());\r
+ ExecutorService listeningExecutor = SingletonHolder.getDefaultCommitExecutor();\r
+ \r
+ if (getDomBrokerDependency() != null && getMappingServiceDependency() != null) {\r
+ \r
+ dataBindingBroker = createDomConnectedBroker(listeningExecutor);\r
+ } else {\r
+ dataBindingBroker = createStandAloneBroker(listeningExecutor);\r
}\r
- getRootRuntimeBeanRegistratorWrapper().register(dataBindingBroker);\r
+ dataBindingBroker.registerRuntimeBean(getRootRuntimeBeanRegistratorWrapper());\r
+\r
return dataBindingBroker;\r
}\r
+ private RootDataBrokerImpl createStandAloneBroker(ExecutorService listeningExecutor) {\r
+ RootDataBrokerImpl broker = new RootDataBrokerImpl();\r
+ broker.setExecutor(listeningExecutor);\r
+ return broker;\r
+ }\r
+\r
+ private RootDataBrokerImpl createDomConnectedBroker(ExecutorService listeningExecutor) {\r
+ DomForwardedDataBrokerImpl forwardedBroker = new DomForwardedDataBrokerImpl();\r
+ forwardedBroker.setExecutor(listeningExecutor);\r
+ BindingIndependentConnector connector = BindingDomConnectorDeployer.createConnector(getMappingServiceDependency());\r
+ getDomBrokerDependency().registerProvider(forwardedBroker, getBundleContext());\r
+ ProviderSession domContext = forwardedBroker.getDomProviderContext();\r
+ forwardedBroker.setConnector(connector);\r
+ forwardedBroker.setDomProviderContext(domContext);\r
+ forwardedBroker.startForwarding();\r
+ return forwardedBroker;\r
+ }\r
\r
public BundleContext getBundleContext() {\r
return bundleContext;\r
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
import com.google.common.util.concurrent.ListeningExecutorService;
@Override
public java.lang.AutoCloseable createInstance() {
- ExecutorService executor = Executors.newFixedThreadPool(5);
- ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+ ListeningExecutorService listeningExecutor = SingletonHolder.getDefaultNotificationExecutor();
NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor);
return broker;
}
+++ /dev/null
-package org.opendaylight.controller.config.yang.md.sal.binding.statistics;\r
-\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
-import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
-import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;\r
-\r
-public class DataBrokerRuntimeMXBeanImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
- \r
- private final Transactions transactions = new Transactions();\r
- private final Data data = new Data();\r
- \r
- public Transactions getTransactions() {\r
- transactions.setCreated(getCreatedTransactionsCount().get());\r
- transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
- transactions.setSuccessful(getFinishedTransactionsCount().get());\r
- transactions.setFailed(getFailedTransactionsCount().get());\r
- return transactions;\r
- }\r
-\r
- @Override\r
- public Data getData() {\r
- transactions.setCreated(getCreatedTransactionsCount().get());\r
- transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
- transactions.setSuccessful(getFinishedTransactionsCount().get());\r
- transactions.setFailed(getFailedTransactionsCount().get());\r
- data.setTransactions(transactions);\r
- return data;\r
- }\r
-}\r
*/
package org.opendaylight.controller.sal.binding.codegen;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import java.util.Set;
import java.util.HashMap;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.RpcImplementation;
import org.opendaylight.controller.md.sal.common.api.routing.MutableRoutingTable;
@Override
public void unregisterPath(Class<? extends BaseIdentity> context, InstanceIdentifier<?> path) {
routingTables.get(context).removeRoute(path, getInstance());
-
}
@Override
package org.opendaylight.controller.sal.binding.codegen.impl;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
package org.opendaylight.controller.sal.binding.codegen.impl;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
import javassist.ClassPool;
public class SingletonHolder {
- public static final ClassPool CLASS_POOL = new ClassPool();
- public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(CLASS_POOL);
+ public static final ClassPool CLASS_POOL = new ClassPool();
+ public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator(
+ CLASS_POOL);
public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL;
public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory();
+ private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
+ private static ListeningExecutorService COMMIT_EXECUTOR = null;
+
+ public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
+ if (NOTIFICATION_EXECUTOR == null) {
+ NOTIFICATION_EXECUTOR = createNamedExecutor("md-sal-binding-notification-%d");
+ }
+ return NOTIFICATION_EXECUTOR;
+ }
+
+ public static synchronized final ListeningExecutorService getDefaultCommitExecutor() {
+ if (COMMIT_EXECUTOR == null) {
+ COMMIT_EXECUTOR = createNamedExecutor("md-sal-binding-commit-%d");
+ }
+
+ return COMMIT_EXECUTOR;
+ }
+
+ private static ListeningExecutorService createNamedExecutor(String format) {
+ ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(format).build();
+ ExecutorService executor = Executors.newCachedThreadPool(factory);
+ return MoreExecutors.listeningDecorator(executor);
+
+ }
+
}
+++ /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.binding.api.BindingAwareConsumer
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider
-import org.osgi.framework.BundleContext
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.slf4j.LoggerFactory
-
-class BindingAwareBrokerImpl extends RpcProviderRegistryImpl implements BindingAwareBroker, AutoCloseable {
- private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
-
- private InstanceIdentifier<? extends DataObject> root = InstanceIdentifier.builder().toInstance();
-
- @Property
- private var NotificationProviderService notifyBroker
-
- @Property
- private var DataProviderService dataBroker
-
- @Property
- var BundleContext brokerBundleContext
-
- public new(String name,BundleContext bundleContext) {
- super(name);
- _brokerBundleContext = bundleContext;
- }
-
- def start() {
- log.info("Starting MD-SAL: Binding Aware Broker");
- }
-
-
-
- override registerConsumer(BindingAwareConsumer consumer, BundleContext bundleCtx) {
- val ctx = consumer.createContext(bundleCtx)
- consumer.onSessionInitialized(ctx)
- return ctx
- }
-
- override registerProvider(BindingAwareProvider provider, BundleContext bundleCtx) {
- val ctx = provider.createContext(bundleCtx)
- provider.onSessionInitialized(ctx)
- provider.onSessionInitiated(ctx as ProviderContext)
- return ctx
- }
-
- private def createContext(BindingAwareConsumer consumer, BundleContext consumerCtx) {
- new OsgiConsumerContext(consumerCtx, this)
- }
-
- private def createContext(BindingAwareProvider provider, BundleContext providerCtx) {
- new OsgiProviderContext(providerCtx, this)
- }
-
- override <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> registerRouteChangeListener(L listener) {
- super.<L>registerRouteChangeListener(listener)
- }
-
- override close() throws Exception {
-
- }
-}
\ No newline at end of file
import java.util.Set;
import java.util.concurrent.Future;\r
import java.util.concurrent.atomic.AtomicLong;\r
-
+\r
import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;\r
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;\r
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;\r
import org.opendaylight.controller.sal.common.DataStoreIdentifier;\r
import org.opendaylight.yangtools.yang.binding.DataObject;\r
import org.opendaylight.yangtools.yang.binding.DataRoot;\r
+import org.opendaylight.yangtools.yang.binding.Identifiable;\r
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
import org.opendaylight.yangtools.yang.common.RpcResult;\r
\r
\r
-public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements\r
- DataProviderService, AutoCloseable {\r
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> //\r
+ implements DataProviderService, AutoCloseable {\r
\r
private final AtomicLong nextTransaction = new AtomicLong();\r
private final AtomicLong createdTransactionsCount = new AtomicLong();\r
return true;
}
}
-
return false;
}\r
}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class MountPointManagerImpl implements MountProviderService {
+
+ public final Logger LOG = LoggerFactory.getLogger(MountPointManagerImpl.class);
+
+ private final ConcurrentMap<InstanceIdentifier<?>, BindingMountPointImpl> mountPoints;
+ private final ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create();
+
+ private ListeningExecutorService notificationExecutor;
+ private ListeningExecutorService dataCommitExecutor;
+
+ public MountPointManagerImpl() {
+ mountPoints = new ConcurrentHashMap<>();
+ }
+
+ public ListeningExecutorService getNotificationExecutor() {
+ return notificationExecutor;
+ }
+
+ public void setNotificationExecutor(ListeningExecutorService notificationExecutor) {
+ this.notificationExecutor = notificationExecutor;
+ }
+
+ public ListeningExecutorService getDataCommitExecutor() {
+ return dataCommitExecutor;
+ }
+
+ public void setDataCommitExecutor(ListeningExecutorService dataCommitExecutor) {
+ this.dataCommitExecutor = dataCommitExecutor;
+ }
+
+ @Override
+ public synchronized BindingMountPointImpl createMountPoint(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = mountPoints.get(path);
+ if (potential != null) {
+ throw new IllegalStateException("Mount point already exists.");
+ }
+ return createOrGetMountPointImpl(path);
+ }
+
+ @Override
+ public BindingMountPointImpl createOrGetMountPoint(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = getMountPoint(path);
+ if (potential != null) {
+ return potential;
+ }
+ return createOrGetMountPointImpl(path);
+ }
+
+ @Override
+ public BindingMountPointImpl getMountPoint(InstanceIdentifier<?> path) {
+ return mountPoints.get(path);
+ }
+
+ private synchronized BindingMountPointImpl createOrGetMountPointImpl(InstanceIdentifier<?> path) {
+ BindingMountPointImpl potential = getMountPoint(path);
+ if (potential != null) {
+ return potential;
+ }
+ RpcProviderRegistryImpl rpcRegistry = new RpcProviderRegistryImpl("mount");
+ NotificationBrokerImpl notificationBroker = new NotificationBrokerImpl();
+ notificationBroker.setExecutor(getNotificationExecutor());
+ DataBrokerImpl dataBroker = new DataBrokerImpl();
+ dataBroker.setExecutor(getDataCommitExecutor());
+ BindingMountPointImpl mountInstance = new BindingMountPointImpl(path, rpcRegistry, notificationBroker,
+ dataBroker);
+ mountPoints.putIfAbsent(path, mountInstance);
+ notifyMountPointCreated(path);
+ return mountInstance;
+ }
+
+ private void notifyMountPointCreated(InstanceIdentifier<?> path) {
+ for (ListenerRegistration<MountProvisionListener> listener : listeners) {
+ try {
+ listener.getInstance().onMountPointCreated(path);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener.", e);
+ }
+ }
+ }
+
+ @Override
+ public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+ return listeners.register(listener);
+ }
+
+ public class BindingMountPointImpl extends
+ AbstractBindingSalProviderInstance<DataBrokerImpl, NotificationBrokerImpl, RpcProviderRegistryImpl>
+ implements MountProviderInstance {
+
+ private InstanceIdentifier<?> identifier;
+
+ public BindingMountPointImpl(org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> identifier,
+ RpcProviderRegistryImpl rpcRegistry, NotificationBrokerImpl notificationBroker,
+ DataBrokerImpl dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ this.identifier = identifier;
+ }
+
+ @Override
+ public InstanceIdentifier<?> getIdentifier() {
+ return this.identifier;
+ }
+ }
+}
\r
private static val log = LoggerFactory.getLogger(NotifyTask);\r
\r
+ @SuppressWarnings("rawtypes")\r
val NotificationListener listener;\r
val Notification notification;\r
\r
+++ /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.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareService;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.LoggerFactory
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class OsgiConsumerContext implements ConsumerContext {
-
- static val log = LoggerFactory.getLogger(OsgiConsumerContext)
- protected val BundleContext bundleContext;
- protected val BindingAwareBrokerImpl broker;
-
- new(BundleContext ctx, BindingAwareBrokerImpl broker) {
- this.bundleContext = ctx;
- this.broker = broker;
- }
-
- override def <T extends BindingAwareService> getSALService(Class<T> service) {
-
- // SAL Services are global
- var ref = bundleContext.getServiceReference(service);
- return bundleContext.getService(ref) as T;
- }
-
- override def <T extends RpcService> T getRpcService(Class<T> module) {
- try {
-
- val services = bundleContext.getServiceReferences(module, getProxyFilter());
-
- // Proxy service found / using first implementation
- // FIXME: Add advanced logic to retrieve service with right set of models
- if (false == services.empty) {
- val ref = services.iterator().next() as ServiceReference<T>;
- return bundleContext.getService(ref) as T;
- } else {
- return broker.getRpcService(module);
- }
- } catch (InvalidSyntaxException e) {
- log.error("Created filter was invalid:", e.message, e)
- }
- return null;
-
- }
-
- private def getProxyFilter() {
- return '''(«SAL_SERVICE_TYPE»=«SAL_SERVICE_TYPE_CONSUMER_PROXY»)'''
- }
-}
+++ /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 java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.BundleContext;
-
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*;
-import static extension org.opendaylight.controller.sal.binding.impl.osgi.PropertiesUtils.*;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality
-import static com.google.common.base.Preconditions.*
-
-class OsgiProviderContext extends OsgiConsumerContext implements ProviderContext {
-
- @Property
- val Map<Class<? extends RpcService>, RpcRegistration<? extends RpcService>> registeredServices
-
- new(BundleContext ctx, BindingAwareBrokerImpl broker) {
- super(ctx, broker);
- _registeredServices = new HashMap();
- }
-
- override <T extends RpcService> addRpcImplementation(Class<T> type, T implementation) {
- val salReg = broker.addRpcImplementation(type, implementation)
- registeredServices.put(type, salReg)
- return salReg;
- }
-
- override <T extends RpcService> addRoutedRpcImplementation(Class<T> type, T implementation) throws IllegalStateException {
- val salReg = broker.addRoutedRpcImplementation(type, implementation)
- registeredServices.put(type, salReg)
- return salReg;
- }
-
- override registerFunctionality(ProviderFunctionality functionality) {
- // NOOP for now
- }
-
- override unregisterFunctionality(ProviderFunctionality functionality) {
- // NOOP for now
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
+import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountService;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Mutable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableClassToInstanceMap;
+
+public class RootBindingAwareBroker implements //
+ Mutable, //
+ Identifiable<String>, //
+ BindingAwareBroker, AutoCloseable,
+ RpcProviderRegistry {
+
+ private final static Logger LOG = LoggerFactory.getLogger(RootBindingAwareBroker.class);
+
+ RootSalInstance controllerRoot;
+
+ private final String identifier;
+
+ private RpcProviderRegistry rpcBroker;
+
+ private NotificationProviderService notificationBroker;
+
+ private DataProviderService dataBroker;
+
+ private MountPointManagerImpl mountManager;
+
+ public MountPointManagerImpl getMountManager() {
+ return mountManager;
+ }
+
+ public void setMountManager(MountPointManagerImpl mountManager) {
+ this.mountManager = mountManager;
+ }
+
+ private ImmutableClassToInstanceMap<BindingAwareService> supportedConsumerServices;
+
+ private ImmutableClassToInstanceMap<BindingAwareService> supportedProviderServices;
+
+ public RootBindingAwareBroker(String instanceName) {
+ this.identifier = instanceName;
+ mountManager = new MountPointManagerImpl();
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public RootSalInstance getRoot() {
+ return controllerRoot;
+ }
+
+ public DataProviderService getDataBroker() {
+ return this.dataBroker;
+ }
+
+ public NotificationProviderService getNotificationBroker() {
+ return this.notificationBroker;
+ }
+
+ public RpcProviderRegistry getRpcProviderRegistry() {
+ return this.rpcBroker;
+ }
+
+ public RpcProviderRegistry getRpcBroker() {
+ return rpcBroker;
+ }
+
+ public void setRpcBroker(RpcProviderRegistry rpcBroker) {
+ this.rpcBroker = rpcBroker;
+ }
+
+ public void setNotificationBroker(NotificationProviderService notificationBroker) {
+ this.notificationBroker = notificationBroker;
+ }
+
+ public void setDataBroker(DataProviderService dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ public void start() {
+ checkState(controllerRoot == null, "Binding Aware Broker was already started.");
+ LOG.info("Starting Binding Aware Broker: {}", identifier);
+
+ controllerRoot = new RootSalInstance(getRpcProviderRegistry(), getNotificationBroker(), getDataBroker());
+
+
+ supportedConsumerServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+ .put(NotificationService.class, getRoot()) //
+ .put(DataBrokerService.class, getRoot()) //
+ .put(RpcConsumerRegistry.class, getRoot()) //
+ .put(MountService.class, mountManager).build();
+
+ supportedProviderServices = ImmutableClassToInstanceMap.<BindingAwareService> builder()
+ .putAll(supportedConsumerServices)
+ .put(NotificationProviderService.class, getRoot()) //
+ .put(DataProviderService.class, getRoot()) //
+ .put(RpcProviderRegistry.class, getRoot()) //
+ .put(MountProviderService.class, mountManager).build();
+ }
+
+ @Override
+ public ConsumerContext registerConsumer(BindingAwareConsumer consumer, BundleContext ctx) {
+ checkState(supportedConsumerServices != null, "Broker is not initialized.");
+ return BindingContextUtils.createConsumerContextAndInitialize(consumer, supportedConsumerServices);
+ }
+
+ @Override
+ public ProviderContext registerProvider(BindingAwareProvider provider, BundleContext ctx) {
+ checkState(supportedProviderServices != null, "Broker is not initialized.");
+ return BindingContextUtils.createProviderContextAndInitialize(provider, supportedProviderServices);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // FIXME: Close all sessions
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRoot().addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRoot().addRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> module) {
+ return getRoot().getRpcService(module);
+ }
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L arg0) {
+ return getRoot().registerRouteChangeListener(arg0);
+ }
+
+
+ public class RootSalInstance extends
+ AbstractBindingSalProviderInstance<DataProviderService, NotificationProviderService, RpcProviderRegistry> {
+
+ public RootSalInstance(RpcProviderRegistry rpcRegistry, NotificationProviderService notificationBroker,
+ DataProviderService dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;\r
+\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Data;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeMXBean;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistration;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplRuntimeRegistrator;\r
+import org.opendaylight.controller.config.yang.md.sal.binding.impl.Transactions;\r
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;\r
+\r
+public class RootDataBrokerImpl extends DataBrokerImpl implements DataBrokerImplRuntimeMXBean {\r
+\r
+ private final Transactions transactions = new Transactions();\r
+ private final Data data = new Data();\r
+ private BindingIndependentConnector bindingIndependentConnector;\r
+ private DataBrokerImplRuntimeRegistration runtimeBeanRegistration;\r
+\r
+ public BindingIndependentConnector getBindingIndependentConnector() {\r
+ return bindingIndependentConnector;\r
+ }\r
+\r
+ public Transactions getTransactions() {\r
+ transactions.setCreated(getCreatedTransactionsCount().get());\r
+ transactions.setSubmitted(getSubmittedTransactionsCount().get());\r
+ transactions.setSuccessful(getFinishedTransactionsCount().get());\r
+ transactions.setFailed(getFailedTransactionsCount().get());\r
+ return transactions;\r
+ }\r
+\r
+ @Override\r
+ public Data getData() {\r
+ data.setTransactions(getTransactions());\r
+ return data;\r
+ }\r
+\r
+ public void setBindingIndependentConnector(BindingIndependentConnector runtimeMapping) {\r
+ this.bindingIndependentConnector = runtimeMapping;\r
+ }\r
+\r
+ public void registerRuntimeBean(DataBrokerImplRuntimeRegistrator rootRegistrator) {\r
+ runtimeBeanRegistration = rootRegistrator.register(this);\r
+ }\r
+\r
+}\r
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+
+public class BindingDomConnectorDeployer {
+
+ private static BindingIndependentMappingService mappingService;
+
+ public static BindingIndependentConnector tryToDeployConnector(RootBindingAwareBroker baBroker,
+ ProviderSession domSession) {
+ checkNotNull(baBroker);
+ checkNotNull(domSession);
+ BindingIndependentConnector connector = createConnector(mappingService);
+ return connector;
+ }
+
+ public static BindingIndependentConnector createConnector(BindingIndependentMappingService mappingService) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+ connector.setMappingService(mappingService);
+ return connector;
+ }
+
+ public static BindingIndependentConnector createConnector(BindingIndependentConnector source) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+ connector.setMappingService(source.getMappingService());
+ return connector;
+ }
+
+ public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+ ProviderSession domContext) {
+ startDataForwarding(connector, baService,
+ domContext.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+ }
+
+ public static void startRpcForwarding(BindingIndependentConnector connector,
+ RpcProviderRegistry rpcProviderRegistry, ProviderSession domProviderContext) {
+ startRpcForwarding(connector, rpcProviderRegistry, domProviderContext.getService(RpcProvisionRegistry.class));
+
+ }
+
+ public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService provider,ProviderSession domProviderContext) {
+ startNotificationForwarding(connector, provider, domProviderContext.getService(NotificationPublishService.class));
+ }
+
+ public static void startRpcForwarding(BindingIndependentConnector connector, RpcProviderRegistry baService,
+ RpcProvisionRegistry domService) {
+ if (connector.isRpcForwarding()) {
+ return;
+ }
+
+ connector.setDomRpcRegistry(domService);
+ connector.setBindingRpcRegistry(baService);
+ connector.startRpcForwarding();
+ }
+
+ public static void startDataForwarding(BindingIndependentConnector connector, DataProviderService baService,
+ org.opendaylight.controller.sal.core.api.data.DataProviderService domService) {
+ if (connector.isDataForwarding()) {
+ return;
+ }
+
+ connector.setBindingDataService(baService);
+ connector.setDomDataService(domService);
+ connector.startDataForwarding();
+ }
+
+ public static void startNotificationForwarding(BindingIndependentConnector connector, NotificationProviderService baService, NotificationPublishService domService) {
+ if(connector.isNotificationForwarding()) {
+ return;
+ }
+
+ // FIXME
+ }
+
+ //
+ // public static BindingIndependentMappingService getGlobalMappingService()
+ // {
+ // return mappingService;
+ // }
+ //
+ // protected static BindingIndependentMappingService
+ // setGlobalMappingService(BindingIndependentMappingService service) {
+ // mappingService= service;
+ // return mappingService;
+ // }
+ //
+ // public static BindingIndependentConnector
+ // tryToDeployConnector(MountProviderInstance baMount,MountProvisionInstance
+ // domMount) {
+ //
+ //
+ // return null;
+ // }
+
+}
package org.opendaylight.controller.sal.binding.impl.connect.dom;
import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-
import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.spi.RpcContextIdentifier;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcInput;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.common.QName;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.Preconditions.*;
-import static org.opendaylight.yangtools.concepts.util.ClassLoaderUtils.*;
public class BindingIndependentConnector implements //
RuntimeDataProvider, //
private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
private RpcProvisionRegistry biRpcRegistry;
- private RpcProviderRegistryImpl baRpcRegistry;
+ private RpcProviderRegistry baRpcRegistry;
private ListenerRegistration<DomToBindingRpcForwardingManager> domToBindingRpcManager;
// private ListenerRegistration<BindingToDomRpcForwardingManager>
};
+ private Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> baDataReaderRegistration;
+
+ private boolean rpcForwarding = false;
+
+ private boolean dataForwarding = false;
+
+ private boolean notificationForwarding = false;
+
@Override
public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
try {
return biDataService;
}
- public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+ protected void setDomDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
this.biDataService = biDataService;
}
return baDataService;
}
- public void setBaDataService(DataProviderService baDataService) {
+ protected void setBindingDataService(DataProviderService baDataService) {
this.baDataService = baDataService;
}
return baRpcRegistry;
}
- public void setRpcRegistry(RpcProviderRegistryImpl rpcRegistry) {
+ protected void setBindingRpcRegistry(RpcProviderRegistry rpcRegistry) {
this.baRpcRegistry = rpcRegistry;
}
- public void start() {
- baDataService.registerDataReader(ROOT, this);
+ public void startDataForwarding() {
+ checkState(!dataForwarding, "Connector is already forwarding data.");
+ baDataReaderRegistration = baDataService.registerDataReader(ROOT, this);
baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
-
- if (baRpcRegistry != null && biRpcRegistry != null) {
+ dataForwarding = true;
+ }
+
+ public void startRpcForwarding() {
+ if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
+ checkState(!rpcForwarding,"Connector is already forwarding RPCs");
domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
-
+ rpcForwarding = true;
}
}
+
+ public void startNotificationForwarding() {
+ checkState(!notificationForwarding, "Connector is already forwarding notifications.");
+ notificationForwarding = true;
+ }
- public void setMappingService(BindingIndependentMappingService mappingService) {
+ protected void setMappingService(BindingIndependentMappingService mappingService) {
this.mappingService = mappingService;
}
@Override
public void onSessionInitiated(ProviderSession session) {
- setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
- start();
+ setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+ setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
+
}
public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
*/
if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(bindingTransaction);
}
DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
* duplicating data.
*/
if (domOpenedTransactions.containsKey(identifier)) {
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(domTransaction);
}
org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
@SuppressWarnings("rawtypes")
private WeakReference<Class> outputClass;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
Class<? extends DataContainer> inputClass) {
super(targetMethod);
}
public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
+ @SuppressWarnings("unchecked")
Future<RpcResult<Void>> result = (Future<RpcResult<Void>>) targetMethod.invoke(rpcService);
RpcResult<Void> bindingResult = result.get();
return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
}
+ }
+
+ public boolean isRpcForwarding() {
+ return rpcForwarding;
+ }
+
+ public boolean isDataForwarding() {
+ return dataForwarding;
+ }
+
+ public boolean isNotificationForwarding() {
+ // TODO Auto-generated method stub
+ return notificationForwarding;
+ }
+ public BindingIndependentMappingService getMappingService() {
+ return mappingService;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class BindingIndependentMountPointForwarder {
+
+ private MountProvisionService domMountService;
+ private MountProviderService baMountService;
+ private BindingIndependentMappingService mappingService;
+
+ private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+ private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+ private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors;
+ private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded;
+ private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+ private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+ public MountProvisionService getDomMountService() {
+ return domMountService;
+ }
+
+ public void setDomMountService(MountProvisionService domMountService) {
+ this.domMountService = domMountService;
+ }
+
+ public void start() {
+ if(domMountService != null && baMountService != null) {
+ domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+ baListenerRegistration = baMountService.registerProvisionListener(bindingForwardingManager);
+ }
+ }
+
+ private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+ if(previous != null) {
+ return;
+ }
+ MountProviderInstance baMountPoint = baMountService.getMountPoint(baPath);
+ MountProvisionInstance domMountPoint = domMountService.getMountPoint(biPath);
+ BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+ connectors.put(baPath, connector);
+ connector.startDataForwarding();
+ connector.startRpcForwarding();
+ connector.startNotificationForwarding();
+ }
+
+ private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+ MountProvisionInstance domMountPoint) {
+ BindingIndependentConnector connector = new BindingIndependentConnector();
+
+ connector.setBindingDataService(baMountPoint);
+ connector.setBindingRpcRegistry(baMountPoint);
+ //connector.setBindingNotificationBroker(baMountPoint);
+
+ connector.setDomDataService(domMountPoint);
+ connector.setDomRpcRegistry(domMountPoint);
+ //connector.setDomNotificationBroker(domMountPoint);
+ return connector;
+ }
+
+ public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+ InstanceIdentifier<?> baPath;
+ try {
+ baPath = mappingService.fromDataDom(domPath);
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if(potentialConnector != null) {
+ return;
+ }
+ tryToDeployConnector(baPath,domPath);
+ } catch (DeserializationException e) {
+
+ }
+ }
+
+ public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ BindingIndependentConnector potentialConnector =connectors.get(baPath);
+ if(potentialConnector != null) {
+ return;
+ }
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(baPath);
+ tryToDeployConnector(baPath, domPath);
+ }
+
+ public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ private class DomMountPointForwardingManager implements MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ tryToDeployDomForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ undeployDomForwarder(path);
+ }
+ }
+
+ private class BindingMountPointForwardingManager implements
+ org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(InstanceIdentifier<?> path) {
+ tryToDeployBindingForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(InstanceIdentifier<?> path) {
+ undeployBindingForwarder(path);
+ }
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-public class BindingIndependentRpcConnector {
-
-}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.DeserializationException;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DomForwardedBindingBrokerImpl extends RootBindingAwareBroker implements DomForwardedBroker {
+
+ private ProviderSession domProviderContext;
+ private BindingIndependentConnector connector;
+
+ private MountProvisionService domMountService;
+
+ private final DomMountPointForwardingManager domForwardingManager = new DomMountPointForwardingManager();
+ private final BindingMountPointForwardingManager bindingForwardingManager = new BindingMountPointForwardingManager();
+
+ private ConcurrentMap<InstanceIdentifier<?>, BindingIndependentConnector> connectors = new ConcurrentHashMap<>();
+ private ConcurrentMap<InstanceIdentifier<?>, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier> forwarded = new ConcurrentHashMap<>();
+ private ListenerRegistration<MountProvisionListener> domListenerRegistration;
+ private ListenerRegistration<org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener> baListenerRegistration;
+
+
+ public DomForwardedBindingBrokerImpl(String instanceName) {
+ super(instanceName);
+ }
+
+ @Override
+ public BindingIndependentConnector getConnector() {
+ return connector;
+ }
+
+ @Override
+ public ProviderSession getDomProviderContext() {
+ return domProviderContext;
+ }
+
+ @Override
+ public void setConnector(BindingIndependentConnector connector) {
+ this.connector = connector;
+ }
+
+ @Override
+ public void setDomProviderContext(ProviderSession domProviderContext) {
+ this.domProviderContext = domProviderContext;
+ }
+
+ @Override
+ public void startForwarding() {
+ BindingDomConnectorDeployer.startDataForwarding(getConnector(), getDataBroker(), getDomProviderContext());
+ BindingDomConnectorDeployer.startRpcForwarding(getConnector(), getRpcProviderRegistry(),
+ getDomProviderContext());
+ BindingDomConnectorDeployer.startNotificationForwarding(getConnector(), getNotificationBroker(),
+ getDomProviderContext());
+ startMountpointForwarding();
+ }
+
+ private void startMountpointForwarding() {
+ domMountService = getDomProviderContext().getService(MountProvisionService.class);
+ if (domMountService != null && getMountManager() != null) {
+ domListenerRegistration = domMountService.registerProvisionListener(domForwardingManager);
+ baListenerRegistration = getMountManager().registerProvisionListener(bindingForwardingManager);
+ }
+ }
+
+ public MountProvisionService getDomMountService() {
+ return domMountService;
+ }
+
+ public void setDomMountService(MountProvisionService domMountService) {
+ this.domMountService = domMountService;
+ }
+
+ private void tryToDeployConnector(InstanceIdentifier<?> baPath,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier previous = forwarded.putIfAbsent(baPath, biPath);
+ if (previous != null) {
+ return;
+ }
+ MountProviderInstance baMountPoint = getMountManager().createOrGetMountPoint(baPath);
+ MountProvisionInstance domMountPoint = domMountService.createOrGetMountPoint(biPath);
+ BindingIndependentConnector connector = createForwarder(baPath, baMountPoint, domMountPoint);
+ connectors.put(baPath, connector);
+ }
+
+ private BindingIndependentConnector createForwarder(InstanceIdentifier<?> path, MountProviderInstance baMountPoint,
+ MountProvisionInstance domMountPoint) {
+ BindingIndependentConnector mountConnector = BindingDomConnectorDeployer.createConnector(getConnector());
+
+ BindingDomConnectorDeployer.startDataForwarding(mountConnector, baMountPoint, domMountPoint);
+ BindingDomConnectorDeployer.startRpcForwarding(mountConnector, baMountPoint, domMountPoint);
+ BindingDomConnectorDeployer.startNotificationForwarding(mountConnector, baMountPoint, domMountPoint);
+ // connector.setDomNotificationBroker(domMountPoint);
+ return connector;
+ }
+
+ public synchronized void tryToDeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
+ InstanceIdentifier<?> baPath;
+ try {
+ baPath = connector.getMappingService().fromDataDom(domPath);
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if (potentialConnector != null) {
+ return;
+ }
+ tryToDeployConnector(baPath, domPath);
+ } catch (DeserializationException e) {
+
+ }
+ }
+
+ public synchronized void tryToDeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ BindingIndependentConnector potentialConnector = connectors.get(baPath);
+ if (potentialConnector != null) {
+ return;
+ }
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = connector.getMappingService().toDataDom(baPath);
+ tryToDeployConnector(baPath, domPath);
+ }
+
+ public synchronized void undeployBindingForwarder(InstanceIdentifier<?> baPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ public synchronized void undeployDomForwarder(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath) {
+ // FIXME: Implement closeMountPoint
+ }
+
+ private class DomMountPointForwardingManager implements MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ tryToDeployDomForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier path) {
+ undeployDomForwarder(path);
+ }
+ }
+
+ private class BindingMountPointForwardingManager implements
+ org.opendaylight.controller.sal.binding.api.mount.MountProviderService.MountProvisionListener {
+
+ @Override
+ public void onMountPointCreated(InstanceIdentifier<?> path) {
+ tryToDeployBindingForwarder(path);
+ }
+
+ @Override
+ public void onMountPointRemoved(InstanceIdentifier<?> path) {
+ undeployBindingForwarder(path);
+ }
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+interface DomForwardedBroker {
+
+ public BindingIndependentConnector getConnector();
+
+ public void setConnector(BindingIndependentConnector connector);
+
+ public void setDomProviderContext(ProviderSession domProviderContext);
+
+ public ProviderSession getDomProviderContext();
+
+ void startForwarding();
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.impl.RootDataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+
+public class DomForwardedDataBrokerImpl extends RootDataBrokerImpl implements Provider, DomForwardedBroker {
+
+ private BindingIndependentConnector connector;
+ private ProviderSession domProviderContext;
+
+ public void setConnector(BindingIndependentConnector connector) {
+ this.connector = connector;
+ }
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+ this.setDomProviderContext(session);
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public BindingIndependentConnector getConnector() {
+ return connector;
+ }
+
+ @Override
+ public ProviderSession getDomProviderContext() {
+ return domProviderContext;
+ }
+
+ public void setDomProviderContext(ProviderSession domProviderContext) {
+ this.domProviderContext = domProviderContext;
+ }
+
+ @Override
+ public void startForwarding() {
+ BindingDomConnectorDeployer.startDataForwarding(getConnector(), this, getDomProviderContext());
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.forward;
+
+import com.google.common.base.Preconditions;
+
+public class DomForwardingUtils {
+
+ public static boolean isDomForwardedBroker(Object obj) {
+ return obj instanceof DomForwardedBroker;
+ }
+
+ public static void reuseForwardingFrom(Object target,Object source) {
+ Preconditions.checkArgument(isDomForwardedBroker(source));
+ Preconditions.checkArgument(isDomForwardedBroker(target));
+ DomForwardedBroker forwardedSource = (DomForwardedBroker) source;
+ DomForwardedBroker forwardedTarget = (DomForwardedBroker) target;
+ reuseForwardingFrom(forwardedTarget, forwardedSource);
+
+ }
+
+ private static void reuseForwardingFrom(DomForwardedBroker target, DomForwardedBroker source) {
+ target.setConnector(source.getConnector());
+ target.setDomProviderContext(source.getDomProviderContext());
+ }
+
+}
+++ /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.osgi
-
-class Constants {
-
- private new() {
- }
-
- public static val SAL_SERVICE_TYPE = "salServiceType"
- public static val SAL_SERVICE_TYPE_CONSUMER_PROXY = "consumerProxy"
- public static val SAL_SERVICE_TYPE_PROVIDER = "provider"
- public static val SAL_SERVICE_TYPE_CONNECTOR = "connector"
-}
+++ /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.osgi
-
-import java.util.Hashtable
-import static org.opendaylight.controller.sal.binding.impl.osgi.Constants.*
-
-class PropertiesUtils {
-
- private new() {
- }
-
- static def setSalServiceType(Hashtable<String, String> properties, String value) {
- properties.put(SAL_SERVICE_TYPE, value)
- return properties
- }
-
- static def getSalServiceType(Hashtable<String, String> properties) {
- return properties.get(SAL_SERVICE_TYPE)
- }
-
- static def newProperties() {
- new Hashtable<String, String>()
- }
-
-}
+++ /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.osgi;
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.sal.binding.spi;
-
-public class RoutingContext {
-
-}
config:required-identity sal:binding-notification-service;
}
}
- }
+ }
}
}
-
+
augment "/config:modules/config:module/config:configuration" {
case binding-data-broker {
when "/config:modules/config:module/config:type = 'binding-data-broker'";
}
}
}
+
container mapping-service {
uses config:service-ref {
refine type {
import static org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper.*;
import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
import org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker;
-import org.opendaylight.controller.sal.binding.spi.RpcRouter;
-import org.opendaylight.controller.sal.binding.spi.RpcRoutingTable;
import org.opendaylight.controller.sal.binding.test.mock.BarListener;
import org.opendaylight.controller.sal.binding.test.mock.BarUpdate;
import org.opendaylight.controller.sal.binding.test.mock.CompositeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.Future;
import javassist.ClassPool;
+import org.eclipse.xtext.xbase.lib.Pure;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+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.BrokerService;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
import org.opendaylight.controller.sal.core.api.data.DataStore;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+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;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.ImmutableClassToInstanceMap;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import static com.google.common.base.Preconditions.*;
public class BindingTestContext implements AutoCloseable {
-
-
+
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
-
+
private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
-
-
- private BindingAwareBrokerImpl baBrokerImpl;
+
+ private DomForwardedBindingBrokerImpl baBrokerImpl;
private DataBrokerImpl baDataImpl;
private NotificationBrokerImpl baNotifyImpl;
- private BindingIndependentConnector baConnectDataServiceImpl;
+ private BindingIndependentConnector baConnectImpl;
private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
private BrokerImpl biBrokerImpl;
private DataStoreStatsWrapper dataStoreStats;
private DataStore dataStore;
-
private boolean dataStoreStatisticsEnabled = false;
-
+
private final ListeningExecutorService executor;
private final ClassPool classPool;
private final boolean startWithSchema;
-
+ private MountPointManagerImpl biMountImpl;
+
protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
this.executor = executor;
this.classPool = classPool;
rawDataStore = new HashMapDataStore();
schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
schemaAwareDataStore.changeDelegate(rawDataStore);
- if(dataStoreStatisticsEnabled) {
- dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
- dataStore = dataStoreStats;
+ if (dataStoreStatisticsEnabled) {
+ dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
+ dataStore = dataStoreStats;
} else {
dataStore = schemaAwareDataStore;
}
-
+
biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
}
-
+
public void startDomDataBroker() {
- checkState(executor != null,"Executor needs to be set");
+ checkState(executor != null, "Executor needs to be set");
biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
biDataImpl.setExecutor(executor);
}
-
+
public void startBindingDataBroker() {
- checkState(executor != null,"Executor needs to be set");
+ checkState(executor != null, "Executor needs to be set");
baDataImpl = new DataBrokerImpl();
baDataImpl.setExecutor(executor);
}
-
+
public void startBindingBroker() {
- checkState(executor != null,"Executor needs to be set");
- checkState(baDataImpl != null,"Binding Data Broker must be started");
+ checkState(executor != null, "Executor needs to be set");
+ checkState(baDataImpl != null, "Binding Data Broker must be started");
checkState(baNotifyImpl != null, "Notification Service must be started");
- baBrokerImpl = new BindingAwareBrokerImpl("test",null);
-
+ baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
+
+ baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
+ baBrokerImpl.getMountManager().setNotificationExecutor(executor);
+ baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
baBrokerImpl.setDataBroker(baDataImpl);
- baBrokerImpl.setNotifyBroker(baNotifyImpl);
-
+ baBrokerImpl.setNotificationBroker(baNotifyImpl);
baBrokerImpl.start();
}
-
- public void startBindingToDomDataConnector() {
- checkState(baDataImpl != null,"Binding Data Broker needs to be started");
- checkState(biDataImpl != null,"DOM Data Broker needs to be started.");
- checkState(mappingServiceImpl != null,"DOM Mapping Service needs to be started.");
- baConnectDataServiceImpl = new BindingIndependentConnector();
- baConnectDataServiceImpl.setRpcRegistry(baBrokerImpl);
- baConnectDataServiceImpl.setDomRpcRegistry(getDomRpcRegistry());
- baConnectDataServiceImpl.setBaDataService(baDataImpl);
- baConnectDataServiceImpl.setBiDataService(biDataImpl);
- baConnectDataServiceImpl.setMappingService(mappingServiceImpl);
- baConnectDataServiceImpl.start();
+
+ public void startForwarding() {
+ checkState(baDataImpl != null, "Binding Data Broker needs to be started");
+ checkState(biDataImpl != null, "DOM Data Broker needs to be started.");
+ checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
+
+ baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
+ baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
+ baBrokerImpl.setConnector(baConnectImpl);
+ baBrokerImpl.setDomProviderContext(createMockContext());
+ baBrokerImpl.startForwarding();
}
-
+
+ private ProviderSession createMockContext() {
+ // TODO Auto-generated method stub
+ final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
+ .<BrokerService> builder()
+ //
+ .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) //
+ .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
+ .put(MountProvisionService.class, biMountImpl) //
+ .build();
+
+ return new ProviderSession() {
+
+ @Override
+ public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends BrokerService> T getService(Class<T> service) {
+ return domBrokerServices.getInstance(service);
+ }
+
+ @Override
+ public boolean isClosed() {
+ return false;
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
+ RpcRegistrationListener listener) {
+ return null;
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return null;
+ }
+
+ @Override
+ public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return null;
+ }
+ };
+ }
+
public void startBindingToDomMappingService() {
- checkState(classPool != null,"ClassPool needs to be present");
+ checkState(classPool != null, "ClassPool needs to be present");
mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
mappingServiceImpl.setPool(classPool);
mappingServiceImpl.start(null);
}
-
-
+
public void updateYangSchema(String[] files) {
SchemaContext context = getContext(files);
- if(schemaAwareDataStore != null) {
+ if (schemaAwareDataStore != null) {
schemaAwareDataStore.onGlobalContextUpdated(context);
}
- if(mappingServiceImpl != null) {
+ if (mappingServiceImpl != null) {
mappingServiceImpl.onGlobalContextUpdated(context);
}
}
-
-
+
public static String[] getAllYangFilesOnClasspath() {
Predicate<String> predicate = new Predicate<String>() {
@Override
Set<String> result = reflection.getResources(predicate);
return (String[]) result.toArray(new String[result.size()]);
}
-
+
private static SchemaContext getContext(String[] yangFiles) {
ClassLoader loader = BindingTestContext.class.getClassLoader();
List<InputStream> streams = new ArrayList<>();
Set<Module> modules = parser.parseYangModelsFromStreams(streams);
return parser.resolveSchemaContext(modules);
}
-
+
public void start() {
startBindingDataBroker();
startBindingNotificationBroker();
startDomDataBroker();
startDomDataStore();
startDomBroker();
+ startDomMountPoint();
startBindingToDomMappingService();
- startBindingToDomDataConnector();
- if(startWithSchema) {
+ startForwarding();
+ if (startWithSchema) {
loadYangSchemaFromClasspath();
}
}
+ private void startDomMountPoint() {
+ biMountImpl = new MountPointManagerImpl();
+ biMountImpl.setDataBroker(getDomDataBroker());
+ }
+
private void startDomBroker() {
checkState(executor != null);
biBrokerImpl = new BrokerImpl();
public void startBindingNotificationBroker() {
checkState(executor != null);
baNotifyImpl = new NotificationBrokerImpl(executor);
-
+
}
public void loadYangSchemaFromClasspath() {
}
public void logDataStoreStatistics() {
- if(dataStoreStats == null) {
+ if (dataStoreStats == null) {
return;
}
-
+
LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
dataStoreStats.getConfigurationReadAverageTime());
}
public RpcProviderRegistry getBindingRpcRegistry() {
- return baBrokerImpl;
+ return baBrokerImpl.getRoot();
}
public RpcProvisionRegistry getDomRpcRegistry() {
- if(biBrokerImpl == null) {
+ if (biBrokerImpl == null) {
return null;
}
return biBrokerImpl.getRouter();
}
-
+
public RpcImplementation getDomRpcInvoker() {
return biBrokerImpl.getRouter();
}
-
+
@Override
public void close() throws Exception {
-
+
+ }
+
+ public MountProviderService getBindingMountProviderService() {
+ return baBrokerImpl.getMountManager();
+ }
+
+ public MountProvisionService getDomMountProviderService() {
+ return biMountImpl;
}
}
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.CommitHandlersTransactions;
+import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpVersion;
public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
modificationCapture = modification;
- return CommitHandlersTransactions.allwaysSuccessfulTransaction(modification);
+ return CommitHandlerTransactions.allwaysSuccessfulTransaction(modification);
}
};
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.management.Notification;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
+import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
+import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+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.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class CrossBrokerMountPointTest {
+
+ private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+ private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
+ private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
+ private static final QName TABLE_ID_QNAME = QName.create(Table.QNAME, "id");
+
+ private static final String NODE_ID = "node:1";
+
+ private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+
+ private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+ NODE_ID);
+
+ private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder(Nodes.class) //
+ .child(Node.class, NODE_KEY).toInstance();
+ private static GroupKey GROUP_KEY = new GroupKey(new GroupId(0L));
+
+ private static final InstanceIdentifier<GroupStatistics> GROUP_STATISTICS_ID_BA = InstanceIdentifier
+ .builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class) //
+ .child(Group.class, GROUP_KEY) //
+ .augmentation(NodeGroupStatistics.class) //
+ .child(GroupStatistics.class) //
+ .toInstance();
+
+ private static final QName AUGMENTED_GROUP_STATISTICS = QName.create(NodeGroupStatistics.QNAME,
+ GroupStatistics.QNAME.getLocalName());
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+ .node(Nodes.QNAME) //
+ .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+ .toInstance();
+
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier GROUP_STATISTICS_ID_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+ //
+ .builder(NODE_INSTANCE_ID_BI)
+ .nodeWithKey(QName.create(FlowCapableNode.QNAME, "group"), QName.create(FlowCapableNode.QNAME, "group-id"),
+ 0L).node(AUGMENTED_GROUP_STATISTICS).toInstance();
+
+ private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+
+ private BindingTestContext testContext;
+ private MountProviderService bindingMountPointService;
+ private MountProvisionService domMountPointService;
+
+ @Before
+ public void setup() {
+ BindingBrokerTestFactory testFactory = new BindingBrokerTestFactory();
+ testFactory.setExecutor(MoreExecutors.sameThreadExecutor());
+ testFactory.setStartWithParsedSchema(true);
+ testContext = testFactory.getTestContext();
+
+ testContext.start();
+ bindingMountPointService = testContext.getBindingMountProviderService();
+ domMountPointService = testContext.getDomMountProviderService();
+
+ // biRpcInvoker = testContext.getDomRpcInvoker();
+ assertNotNull(bindingMountPointService);
+ assertNotNull(domMountPointService);
+
+ // flowService = MessageCapturingFlowService.create(baRpcRegistry);
+ }
+
+ @Test
+ public void testMountPoint() {
+
+ testContext.getBindingDataBroker().readOperationalData(NODE_INSTANCE_ID_BA);
+
+ MountProvisionInstance domMountPoint = domMountPointService.createMountPoint(NODE_INSTANCE_ID_BI);
+ assertNotNull(domMountPoint);
+ MountProviderInstance bindingMountPoint = bindingMountPointService.getMountPoint(NODE_INSTANCE_ID_BA);
+ assertNotNull(bindingMountPoint);
+
+ final BigInteger packetCount = BigInteger.valueOf(500L);
+
+
+ DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> simpleReader = new DataReader<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>() {
+
+ @Override
+ public CompositeNode readConfigurationData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+ return null;
+ }
+
+
+ @Override
+ public CompositeNode readOperationalData(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier arg0) {
+ if (arg0.equals(GROUP_STATISTICS_ID_BI)) {
+ ImmutableCompositeNode data = ImmutableCompositeNode
+ .builder()
+ .setQName(AUGMENTED_GROUP_STATISTICS)
+ .addLeaf(QName.create(AUGMENTED_GROUP_STATISTICS, "packet-count"), packetCount) //
+ .toInstance();
+
+ return data;
+ }
+ return null;
+ }
+
+ };
+ domMountPoint.registerOperationalReader(NODE_INSTANCE_ID_BI, simpleReader);
+
+ GroupStatistics data = (GroupStatistics) bindingMountPoint.readOperationalData(GROUP_STATISTICS_ID_BA);
+ assertNotNull(data);
+ assertEquals(packetCount,data.getPacketCount().getValue());
+ }
+}
mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), // //
mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(), //
mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), // //
+ mavenBundle(CONTROLLER, "sal-binding-util").versionAsInProject(), //
mavenBundle("org.javassist", "javassist").versionAsInProject(), // //
mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // //
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.controller.sal.binding.api.NotificationService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.binding.RpcService;
public class NoficationTest extends AbstractTest {
* The registration of the Consumer 2. SalFlowListener is registered
* registered as notification listener.
*/
- BindingAwareConsumer consumer2 = new BindingAwareConsumer() {
+ BindingAwareProvider provider = new BindingAwareProvider() {
+
@Override
- public void onSessionInitialized(ConsumerContext session) {
+ public void onSessionInitiated(ProviderContext session) {
listener2Reg = session.getSALService(NotificationProviderService.class).registerNotificationListener(
listener2);
}
+
+ @Override
+ public void onSessionInitialized(ConsumerContext session) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Collection<? extends RpcService> getImplementations() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Collection<? extends ProviderFunctionality> getFunctionality() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
};
// registerConsumer method calls onSessionInitialized method above
- broker.registerConsumer(consumer2, getBundleContext());
+ broker.registerProvider(provider, getBundleContext());
/**
* 3 notifications are published
<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 java.util.concurrent.Future;
+import java.util.zip.Checksum;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.mount.MountInstance;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractBindingSalConsumerInstance<D extends DataBrokerService, N extends NotificationService, R extends RpcConsumerRegistry> //
+ implements //
+ RpcConsumerRegistry, //
+ NotificationService, //
+ DataBrokerService {
+
+ private final R rpcRegistry;
+ private final N notificationBroker;
+ private final D dataBroker;
+
+ protected final R getRpcRegistry() {
+ return rpcRegistry;
+ }
+
+ protected final N getNotificationBroker() {
+ return notificationBroker;
+ }
+
+ protected final D getDataBroker() {
+ return dataBroker;
+ }
+
+ protected final R getRpcRegistryChecked() {
+ Preconditions.checkState(rpcRegistry != null,"Rpc Registry is not available.");
+ return rpcRegistry;
+ }
+
+ protected final N getNotificationBrokerChecked() {
+ Preconditions.checkState(notificationBroker != null,"Notification Broker is not available.");
+ return notificationBroker;
+ }
+
+ protected final D getDataBrokerChecked() {
+ Preconditions.checkState(dataBroker != null, "Data Broker is not available");
+ return dataBroker;
+ }
+
+
+ protected AbstractBindingSalConsumerInstance(R rpcRegistry, N notificationBroker, D dataBroker) {
+ this.rpcRegistry = rpcRegistry;
+ this.notificationBroker = notificationBroker;
+ this.dataBroker = dataBroker;
+ }
+
+ public <T extends RpcService> T getRpcService(Class<T> module) {
+ return getRpcRegistryChecked().getRpcService(module);
+ }
+
+ @Deprecated
+ public <T extends Notification> void addNotificationListener(Class<T> notificationType,
+ NotificationListener<T> listener) {
+ getNotificationBrokerChecked().addNotificationListener(notificationType, listener);
+ }
+
+ @Deprecated
+ public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ getNotificationBrokerChecked().addNotificationListener(listener);
+ }
+
+ @Deprecated
+ public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ getNotificationBrokerChecked().removeNotificationListener(listener);
+ }
+
+ @Deprecated
+ public <T extends Notification> void removeNotificationListener(Class<T> notificationType,
+ NotificationListener<T> listener) {
+ getNotificationBrokerChecked().removeNotificationListener(notificationType, listener);
+ }
+
+ public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+ Class<T> notificationType, NotificationListener<T> listener) {
+ return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener);
+ }
+
+ public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+ org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ return getNotificationBrokerChecked().registerNotificationListener(listener);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+ return getDataBrokerChecked().getData(store, rootType);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+ return getDataBrokerChecked().getData(store, filter);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+ return getDataBrokerChecked().getCandidateData(store, rootType);
+ }
+
+ @Deprecated
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+ return getDataBrokerChecked().getCandidateData(store, filter);
+ }
+
+ @Deprecated
+ public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+ return getDataBrokerChecked().editCandidateData(store, changeSet);
+ }
+
+ @Deprecated
+ public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+ return getDataBrokerChecked().commit(store);
+ }
+
+ @Deprecated
+ public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+ return getDataBrokerChecked().getData(data);
+ }
+
+ @Deprecated
+ public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+ return getDataBrokerChecked().getConfigurationData(data);
+ }
+
+ public DataModificationTransaction beginTransaction() {
+ return getDataBrokerChecked().beginTransaction();
+ }
+
+ @Deprecated
+ public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+ getDataBrokerChecked().registerChangeListener(path, changeListener);
+ }
+
+ @Deprecated
+ public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+ DataChangeListener changeListener) {
+ getDataBrokerChecked().unregisterChangeListener(path, changeListener);
+ }
+
+ @Deprecated
+ public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+ return getDataBrokerChecked().readConfigurationData(path);
+ }
+
+ public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ return getDataBrokerChecked().readOperationalData(path);
+ }
+
+ @Deprecated
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(
+ InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
+ return getDataBrokerChecked().registerDataChangeListener(path, listener);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.util.concurrent.ExecutorService;
+
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.mount.MountProviderInstance;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public abstract class AbstractBindingSalProviderInstance<D extends DataProviderService, N extends NotificationProviderService, R extends RpcProviderRegistry> //
+ extends AbstractBindingSalConsumerInstance<D, N, R> //
+ implements //
+ DataProviderService, //
+ RpcProviderRegistry, //
+ NotificationProviderService {
+
+ public AbstractBindingSalProviderInstance(R rpcRegistry, N notificationBroker,
+ D dataBroker) {
+ super(rpcRegistry, notificationBroker, dataBroker);
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier<? extends DataObject>, DataObject>> registerDataReader(
+ InstanceIdentifier<? extends DataObject> path,
+ DataReader<InstanceIdentifier<? extends DataObject>, DataObject> reader) {
+ return getDataBrokerChecked().registerDataReader(path, reader);
+ }
+
+ @Override
+ public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> registerCommitHandler(
+ InstanceIdentifier<? extends DataObject> path,
+ DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
+ return getDataBrokerChecked().registerCommitHandler(path, commitHandler);
+ }
+
+ @Override
+ public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>>> registerCommitHandlerListener(
+ RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlerListener) {
+ return getDataBrokerChecked().registerCommitHandlerListener(commitHandlerListener);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRpcRegistryChecked().addRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getRpcRegistryChecked().addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ @Deprecated
+ public void notify(Notification notification) {
+ getNotificationBrokerChecked().notify(notification);
+ }
+
+ @Override
+ @Deprecated
+ public void notify(Notification notification, ExecutorService service) {
+ getNotificationBrokerChecked().notify(notification, service);
+ }
+
+ @Override
+ public void publish(Notification notification) {
+ getNotificationBrokerChecked().publish(notification);
+ }
+
+ @Override
+ public void publish(Notification notification, ExecutorService service) {
+ getNotificationBrokerChecked().publish(notification, service);
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return getRpcRegistryChecked().registerRouteChangeListener(listener);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.md.sal.binding.util;
+
+import java.awt.image.SinglePixelPackedSampleModel;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+import static com.google.common.base.Preconditions.*;
+
+import com.google.common.collect.ClassToInstanceMap;
+import com.google.common.collect.MutableClassToInstanceMap;
+
+public class BindingContextUtils {
+
+ public static ConsumerContext createConsumerContext(BindingAwareConsumer consumer,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ checkNotNull(consumer,"Consumer should not be null");
+ checkNotNull(serviceProvider,"Service map should not be null");
+ return new SingleConsumerContextImpl(serviceProvider);
+ }
+
+ public static ProviderContext createProviderContext(BindingAwareProvider provider,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ checkNotNull(provider,"Provider should not be null");
+ checkNotNull(serviceProvider,"Service map should not be null");
+ return new SingleProviderContextImpl(serviceProvider);
+ }
+
+ public static ConsumerContext createConsumerContextAndInitialize(BindingAwareConsumer consumer,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ ConsumerContext context = createConsumerContext(consumer, serviceProvider);
+ consumer.onSessionInitialized(context);
+ return context;
+ }
+
+ public static ProviderContext createProviderContextAndInitialize(BindingAwareProvider provider,
+ ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ ProviderContext context = createProviderContext(provider, serviceProvider);
+ provider.onSessionInitiated(context);
+ return context;
+ }
+
+ public static <T extends BindingAwareService> T createContextProxyOrReturnService(Class<T> service, T instance) {
+ // FIXME: Create Proxy
+ return instance;
+ }
+
+ private static class SingleConsumerContextImpl implements ConsumerContext, AutoCloseable {
+
+ private ClassToInstanceMap<BindingAwareService> alreadyRetrievedServices;
+ private ClassToInstanceMap<BindingAwareService> serviceProvider;
+
+ public SingleConsumerContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ this.alreadyRetrievedServices = MutableClassToInstanceMap.create();
+ this.serviceProvider = serviceProvider;
+ }
+
+ @Override
+ public final <T extends RpcService> T getRpcService(Class<T> module) {
+ return getSALService(RpcConsumerRegistry.class).getRpcService(module);
+ }
+
+ @Override
+ public final <T extends BindingAwareService> T getSALService(Class<T> service) {
+ checkNotNull(service,"Service class should not be null.");
+ T potential = alreadyRetrievedServices.getInstance(service);
+ if(potential != null) {
+ return potential;
+ }
+ return tryToRetrieveSalService(service);
+ }
+
+ private synchronized <T extends BindingAwareService> T tryToRetrieveSalService(Class<T> service) {
+ final T potential = alreadyRetrievedServices.getInstance(service);
+ if(potential != null) {
+ return potential;
+ }
+ final T requested = serviceProvider.getInstance(service);
+ if(requested == null) {
+ throw new IllegalArgumentException("Requested service "+service.getName() +" is not available.");
+ }
+ final T retrieved = BindingContextUtils.createContextProxyOrReturnService(service,requested);
+ alreadyRetrievedServices.put(service, retrieved);
+ return retrieved;
+ }
+
+ @Override
+ public final void close() throws Exception {
+ alreadyRetrievedServices = null;
+ serviceProvider = null;
+ }
+ }
+
+ private static class SingleProviderContextImpl extends SingleConsumerContextImpl implements ProviderContext {
+
+ public SingleProviderContextImpl(ClassToInstanceMap<BindingAwareService> serviceProvider) {
+ super(serviceProvider);
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return getSALService(RpcProviderRegistry.class).registerRouteChangeListener(listener);
+ }
+
+ @Override
+ public <T extends RpcService> RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> type,
+ T implementation) throws IllegalStateException {
+ return getSALService(RpcProviderRegistry.class).addRoutedRpcImplementation(type, implementation);
+ }
+
+ @Override
+ public <T extends RpcService> RpcRegistration<T> addRpcImplementation(Class<T> type, T implementation)
+ throws IllegalStateException {
+ return getSALService(RpcProviderRegistry.class).addRpcImplementation(type, implementation);
+ }
+
+ @Deprecated
+ @Override
+ public void registerFunctionality(ProviderFunctionality functionality) {
+ // NOOP
+ }
+
+ @Deprecated
+ @Override
+ public void unregisterFunctionality(ProviderFunctionality functionality) {
+ // NOOP
+ }
+ }
+}
public final class TypeSafeDataReader {
-
- private final DataReader<InstanceIdentifier<? extends DataObject>,DataObject> delegate;
-
-
-
+ private final DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate;
+
public DataReader<InstanceIdentifier<?>, DataObject> getDelegate() {
return delegate;
}
-
public TypeSafeDataReader(DataReader<InstanceIdentifier<? extends DataObject>, 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) {
+ public <D extends DataObject> D readOperationalData(InstanceIdentifier<D> path) {
return (D) delegate.readOperationalData(path);
}
-
+
public static TypeSafeDataReader forReader(DataReader<InstanceIdentifier<? extends DataObject>, DataObject> delegate) {
return new TypeSafeDataReader(delegate);
}
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
</dependencies>
<packaging>bundle</packaging>
+/*
+ * 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.common.util;
public class Arguments {
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
+package org.opendaylight.controller.sal.common.util;
import java.util.Collections;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
-import org.opendaylight.controller.sal.common.util.Rpcs;
import org.opendaylight.yangtools.concepts.Path;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
-public class CommitHandlersTransactions {
+public class CommitHandlerTransactions {
private static class AllwaysSuccessfulTransaction<P extends Path<P>,D> implements DataCommitTransaction<P, D> {
}
}
-
public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification) {
return new AllwaysSuccessfulTransaction<>(modification);
}
+/*
+ * 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.common.util;
import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
import org.opendaylight.yangtools.yang.common.QName;
-public interface RpcProvisionRegistry {
+public interface RpcProvisionRegistry extends BrokerService {
/**
* Registers an implementation of the rpc.
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.controller.sal.core.api.mount;
import java.util.concurrent.Future;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public interface MountInstance extends NotificationService, DataBrokerService {
+public interface MountInstance extends //
+ NotificationService, //
+ DataBrokerService {
Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
-
+
SchemaContext getSchemaContext();
}
package org.opendaylight.controller.sal.core.api.mount;
+import java.util.EventListener;
+
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
public interface MountProvisionService extends MountService {
MountProvisionInstance createMountPoint(InstanceIdentifier path);
MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
+
+ ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
+
+ public interface MountProvisionListener extends EventListener {
+
+ void onMountPointCreated(InstanceIdentifier path);
+
+ void onMountPointRemoved(InstanceIdentifier path);
+
+ }
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+public class $ModuleInfo {
+
+
+}
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import com.google.common.util.concurrent.MoreExecutors;
+
public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
DataProviderService, AutoCloseable {
public DataBrokerImpl() {
setDataReadRouter(new DataReaderRouter());
+ setExecutor(MoreExecutors.sameThreadExecutor());
}
public AtomicLong getCreatedTransactionsCount() {
public class MountPointImpl implements MountProvisionInstance {
private final RpcRouter rpcs;
- private final DataReaderRouter dataReader;
+ private final DataBrokerImpl dataReader;
private final NotificationRouter notificationRouter;
private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
public MountPointImpl(InstanceIdentifier path) {
this.mountPath = path;
rpcs = new RpcRouterImpl("");
- dataReader = new DataReaderRouter();
+ dataReader = new DataBrokerImpl();
notificationRouter = new NotificationRouterImpl();
readWrapper = new ReadWrapper();
}
@Override
public DataModificationTransaction beginTransaction() {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.beginTransaction();
}
@Override
public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
DataChangeListener listener) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerDataChangeListener(path, listener);
}
@Override
@Override
public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerCommitHandler(path, commitHandler);
}
@Override
@Override
public ListenerRegistration<RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>>> registerCommitHandlerListener(
RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
- // TODO Auto-generated method stub
- return null;
+ return dataReader.registerCommitHandlerListener(commitHandlerListener);
}
}
import java.util.concurrent.ConcurrentHashMap
import static com.google.common.base.Preconditions.*;
import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry
class MountPointManagerImpl implements MountProvisionService {
@Property
DataProviderService dataBroker;
+ val ListenerRegistry<MountProvisionListener> listeners = ListenerRegistry.create()
+
ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
override createMountPoint(InstanceIdentifier path) {
val mount = new MountPointImpl(path);
registerMountPoint(mount);
mounts.put(path,mount);
+ notifyMountCreated(path);
return mount;
}
+ def notifyMountCreated(InstanceIdentifier identifier) {
+ for(listener : listeners) {
+ listener.instance.onMountPointCreated(identifier);
+ }
+ }
+
def registerMountPoint(MountPointImpl impl) {
dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
}
+ override registerProvisionListener(MountProvisionListener listener) {
+ listeners.register(listener)
+ }
+
override createOrGetMountPoint(InstanceIdentifier path) {
val mount = mounts.get(path);
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.osgi.framework.ServiceReference;
public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
return getDelegate().createOrGetMountPoint(path);
}
+
+ @Override
+ public ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener) {
+ return getDelegate().registerProvisionListener(listener);
+ }
}
private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider(BundleContext bundleContext) {
if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
String storageFile = "cache/schema";
- File directory = bundleContext.getDataFile(storageFile);
+// File directory = bundleContext.getDataFile(storageFile);
+ File directory = new File("cache/schema");
SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
}
package org.opendaylight.controller.sal.connect.netconf
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.netconf.client.NetconfClient
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import com.google.common.base.Optional
+import com.google.common.collect.FluentIterable
+import io.netty.util.concurrent.EventExecutor
+import java.io.InputStream
import java.net.InetSocketAddress
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.api.SimpleNode
-import org.opendaylight.yangtools.yang.common.QName
+import java.net.URI
import java.util.Collections
+import java.util.List
+import java.util.Set
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import org.opendaylight.controller.netconf.client.NetconfClient
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.controller.sal.core.api.Provider
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
-import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
-import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import org.opendaylight.controller.sal.core.api.Provider
+import org.opendaylight.controller.sal.core.api.RpcImplementation
import org.opendaylight.controller.sal.core.api.data.DataBrokerService
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
import org.opendaylight.protocol.framework.ReconnectStrategy
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import com.google.common.collect.FluentIterable
-import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yangtools.concepts.Registration
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
+import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
-import java.io.InputStream
-import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
import org.slf4j.Logger
-import org.opendaylight.controller.netconf.client.AbstractNetconfClientNotifySessionListener
-import org.opendaylight.controller.netconf.client.NetconfClientSession
-import org.opendaylight.controller.netconf.api.NetconfMessage
-import io.netty.util.concurrent.EventExecutor
+import org.slf4j.LoggerFactory
-import java.util.Map
-import java.util.Set
-import com.google.common.collect.ImmutableMap
+import static com.google.common.base.Preconditions.*
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
-import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
-import com.google.common.base.Optional
-import com.google.common.collect.ImmutableList
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
-import static com.google.common.base.Preconditions.*;
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Future
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener
-import io.netty.util.concurrent.Promise
-import org.opendaylight.controller.netconf.util.xml.XmlElement
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.locks.ReentrantLock
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
class NetconfDevice implements Provider, //
DataReader<InstanceIdentifier, CompositeNode>, //
@Property
var AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider;
- private NetconfDeviceSchemaContextProvider schemaContextProvider
+ @Property
+ private NetconfDeviceSchemaContextProvider deviceContextProvider
protected val Logger logger
@Property
var NetconfClientDispatcher dispatcher
-
+
static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
+ @Property
+ var SchemaSourceProvider<InputStream> remoteSourceProvider
+
public new(String name) {
this.name = name;
this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name);
checkState(schemaSourceProvider != null, "Schema Source Provider must be set.")
checkState(eventExecutor != null, "Event executor must be set.");
- val listener = new NetconfDeviceListener(this,eventExecutor);
+ val listener = new NetconfDeviceListener(this, eventExecutor);
val task = startClientTask(dispatcher, listener)
- if(mountInstance != null) {
+ if (mountInstance != null) {
confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+ commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
}
return processingExecutor.submit(task) as Future<Void>;
}
def Optional<SchemaContext> getSchemaContext() {
- if (schemaContextProvider == null) {
+ if (deviceContextProvider == null) {
return Optional.absent();
}
- return schemaContextProvider.currentContext;
+ return deviceContextProvider.currentContext;
}
private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
+
return [ |
logger.info("Starting Netconf Client on: {}", socketAddress);
client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
logger.debug("Initial capabilities {}", initialCapabilities);
var SchemaSourceProvider<String> delegate;
- if (initialCapabilities.contains(NetconfMapping.IETF_NETCONF_MONITORING_MODULE)) {
- delegate = new NetconfDeviceSchemaSourceProvider(this);
+ if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+ delegate = new NetconfRemoteSchemaSourceProvider(this);
+ } else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
+ delegate = new NetconfRemoteSchemaSourceProvider(this);
} else {
- logger.info("Device does not support IETF Netconf Monitoring.", socketAddress);
+ logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
delegate = SchemaSourceProviders.<String>noopProvider();
}
- val sourceProvider = schemaSourceProvider.createInstanceFor(delegate);
- schemaContextProvider = new NetconfDeviceSchemaContextProvider(this, sourceProvider);
- schemaContextProvider.createContextFromCapabilities(initialCapabilities);
+ remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+ deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+ deviceContextProvider.createContextFromCapabilities(initialCapabilities);
if (mountInstance != null && schemaContext.isPresent) {
mountInstance.schemaContext = schemaContext.get();
}
override getSupportedRpcs() {
Collections.emptySet;
}
-
+
def createSubscription(String streamName) {
val it = ImmutableCompositeNode.builder()
QName = NETCONF_CREATE_SUBSCRIPTION_QNAME
- addLeaf("stream",streamName);
- invokeRpc(QName,toInstance())
+ addLeaf("stream", streamName);
+ invokeRpc(QName, toInstance())
}
override invokeRpc(QName rpc, CompositeNode input) {
- val message = rpc.toRpcMessage(input);
- val result = client.sendMessage(message, messegeRetryCount, messageTimeoutCount);
- return result.toRpcResult();
+ try {
+ val message = rpc.toRpcMessage(input,schemaContext);
+ val result = sendMessageImpl(message, messegeRetryCount, messageTimeoutCount);
+ return result.toRpcResult(rpc, schemaContext);
+
+ } catch (Exception e) {
+ logger.error("Rpc was not processed correctly.", e)
+ throw e;
+ }
+ }
+
+ def NetconfMessage sendMessageImpl(NetconfMessage message, int retryCount, int timeout) {
+ logger.debug("Send message {}",XmlUtil.toString(message.document))
+ val result = client.sendMessage(message, retryCount, timeout);
+ NetconfMapping.checkValidReply(message, result)
+ return result;
}
override getProviderFunctionality() {
return null === transaction.readOperationalData(path);
}
- def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
+ static def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
var Node<?> current = node;
for (arg : identifier.path) {
return null;
} else if (current instanceof CompositeNode) {
val currentComposite = (current as CompositeNode);
-
- current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
- if (current == null) {
- current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+
+ current = currentComposite.getFirstCompositeByName(arg.nodeType);
+ if(current == null) {
+ current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
+ }
+ if(current == null) {
+ current = currentComposite.getFirstSimpleByName(arg.nodeType);
}
if (current == null) {
+ current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
+ } if (current == null) {
return null;
}
}
}
override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification);
+ twoPhaseCommit.prepare()
+ return twoPhaseCommit;
}
def getInitialCapabilities() {
val parts = split("\\?");
val namespace = parts.get(0);
val queryParams = FluentIterable.from(parts.get(1).split("&"));
- val revision = queryParams.findFirst[startsWith("revision=")].replaceAll("revision=", "");
- val moduleName = queryParams.findFirst[startsWith("module=")].replaceAll("module=", "");
+ var revision = queryParams.findFirst[startsWith("revision=")]?.replaceAll("revision=", "");
+ val moduleName = queryParams.findFirst[startsWith("module=")]?.replaceAll("module=", "");
+ if (revision === null) {
+ logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision=");
+ revision = queryParams.findFirst[startsWith("&revision=")]?.replaceAll("revision=", "");
+ if (revision != null) {
+ logger.warn("Netconf device returned revision incorectly escaped for {}", it)
+ }
+ }
+ if (revision == null) {
+ return QName.create(URI.create(namespace), null, moduleName);
+ }
return QName.create(namespace, revision, moduleName);
].toSet();
}
}
-package class NetconfDeviceListener extends NetconfClientSessionListener {
-
- val NetconfDevice device
- val EventExecutor eventExecutor
-
- new(NetconfDevice device,EventExecutor eventExecutor) {
- this.device = device
- this.eventExecutor = eventExecutor
- }
-
- var Promise<NetconfMessage> messagePromise;
- val promiseLock = new ReentrantLock;
-
- override onMessage(NetconfClientSession session, NetconfMessage message) {
- if (isNotification(message)) {
- onNotification(session, message);
- } else try {
- promiseLock.lock
- if (messagePromise != null) {
- messagePromise.setSuccess(message);
- messagePromise = null;
- }
- } finally {
- promiseLock.unlock
- }
- }
-
- /**
- * Method intended to customize notification processing.
- *
- * @param session
- * {@see
- * NetconfClientSessionListener#onMessage(NetconfClientSession,
- * NetconfMessage)}
- * @param message
- * {@see
- * NetconfClientSessionListener#onMessage(NetconfClientSession,
- * NetconfMessage)}
- */
- def void onNotification(NetconfClientSession session, NetconfMessage message) {
- device.logger.debug("Received NETCONF notification.",message);
- val domNotification = message?.toCompositeNode?.notificationBody;
- if(domNotification != null) {
- device?.mountInstance?.publish(domNotification);
- }
- }
-
- private static def CompositeNode getNotificationBody(CompositeNode node) {
- for(child : node.children) {
- if(child instanceof CompositeNode) {
- return child as CompositeNode;
- }
- }
- }
-
- override getLastMessage(int attempts, int attemptMsDelay) throws InterruptedException {
- val promise = promiseReply();
- val messageAvailable = promise.await(attempts + attemptMsDelay);
- if (messageAvailable) {
- try {
- return promise.get();
- } catch (ExecutionException e) {
- throw new IllegalStateException(e);
- }
- }
-
- throw new IllegalStateException("Unsuccessful after " + attempts + " attempts.");
-
- // throw new TimeoutException("Message was not received on time.");
- }
-
- def Promise<NetconfMessage> promiseReply() {
- promiseLock.lock
- try {
- if (messagePromise == null) {
- messagePromise = eventExecutor.newPromise();
- return messagePromise;
- }
- return messagePromise;
- } finally {
- promiseLock.unlock
- }
- }
-
- def boolean isNotification(NetconfMessage message) {
- val xmle = XmlElement.fromDomDocument(message.getDocument());
- return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName());
- }
-}
-
package class NetconfDeviceSchemaContextProvider {
@Property
new(NetconfDevice device, SchemaSourceProvider<InputStream> sourceProvider) {
_device = device
_sourceProvider = sourceProvider
+ _currentContext = Optional.absent();
}
def createContextFromCapabilities(Iterable<QName> capabilities) {
-
- val modelsToParse = ImmutableMap.<QName, InputStream>builder();
- for (cap : capabilities) {
- val source = sourceProvider.getSchemaSource(cap.localName, Optional.fromNullable(cap.formattedRevision));
- if (source.present) {
- modelsToParse.put(cap, source.get());
- }
+ val sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider)
+ if (!sourceContext.missingSources.empty) {
+ device.logger.warn("Sources for following models are missing {}", sourceContext.missingSources);
+ }
+ device.logger.debug("Trying to create schema context from {}", sourceContext.validSources)
+ val modelsToParse = YangSourceContext.getValidInputStreams(sourceContext);
+ if (!sourceContext.validSources.empty) {
+ val schemaContext = tryToCreateContext(modelsToParse);
+ currentContext = Optional.fromNullable(schemaContext);
+ } else {
+ currentContext = Optional.absent();
}
- val context = tryToCreateContext(modelsToParse.build);
- currentContext = Optional.fromNullable(context);
+ if (currentContext.present) {
+ device.logger.debug("Schema context successfully created.");
+ }
+
}
- def SchemaContext tryToCreateContext(Map<QName, InputStream> modelsToParse) {
+ def SchemaContext tryToCreateContext(List<InputStream> modelsToParse) {
val parser = new YangParserImpl();
try {
- val models = parser.parseYangModelsFromStreams(ImmutableList.copyOf(modelsToParse.values));
+
+ val models = parser.parseYangModelsFromStreams(modelsToParse);
val result = parser.resolveSchemaContext(models);
return result;
} catch (Exception e) {
}
}
}
-
-package class NetconfDeviceSchemaSourceProvider implements SchemaSourceProvider<String> {
-
- val NetconfDevice device;
-
- new(NetconfDevice device) {
- this.device = device;
- }
-
- override getSchemaSource(String moduleName, Optional<String> revision) {
- val it = ImmutableCompositeNode.builder() //
- setQName(QName::create(NetconfState.QNAME, "get-schema")) //
- addLeaf("format", "yang")
- addLeaf("identifier", moduleName)
- if (revision.present) {
- addLeaf("version", revision.get())
- }
-
- device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision)
- val schemaReply = device.invokeRpc(getQName(), toInstance());
-
- if (schemaReply.successful) {
- val schemaBody = schemaReply.result.getFirstSimpleByName(
- QName::create(NetconfState.QNAME.namespace, null, "data"))?.value;
- device.logger.info("YANG Schema successfully received for: {}:{}", moduleName, revision);
- return Optional.of(schemaBody as String);
- }
- return Optional.absent();
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import com.google.common.base.Objects;
+
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.Promise;
+
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClientSession;
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfMapping;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.w3c.dom.Document;
+
+@SuppressWarnings("all")
+class NetconfDeviceListener extends NetconfClientSessionListener {
+ private final NetconfDevice device;
+ private final EventExecutor eventExecutor;
+
+ public NetconfDeviceListener(final NetconfDevice device, final EventExecutor eventExecutor) {
+ this.device = device;
+ this.eventExecutor = eventExecutor;
+ }
+
+ private Promise<NetconfMessage> messagePromise;
+ private ConcurrentMap<String, Promise<NetconfMessage>> promisedMessages;
+
+ private final ReentrantLock promiseLock = new ReentrantLock();
+
+ public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
+ if (isNotification(message)) {
+ this.onNotification(session, message);
+ } else {
+ try {
+ this.promiseLock.lock();
+ boolean _notEquals = (!Objects.equal(this.messagePromise, null));
+ if (_notEquals) {
+ this.device.logger.debug("Setting promised reply {} with message {}", this.messagePromise, message);
+ this.messagePromise.setSuccess(message);
+ this.messagePromise = null;
+ }
+ } finally {
+ this.promiseLock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Method intended to customize notification processing.
+ *
+ * @param session
+ * {@see
+ * NetconfClientSessionListener#onMessage(NetconfClientSession,
+ * NetconfMessage)}
+ * @param message
+ * {@see
+ * NetconfClientSessionListener#onMessage(NetconfClientSession,
+ * NetconfMessage)}
+ */
+ public void onNotification(final NetconfClientSession session, final NetconfMessage message) {
+ this.device.logger.debug("Received NETCONF notification.", message);
+ CompositeNode _notificationBody = null;
+ CompositeNode _compositeNode = null;
+ if (message != null) {
+ _compositeNode = NetconfMapping.toCompositeNode(message,device.getSchemaContext());
+ }
+ if (_compositeNode != null) {
+ _notificationBody = NetconfDeviceListener.getNotificationBody(_compositeNode);
+ }
+ final CompositeNode domNotification = _notificationBody;
+ boolean _notEquals = (!Objects.equal(domNotification, null));
+ if (_notEquals) {
+ MountProvisionInstance _mountInstance = null;
+ if (this.device != null) {
+ _mountInstance = this.device.getMountInstance();
+ }
+ if (_mountInstance != null) {
+ _mountInstance.publish(domNotification);
+ }
+ }
+ }
+
+ private static CompositeNode getNotificationBody(final CompositeNode node) {
+ List<Node<? extends Object>> _children = node.getChildren();
+ for (final Node<? extends Object> child : _children) {
+ if ((child instanceof CompositeNode)) {
+ return ((CompositeNode) child);
+ }
+ }
+ return null;
+ }
+
+ public NetconfMessage getLastMessage(final int attempts, final int attemptMsDelay) throws InterruptedException {
+ final Promise<NetconfMessage> promise = this.promiseReply();
+ this.device.logger.debug("Waiting for reply {}", promise);
+ int _plus = (attempts * attemptMsDelay);
+ final boolean messageAvailable = promise.await(_plus);
+ if (messageAvailable) {
+ try {
+ try {
+ return promise.get();
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ } catch (final Throwable _t) {
+ if (_t instanceof ExecutionException) {
+ final ExecutionException e = (ExecutionException) _t;
+ IllegalStateException _illegalStateException = new IllegalStateException(e);
+ throw _illegalStateException;
+ } else {
+ throw Exceptions.sneakyThrow(_t);
+ }
+ }
+ }
+ String _plus_1 = ("Unsuccessful after " + Integer.valueOf(attempts));
+ String _plus_2 = (_plus_1 + " attempts.");
+ IllegalStateException _illegalStateException_1 = new IllegalStateException(_plus_2);
+ throw _illegalStateException_1;
+ }
+
+ public synchronized Promise<NetconfMessage> promiseReply() {
+ this.device.logger.debug("Promising reply.");
+ this.promiseLock.lock();
+ try {
+ boolean _equals = Objects.equal(this.messagePromise, null);
+ if (_equals) {
+ Promise<NetconfMessage> _newPromise = this.eventExecutor.<NetconfMessage> newPromise();
+ this.messagePromise = _newPromise;
+ return this.messagePromise;
+ }
+ return this.messagePromise;
+ } finally {
+ this.promiseLock.unlock();
+ }
+ }
+
+ public boolean isNotification(final NetconfMessage message) {
+ Document _document = message.getDocument();
+ final XmlElement xmle = XmlElement.fromDomDocument(_document);
+ String _name = xmle.getName();
+ return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(_name);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*;
+
+public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
+
+ private NetconfDevice device;
+ private final DataModification<InstanceIdentifier, CompositeNode> modification;
+ private boolean candidateSupported = true;
+
+ public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
+ DataModification<InstanceIdentifier, CompositeNode> modification) {
+ super();
+ this.device = device;
+ this.modification = modification;
+ }
+
+ public void prepare() {
+ for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) {
+ sendRemove(toRemove);
+ }
+ for(Entry<InstanceIdentifier, CompositeNode> toUpdate : modification.getUpdatedConfigurationData().entrySet()) {
+ sendMerge(toUpdate.getKey(),toUpdate.getValue());
+ }
+
+ }
+
+ private void sendMerge(InstanceIdentifier key, CompositeNode value) {
+ sendEditRpc(createEditStructure(key, Optional.<String>absent(), Optional.of(value)));
+ }
+
+ private void sendRemove(InstanceIdentifier toRemove) {
+ sendEditRpc(createEditStructure(toRemove, Optional.of("remove"), Optional.<CompositeNode> absent()));
+ }
+
+ private void sendEditRpc(CompositeNode editStructure) {
+ CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
+ builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
+ builder.add(editStructure);
+
+ RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance());
+ Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful");
+
+ }
+
+ private CompositeNodeBuilder<ImmutableCompositeNode> configurationRpcBuilder() {
+ CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+
+ Node<?> targetNode;
+ if(candidateSupported) {
+ targetNode = ImmutableCompositeNode.create(NETCONF_CANDIDATE_QNAME, ImmutableList.<Node<?>>of());
+ } else {
+ targetNode = ImmutableCompositeNode.create(NETCONF_RUNNING_QNAME, ImmutableList.<Node<?>>of());
+ }
+ Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
+ ret.add(targetWrapperNode);
+ return ret;
+ }
+
+ private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional<String> action,
+ Optional<CompositeNode> lastChildOverride) {
+ List<PathArgument> path = dataPath.getPath();
+ List<PathArgument> reversed = Lists.reverse(path);
+ CompositeNode previous = null;
+ boolean isLast = true;
+ for (PathArgument arg : reversed) {
+ CompositeNodeBuilder<ImmutableCompositeNode> builder = ImmutableCompositeNode.builder();
+ builder.setQName(arg.getNodeType());
+ Map<QName, Object> predicates = Collections.emptyMap();
+ if (arg instanceof NodeIdentifierWithPredicates) {
+ predicates = ((NodeIdentifierWithPredicates) arg).getKeyValues();
+ }
+ for (Entry<QName, Object> entry : predicates.entrySet()) {
+ builder.addLeaf(entry.getKey(), entry.getValue());
+ }
+
+ if (isLast) {
+ if (action.isPresent()) {
+ builder.setAttribute(NETCONF_ACTION_QNAME, action.get());
+ }
+ if (lastChildOverride.isPresent()) {
+ List<Node<?>> children = lastChildOverride.get().getChildren();
+ for(Node<?> child : children) {
+ if(!predicates.containsKey(child.getKey())) {
+ builder.add(child);
+ }
+ }
+
+ }
+ } else {
+ builder.add(previous);
+ }
+ previous = builder.toInstance();
+ isLast = false;
+ }
+ return ImmutableCompositeNode.create(NETCONF_CONFIG_QNAME, ImmutableList.<Node<?>>of(previous));
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
+ commitInput.setQName(NETCONF_COMMIT_QNAME);
+ RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance());
+ return (RpcResult<Void>) rpcResult;
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+ return this.modification;
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
import com.google.common.collect.ImmutableList
import org.opendaylight.yangtools.yang.data.api.SimpleNode
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import com.google.common.base.Preconditions
+import com.google.common.base.Optional
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils
class NetconfMapping {
public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+ public static val NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
+ public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config");
+ public static val NETCONF_ACTION_QNAME = QName.create(NETCONF_QNAME, "action");
+ public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
+
+ public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+ public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
+
+ public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+
+
public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
}
}
- static def CompositeNode toCompositeNode(NetconfMessage message) {
- return message.toRpcResult().result;
+ static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> ctx) {
+ return null//message.toRpcResult().result;
}
- static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
+ static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional<SchemaContext> ctx) {
val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement);
}
- static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
- val rawRpc = message.document.toCompositeNode() as CompositeNode;
-
+ static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message,QName rpc,Optional<SchemaContext> context) {
+ var CompositeNode rawRpc;
+ if(context.present) {
+ if(isDataRetrievalReply(rpc)) {
+
+ val xmlData = message.document.dataSubtree
+ val dataNodes = XmlDocumentUtils.toDomNodes(xmlData,Optional.of(context.get.dataDefinitions))
+
+ val it = ImmutableCompositeNode.builder()
+ setQName(NETCONF_RPC_REPLY_QNAME)
+ add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME,dataNodes));
+
+ rawRpc = it.toInstance;
+ //sys(xmlData)
+ } else {
+ val rpcSchema = context.get.operations.findFirst[QName == rpc]
+ rawRpc = message.document.toCompositeNode() as CompositeNode;
+ }
+
+
+
+ } else {
+ rawRpc = message.document.toCompositeNode() as CompositeNode;
+ }
//rawRpc.
return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet());
}
+
+ def static Element getDataSubtree(Document doc) {
+ doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element
+ }
+
+ def static boolean isDataRetrievalReply(QName it) {
+ return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName)
+ }
static def wrap(QName name, Node<?> node) {
if (node != null) {
}
public static def Node<?> toCompositeNode(Document document) {
- return XmlDocumentUtils.toNode(document) as Node<?>
+ return XmlDocumentUtils.toDomNode(document) as Node<?>
}
+
+ public static def checkValidReply(NetconfMessage input, NetconfMessage output) {
+ val inputMsgId = input.document.documentElement.getAttribute("message-id")
+ val outputMsgId = output.document.documentElement.getAttribute("message-id")
+ Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same.");
+
+ }
+
}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+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.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider<String> {
+
+ public static final QName IETF_NETCONF_MONITORING = QName.create(
+ "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+ public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
+ public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
+
+ NetconfDevice device;
+
+ public NetconfRemoteSchemaSourceProvider(NetconfDevice device) {
+ super();
+ this.device = device;
+ }
+
+ @Override
+ public Optional<String> getSchemaSource(String moduleName, Optional<String> revision) {
+ CompositeNodeBuilder<ImmutableCompositeNode> request = ImmutableCompositeNode.builder(); //
+ request.setQName(GET_SCHEMA_QNAME) //
+ .addLeaf("format", "yang") //
+ .addLeaf("identifier", moduleName); //
+ if (revision.isPresent()) {
+ request.addLeaf("version", revision.get());
+ }
+
+ device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+ RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
+ if (schemaReply.isSuccessful()) {
+ String schemaBody = getSchemaFromRpc(schemaReply.getResult());
+ if (schemaBody != null) {
+ device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+ return Optional.of(schemaBody);
+ }
+ }
+ device.logger.info("YANG shcema was not successfully retrieved.");
+ return Optional.absent();
+ }
+
+ private String getSchemaFromRpc(CompositeNode result) {
+ if (result == null) {
+ return null;
+ }
+ SimpleNode<?> simpleNode = result.getFirstSimpleByName(GET_DATA_QNAME.withoutRevision());
+ Object potential = simpleNode.getValue();
+ if (potential instanceof String) {
+ return (String) potential;
+ }
+ return null;
+ }
+
+ public static final boolean isSupportedFor(Set<QName> capabilities) {
+ return capabilities.contains(IETF_NETCONF_MONITORING);
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.sal.connect.netconf;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import com.google.common.base.Strings;
-
-public class XmlDocumentUtils {
-
- public static Node<?> toNode(Document doc) {
- return toCompositeNode(doc.getDocumentElement());
- }
-
- private static Node<?> toCompositeNode(Element element) {
- String orgNamespace = element.getNamespaceURI();
- URI biNamespace = null;
- if (orgNamespace != null) {
- biNamespace = URI.create(orgNamespace);
- }
- QName qname = new QName(biNamespace, element.getLocalName());
-
- List<Node<?>> values = new ArrayList<>();
- NodeList nodes = element.getChildNodes();
- boolean isSimpleObject = true;
- String value = null;
- for (int i = 0; i < nodes.getLength(); i++) {
- org.w3c.dom.Node child = nodes.item(i);
- if (child instanceof Element) {
- isSimpleObject = false;
- values.add(toCompositeNode((Element) child));
- }
- if (isSimpleObject && child instanceof org.w3c.dom.Text) {
- value = element.getTextContent();
- if (!Strings.isNullOrEmpty(value)) {
- isSimpleObject = true;
- }
- }
- }
-
- if (isSimpleObject) {
- return new SimpleNodeTOImpl<>(qname, null, value);
- }
- return new CompositeNodeTOImpl(qname, null, values);
- }
-}
import org.opendaylight.yangtools.yang.data.api.CompositeNode
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
LOG.info("Read Configuration via Restconf: {}", path)
return dataService.readConfigurationData(path);
}
+
+ def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ LOG.info("Read Configuration via Restconf: {}", path)
+ return mountPoint.readConfigurationData(path);
+ }
override readOperationalData(InstanceIdentifier path) {
checkPreconditions
LOG.info("Read Operational via Restconf: {}", path)
return dataService.readOperationalData(path);
}
+
+ def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ LOG.info("Read Operational via Restconf: {}", path)
+ return mountPoint.readOperationalData(path);
+ }
def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
checkPreconditions
transaction.putConfigurationData(path, payload);
return transaction.commit
}
+
+ def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
+ LOG.info("Put Configuration via Restconf: {}", path)
+ transaction.putConfigurationData(path, payload);
+ return transaction.commit
+ }
def commitConfigurationDataPost(InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
return null;
}
+
+ def commitConfigurationDataPostBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
+ transaction.putConfigurationData(path, payload);
+ if (payload == transaction.createdConfigurationData.get(path)) {
+ LOG.info("Post Configuration via Restconf: {}", path)
+ return transaction.commit
+ }
+ LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ return null;
+ }
def commitConfigurationDataDelete(InstanceIdentifier path) {
checkPreconditions
transaction.removeConfigurationData(path)
return transaction.commit
}
+
+ def commitConfigurationDataDeleteBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+ checkPreconditions
+ val transaction = mountPoint.beginTransaction;
+ transaction.removeConfigurationData(path)
+ return transaction.commit
+ }
}
import java.util.List
import java.util.Map
import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.core.Response
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
import org.opendaylight.controller.sal.core.api.mount.MountService
import org.opendaylight.controller.sal.rest.impl.RestUtil
import org.slf4j.LoggerFactory
import static com.google.common.base.Preconditions.*
-import java.util.ArrayList
+import static javax.ws.rs.core.Response.Status.*
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
class ControllerContext implements SchemaServiceListener {
val static LOG = LoggerFactory.getLogger(ControllerContext)
val static ControllerContext INSTANCE = new ControllerContext
val static NULL_VALUE = "null"
+ val static MOUNT_MODULE = "yang-ext"
+ val static MOUNT_NODE = "mount"
+ val static MOUNT = "yang-ext:mount"
@Property
var SchemaContext globalSchema;
private def void checkPreconditions() {
if (globalSchema === null) {
- throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
+ throw new ResponseException(SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
}
}
public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
checkPreconditions
- val ret = InstanceIdentifier.builder();
val pathArgs = restconfInstance.split("/");
if (pathArgs.empty) {
return null;
if (pathArgs.head.empty) {
pathArgs.remove(0)
}
- val mountPoints = new ArrayList
- val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head), mountPoints);
- if (schemaNode === null) {
- return null
+ val startModule = pathArgs.head.toModuleName();
+ if (startModule === null) {
+ throw new ResponseException(BAD_REQUEST, "First node in URI has to be in format \"moduleName:nodeName\"")
}
- return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode, mountPoints.last)
+ val iiWithSchemaNode = collectPathArguments(InstanceIdentifier.builder(), pathArgs,
+ globalSchema.getLatestModule(startModule), null);
+ if (iiWithSchemaNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format")
+ }
+ return iiWithSchemaNode
}
- private def findModule(SchemaContext context,String argument) {
- checkNotNull(argument);
- val startModule = argument.toModuleName();
- return context.getLatestModule(startModule)
- }
-
- private def getLatestModule(SchemaContext schema,String moduleName) {
+ private def getLatestModule(SchemaContext schema, String moduleName) {
checkArgument(schema !== null);
checkArgument(moduleName !== null && !moduleName.empty)
val modules = schema.modules.filter[m|m.name == moduleName]
return globalSchema.getLatestModule(moduleName)
}
- def findModuleByName(String moduleName, InstanceIdentifier partialPath) {
- checkArgument(moduleName !== null && !moduleName.empty && partialPath !== null && !partialPath.path.empty)
- val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
+ def findModuleByName(MountInstance mountPoint, String moduleName) {
+ checkArgument(moduleName !== null && mountPoint !== null)
+ val mountPointSchema = mountPoint.schemaContext;
return mountPointSchema?.getLatestModule(moduleName);
}
return moduleSchemas?.filterLatestModule
}
- def findModuleByNamespace(URI namespace, InstanceIdentifier partialPath) {
- checkArgument(namespace !== null && !namespace.toString.empty && partialPath !== null && !partialPath.path.empty)
- val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
+ def findModuleByNamespace(MountInstance mountPoint, URI namespace) {
+ checkArgument(namespace !== null && mountPoint !== null)
+ val mountPointSchema = mountPoint.schemaContext;
val moduleSchemas = mountPointSchema?.findModuleByNamespace(namespace)
return moduleSchemas?.filterLatestModule
}
if(object === null) return "";
return URLEncoder.encode(object.toString)
}
-
- private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
- DataNodeContainer parentNode, List<InstanceIdentifier> mountPoints) {
+
+ private def InstanceIdWithSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
+ DataNodeContainer parentNode, MountInstance mountPoint) {
checkNotNull(strings)
if (parentNode === null) {
return null;
}
if (strings.empty) {
- return parentNode as DataSchemaNode;
- }
- val nodeRef = strings.head;
-
- val nodeName = nodeRef.toNodeName;
- var targetNode = parentNode.findInstanceDataChild(nodeName);
- if (targetNode instanceof ChoiceNode) {
- return null
+ return new InstanceIdWithSchemaNode(builder.toInstance, parentNode as DataSchemaNode, mountPoint)
}
- if (targetNode === null) {
- // Node is possibly in other mount point
- val partialPath = builder.toInstance;
- val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
- if(mountPointSchema !== null) {
- val module = mountPointSchema.findModule(strings.head)
- if (module !== null) {
- mountPoints.add(partialPath)
+ val nodeName = strings.head.toNodeName
+ val moduleName = strings.head.toModuleName
+ var DataSchemaNode targetNode = null
+ if (!moduleName.nullOrEmpty) {
+ // if it is mount point
+ if (moduleName == MOUNT_MODULE && nodeName == MOUNT_NODE) {
+ if (mountPoint !== null) {
+ throw new ResponseException(BAD_REQUEST, "Restconf supports just one mount point in URI.")
+ }
+
+ if (mountService === null) {
+ throw new ResponseException(SERVICE_UNAVAILABLE, "MountService was not found. "
+ + "Finding behind mount points does not work."
+ )
+ }
+
+ val partialPath = builder.toInstance;
+ val mount = mountService.getMountPoint(partialPath)
+ if (mount === null) {
+ LOG.debug("Instance identifier to missing mount point: {}", partialPath)
+ throw new ResponseException(BAD_REQUEST, "Mount point does not exist.")
+ }
+
+ val mountPointSchema = mount.schemaContext;
+ if (mountPointSchema === null) {
+ throw new ResponseException(BAD_REQUEST, "Mount point does not contain any schema with modules.")
+ }
+
+ if (strings.size == 1) { // any data node is not behind mount point
+ return new InstanceIdWithSchemaNode(InstanceIdentifier.builder().toInstance, mountPointSchema, mount)
+ }
+
+ val moduleNameBehindMountPoint = strings.get(1).toModuleName()
+ if (moduleNameBehindMountPoint === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "First node after mount point in URI has to be in format \"moduleName:nodeName\"")
+ }
+
+ val moduleBehindMountPoint = mountPointSchema.getLatestModule(moduleNameBehindMountPoint)
+ if (moduleBehindMountPoint === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+ }
+
+ return collectPathArguments(InstanceIdentifier.builder(), strings.subList(1, strings.size),
+ moduleBehindMountPoint, mount);
+ }
+
+ var Module module = null;
+ if (mountPoint === null) {
+ module = globalSchema.getLatestModule(moduleName)
+ if (module === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist.")
}
- return builder.collectPathArguments(strings, module, mountPoints);
+ } else {
+ module = mountPoint.schemaContext?.getLatestModule(moduleName)
+ if (module === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+ }
+ }
+ targetNode = parentNode.findInstanceDataChild(nodeName, module.namespace)
+ if (targetNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. Possible reasons:\n" +
+ "1. \"" + strings.head + "\" was not found in parent data node.\n" +
+ "2. \"" + strings.head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + strings.head + "\".")
+ }
+ } else { // string without module name
+ targetNode = parentNode.findInstanceDataChild(nodeName, null)
+ if (targetNode === null) {
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. \"" + nodeName + "\" was not found in parent data node.\n")
}
- return null
}
-
// Number of consumed elements
var consumed = 1;
if (targetNode instanceof ListSchemaNode) {
// every key has to be filled
if ((strings.length - consumed) < keysSize) {
- return null;
+ throw new ResponseException(BAD_REQUEST,"Missing key for list \"" + listNode.QName.localName + "\".")
}
val uriKeyValues = strings.subList(consumed, consumed + keysSize);
val keyValues = new HashMap<QName, Object>();
// key value cannot be NULL
if (uriKeyValue.equals(NULL_VALUE)) {
- return null
+ throw new ResponseException(BAD_REQUEST, "URI has bad format. List \"" + listNode.QName.localName
+ + "\" cannot contain \"null\" value as a key."
+ )
}
keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue);
i = i + 1;
}
if (targetNode instanceof DataNodeContainer) {
val remaining = strings.subList(consumed, strings.length);
- val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoints);
+ val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoint);
return result
}
- return targetNode
+ return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint)
}
-
- static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) {
- // FIXME: Add namespace comparison
- var potentialNode = container.getDataChildByName(name);
- if(potentialNode.instantiatedDataSchema) {
+
+ def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name, URI moduleNamespace) {
+ var DataSchemaNode potentialNode = null
+ if (moduleNamespace === null) {
+ potentialNode = container.getDataChildByName(name);
+ } else {
+ potentialNode = container.childNodes.filter[n|n.QName.localName == name && n.QName.namespace == moduleNamespace].head
+ }
+
+ if (potentialNode.instantiatedDataSchema) {
return potentialNode;
}
val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten
for (caze : allCases) {
- potentialNode = caze.findInstanceDataChild(name);
- if(potentialNode !== null) {
+ potentialNode = caze.findInstanceDataChild(name, moduleNamespace);
+ if (potentialNode !== null) {
return potentialNode;
}
}
checkNotNull(str)
if (str.contains(":")) {
val args = str.split(":");
- checkArgument(args.size === 2);
- return args.get(0);
- } else {
- return null;
+ if (args.size === 2) {
+ return args.get(0);
+ }
}
+ return null;
}
private def String toNodeName(String str) {
if (str.contains(":")) {
val args = str.split(":");
- checkArgument(args.size === 2);
- return args.get(1);
- } else {
- return str;
+ if (args.size === 2) {
+ return args.get(1);
+ }
}
+ return str;
}
private def QName toQName(String name) {
package org.opendaylight.controller.sal.restconf.impl;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
private final InstanceIdentifier instanceIdentifier;
private final DataSchemaNode schemaNode;
- private final InstanceIdentifier mountPoint;
+ private final MountInstance mountPoint;
- public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, InstanceIdentifier mountPoint) {
+ public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) {
this.instanceIdentifier = instanceIdentifier;
this.schemaNode = schemaNode;
this.mountPoint = mountPoint;
return schemaNode;
}
- public InstanceIdentifier getMountPoint() {
+ public MountInstance getMountPoint() {
return mountPoint;
}
package org.opendaylight.controller.sal.restconf.impl
+import com.google.common.base.Preconditions
+import java.net.URI
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Set
import javax.ws.rs.core.Response
import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
import org.opendaylight.controller.sal.rest.api.RestconfService
import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
import org.opendaylight.yangtools.yang.data.api.CompositeNode
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
import org.opendaylight.yangtools.yang.model.api.Module
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
import org.opendaylight.yangtools.yang.model.api.TypeDefinition
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
import static javax.ws.rs.core.Response.Status.*
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition
class RestconfImpl implements RestconfService {
}
override readData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.instanceIdentifier)
+ } else {
+ data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
}
override readConfigurationData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readConfigurationData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readConfigurationDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+ } else {
+ data = broker.readConfigurationData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
}
override readOperationalData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
- return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ val iiWithData = identifier.toInstanceIdentifier
+ var CompositeNode data = null;
+ if (iiWithData.mountPoint !== null) {
+ data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+ } else {
+ data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+ }
+ return new StructuredData(data, iiWithData.schemaNode)
}
override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
}
override updateConfigurationData(String identifier, CompositeNode payload) {
- val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode, identifierWithSchemaNode.mountPoint)
- val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
+ val iiWithData = identifier.toInstanceIdentifier
+ val value = normalizeNode(payload, iiWithData.schemaNode, iiWithData.mountPoint)
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPutBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.instanceIdentifier, value).get()
+ } else {
+ status = broker.commitConfigurationDataPut(iiWithData.instanceIdentifier, value).get();
+ }
switch status.result {
case TransactionStatus.COMMITED: Response.status(OK).build
default: Response.status(INTERNAL_SERVER_ERROR).build
}
override createConfigurationData(String identifier, CompositeNode payload) {
- val uncompleteIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- var schemaNode = (uncompleteIdentifierWithSchemaNode.schemaNode as DataNodeContainer).getSchemaChildNode(payload)
- if (schemaNode === null) {
- schemaNode = payload.findModule(uncompleteIdentifierWithSchemaNode.instanceIdentifier)?.getSchemaChildNode(payload)
- }
- val value = normalizeNode(payload, schemaNode, uncompleteIdentifierWithSchemaNode.instanceIdentifier)
- val completeIdentifierWithSchemaNode = uncompleteIdentifierWithSchemaNode.addLastIdentifierFromData(value, schemaNode)
- val status = broker.commitConfigurationDataPost(completeIdentifierWithSchemaNode.instanceIdentifier, value)?.get();
+ if (payload.namespace === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+ }
+ val uncompleteInstIdWithData = identifier.toInstanceIdentifier
+ val schemaNode = uncompleteInstIdWithData.mountPoint.findModule(payload)?.getSchemaChildNode(payload)
+ val value = normalizeNode(payload, schemaNode, uncompleteInstIdWithData.mountPoint)
+ val completeInstIdWithData = uncompleteInstIdWithData.addLastIdentifierFromData(value, schemaNode)
+ var RpcResult<TransactionStatus> status = null
+ if (completeInstIdWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPostBehindMountPoint(completeInstIdWithData.mountPoint,
+ completeInstIdWithData.instanceIdentifier, value)?.get();
+ } else {
+ status = broker.commitConfigurationDataPost(completeInstIdWithData.instanceIdentifier, value)?.get();
+ }
if (status === null) {
return Response.status(ACCEPTED).build
}
}
override createConfigurationData(CompositeNode payload) {
- val schemaNode = payload.findModule(null)?.getSchemaChildNode(payload)
+ if (payload.namespace === null) {
+ throw new ResponseException(BAD_REQUEST,
+ "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+ }
+ val schemaNode = findModule(null, payload)?.getSchemaChildNode(payload)
val value = normalizeNode(payload, schemaNode, null)
- val identifierWithSchemaNode = addLastIdentifierFromData(null, value, schemaNode)
- val status = broker.commitConfigurationDataPost(identifierWithSchemaNode.instanceIdentifier, value)?.get();
+ val iiWithData = addLastIdentifierFromData(null, value, schemaNode)
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataPostBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.instanceIdentifier, value)?.get();
+ } else {
+ status = broker.commitConfigurationDataPost(iiWithData.instanceIdentifier, value)?.get();
+ }
if (status === null) {
return Response.status(ACCEPTED).build
}
}
override deleteConfigurationData(String identifier) {
- val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
- val status = broker.commitConfigurationDataDelete(instanceIdentifierWithSchemaNode.getInstanceIdentifier).get;
+ val iiWithData = identifier.toInstanceIdentifier
+ var RpcResult<TransactionStatus> status = null
+ if (iiWithData.mountPoint !== null) {
+ status = broker.commitConfigurationDataDeleteBehindMountPoint(iiWithData.mountPoint,
+ iiWithData.getInstanceIdentifier).get;
+ } else {
+ status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier).get;
+ }
switch status.result {
case TransactionStatus.COMMITED: Response.status(OK).build
default: Response.status(INTERNAL_SERVER_ERROR).build
}
}
-
- private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
- val identifierWithSchemaNode = identifier.toInstanceIdentifier
- if (identifierWithSchemaNode === null) {
- throw new ResponseException(BAD_REQUEST, "URI has bad format");
- }
- return identifierWithSchemaNode
+
+ private def dispatch URI namespace(CompositeNode data) {
+ return data.nodeType.namespace
+ }
+
+ private def dispatch URI namespace(CompositeNodeWrapper data) {
+ return data.namespace
}
- private def dispatch Module findModule(CompositeNode data, InstanceIdentifier partialPath) {
- if (partialPath !== null && !partialPath.path.empty) {
- return data.nodeType.namespace.findModuleByNamespace(partialPath)
+ private def dispatch Module findModule(MountInstance mountPoint, CompositeNode data) {
+ if (mountPoint !== null) {
+ return mountPoint.findModuleByNamespace(data.nodeType.namespace)
} else {
- return data.nodeType.namespace.findModuleByNamespace
+ return findModuleByNamespace(data.nodeType.namespace)
}
}
- private def dispatch Module findModule(CompositeNodeWrapper data, InstanceIdentifier partialPath) {
+ private def dispatch Module findModule(MountInstance mountPoint, CompositeNodeWrapper data) {
+ Preconditions.checkNotNull(data.namespace)
var Module module = null;
- if (partialPath !== null && !partialPath.path.empty) {
- module = data.namespace.findModuleByNamespace(partialPath) // namespace from XML
+ if (mountPoint !== null) {
+ module = mountPoint.findModuleByNamespace(data.namespace) // namespace from XML
if (module === null) {
- module = data.namespace.toString.findModuleByName(partialPath) // namespace (module name) from JSON
+ module = mountPoint.findModuleByName(data.namespace.toString) // namespace (module name) from JSON
}
} else {
module = data.namespace.findModuleByNamespace // namespace from XML
return parentSchemaNode?.getDataChildByName(data.localName)
}
- private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode, CompositeNode data, DataSchemaNode schemaOfData) {
+ private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode,
+ CompositeNode data, DataSchemaNode schemaOfData) {
val iiOriginal = identifierWithSchemaNode?.instanceIdentifier
- var InstanceIdentifierBuilder iiBuilder = null
- if (iiOriginal === null) {
+ var InstanceIdentifierBuilder iiBuilder = null
+ if (iiOriginal === null) {
iiBuilder = InstanceIdentifier.builder
} else {
iiBuilder = InstanceIdentifier.builder(iiOriginal)
for (key : listNode.keyDefinition) {
val dataNodeKeyValueObject = dataNode.getSimpleNodesByName(key.localName)?.head?.value
if (dataNodeKeyValueObject === null) {
- throw new ResponseException(BAD_REQUEST, "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" + key.localName + "\"")
+ throw new ResponseException(BAD_REQUEST,
+ "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" +
+ key.localName + "\"")
}
keyValues.put(key, dataNodeKeyValueObject);
}
return keyValues
}
- private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, InstanceIdentifier mountPoint) {
- if (schema !== null && !schema.containerOrList) {
+ private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, MountInstance mountPoint) {
+ if (schema === null) {
+ throw new ResponseException(INTERNAL_SERVER_ERROR, "Data schema node was not found for " + node?.nodeType?.localName)
+ }
+ if (!(schema instanceof DataNodeContainer)) {
throw new ResponseException(BAD_REQUEST, "Root element has to be container or list yang datatype.");
}
if (node instanceof CompositeNodeWrapper) {
return node
}
- private def isContainerOrList(DataSchemaNode schemaNode) {
- return (schemaNode instanceof ContainerSchemaNode) || (schemaNode instanceof ListSchemaNode)
- }
-
private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment,
- InstanceIdentifier mountPoint) {
+ MountInstance mountPoint) {
if (schema === null) {
throw new ResponseException(BAD_REQUEST,
"Data has bad format.\n\"" + nodeBuilder.localName + "\" does not exist in yang schema.");
} else if (previousAugment !== null && schema.QName.namespace !== previousAugment.namespace) {
validQName = QName.create(currentAugment, schema.QName.localName);
}
- var moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
- if (moduleName === null && mountPoint !== null && !mountPoint.path.empty) {
- moduleName = controllerContext.findModuleByNamespace(validQName.namespace, mountPoint)?.name
+ var String moduleName = null;
+ if (mountPoint === null) {
+ moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
+ } else {
+ moduleName = mountPoint.findModuleByNamespace(validQName.namespace)?.name
}
if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
nodeBuilder.namespace.toString == moduleName) {
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+ }
+
+ @Test
+ public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException {
+ SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+ String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+ StructuredDataToJsonProvider.INSTANCE);
+
+// String output =
+// String.format("\"data\" : {\n" +
+// "\t\"cont_m1\" : {\n" +
+// "\t\t\"lf1_m1\" : \"lf1 m1 value\"\n" +
+// "\t}\n" +
+// "\t\"cont_m2\" : {\n" +
+// "\t\t\"lf1_m2\" : \"lf1 m2 value\"\n" +
+// "\t}\n" +
+// "}");
+
+ StringBuilder regex = new StringBuilder();
+ regex.append("^");
+
+ regex.append(".*\"data\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+
+ regex.append(".*\"contB_m1\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"cont_m1\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"contB_m2\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\"cont_m2\"");
+ regex.append(".*:");
+ regex.append(".*\\{");
+ regex.append(".*\\}");
+
+ regex.append(".*\\}");
+
+ regex.append(".*");
+ regex.append("$");
+
+ Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+ Matcher matcher = ptrn.matcher(output);
+
+ assertTrue(matcher.find());
+
+ }
+
+ private CompositeNode prepareCnSn() throws URISyntaxException {
+ CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+ URI uriModule1 = new URI("module:one");
+ CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+ SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+ cont_m1.addValue(lf1_m1);
+ CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+
+ data.addValue(contB_m1);
+ data.addValue(cont_m1);
+
+ URI uriModule2 = new URI("module:two");
+ CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+ SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+ cont_m2.addValue(lf1_m2);
+ CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+ data.addValue(contB_m2);
+ data.addValue(cont_m2);
+ return data;
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+ @BeforeClass
+ public static void initialize() {
+ dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+ }
+
+ @Test
+ public void dataFromSeveralModulesToXmlTest() throws WebApplicationException, IOException, URISyntaxException {
+ SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+ String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+ StructuredDataToXmlProvider.INSTANCE);
+
+// String output =
+// String.format("<data>" +
+// "\n<cont_m1>" +
+// "\n\t<lf1_m1>" +
+// "\n\t\tlf1 m1 value" +
+// "\n\t</lf1_m1>" +
+// "\n</cont_m1>" +
+// "\n<cont_m2>" +
+// "\n\t<lf1_m2>" +
+// "\n\t\tlf1 m2 value" +
+// "\n\t</lf1_m2>" +
+// "\n</cont_m2>" +
+// "\n</data>");
+
+ StringBuilder regex = new StringBuilder();
+ regex.append("^");
+
+ regex.append(".*<data.*");
+ regex.append(".*xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"");
+ regex.append(".*>");
+
+
+ regex.append(".*<contB_m1.*\\/>");
+ regex.append(".*xmlns=\"module:one\"");
+ regex.append(".*>");
+ regex.append(".*<lf1_m1.*>");
+ regex.append(".*<\\/lf1_m1>");
+ regex.append(".*<\\/cont_m1>");
+
+ regex.append(".*<contB_m2.*/>");
+ regex.append(".*<cont_m2.*");
+ regex.append(".*xmlns=\"module:two\"");
+ regex.append(".*>");
+ regex.append(".*<lf1_m2.*>");
+ regex.append(".*<\\/lf1_m2>");
+ regex.append(".*<\\/cont_m2>");
+
+ regex.append(".*<\\/data.*>");
+
+ regex.append(".*");
+ regex.append("$");
+
+ Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+ Matcher matcher = ptrn.matcher(output);
+
+ assertTrue(matcher.find());
+
+ }
+
+ private CompositeNode prepareCnSn() throws URISyntaxException {
+ CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+ URI uriModule1 = new URI("module:one");
+ CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+ SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+ cont_m1.addValue(lf1_m1);
+ CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+
+ data.addValue(contB_m1);
+ data.addValue(cont_m1);
+
+ URI uriModule2 = new URI("module:two");
+ CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+ SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+ cont_m2.addValue(lf1_m2);
+ CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+ data.addValue(contB_m2);
+ data.addValue(cont_m2);
+ return data;
+ }
+
+}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import java.io.FileNotFoundException;
import java.util.Set;
+import org.junit.After;
import org.junit.BeforeClass;
+import org.junit.Rule;
import org.junit.Test;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.junit.rules.ExpectedException;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
private static final ControllerContext controllerContext = ControllerContext.getInstance();
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
@BeforeClass
public static void init() throws FileNotFoundException {
Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
controllerContext.setSchemas(schemaContext);
}
+ @After
+ public void releaseMountService() {
+ controllerContext.setMountService(null);
+ }
+
@Test
public void testToInstanceIdentifierList() throws FileNotFoundException {
InstanceIdWithSchemaNode instanceIdentifier = controllerContext
instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users/user/foo");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
- assertNull(instanceIdentifier);
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
- assertNull(instanceIdentifier);
-
}
@Test
- public void testToInstanceIdentifierMountPoint() throws FileNotFoundException {
- try {
- String mountPointPath = "simple-nodes:user/foo/boo";
- String nestedPath = "simple-nodes:user/foo/boo/simple-nodes:users";
- InstanceIdWithSchemaNode mountInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath);
- assertEquals("user", mountInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
- MountInstance mountInstance = mock(MountInstance.class);
- MountService mountService = mock(MountService.class);
-
- controllerContext.setMountService(mountService);
- // when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(null);
-
- when(mountService.getMountPoint(eq(mountInstanceIdentifier.getInstanceIdentifier()))).thenReturn(
- mountInstance);
-
- when(mountInstance.getSchemaContext()).thenReturn(controllerContext.getGlobalSchema());
-
- InstanceIdWithSchemaNode mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(nestedPath);
- assertEquals("users", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
- mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath + "/" + mountPointPath);
- assertEquals("user", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
- mountedInstanceIdentifier = controllerContext
- .toInstanceIdentifier("simple-nodes:user/foo/var/simple-nodes:users");
- assertNull(mountedInstanceIdentifier);
-
- } finally {
- controllerContext.setMountService(null);
- }
+ public void testToInstanceIdentifierListWithNullKey() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
+ }
+ @Test
+ public void testToInstanceIdentifierListWithMissingKey() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
}
@Test
@Test
public void testToInstanceIdentifierChoice() throws FileNotFoundException {
- InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer");
+ InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+ .toInstanceIdentifier("simple-nodes:food/nonalcoholic/beer");
assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer");
+ }
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
- assertNull(instanceIdentifier);
-
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
- assertNull(instanceIdentifier);
+ @Test
+ public void testToInstanceIdentifierChoiceException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
+ }
- instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
- assertNull(instanceIdentifier);
+ @Test
+ public void testToInstanceIdentifierCaseException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
+ }
+ @Test
+ public void testToInstanceIdentifierChoiceCaseException() {
+ exception.expect(ResponseException.class);
+ exception.expectMessage("HTTP 400 Bad Request");
+ controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
}
}
+++ /dev/null
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import java.util.concurrent.Future;
-
-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.MountInstance;
-import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-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;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-class DummyMountInstanceImpl implements MountInstance {
-
- SchemaContext schemaContext;
-
- public static class Builder {
- SchemaContext schemaContext;
-
- public Builder setSchemaContext(SchemaContext schemaContext) {
- this.schemaContext = schemaContext;
- return this;
- }
-
- public MountInstance build() {
- DummyMountInstanceImpl instance = new DummyMountInstanceImpl();
- instance.schemaContext = schemaContext;
- return instance;
- }
- }
-
- @Override
- public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public CompositeNode readConfigurationData(InstanceIdentifier path) {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public CompositeNode readOperationalData(InstanceIdentifier path) {
- // 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 SchemaContext getSchemaContext() {
- return schemaContext;
- }
-
- @Override
- public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
- // TODO Auto-generated method stub
- return null;
- }
-
-}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class MediaTypesTest extends JerseyTest {
+
+ private static RestconfService restconfService;
+ private static String jsonData;
+ private static String xmlData;
+
+ @BeforeClass
+ public static void init() throws IOException {
+ restconfService = mock(RestconfService.class);
+ String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
+ jsonData = TestUtils.loadTextFile(jsonPath);
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+ xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+ }
+
+ @Override
+ protected Application configure() {
+ /* enable/disable Jersey logs to console */
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+ ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig = resourceConfig.registerInstances(restconfService, StructuredDataToXmlProvider.INSTANCE,
+ StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+ JsonToCompositeNodeProvider.INSTANCE);
+ return resourceConfig;
+ }
+
+ @Test
+ public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/operations/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ post(uri, Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, Draft02.MediaTypes.DATA+XML, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+
+ // negative tests
+ post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
+ verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.readConfigurationData(uriPath)).thenReturn(null);
+ get(uri, Draft02.MediaTypes.DATA+JSON);
+ verify(restconfService, times(1)).readConfigurationData(uriPath);
+ get(uri, Draft02.MediaTypes.DATA+XML);
+ verify(restconfService, times(2)).readConfigurationData(uriPath);
+ get(uri, MediaType.APPLICATION_JSON);
+ verify(restconfService, times(3)).readConfigurationData(uriPath);
+ get(uri, MediaType.APPLICATION_XML);
+ verify(restconfService, times(4)).readConfigurationData(uriPath);
+ get(uri, MediaType.TEXT_XML);
+ verify(restconfService, times(5)).readConfigurationData(uriPath);
+
+ // negative tests
+ get(uri, MediaType.TEXT_PLAIN);
+ verify(restconfService, times(5)).readConfigurationData(uriPath);
+ }
+
+ @Test
+ public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/operational/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.readOperationalData(uriPath)).thenReturn(null);
+ get(uri, Draft02.MediaTypes.DATA+JSON);
+ verify(restconfService, times(1)).readOperationalData(uriPath);
+ get(uri, Draft02.MediaTypes.DATA+XML);
+ verify(restconfService, times(2)).readOperationalData(uriPath);
+ get(uri, MediaType.APPLICATION_JSON);
+ verify(restconfService, times(3)).readOperationalData(uriPath);
+ get(uri, MediaType.APPLICATION_XML);
+ verify(restconfService, times(4)).readOperationalData(uriPath);
+ get(uri, MediaType.TEXT_XML);
+ verify(restconfService, times(5)).readOperationalData(uriPath);
+
+ // negative tests
+ get(uri, MediaType.TEXT_PLAIN);
+ verify(restconfService, times(5)).readOperationalData(uriPath);
+ }
+
+ @Test
+ public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.updateConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ put(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.createConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+ post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+ }
+
+ @Test
+ public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uri = createUri(uriPrefix, "");
+ when(restconfService.createConfigurationData(any(CompositeNode.class))).thenReturn(null);
+ post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+ verify(restconfService, times(1)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+ verify(restconfService, times(2)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+ verify(restconfService, times(3)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.APPLICATION_XML, xmlData);
+ verify(restconfService, times(4)).createConfigurationData(any(CompositeNode.class));
+ post(uri, null, MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(5)).createConfigurationData(any(CompositeNode.class));
+ post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+ verify(restconfService, times(6)).createConfigurationData(any(CompositeNode.class));
+ }
+
+ @Test
+ public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
+ String uriPrefix = "/config/";
+ String uriPath = "ietf-interfaces:interfaces";
+ String uri = createUri(uriPrefix, uriPath);
+ when(restconfService.deleteConfigurationData(eq(uriPath))).thenReturn(null);
+ target(uri).request("fooMediaType").delete();
+ verify(restconfService, times(1)).deleteConfigurationData(uriPath);
+ }
+
+ private int get(String uri, String acceptMediaType) {
+ return target(uri).request(acceptMediaType).get().getStatus();
+ }
+
+ private int put(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+ if (acceptMediaType == null) {
+ return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+ return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+
+ private int post(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+ if (acceptMediaType == null) {
+ if (contentTypeMediaType == null || data == null) {
+ return target(uri).request().post(null).getStatus();
+ }
+ return target(uri).request().post(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+ if (contentTypeMediaType == null || data == null) {
+ return target(uri).request(acceptMediaType).post(null).getStatus();
+ }
+ return target(uri).request(acceptMediaType).post(Entity.entity(data, contentTypeMediaType)).getStatus();
+ }
+
+}
restconfImpl.setControllerContext(controllerContext);
}
- @Test
+// @Test
+ // TODO
public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
initMocking();
String URI_1 = createUri("/config", "");
assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
}
- @Test
+// @Test
+ // TODO
public void testExistingData() throws UnsupportedEncodingException {
initMocking();
String URI_1 = createUri("/config", "");
import java.io.UnsupportedEncodingException;
import java.util.Set;
import java.util.concurrent.Future;
-import java.util.logging.Level;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
private static ControllerContext controllerContext;
private static BrokerFacade brokerFacade;
private static RestconfImpl restconfImpl;
- private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
@BeforeClass
public static void init() throws FileNotFoundException {
@Override
protected Application configure() {
/* enable/disable Jersey logs to console */
- /*
- * enable(TestProperties.LOG_TRAFFIC);
- */
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
XmlToCompositeNodeProvider.INSTANCE);
}
@Test
- public void testDeleteConfigurationData() throws UnsupportedEncodingException, FileNotFoundException {
- String uri2 = createUri("/config/", "test-interface:interfaces");
-
- RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
- TransactionStatus.COMMITED).build();
- Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/config/", "test-interface:interfaces");
+ Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
-
- Response response = target(uri2).request(MEDIA_TYPE_DRAFT02).delete();
+ Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
assertEquals(200, response.getStatus());
-
- rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.FAILED).build();
- dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
-
+
+ dummyFuture = createFuture(TransactionStatus.FAILED);
when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
-
- response = target(uri2).request(MEDIA_TYPE_DRAFT02).delete();
+ response = target(uri).request(MediaType.APPLICATION_XML).delete();
assertEquals(500, response.getStatus());
}
+
+ private Future<RpcResult<TransactionStatus>> createFuture(TransactionStatus statusName) {
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName).build();
+ return DummyFuture.builder().rpcResult(rpcResult).build();
+ }
}
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
-import java.util.logging.Level;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.core.api.mount.MountService;
-import org.opendaylight.controller.sal.rest.api.Draft01;
import org.opendaylight.controller.sal.rest.api.Draft02;
-import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
private static RestconfImpl restconfImpl;
private static SchemaContext schemaContextYangsIetf;
private static SchemaContext schemaContextTestModule;
+ private static CompositeNode answerFromGet;
@BeforeClass
public static void init() throws FileNotFoundException {
restconfImpl = RestconfImpl.getInstance();
restconfImpl.setBroker(brokerFacade);
restconfImpl.setControllerContext(controllerContext);
- }
-
- @Before
- public void logs() {
- /* enable/disable Jersey logs to console */
- /*
- * List<LogRecord> loggedRecords = getLoggedRecords(); for (LogRecord l
- * : loggedRecords) { System.out.println(l.getMessage()); }
- */
+ answerFromGet = prepareCompositeNodeWithIetfInterfacesInterfacesData();
}
@Override
protected Application configure() {
/* enable/disable Jersey logs to console */
- /*
- * enable(TestProperties.LOG_TRAFFIC);
- */
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
}
/**
- * Tests {@link RestconfImpl#readData() readAllData()} method of
- * RestconfImpl with url {@code "/datastore/ identifier}"}. Status codes 200
- * is tested.
+ * Tests of status codes for "/datastore/{identifier}".
*/
@Test
- public void getDatastoreDataViaUrlTest200() throws FileNotFoundException, UnsupportedEncodingException {
+ public void getDatastoreStatusCodes() throws FileNotFoundException, UnsupportedEncodingException {
mockReadOperationalDataMethod();
- getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + JSON, 200);
- getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + XML, 200);
- getDataWithUrl("/datastore/", MediaType.APPLICATION_JSON, 200);
- getDataWithUrl("/datastore/", MediaType.APPLICATION_XML, 200);
- getDataWithUrl("/datastore/", MediaType.TEXT_XML, 200);
- }
-
- /**
- * Tests {@link RestconfImpl#readData() readAllData()} method of
- * RestconfImpl with url {@code "/datastore/ identifier}"}. Status codes 400
- * is tested.
- */
- @Test
- public void getDatastoreDataViaUrlTest400() throws FileNotFoundException, UnsupportedEncodingException {
- mockReadOperationalDataMethod();
- getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + JSON, 400);
- getDataWithUrl("/datastore/", Draft01.MediaTypes.DATA + XML, 400);
- getDataWithUrl("/datastore/", MediaType.APPLICATION_JSON, 400);
- getDataWithUrl("/datastore/", MediaType.APPLICATION_XML, 400);
- getDataWithUrl("/datastore/", MediaType.TEXT_XML, 400);
- }
-
- /**
- * Tests {@link RestconfImpl#readOperationalData(String)
- * readOperationalData(String)} method of RestconfImpl with url
- * {@code "/operational/...identifier..."}. Status codes 200 is tested.
- */
- @Test
- public void getOperationalDataViaUrl200() throws UnsupportedEncodingException {
- mockReadOperationalDataMethod();
- getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + JSON, 200);
- getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + XML, 200);
- getDataWithUrl("/operational/", MediaType.APPLICATION_JSON, 200);
- getDataWithUrl("/operational/", MediaType.APPLICATION_XML, 200);
- getDataWithUrl("/operational/", MediaType.TEXT_XML, 200);
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/datastore/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
+
+ // Test of request for not existing data. Returning status code 404
+ uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+ assertEquals(404, get(uri, MediaType.APPLICATION_XML));
}
/**
- * Tests {@link RestconfImpl#readOperationalData(String)
- * readOperationalData(String)} method of RestconfImpl with url
- * {@code "/operational/...identifier..."}. Status codes 400 is tested.
+ * Tests of status codes for "/operational/{identifier}".
*/
@Test
- public void getOperationalDataViaUrl400() throws UnsupportedEncodingException {
+ public void getOperationalStatusCodes() throws UnsupportedEncodingException {
mockReadOperationalDataMethod();
- getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + JSON, 400);
- getDataWithUrl("/operational/", Draft02.MediaTypes.DATA + XML, 400);
- getDataWithUrl("/operational/", MediaType.APPLICATION_JSON, 400);
- getDataWithUrl("/operational/", MediaType.APPLICATION_XML, 400);
- getDataWithUrl("/operational/", MediaType.TEXT_XML, 400);
- }
-
- /**
- * Tests {@link RestconfImpl#readOperationalData
- * #readConfigurationData(String) readConfigurationData(String)} method of
- * RestconfImpl with url {@code "/config/...identifier..."}. Status codes
- * 200 is tested.
- */
- @Test
- public void getConfigDataViaUrl200() throws UnsupportedEncodingException {
- mockReadConfigurationDataMethod();
- getDataWithUrl("/config/", Draft02.MediaTypes.DATA + JSON, 200);
- getDataWithUrl("/config/", Draft02.MediaTypes.DATA + XML, 200);
- getDataWithUrl("/config/", MediaType.APPLICATION_JSON, 200);
- getDataWithUrl("/config/", MediaType.APPLICATION_XML, 200);
- getDataWithUrl("/config/", MediaType.TEXT_XML, 200);
+ String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/operational/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
}
/**
- * Tests {@link RestconfImpl#readOperationalData
- * #readConfigurationData(String) readConfigurationData(String)} method of
- * RestconfImpl with url {@code "/config/...identifier..."}. Status codes
- * 400 is tested.
+ * Tests of status codes for "/config/{identifier}".
*/
@Test
- public void getConfigDataViaUrl400() throws UnsupportedEncodingException {
+ public void getConfigStatusCodes() throws UnsupportedEncodingException {
mockReadConfigurationDataMethod();
- getDataWithUrl("/config/", Draft02.MediaTypes.DATA + JSON, 400);
- getDataWithUrl("/config/", Draft02.MediaTypes.DATA + XML, 400);
- getDataWithUrl("/config/", MediaType.APPLICATION_JSON, 400);
- getDataWithUrl("/config/", MediaType.APPLICATION_XML, 400);
- getDataWithUrl("/config/", MediaType.TEXT_XML, 400);
- }
-
- /**
- * Tests {@link RestconfImpl#readAllData() readAllData()} method of
- * RestconfImpl with url {@code "/datastore"}. Currently the method isn't
- * supported so it returns 500
- */
- @Test
- public void getDatastoreDataAllTest500() throws UnsupportedEncodingException {
- getDatastoreAllDataTest(Draft01.MediaTypes.DATASTORE + XML);
- getDatastoreAllDataTest(Draft01.MediaTypes.DATASTORE + JSON);
- }
-
- /**
- *
- * Tests {@link RestconfImpl#getModules getModules} method of RestconfImpl
- * with uri {@code "/modules"}. Currently the method isn't supported so it
- * returns 500
- */
- @Test
- public void getModulesDataTest500() throws UnsupportedEncodingException {
- getModulesDataTest(Draft01.MediaTypes.API + JSON);
- getModulesDataTest(Draft01.MediaTypes.API + XML);
- getModulesDataTest(Draft02.MediaTypes.API + JSON);
- getModulesDataTest(Draft02.MediaTypes.API + XML);
- }
-
- /**
- * Test of request for not existing data. Returning status code 404
- */
- @Test
- public void getDataWithUrlNoExistingDataTest404() throws UnsupportedEncodingException, URISyntaxException {
- String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
-
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
-
- Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).get();
- assertEquals(404, response.getStatus());
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
+ assertEquals(200, get(uri, MediaType.APPLICATION_XML));
+
+ uri = createUri("/config/", "wrong-module:interfaces/interface/eth0");
+ assertEquals(400, get(uri, MediaType.APPLICATION_XML));
}
/**
* MountPoint test. URI represents mount point.
*/
@Test
- public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, FileNotFoundException,
- URISyntaxException {
- when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(
- prepareCnDataForMountPointTest());
-
+ public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException {
+ when(brokerFacade.readConfigurationDataBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class))).thenReturn(prepareCnDataForMountPointTest());
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
MountService mockMountService = mock(MountService.class);
-
- when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(
- new DummyMountInstanceImpl.Builder().setSchemaContext(schemaContextTestModule).build());
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
ControllerContext.getInstance().setMountService(mockMountService);
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont/cont1");
+ String uri = createUri("/config/",
+ "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
assertEquals(200, response.getStatus());
+
+ uri = createUri("/config/",
+ "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1");
+ response = target(uri).request(Draft02.MediaTypes.DATA + XML).get();
+ assertEquals(200, response.getStatus());
}
-
- private void getDataWithUrl(String mediaTypePrefix, String mediaType, int statusCode)
- throws UnsupportedEncodingException {
- String uri = null;
- switch (statusCode) {
- case 400:
- uri = createUri(mediaTypePrefix, "wrong-module:interfaces/interface/eth0");
- break;
- case 200:
- uri = createUri(mediaTypePrefix, "ietf-interfaces:interfaces/interface/eth0");
- break;
- }
- Response response = target(uri).request(mediaType).get();
- assertEquals("Status is incorrect for media type " + mediaType + ".", statusCode, response.getStatus());
-
- }
-
- private void getModulesDataTest(String mediaType) throws UnsupportedEncodingException {
- String uri = createUri("/modules", "");
- Response response = target(uri).request(mediaType).get();
-
- assertEquals("Status is incorrect for media type " + mediaType + ".", 500, response.getStatus());
- }
-
- private void getDatastoreAllDataTest(String mediaType) throws UnsupportedEncodingException {
- String uri = createUri("/datastore", "");
- Response response = target(uri).request(mediaType).get();
-
- assertEquals(500, response.getStatus());
+
+ private int get(String uri, String mediaType) {
+ return target(uri).request(mediaType).get().getStatus();
}
private CompositeNode prepareCnDataForMountPointTest() throws URISyntaxException {
return cont1.unwrap();
}
- private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+ private void mockReadOperationalDataMethod() {
+ when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+ }
+
+ private void mockReadConfigurationDataMethod() {
+ when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(answerFromGet);
+ }
+
+ private static CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
CompositeNode intface;
try {
intface = new CompositeNodeWrapper(new URI("interface"), "interface");
return null;
}
- private void mockReadOperationalDataMethod() {
- CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
- when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
- }
-
- private void mockReadConfigurationDataMethod() {
- CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
- when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
- }
}
import java.net.URI;
import java.net.URLEncoder;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.MediaType;
-
import com.google.common.base.Charsets;
public class RestOperationUtils {
private RestOperationUtils() {
}
- static Entity<String> entity(String data, MediaType mediaType) {
- return Entity.entity(data, mediaType);
- }
-
- static Entity<String> entity(String data, String mediaType) {
- return Entity.entity(data, mediaType);
- }
-
static String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
}
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.entity;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.Future;
-import java.util.logging.Level;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.core.api.mount.MountService;
-import org.opendaylight.controller.sal.rest.api.Draft01;
import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
public class RestPostOperationTest extends JerseyTest {
- private static String xmlData;
private static String xmlDataAbsolutePath;
- private static String jsonData;
- private static String jsonDataAbsolutePath;
private static String xmlDataRpcInput;
private static CompositeNodeWrapper cnSnDataOutput;
- private static String jsonDataRpcInput;
private static String xmlData2;
private static ControllerContext controllerContext;
loadData();
}
- @Before
- public void logs() throws IOException, URISyntaxException {
- /* enable/disable Jersey logs to console */
- /*
- * List<LogRecord> loggedRecords = getLoggedRecords(); for (LogRecord l
- * : loggedRecords) { System.out.println(l.getMessage()); }
- */
- }
-
@Override
protected Application configure() {
/* enable/disable Jersey logs to console */
-
- /*
- * enable(TestProperties.LOG_TRAFFIC);
- */
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
}
@Test
- public void postOperationsDataViaUrl200() throws URISyntaxException, IOException {
- controllerContext.setSchemas(schemaContextTestModule);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 200);
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 200);
- postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 200);
-
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 200);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 200);
- postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 200);
- postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 200);
- }
-
- @Test
- public void postOperationsDataViaUrl204() throws URISyntaxException, IOException {
- controllerContext.setSchemas(schemaContextTestModule);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 204);
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 204);
- postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 204);
-
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 204);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 204);
- postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 204);
- postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 204);
- }
-
- @Test
- public void postOperationsDataViaUrl500() throws URISyntaxException, IOException {
- controllerContext.setSchemas(schemaContextTestModule);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 500);
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 500);
- postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 500);
-
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 500);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 500);
- postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 500);
- postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 500);
- }
-
- @Test
- public void postOperationsDataViaUrl400() throws URISyntaxException, IOException {
- controllerContext.setSchemas(schemaContextTestModule);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 400);
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 400);
- postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 400);
-
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 400);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 400);
- postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 400);
- postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 400);
- }
-
- @Test
- public void postOperationsDataViaUrl404() throws URISyntaxException, IOException {
+ public void postOperationsStatusCodes() throws UnsupportedEncodingException {
controllerContext.setSchemas(schemaContextTestModule);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 404);
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + JSON, cnSnDataOutput, jsonDataRpcInput, 404);
- postOperationsDataViaUrl(MediaType.APPLICATION_JSON, cnSnDataOutput, jsonDataRpcInput, 404);
-
- postOperationsDataViaUrl(Draft01.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 404);
- postOperationsDataViaUrl(Draft02.MediaTypes.DATA + XML, cnSnDataOutput, xmlDataRpcInput, 404);
- postOperationsDataViaUrl(MediaType.APPLICATION_XML, cnSnDataOutput, xmlDataRpcInput, 404);
- postOperationsDataViaUrl(MediaType.TEXT_XML, cnSnDataOutput, xmlDataRpcInput, 404);
+ mockInvokeRpc(cnSnDataOutput, true);
+ String uri = createUri("/operations/", "test-module:rpc-test");
+ assertEquals(200, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ mockInvokeRpc(null, true);
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ mockInvokeRpc(null, false);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
+
+ uri = createUri("/operations/", "test-module:rpc-wrongtest");
+ assertEquals(404, post(uri, MediaType.APPLICATION_XML, xmlDataRpcInput));
}
@Test
- public void postConfigDataViaUrlConfigOnlyTest204() throws UnsupportedEncodingException, FileNotFoundException {
+ public void postConfigOnlyStatusCodes() throws UnsupportedEncodingException {
controllerContext.setSchemas(schemaContextYangsIetf);
mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 204);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 204);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 204);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 204);
- postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 204);
- }
-
- @Test
- public void postConfigDataViaUrlConfigOnlyTest202() throws UnsupportedEncodingException, FileNotFoundException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ String uri = createUri("/config", "");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(null);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 202);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 202);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 202);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 202);
- postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 202);
- }
-
- @Test
- public void postConfigDataViaUrlConfigOnlyTest500() throws UnsupportedEncodingException, FileNotFoundException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + JSON, jsonDataAbsolutePath, 500);
- postDataViaUrlTest("/config", "", Draft02.MediaTypes.DATA + XML, xmlDataAbsolutePath, 500);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_JSON, jsonDataAbsolutePath, 500);
- postDataViaUrlTest("/config", "", MediaType.APPLICATION_XML, xmlDataAbsolutePath, 500);
- postDataViaUrlTest("/config", "", MediaType.TEXT_XML, xmlDataAbsolutePath, 500);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
}
@Test
- public void postConfigDataViaUrlTest204() throws UnsupportedEncodingException {
+ public void postConfigStatusCodes() throws UnsupportedEncodingException {
controllerContext.setSchemas(schemaContextYangsIetf);
mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 204);
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 204);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 204);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 204);
- postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 204);
- }
-
- @Test
- public void postConfigDataViaUrlTest202() throws UnsupportedEncodingException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ String uri = createUri("/config/", "ietf-interfaces:interfaces");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(null);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 202);
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 202);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 202);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 202);
- postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 202);
- }
-
- @Test
- public void postConfigDataViaUrlTest500() throws UnsupportedEncodingException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + JSON, jsonData, 500);
- postDataViaUrlTest("/config/", urlPath, Draft02.MediaTypes.DATA + XML, xmlData, 500);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_JSON, jsonData, 500);
- postDataViaUrlTest("/config/", urlPath, MediaType.APPLICATION_XML, xmlData, 500);
- postDataViaUrlTest("/config/", urlPath, MediaType.TEXT_XML, xmlData, 500);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
}
@Test
- public void postDatastoreDataViaUrlTest204() throws UnsupportedEncodingException {
+ public void postDatastoreStatusCodes() throws UnsupportedEncodingException {
controllerContext.setSchemas(schemaContextYangsIetf);
mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 204);
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 204);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 204);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 204);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 204);
- }
-
- @Test
- public void postDatastoreDataViaUrlTest202() throws UnsupportedEncodingException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces");
+ assertEquals(204, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(null);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 202);
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 202);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 202);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 202);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 202);
- }
-
- @Test
- public void postDatastoreDataViaUrlTest500() throws UnsupportedEncodingException {
- controllerContext.setSchemas(schemaContextYangsIetf);
+ assertEquals(202, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
+
mockCommitConfigurationDataPostMethod(TransactionStatus.FAILED);
- String urlPath = "ietf-interfaces:interfaces";
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + JSON, jsonData, 500);
- postDataViaUrlTest("/datastore/", urlPath, Draft01.MediaTypes.DATA + XML, xmlData, 500);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_JSON, jsonData, 500);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.APPLICATION_XML, xmlData, 500);
- postDataViaUrlTest("/datastore/", urlPath, MediaType.TEXT_XML, xmlData, 500);
+ assertEquals(500, post(uri, MediaType.APPLICATION_XML, xmlDataAbsolutePath));
}
@Test
public void postDataViaUrlMountPoint() throws UnsupportedEncodingException {
controllerContext.setSchemas(schemaContextYangsIetf);
- mockCommitConfigurationDataPostMethod(TransactionStatus.COMMITED);
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ when(brokerFacade.commitConfigurationDataPostBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
MountService mockMountService = mock(MountService.class);
- SchemaContext otherSchemaContext = schemaContextTestModule;
- when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(
- new DummyMountInstanceImpl.Builder().setSchemaContext(otherSchemaContext).build());
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
ControllerContext.getInstance().setMountService(mockMountService);
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont/cont1");
- Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).post(
- entity(xmlData2, Draft02.MediaTypes.DATA + XML));
- // 204 code is returned when COMMITED transaction status is put as input
- // to mock method
- assertEquals(204, response.getStatus());
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont/cont1");
+ assertEquals(204, post(uri, Draft02.MediaTypes.DATA + XML, xmlData2));
}
-
- private void postDataViaUrlTest(String urlPrefix, String urlPath, String mediaType, String data, int responseStatus)
- throws UnsupportedEncodingException {
- String url = createUri(urlPrefix, urlPath);
- Response response = target(url).request(mediaType).post(entity(data, mediaType));
- assertEquals(responseStatus, response.getStatus());
+
+ private void mockInvokeRpc(CompositeNode result, boolean sucessful) {
+ RpcResult<CompositeNode> rpcResult = new DummyRpcResult.Builder<CompositeNode>().result(result)
+ .isSuccessful(sucessful).build();
+ when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult);
}
private void mockCommitConfigurationDataPostMethod(TransactionStatus statusName) {
when(brokerFacade.commitConfigurationDataPost(any(InstanceIdentifier.class), any(CompositeNode.class)))
.thenReturn(dummyFuture);
}
-
- private static CompositeNodeWrapper prepareCnSnRpcOutput() throws URISyntaxException {
- CompositeNodeWrapper cnSnDataOutput = new CompositeNodeWrapper(new URI("test:module"), "output");
- CompositeNodeWrapper cont = new CompositeNodeWrapper(new URI("test:module"), "cont-output");
- cnSnDataOutput.addValue(cont);
- cnSnDataOutput.unwrap();
- return cnSnDataOutput;
- }
-
- private void mockInvokeRpc(CompositeNode compositeNode, boolean sucessful) {
- RpcResult<CompositeNode> rpcResult = new DummyRpcResult.Builder<CompositeNode>().result(compositeNode)
- .isSuccessful(sucessful).build();
- when(brokerFacade.invokeRpc(any(QName.class), any(CompositeNode.class))).thenReturn(rpcResult);
- }
-
- private void postOperationsDataViaUrl(String mediaType, CompositeNode cnSnDataOut, String dataIn, int statusCode)
- throws FileNotFoundException, UnsupportedEncodingException {
- String url = createUri("/operations/", "test-module:rpc-test");
- Response response = null;
- switch (statusCode) {
- case 200:
- mockInvokeRpc(cnSnDataOut, true);
- break;
- case 204:
- mockInvokeRpc(null, true);
- break;
- case 500:
- mockInvokeRpc(null, false);
- break;
- case 400:
- response = target(url).request(mediaType).post(Entity.entity("{}", mediaType));
- break;
- case 404:
- url = createUri("/operations/", "test-module:rpc-wrongtest");
- break;
- }
- response = response == null ? target(url).request(mediaType).post(Entity.entity(dataIn, mediaType)) : response;
- assertEquals(statusCode, response.getStatus());
+
+ private int post(String uri, String mediaType, String data) {
+ return target(uri).request(mediaType).post(Entity.entity(data, mediaType)).getStatus();
}
private static void loadData() throws IOException, URISyntaxException {
-
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-
- xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml");
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces_absolute_path.xml");
xmlDataAbsolutePath = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-
- String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
- jsonData = TestUtils.loadTextFile(jsonPath);
-
- String jsonFullPath = RestconfImplTest.class
- .getResource("/parts/ietf-interfaces_interfaces_absolute_path.json").getPath();
- jsonDataAbsolutePath = TestUtils.loadTextFile(jsonFullPath);
-
String xmlPathRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.xml")
.getPath();
xmlDataRpcInput = TestUtils.loadTextFile(xmlPathRpcInput);
cnSnDataOutput = prepareCnSnRpcOutput();
-
- String jsonPathToRpcInput = RestconfImplTest.class.getResource("/full-versions/test-data2/data-rpc-input.json")
- .getPath();
- jsonDataRpcInput = TestUtils.loadTextFile(jsonPathToRpcInput);
-
String data2Input = RestconfImplTest.class.getResource("/full-versions/test-data2/data2.xml").getPath();
xmlData2 = TestUtils.loadTextFile(data2Input);
+ }
+ private static CompositeNodeWrapper prepareCnSnRpcOutput() throws URISyntaxException {
+ CompositeNodeWrapper cnSnDataOutput = new CompositeNodeWrapper(new URI("test:module"), "output");
+ CompositeNodeWrapper cont = new CompositeNodeWrapper(new URI("test:module"), "cont-output");
+ cnSnDataOutput.addValue(cont);
+ cnSnDataOutput.unwrap();
+ return cnSnDataOutput;
}
}
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.entity;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.concurrent.Future;
-import java.util.logging.Level;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.core.api.mount.MountService;
-import org.opendaylight.controller.sal.rest.api.Draft01;
import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
public class RestPutOperationTest extends JerseyTest {
private static String xmlData;
- private static String jsonData;
private static BrokerFacade brokerFacade;
private static RestconfImpl restconfImpl;
loadData();
}
- @Before
- public void logs() throws IOException {
- /* enable/disable Jersey logs to console */
- /*
- * List<LogRecord> loggedRecords = getLoggedRecords(); for (LogRecord l
- * : loggedRecords) { System.out.println(l.getMessage()); }
- */
+ private static void loadData() throws IOException {
+ InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+ xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
}
@Override
protected Application configure() {
/* enable/disable Jersey logs to console */
- /*
- * enable(TestProperties.LOG_TRAFFIC);
- */
- enable(TestProperties.DUMP_ENTITY);
- enable(TestProperties.RECORD_LOG_LEVEL);
- set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
+// enable(TestProperties.LOG_TRAFFIC);
+// enable(TestProperties.DUMP_ENTITY);
+// enable(TestProperties.RECORD_LOG_LEVEL);
+// set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
}
/**
- * Test method
- * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of
- * RestconfImpl for "/config/...identifier..." URL. Return status code is
- * 200.
- *
+ * Tests of status codes for "/config/{identifier}".
*/
@Test
- public void putConfigDataViaUrlTest200() throws UnsupportedEncodingException {
+ public void putConfigStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
- putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + JSON, jsonData, 200);
- putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + XML, xmlData, 200);
- putDataViaUrlTest("/config/", MediaType.APPLICATION_JSON, jsonData, 200);
- putDataViaUrlTest("/config/", MediaType.APPLICATION_XML, xmlData, 200);
- putDataViaUrlTest("/config/", MediaType.TEXT_XML, xmlData, 200);
-
- }
-
- /**
- * Test method
- * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of
- * RestconfImpl for "/config/...identifier..." URL. Return status code is
- * 500.
- *
- */
- @Test
- public void putConfigDataViaUrlTest500() throws UnsupportedEncodingException {
+ assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+
mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
- putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + JSON, jsonData, 500);
- putDataViaUrlTest("/config/", Draft02.MediaTypes.DATA + XML, xmlData, 500);
- putDataViaUrlTest("/config/", MediaType.APPLICATION_JSON, jsonData, 500);
- putDataViaUrlTest("/config/", MediaType.APPLICATION_XML, xmlData, 500);
- putDataViaUrlTest("/config/", MediaType.TEXT_XML, xmlData, 500);
-
+ assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
}
- /**
- * Test method
- * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of
- * RestconfImpl for "/datastore/...identifier..." URL. Return status code is
- * 200.
- *
- */
- @Test
- public void putDatastoreDataViaUrlTest200() throws UnsupportedEncodingException {
- mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
- putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + JSON, jsonData, 200);
- putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + XML, xmlData, 200);
- putDataViaUrlTest("/datastore/", MediaType.APPLICATION_JSON, jsonData, 200);
- putDataViaUrlTest("/datastore/", MediaType.APPLICATION_XML, xmlData, 200);
- putDataViaUrlTest("/datastore/", MediaType.TEXT_XML, xmlData, 200);
- }
/**
- * Test method
- * {@link RestconfImpl#updateConfigurationData(String, CompositeNode)} of
- * RestconfImpl for "/datastore/...identifier..." URL. Return status code is
- * 500.
- *
+ * Tests of status codes for "/datastore/{identifier}".
*/
@Test
- public void putDatastoreDataViaUrlTest500() throws UnsupportedEncodingException {
+ public void putDatastoreStatusCodes() throws UnsupportedEncodingException {
+ String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+ mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+ assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData));
+
mockCommitConfigurationDataPutMethod(TransactionStatus.FAILED);
- putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + JSON, jsonData, 500);
- putDataViaUrlTest("/datastore/", Draft01.MediaTypes.DATA + XML, xmlData, 500);
- putDataViaUrlTest("/datastore/", MediaType.APPLICATION_JSON, jsonData, 500);
- putDataViaUrlTest("/datastore/", MediaType.APPLICATION_XML, xmlData, 500);
- putDataViaUrlTest("/datastore/", MediaType.TEXT_XML, xmlData, 500);
+ assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
}
@Test
public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
FileNotFoundException, URISyntaxException {
- mockCommitConfigurationDataPutMethod(TransactionStatus.COMMITED);
+ RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+ .build();
+ Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+ when(brokerFacade.commitConfigurationDataPutBehindMountPoint(any(MountInstance.class),
+ any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
+
InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml");
String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
Entity<String> entity = Entity.entity(xml, Draft02.MediaTypes.DATA + XML);
+ MountInstance mountInstance = mock(MountInstance.class);
+ when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
MountService mockMountService = mock(MountService.class);
- when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(
- new DummyMountInstanceImpl.Builder().setSchemaContext(schemaContextTestModule).build());
+ when(mockMountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(mountInstance);
ControllerContext.getInstance().setMountService(mockMountService);
- String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/test-module:cont");
+ String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont");
Response response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
assertEquals(200, response.getStatus());
+
+ uri = createUri("/config/", "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont");
+ response = target(uri).request(Draft02.MediaTypes.DATA + XML).put(entity);
+ assertEquals(200, response.getStatus());
}
- private void putDataViaUrlTest(String uriPrefix, String mediaType, String data, int responseStatus)
- throws UnsupportedEncodingException {
- String uri = createUri(uriPrefix, "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(mediaType).put(entity(data, mediaType));
- assertEquals(responseStatus, response.getStatus());
- }
-
- private static void loadData() throws IOException {
- InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
- xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
-
- String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
- jsonData = TestUtils.loadTextFile(jsonPath);
+ private int put(String uri, String mediaType, String data) throws UnsupportedEncodingException {
+ return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
}
private void mockCommitConfigurationDataPutMethod(TransactionStatus statusName) {
leaf beer {
type string;
}
+ container nonalcoholic {
+ leaf beer {
+ type string;
+ }
+ }
}
case late-night {
leaf chocolate {
--- /dev/null
+module module1 {
+ namespace "module:one";
+
+ prefix "m1";
+ revision 2014-01-17 {
+ }
+
+ container cont_m1 {
+ leaf lf1_m1 {
+ type string;
+ }
+ }
+ container contB_m1 {
+ }
+
+}
\ No newline at end of file
--- /dev/null
+module module2 {
+ namespace "module:two";
+
+ prefix "m2";
+ revision 2014-01-17 {
+ }
+
+ container cont_m2 {
+ leaf lf1_m2 {
+ type string;
+ }
+ }
+ container contB_m2 {
+ }
+
+
+}
\ No newline at end of file
for (Node targetNode : targetNodes){
- InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
- NodeRef targetNodeRef = new NodeRef(targetInstanceId);
+ if(targetNode.getAugmentation(FlowCapableNode.class) != null){
+
+ spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
+
+ InstanceIdentifier<Node> targetInstanceId = InstanceIdentifier.builder(Nodes.class).child(Node.class,targetNode.getKey()).toInstance();
+
+ NodeRef targetNodeRef = new NodeRef(targetInstanceId);
- try {
+ try{
+ sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
- sendAggregateFlowsStatsFromAllTablesRequest(targetNode.getKey());
+ sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
- sendAllFlowsStatsFromAllTablesRequest(targetNodeRef);
-
- sendAllNodeConnectorsStatisticsRequest(targetNodeRef);
+ sendAllNodeConnectorsStatisticsRequest(targetNodeRef);
- sendAllFlowTablesStatisticsRequest(targetNodeRef);
+ sendAllFlowTablesStatisticsRequest(targetNodeRef);
- sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
-
- }catch(Exception e){
- spLogger.error("Exception occured while sending statistics requests : {}",e);
- }
-
- if(targetNode.getAugmentation(FlowCapableNode.class) != null){
-
- spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
-
- try{
- sendAllGroupStatisticsRequest(targetNodeRef);
- sendAllMeterStatisticsRequest(targetNodeRef);
- sendGroupDescriptionRequest(targetNodeRef);
- sendMeterConfigStatisticsRequest(targetNodeRef);
+ sendAllQueueStatsFromAllNodeConnector (targetNodeRef);
+
+ sendAllGroupStatisticsRequest(targetNodeRef);
+
+ sendAllMeterStatisticsRequest(targetNodeRef);
+
+ sendGroupDescriptionRequest(targetNodeRef);
+
+ sendMeterConfigStatisticsRequest(targetNodeRef);
}catch(Exception e){
spLogger.error("Exception occured while sending statistics requests : {}", e);
}
import com.google.common.base.Preconditions;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.List;
public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy {
+ private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class);
+
public SimpleAttributeReadingStrategy(String nullableDefault) {
super(nullableDefault);
Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement
+ " but was " + configNodes.size());
- String textContent = xmlElement.getTextContent();
+ String textContent = "";
+ try{
+ textContent = xmlElement.getTextContent();
+ }catch(IllegalStateException | NullPointerException e) {
+ // yuma sends <attribute /> for empty value instead of <attribute></attribute>
+ logger.warn("Ignoring exception caused by failure to read text element", e);
+ }
Preconditions.checkNotNull(textContent, "This element should contain text %s", xmlElement);
return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()),
commit();
response = getConfigCandidate();
final String responseFromCandidate = XmlUtil.toString(response).replaceAll("\\s+", "");
- // System.out.println(responseFromCandidate);
response = getConfigRunning();
final String responseFromRunning = XmlUtil.toString(response).replaceAll("\\s+", "");
- // System.out.println(responseFromRunning);
assertEquals(responseFromCandidate, responseFromRunning);
final String expectedResult = XmlFileLoader.fileToString("netconfMessages/editConfig_expectedResult.xml")
+/*
+ * 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.impl.util;
import com.google.common.base.Preconditions;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.impl;\r
\r
import static junit.framework.Assert.assertNotNull;\r
responseBuilder.append(line);
responseBuilder.append(System.lineSeparator());
- System.out.println(responseBuilder.toString());
if(line.contains("</rpc-reply>"))
break;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.mapping.api;\r
\r
import org.opendaylight.controller.netconf.api.NetconfSession;\r
+/*
+ * 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
+ */
@XmlSchema(
elementFormDefault = XmlNsForm.QUALIFIED,
// xmlns = {
*/
package org.opendaylight.controller.netconf.monitoring.xml;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.util.Date;
-
+import com.google.common.collect.Lists;
import org.junit.Test;
import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
import org.w3c.dom.Element;
-import com.google.common.collect.Lists;
+import java.util.Date;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class JaxBSerializerTest {
};
NetconfState model = new NetconfState(service);
Element xml = new JaxBSerializer().toXml(model);
- System.out.println(XmlUtil.toString(xml));
}
private Session getMockSession() {
+/*
+ * 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.ssh.threads;
+/*
+ * 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.client;
import java.io.IOException;
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.util.xml;\r
\r
import com.siemens.ct.exi.CodingMode;\r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
package org.opendaylight.controller.netconf.util.xml;\r
\r
import io.netty.buffer.ByteBuf;\r
public String getTextContent() {
Node textChild = element.getFirstChild();
- Preconditions.checkState(textChild instanceof Text, getName() + " should contain text");
+ Preconditions.checkNotNull(textChild, "Child node expected, got null for " + getName() + " : " + element);
+ Preconditions.checkState(textChild instanceof Text, getName() + " should contain text." +
+ Text.class.getName() + " expected, got " + textChild);
String content = textChild.getTextContent();
// Trim needed
return content.trim();
<instructions>
<Import-Package>
org.opendaylight.controller.clustering.services,
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.sal.core,
org.opendaylight.controller.sal.utils,
org.apache.felix.dm,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
<version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import java.util.Hashtable;
import java.util.Dictionary;
+
import org.apache.felix.dm.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
* ComponentActivatorAbstractBase.
*
*/
+ @Override
public void init() {
}
* cleanup done by ComponentActivatorAbstractBase
*
*/
+ @Override
public void destroy() {
}
* instantiated in order to get an fully working implementation
* Object
*/
+ @Override
public Object[] getImplementations() {
Object[] res = { NeutronFloatingIPInterface.class,
NeutronRouterInterface.class,
* also optional per-container different behavior if needed, usually
* should not be the case though.
*/
+ @Override
public void configureInstance(Component c, Object imp, String containerName) {
if (imp.equals(NeutronFloatingIPInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronFloatingIPCRUD.class.getName() }, null);
+ new String[] { INeutronFloatingIPCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronRouterInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronRouterCRUD.class.getName() }, null);
+ new String[] { INeutronRouterCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronPortInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronPortCRUD.class.getName() }, null);
+ new String[] { INeutronPortCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronSubnetInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronSubnetCRUD.class.getName() }, null);
+ new String[] { INeutronSubnetCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
if (imp.equals(NeutronNetworkInterface.class)) {
// export the service
c.setInterface(
- new String[] { INeutronNetworkCRUD.class.getName() }, null);
+ new String[] { INeutronNetworkCRUD.class.getName(),
+ IConfigurationContainerAware.class.getName()}, null);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put("salListenerName", "neutron");
c.add(createContainerServiceDependency(containerName)
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.floatingip";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (floatingIPDB.isEmpty()) {
+ loadConfiguration();
+ }
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBFloatingIPCRUD interface methods
+ @Override
public boolean floatingIPExists(String uuid) {
return floatingIPDB.containsKey(uuid);
}
+ @Override
public NeutronFloatingIP getFloatingIP(String uuid) {
if (!floatingIPExists(uuid))
return null;
return floatingIPDB.get(uuid);
}
+ @Override
public List<NeutronFloatingIP> getAllFloatingIPs() {
Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {
return ans;
}
+ @Override
public boolean addFloatingIP(NeutronFloatingIP input) {
INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
return true;
}
+ @Override
public boolean removeFloatingIP(String uuid) {
INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
return true;
}
+ @Override
public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
target.setFixedIPAddress(delta.getFixedIPAddress());
return true;
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronFloatingIP> confList = (ConcurrentMap<String, NeutronFloatingIP>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ floatingIPDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronFloatingIP>(floatingIPDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronNetworkInterface implements INeutronNetworkCRUD {
+public class NeutronNetworkInterface implements INeutronNetworkCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.network";
+ private static String fileName;
private String containerName = null;
private ConcurrentMap<String, NeutronNetwork> networkDB;
private void startUp() {
allocateCache();
retrieveCache();
+ if (networkDB.isEmpty()) {
+ loadConfiguration();
+ }
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBNetworkCRUD methods
+ @Override
public boolean networkExists(String uuid) {
return networkDB.containsKey(uuid);
}
+ @Override
public NeutronNetwork getNetwork(String uuid) {
if (!networkExists(uuid))
return null;
return networkDB.get(uuid);
}
+ @Override
public List<NeutronNetwork> getAllNetworks() {
Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {
return ans;
}
+ @Override
public boolean addNetwork(NeutronNetwork input) {
if (networkExists(input.getID()))
return false;
return true;
}
+ @Override
public boolean removeNetwork(String uuid) {
if (!networkExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateNetwork(String uuid, NeutronNetwork delta) {
if (!networkExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean networkInUse(String netUUID) {
if (!networkExists(netUUID))
return true;
return true;
return false;
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronNetwork> confList = (ConcurrentMap<String, NeutronNetwork>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ networkDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronNetwork>(networkDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronPortInterface implements INeutronPortCRUD {
+public class NeutronPortInterface implements INeutronPortCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.port";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (portDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
return null;
}
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronPort> confList = (ConcurrentMap<String, NeutronPort>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ portDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronPort>(portDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronRouterInterface implements INeutronRouterCRUD {
+public class NeutronRouterInterface implements INeutronRouterCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.router";
+ private static String fileName;
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (routerDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBRouterCRUD Interface methods
+ @Override
public boolean routerExists(String uuid) {
return routerDB.containsKey(uuid);
}
+ @Override
public NeutronRouter getRouter(String uuid) {
if (!routerExists(uuid))
return null;
return routerDB.get(uuid);
}
+ @Override
public List<NeutronRouter> getAllRouters() {
Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
return ans;
}
+ @Override
public boolean addRouter(NeutronRouter input) {
if (routerExists(input.getID()))
return false;
return true;
}
+ @Override
public boolean removeRouter(String uuid) {
if (!routerExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateRouter(String uuid, NeutronRouter delta) {
if (!routerExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean routerInUse(String routerUUID) {
if (!routerExists(routerUUID))
return true;
NeutronRouter target = routerDB.get(routerUUID);
return (target.getInterfaces().size() > 0);
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronRouter> confList = (ConcurrentMap<String, NeutronRouter>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ routerDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronRouter>(routerDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
package org.opendaylight.controller.networkconfig.neutron.implementation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.felix.dm.Component;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectReader;
+import org.opendaylight.controller.sal.utils.ObjectWriter;
+import org.opendaylight.controller.sal.utils.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NeutronSubnetInterface implements INeutronSubnetCRUD {
+public class NeutronSubnetInterface implements INeutronSubnetCRUD, IConfigurationContainerAware,
+ IObjectReader {
private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+ private static String ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String FILENAME ="neutron.subnet";
+ private static String fileName;
+
private String containerName = null;
private IClusterContainerServices clusterContainerService = null;
private void startUp() {
allocateCache();
retrieveCache();
+ if (subnetDB.isEmpty()) {
+ loadConfiguration();
+ }
+
}
/**
// In the Global instance case the containerName is empty
this.containerName = "";
}
+ fileName = ROOT + FILENAME + "_" + containerName + ".conf";
startUp();
}
// IfNBSubnetCRUD methods
+ @Override
public boolean subnetExists(String uuid) {
return subnetDB.containsKey(uuid);
}
+ @Override
public NeutronSubnet getSubnet(String uuid) {
if (!subnetExists(uuid))
return null;
return subnetDB.get(uuid);
}
+ @Override
public List<NeutronSubnet> getAllSubnets() {
Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {
return ans;
}
+ @Override
public boolean addSubnet(NeutronSubnet input) {
String id = input.getID();
if (subnetExists(id))
return true;
}
+ @Override
public boolean removeSubnet(String uuid) {
if (!subnetExists(uuid))
return false;
return true;
}
+ @Override
public boolean updateSubnet(String uuid, NeutronSubnet delta) {
if (!subnetExists(uuid))
return false;
return overwrite(target, delta);
}
+ @Override
public boolean subnetInUse(String subnetUUID) {
if (!subnetExists(subnetUUID))
return true;
NeutronSubnet target = subnetDB.get(subnetUUID);
return (target.getPortsInSubnet().size() > 0);
}
+
+ @SuppressWarnings("unchecked")
+ private void loadConfiguration() {
+ ObjectReader objReader = new ObjectReader();
+ ConcurrentMap<String, NeutronSubnet> confList = (ConcurrentMap<String, NeutronSubnet>)
+ objReader.read(this, fileName);
+
+ if (confList == null) {
+ return;
+ }
+
+ for (String key : confList.keySet()) {
+ subnetDB.put(key, confList.get(key));
+ }
+ }
+
+ @Override
+ public Status saveConfiguration() {
+ ObjectWriter objWriter = new ObjectWriter();
+ return objWriter.write(new ConcurrentHashMap<String, NeutronSubnet>(subnetDB), fileName);
+ }
+
+ @Override
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+ return ois.readObject();
+ }
+
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronFloatingIP {
+public class NeutronFloatingIP implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@XmlRootElement(name = "network")
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronNetwork {
+public class NeutronNetwork implements Serializable {
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
+ private static final long serialVersionUID = 1L;
+
@XmlElement (name="id")
String networkUUID; // network UUID
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronPort {
+public class NeutronPort implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter {
+public class NeutronRouter implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
@XmlElement (name="id")
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter_Interface {
+public class NeutronRouter_Interface implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronRouter_NetworkReference {
+public class NeutronRouter_NetworkReference implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet {
+public class NeutronSubnet implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_HostRoute {
+public class NeutronSubnet_HostRoute implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class NeutronSubnet_IPAllocationPool {
+public class NeutronSubnet_IPAllocationPool implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
@XmlElement(name="end")
String poolEnd;
- public NeutronSubnet_IPAllocationPool() { }
+ public NeutronSubnet_IPAllocationPool() {
+ }
public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {
poolStart = lowAddress;
package org.opendaylight.controller.networkconfig.neutron;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class Neutron_IPs {
+public class Neutron_IPs implements Serializable {
+ private static final long serialVersionUID = 1L;
+
// See OpenStack Network API v2.0 Reference for description of
// annotated attributes
<Import-Package>
org.opendaylight.controller.sal.core,
org.opendaylight.controller.sal.utils,
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.containermanager,
org.opendaylight.controller.switchmanager,
org.opendaylight.controller.usermanager,
import org.codehaus.enunciate.jaxrs.ResponseCode;
import org.codehaus.enunciate.jaxrs.StatusCodes;
import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.configuration.IConfigurationService;
import org.opendaylight.controller.containermanager.IContainerManager;
import org.opendaylight.controller.northbound.commons.RestMessages;
import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
return NorthboundUtils.getResponse(status);
}
+ /**
+ * Save controller configuration
+ *
+ * Request URL:
+ * http://localhost:8080/controller/nb/v2/controllermanager/configuration
+ *
+ * Request body is empty
+ */
+ @Path("/configuration")
+ @PUT
+ @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
+ @ResponseCode(code = 503, condition = "Configuration service is unavailable.")
+ })
+ public Response saveConfiguration() {
+
+ if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
+ throw new UnauthorizedException("User is not authorized to perform this operation");
+ }
+
+ IConfigurationService configService = (IConfigurationService)
+ ServiceHelper.getGlobalInstance(IConfigurationService.class, this);
+
+ if (configService == null) {
+ throw new ServiceUnavailableException("Configuration Service " +
+ RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ Status status = configService.saveConfigurations();
+ if (status.isSuccess()) {
+ NorthboundUtils.auditlog("Controller Configuration", username,
+ "save", "configuration");
+ return Response.noContent().build();
+ }
+ return NorthboundUtils.getResponse(status);
+ }
+
private boolean isValidContainer(String containerName) {
if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
return true;
for (OFStatistics stats : targetList) {
V6StatsReply v6Stats = (V6StatsReply) stats;
V6Match v6Match = v6Stats.getMatch();
- if (v6Stats.getPriority() == priority && v6Match.equals(targetMatch)) {
+ if (v6Stats.getPriority() == priority && targetMatch.equals(v6Match)) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
} else {
for (OFStatistics stats : statsList) {
OFFlowStatisticsReply flowStats = (OFFlowStatisticsReply) stats;
- if (flowStats.getPriority() == priority && flowStats.getMatch().equals(ofMatch)) {
+ if (flowStats.getPriority() == priority && ofMatch.equals(flowStats.getMatch())) {
List<OFStatistics> list = new ArrayList<OFStatistics>();
list.add(stats);
return list;
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
}
}
+ @Override
+ public Set<Node> getConfiguredNotConnectedNodes() {
+ // TODO
+ return null;
+ }
+
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.0-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.0-SNAPSHOT</version>
+ <version>0.4.1-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
one.f.menu = {
left : {
top : [
- one.f.dashlet.nodesLearnt,
- one.f.dashlet.connection
+ one.f.dashlet.nodesLearnt
],
bottom : [
- one.f.dashlet.staticRouteConfig
+ one.f.dashlet.staticRouteConfig,
+ one.f.dashlet.connection
]
},
right : {
$fieldset.append($label).append($select);
// input port
- var $label = one.lib.form.label("Input Port");
+ var $label = one.lib.form.label("Port");
var $select = one.lib.form.select.create();
one.lib.form.select.prepend($select, {'':'None'});
$select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
$tr = $(tr);
$span = $("td span", $tr);
var flowstatus = $span.data("flowstatus");
- if($span.data("installInHw") != null) {
- var installInHw = $span.data("installInHw").toString();
+ if($span.data("installinhw") != null) {
+ var installInHw = $span.data("installinhw").toString();
if(installInHw == "true" && flowstatus == "Success") {
$tr.addClass("success");
} else {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
+ <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>