<yangtools.binding.version>0.6.0-SNAPSHOT</yangtools.binding.version>
<!--versions for bits of the controller -->
<controller.version>0.4.1-SNAPSHOT</controller.version>
- <config.version>0.2.2-SNAPSHOT</config.version>
- <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+ <config.version>0.2.3-SNAPSHOT</config.version>
+ <netconf.version>0.2.3-SNAPSHOT</netconf.version>
<mdsal.version>1.0-SNAPSHOT</mdsal.version>
<containermanager.version>0.5.1-SNAPSHOT</containermanager.version>
<switchmanager.api.version>0.6.1-SNAPSHOT</switchmanager.api.version>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>config-api</artifactId>
org.opendaylight.controller.config.api.jmx,
org.opendaylight.controller.config.api.jmx.constants,
org.opendaylight.controller.config.api.runtime,
- org.opendaylight.controller.config.stat,
</Export-Package>
</instructions>
</configuration>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.stat;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * Subset of {@link org.osgi.framework.BundleContext}
- */
-public interface ConfigProvider {
- /**
- * Returns the value of the specified property. If the key is not found in
- * the Framework properties, the system properties are then searched. The
- * method returns {@code null} if the property is not found.
- *
- * <p>
- * All bundles must have permission to read properties whose names start
- * with "org.osgi.".
- *
- * @param key
- * The name of the requested property.
- * @return The value of the requested property, or {@code null} if the
- * property is undefined.
- * @throws SecurityException
- * If the caller does not have the appropriate
- * {@code PropertyPermission} to read the property, and the Java
- * Runtime Environment supports permissions.
- */
- String getProperty(String key);
-
- public static class ConfigProviderImpl implements ConfigProvider {
- private final BundleContext context;
-
- public ConfigProviderImpl(BundleContext context) {
- this.context = context;
- }
-
- @Override
- public String getProperty(String key) {
- return context.getProperty(key);
- }
-
- @Override
- public String toString() {
- return "ConfigProviderImpl{" + "context=" + context + '}';
- }
- }
-
-}
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-manager</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-api</artifactId>
com.google.common.base,
org.w3c.dom,
org.osgi.framework,
- org.opendaylight.controller.config.stat
</Import-Package>
<Export-Package>
org.opendaylight.controller.config.persist.api,
package org.opendaylight.controller.config.persist.api.storage;
import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
/**
* Plugins for {@link org.opendaylight.controller.config.persist.api.Persister}
*/
public interface StorageAdapter extends Persister {
- void setProperties(ConfigProvider configProvider);
+ void setProperties(BundleContext bundleContext);
}
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-persister-file-adapter</artifactId>
javax.xml.transform.stream,
org.apache.commons.lang3,
org.opendaylight.controller.config.persist.api,
- org.opendaylight.controller.config.stat,
org.opendaylight.controller.config.persist.api.storage,
org.slf4j,
org.w3c.dom,
import com.google.common.io.Files;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
private File storage;
@Override
- public void setProperties(ConfigProvider configProvider) {
- File storage = extractStorageFileFromProperties(configProvider);
+ public void setProperties(BundleContext bundleContext) {
+ File storage = extractStorageFileFromProperties(bundleContext);
logger.debug("Using file {}", storage.getAbsolutePath());
// Create file if it does not exist
File parentFile = storage.getAbsoluteFile().getParentFile();
numberOfStoredBackups = numberOfBackups;
}
- private static File extractStorageFileFromProperties(ConfigProvider configProvider) {
- String fileStorageProperty = configProvider.getProperty(FILE_STORAGE_PROP);
+ private static File extractStorageFileFromProperties(BundleContext bundleContext) {
+ String fileStorageProperty = bundleContext.getProperty(FILE_STORAGE_PROP);
Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + FILE_STORAGE_PROP
- + " in received properties :" + configProvider);
+ + " in received context :" + bundleContext);
File result = new File(fileStorageProperty);
- String numberOfBAckupsAsString = configProvider.getProperty(NUMBER_OF_BACKUPS);
+ String numberOfBAckupsAsString = bundleContext.getProperty(NUMBER_OF_BACKUPS);
if (numberOfBAckupsAsString != null) {
numberOfStoredBackups = Integer.valueOf(numberOfBAckupsAsString);
} else {
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>config-util</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>logback-config</artifactId>
<name>${project.artifactId}</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
</parent>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<artifactId>config-subsystem</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>threadpool-config-api</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>threadpool-config-impl</artifactId>
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator-it</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-jmx-generator-plugin</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>yang-jmx-generator</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-store-api</artifactId>
<parent>
<artifactId>config-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>yang-store-impl</artifactId>
<parent>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-subsystem</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>yang-test</artifactId>
<artifactId>model-flow-management</artifactId>
<version>${mdsal.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.md</groupId>
+ <artifactId>inventory-manager</artifactId>
+ <version>${mdsal.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-generator-util</artifactId>
+ <artifactId>binding-generator-spi</artifactId>
<version>${yangtools.binding.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-model-api</artifactId>
+ <artifactId>binding-generator-api</artifactId>
<version>${yangtools.binding.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-generator-spi</artifactId>
+ <artifactId>binding-generator-impl</artifactId>
+ <version>${yangtools.binding.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>binding-generator-util</artifactId>
+ <version>${yangtools.binding.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>binding-model-api</artifactId>
<version>${yangtools.binding.version}</version>
</dependency>
<dependency>
</plugins>
</build>
<dependencies>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi</artifactId>
--- /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.datastore;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface ClusteredDataStore extends DataReader<InstanceIdentifier<? extends Object>, Object>, DataCommitHandler<InstanceIdentifier<? extends Object>,Object> {
+}
package org.opendaylight.controller.datastore.internal;
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+
public class Activator extends ComponentActivatorAbstractBase {
protected static final Logger logger = LoggerFactory
.getLogger(Activator.class);
+ @Override
+ protected Object[] getGlobalImplementations(){
+ logger.debug("Calling getGlobalImplementations to return:", ClusteredDataStoreManager.class);
+ return new Object[] {
+ ClusteredDataStoreManager.class
+ };
+ }
+
+
+ @Override
+ protected void configureGlobalInstance(Component c, Object imp){
+ if (imp.equals(ClusteredDataStoreManager.class)) {
+ Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
+
+ c.setInterface(new String[] { ClusteredDataStore.class.getName() }, props);
+ logger.debug("configureGlobalInstance adding dependency:", IClusterGlobalServices.class);
+
+ c.add(createServiceDependency().setService(
+ IClusterGlobalServices.class).setCallbacks(
+ "setClusterGlobalServices",
+ "unsetClusterGlobalServices").setRequired(true));
+
+ }
+ }
+
}
+++ /dev/null
-package org.opendaylight.controller.datastore.internal;
-
-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.yangtools.yang.binding.InstanceIdentifier;
-
-public class ClusteredDataStore implements DataReader<InstanceIdentifier<? extends Object>, Object>, DataCommitHandler<InstanceIdentifier<? extends Object>,Object> {
- @Override
- public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
- return null;
- }
-
- @Override
- public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
- return null;
- }
-
- @Override
- public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
- return null;
- }
-}
--- /dev/null
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.datastore.internal;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * The ClusteredDataStoreImpl stores global data to be shared across a controller cluster. It uses Clustering Services.
+ */
+public class ClusteredDataStoreImpl implements ClusteredDataStore {
+
+
+ public static final String OPERATIONAL_DATA_CACHE = "clustered_data_store.operational_data_cache";
+ public static final String CONFIGURATION_DATA_CACHE = "clustered_data_store.configuration_data_cache";
+
+ private ConcurrentMap operationalDataCache;
+ private ConcurrentMap configurationDataCache;
+
+ public ClusteredDataStoreImpl(IClusterGlobalServices clusterGlobalServices) throws CacheExistException, CacheConfigException {
+ Preconditions.checkNotNull(clusterGlobalServices, "clusterGlobalServices cannot be null");
+
+ operationalDataCache = clusterGlobalServices.createCache(OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ if(operationalDataCache == null){
+ Preconditions.checkNotNull(operationalDataCache, "operationalDataCache cannot be null");
+ }
+
+ configurationDataCache = clusterGlobalServices.createCache(CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+ if(configurationDataCache == null){
+ Preconditions.checkNotNull(configurationDataCache, "configurationDataCache cannot be null");
+ }
+
+ }
+
+ @Override
+ public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
+ return new ClusteredDataStoreTransaction(modification);
+ }
+
+ @Override
+ public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
+ Preconditions.checkNotNull(path, "path cannot be null");
+ return operationalDataCache.get(path);
+ }
+
+ @Override
+ public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
+ Preconditions.checkNotNull(path, "path cannot be null");
+ return configurationDataCache.get(path);
+ }
+
+ private RpcResult<Void> finish(final ClusteredDataStoreTransaction transaction) {
+ final DataModification<InstanceIdentifier<? extends Object>,Object> modification = transaction.getModification();
+
+ this.configurationDataCache.putAll(modification.getUpdatedConfigurationData());
+ this.operationalDataCache.putAll(modification.getUpdatedOperationalData());
+
+ for (final InstanceIdentifier<? extends Object> removal : modification.getRemovedConfigurationData()) {
+ this.configurationDataCache.remove(removal);
+ }
+
+ for (final InstanceIdentifier<? extends Object> removal : modification.getRemovedOperationalData()) {
+ this.operationalDataCache.remove(removal );
+ }
+
+ Set<RpcError> _emptySet = Collections.<RpcError>emptySet();
+ return Rpcs.<Void>getRpcResult(true, null, _emptySet);
+ }
+
+ private RpcResult<Void> rollback(final ClusteredDataStoreTransaction transaction) {
+ Set<RpcError> _emptySet = Collections.<RpcError>emptySet();
+ return Rpcs.<Void>getRpcResult(true, null, _emptySet);
+ }
+
+ private class ClusteredDataStoreTransaction implements DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> {
+ private final DataModification<InstanceIdentifier<? extends Object>,Object> modification;
+
+ public ClusteredDataStoreTransaction(DataModification<InstanceIdentifier<? extends Object>,Object> modification){
+ Preconditions.checkNotNull(modification, "modification cannot be null");
+
+ this.modification = modification;
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier<? extends Object>, Object> getModification() {
+ return this.modification;
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ return ClusteredDataStoreImpl.this.finish(this);
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ return ClusteredDataStoreImpl.this.rollback(this);
+ }
+ }
+}
--- /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.datastore.internal;
+
+import com.google.common.base.Preconditions;
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ClusteredDataStoreManager implements ClusteredDataStore {
+
+ private ClusteredDataStoreImpl clusteredDataStore = null;
+ private IClusterGlobalServices clusterGlobalServices = null;
+
+ @Override
+ public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
+ Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+ return clusteredDataStore.requestCommit(modification);
+ }
+
+ @Override
+ public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
+ Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+ return clusteredDataStore.readOperationalData(path);
+ }
+
+ @Override
+ public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
+ Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+ return clusteredDataStore.readConfigurationData(path);
+ }
+
+
+ public void setClusterGlobalServices(IClusterGlobalServices clusterGlobalServices){
+ this.clusterGlobalServices = clusterGlobalServices;
+ }
+
+ public void unsetClusterGlobalServices(IClusterGlobalServices clusterGlobalServices){
+ this.clusterGlobalServices = null;
+ this.clusteredDataStore = null;
+ }
+
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ try {
+ //Adding creation of the clustered data store in its own method to make the method unit testable
+ clusteredDataStore = createClusteredDataStore(c);
+ } catch (CacheExistException e) {
+ throw new IllegalStateException("could not construct clusteredDataStore");
+ } catch (CacheConfigException e) {
+ throw new IllegalStateException("could not construct clusteredDataStore");
+ }
+ }
+ protected ClusteredDataStoreImpl createClusteredDataStore(Component c) throws CacheExistException,CacheConfigException{
+ return new ClusteredDataStoreImpl(clusterGlobalServices);
+ }
+}
+
+/*
+ * 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.datastore.internal;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ServiceDependency;
+
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class ActivatorTest {
+ private static ServiceDependency serviceDependency;
+
+ @BeforeClass
+ public static void initialize(){
+ serviceDependency = mock(ServiceDependency.class);
+ }
+
+ private class ActivatorTestImpl extends Activator{
+ protected ServiceDependency createServiceDependency() {
+ return ActivatorTest.serviceDependency;
+ }
+ }
+
@Test
public void construct(){
assertNotNull(new Activator());
}
+
+ @Test
+ public void construct_OnInvokeOfGlobalImpl_ShouldReturnNotNullObject(){
+ Activator activator = new Activator();
+
+ assertNotNull(activator.getGlobalImplementations());
+ assertEquals(ClusteredDataStoreManager.class,activator.getGlobalImplementations()[0]);
+ }
+
+ @Test
+ public void construct_OnInvokeOfConfigGlobalInstance_ShouldNotThrowAnyExceptions(){
+ Activator activator = new ActivatorTestImpl();
+
+ Component c = mock(Component.class);
+ Object clusterDataStoreMgr = ClusteredDataStoreManager.class;
+
+ when(serviceDependency.setService(IClusterGlobalServices.class)).thenReturn(serviceDependency);
+ when(serviceDependency.setCallbacks("setClusterGlobalServices",
+ "unsetClusterGlobalServices")).thenReturn(serviceDependency);
+ when(serviceDependency.setRequired(true)).thenReturn(serviceDependency);
+
+
+ activator.configureGlobalInstance(c, clusterDataStoreMgr);
+
+
+ }
+
}
--- /dev/null
+package org.opendaylight.controller.datastore.internal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+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.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ClusteredDataStoreImplTest {
+ @Before
+ public void setUp(){
+
+ }
+
+ @Test
+ public void constructor_WhenPassedANullClusteringServices_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+ try {
+ new ClusteredDataStoreImpl(null);
+ } catch(NullPointerException npe){
+ assertEquals("clusterGlobalServices cannot be null", npe.getMessage());
+ }
+ }
+
+ @Test
+ public void constructor_WhenClusteringServicesReturnsANullOperationalDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+ try {
+ new ClusteredDataStoreImpl(mock(IClusterGlobalServices.class));
+ } catch(NullPointerException npe){
+ assertEquals("operationalDataCache cannot be null", npe.getMessage());
+ }
+ }
+
+ @Test
+ public void constructor_WhenClusteringServicesReturnsANullOConfigurationDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+ // Confused about the following line?
+ // See this http://stackoverflow.com/questions/10952629/a-strange-generics-edge-case-with-mockito-when-and-generic-type-inference
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
+
+
+ try {
+ new ClusteredDataStoreImpl(mockClusterGlobalServices);
+ } catch(NullPointerException npe){
+ assertEquals("configurationDataCache cannot be null", npe.getMessage());
+ }
+ }
+
+ @Test
+ public void constructor_WhenPassedAValidClusteringServices_ShouldNotThrowAnyExceptions() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ new ClusteredDataStoreImpl(mockClusterGlobalServices);
+ }
+
+
+ @Test
+ public void readOperationalData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ try {
+ store.readOperationalData(null);
+ } catch(NullPointerException npe){
+ assertEquals("path cannot be null", npe.getMessage());
+ }
+ }
+
+ @Test
+ public void readOperationalData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
+ InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ assertNull(store.readOperationalData(path));
+ }
+
+ @Test
+ public void readOperationalData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
+ InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+ Object valueObject = mock(Object.class);
+
+ when(mockOperationalDataCache.get(path)).thenReturn(valueObject);
+
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
+
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ assertEquals(valueObject, store.readOperationalData(path));
+ }
+
+
+
+ @Test
+ public void readConfigurationData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ try {
+ store.readConfigurationData(null);
+ } catch(NullPointerException npe){
+ assertEquals("path cannot be null", npe.getMessage());
+ }
+ }
+
+
+ @Test
+ public void readConfigurationData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
+ InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ assertNull(store.readConfigurationData(path));
+ }
+
+ @Test
+ public void readConfigurationData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
+ InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+
+ Object valueObject = mock(Object.class);
+
+ when(mockConfigurationDataCache.get(path)).thenReturn(valueObject);
+
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ assertEquals(valueObject, store.readConfigurationData(path));
+ }
+
+
+ @Test
+ public void requestCommit_ShouldReturnADataTransaction() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ assertNotNull(store.requestCommit(mock(DataModification.class)));
+
+
+ }
+
+ @Test
+ public void finishingADataTransaction_ShouldUpdateTheUnderlyingCache() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+ ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+ ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ DataModification mockModification = mock(DataModification.class);
+
+ Map configurationData = mock(Map.class);
+ Map operationalData = mock(Map.class);
+
+ when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
+ when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
+
+ DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> transaction = store.requestCommit(mockModification);
+
+ transaction.finish();
+
+ verify(mockConfigurationDataCache).putAll(mockModification.getUpdatedConfigurationData());
+ verify(mockOperationalDataCache).putAll(mockModification.getUpdatedOperationalData());
+ }
+
+
+ @Test
+ public void rollingBackADataTransaction_ShouldDoNothing() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+ ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+ ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+ ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+ DataModification mockModification = mock(DataModification.class);
+
+ Map configurationData = mock(Map.class);
+ Map operationalData = mock(Map.class);
+
+ when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
+ when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
+
+ DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> transaction = store.requestCommit(mockModification);
+
+ transaction.rollback();
+
+ verify(mockConfigurationDataCache, never()).putAll(mockModification.getUpdatedConfigurationData());
+ verify(mockOperationalDataCache, never()).putAll(mockModification.getUpdatedOperationalData());
+
+ }
+
+
+ private IClusterGlobalServices createClusterGlobalServices() throws CacheExistException, CacheConfigException {
+ IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+ Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+
+ return mockClusterGlobalServices;
+ }
+}
--- /dev/null
+package org.opendaylight.controller.datastore.internal;
+
+import org.apache.felix.dm.Component;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+public class ClusteredDataStoreManagerTest {
+
+ private static ClusteredDataStoreManager clusteredDSMgr = null;
+ private IClusterGlobalServices icClusterGlbServices = mock(IClusterGlobalServices.class);
+
+ @BeforeClass
+ public static void construct(){
+ clusteredDSMgr = new ClusteredDataStoreManager();
+ assertNotNull(clusteredDSMgr);
+ }
+
+ @Test
+ public void construct_OnSetClusterGlobalServices_AssertNoException(){
+ icClusterGlbServices = mock(IClusterGlobalServices.class);
+
+ clusteredDSMgr.setClusterGlobalServices(icClusterGlbServices);
+ }
+
+ @Test
+ public void construct_OnUnSetClusterGlobalServices_AssertNoException(){
+ IClusterGlobalServices icClusterGlbServices = mock(IClusterGlobalServices.class);
+
+ clusteredDSMgr.unsetClusterGlobalServices(icClusterGlbServices);
+ }
+
+ @Test
+ public void construct_init_AssertNoException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class);
+
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void construct_init_AssertCacheExistException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doThrow(CacheExistException.class).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void construct_init_AssertCacheConfigException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doThrow(CacheConfigException.class).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+ }
+
+ @Test
+ public void construct_readOperationalData_AssertNoException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class);
+
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+
+ Object o = mock(Object.class);
+
+ when(clusteredDSImpl.readOperationalData(any(InstanceIdentifier.class))).thenReturn(o);
+ assertEquals(o,clusteredDSManager.readOperationalData(any(InstanceIdentifier.class)));
+ }
+
+
+ @Test
+ public void construct_readConfigurationData_AssertNoException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class);
+
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+ Object o = mock(Object.class);
+
+ when(clusteredDSImpl.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(o);
+ assertEquals(o,clusteredDSManager.readConfigurationData(any(InstanceIdentifier.class)));
+ }
+
+ @Test
+ public void construct_requestCommit_AssertNoException() throws CacheExistException,CacheConfigException{
+ ClusteredDataStoreImpl clusteredDSImpl = mock(ClusteredDataStoreImpl.class);
+
+ ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+ doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+ Component c = mock(Component.class);
+
+ clusteredDSManager.init(c);
+ DataCommitTransaction dataCommitTransaction = mock(DataCommitTransaction.class);
+
+ when(clusteredDSImpl.requestCommit(any(DataModification.class))).thenReturn(dataCommitTransaction);
+ assertEquals(dataCommitTransaction,clusteredDSManager.requestCommit(any(DataModification.class)));
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.datastore.internal;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-
-public class ClusteredDataStoreTest {
- @Test
- public void construct(){
- assertNotNull(new ClusteredDataStore());
- }
-}
<build>
<plugins>
+
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
+
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.core.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>javassist</artifactId>
<version>3.17.1-GA</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>binding-generator-impl</artifactId>
+ <version>0.6.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-parser-impl</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-broker-impl</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.eclipse.xtend</groupId>
<artifactId>org.eclipse.xtend.lib</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.standalone</artifactId>
+ <version>2.4.3</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-config</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-flow-service</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-model-util</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
import java.util.HashSet
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory
import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker
import java.util.Set
import org.opendaylight.yangtools.yang.binding.BaseIdentity
import com.google.common.collect.Multimap
import com.google.common.collect.HashMultimap
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
import java.util.concurrent.Executors
import java.util.Collections
import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.impl.connect.dom.ConnectorActivator
class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
ServiceRegistration<DataBrokerService> dataConsumerRegistration
- private HashMapDataStore store = new HashMapDataStore();
+ ConnectorActivator connectorActivator
+
public new(BundleContext bundleContext) {
_brokerBundleContext = bundleContext;
notifyConsumerRegistration = brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties)
dataProviderRegistration = brokerBundleContext.registerService(DataProviderService, dataBroker, brokerProperties)
dataConsumerRegistration = brokerBundleContext.registerService(DataBrokerService, dataBroker, brokerProperties)
-
-
- getDataBroker().registerDataReader(root, store);
- getDataBroker().registerCommitHandler(root, store)
-
+
+ connectorActivator = new ConnectorActivator(dataBroker,brokerBundleContext);
+ connectorActivator.start();
log.info("MD-SAL: Binding Aware Broker Started");
}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+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.common.RpcResult;
+
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements
+ DataProviderService {
+
+ public DataBrokerImpl() {
+ setDataReadRouter(new BindingAwareDataReaderRouter());
+ }
+
+ @Override
+ public DataTransactionImpl beginTransaction() {
+ return new DataTransactionImpl(this);
+ }
+
+ @Override
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+ DataChangeListener changeListener) {
+ // TODO Auto-generated method stub
+
+ }
+
+
+}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.yangtools.concepts.ListenerRegistration
-import com.google.common.collect.Multimap
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import com.google.common.collect.HashMultimap
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Callable
-import org.opendaylight.yangtools.yang.common.RpcResult
-import org.opendaylight.controller.sal.common.util.Rpcs
-import java.util.Collections
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import java.util.ArrayList
-import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter
-import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
-import java.util.Arrays
-
-class DataBrokerImpl extends DeprecatedDataAPISupport implements DataProviderService {
-
- @Property
- var ExecutorService executor;
-
- val dataReadRouter = new BindingAwareDataReaderRouter;
-
- Multimap<InstanceIdentifier, DataChangeListenerRegistration> listeners = HashMultimap.create();
- Multimap<InstanceIdentifier, DataCommitHandlerRegistration> commitHandlers = HashMultimap.create();
-
- override beginTransaction() {
- return new DataTransactionImpl(this);
- }
-
- override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
- return dataReadRouter.readConfigurationData(path);
- }
-
- override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- return dataReadRouter.readOperationalData(path);
- }
-
- override registerCommitHandler(InstanceIdentifier<? extends DataObject> path,
- DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
- val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
- commitHandlers.put(path,registration)
- return registration;
- }
-
- override registerDataChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
- val reg = new DataChangeListenerRegistration(path, listener, this);
- listeners.put(path, reg);
- return reg;
- }
-
- override registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader) {
-
- val confReg = dataReadRouter.registerConfigurationReader(path,reader);
- val dataReg = dataReadRouter.registerOperationalReader(path,reader);
-
- return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
- }
-
- protected def removeListener(DataChangeListenerRegistration registration) {
- listeners.remove(registration.path, registration);
- }
-
- protected def removeCommitHandler(DataCommitHandlerRegistration registration) {
- commitHandlers.remove(registration.path, registration);
- }
-
- protected def getActiveCommitHandlers() {
- return commitHandlers.entries.map[ value.instance].toSet
- }
-
- protected def commit(DataTransactionImpl transaction) {
- checkNotNull(transaction);
- transaction.changeStatus(TransactionStatus.SUBMITED);
- val task = new TwoPhaseCommit(transaction, this);
- return executor.submit(task);
- }
-
-}
-
-package class DataChangeListenerRegistration extends AbstractObjectRegistration<DataChangeListener> implements ListenerRegistration<DataChangeListener> {
-
- DataBrokerImpl dataBroker;
-
- @Property
- val InstanceIdentifier<?> path;
-
- new(InstanceIdentifier<?> path, DataChangeListener instance, DataBrokerImpl broker) {
- super(instance)
- dataBroker = broker;
- _path = path;
- }
-
- override protected removeRegistration() {
- dataBroker.removeListener(this);
- dataBroker = null;
- }
-
-}
-
-package class DataCommitHandlerRegistration //
-extends AbstractObjectRegistration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> {
-
- DataBrokerImpl dataBroker;
-
- @Property
- val InstanceIdentifier<?> path;
-
- new(InstanceIdentifier<?> path, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> instance,
- DataBrokerImpl broker) {
- super(instance)
- dataBroker = broker;
- _path = path;
- }
-
- override protected removeRegistration() {
- dataBroker.removeCommitHandler(this);
- dataBroker = null;
- }
-
-}
-
-package class TwoPhaseCommit implements Callable<RpcResult<TransactionStatus>> {
-
- val DataTransactionImpl transaction;
- val DataBrokerImpl dataBroker;
-
- new(DataTransactionImpl transaction, DataBrokerImpl broker) {
- this.transaction = transaction;
- this.dataBroker = broker;
- }
-
- override call() throws Exception {
-
- val Iterable<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlers = dataBroker.activeCommitHandlers;
-
- // requesting commits
- val List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> handlerTransactions = new ArrayList();
- try {
- for (handler : commitHandlers) {
- handlerTransactions.add(handler.requestCommit(transaction));
- }
- } catch (Exception e) {
- return rollback(handlerTransactions,e);
- }
- val List<RpcResult<Void>> results = new ArrayList();
- try {
- for (subtransaction : handlerTransactions) {
- results.add(subtransaction.finish());
- }
- } catch (Exception e) {
- return rollback(handlerTransactions,e);
- }
-
- return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
- }
-
- def rollback(List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> transactions,Exception e) {
- for (transaction : transactions) {
- transaction.rollback()
- }
- // FIXME return encoutered error.
- return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
- }
-}
package org.opendaylight.controller.sal.binding.impl;
-import java.util.concurrent.Future;
-
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
-import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class DataTransactionImpl extends AbstractDataModification<InstanceIdentifier<? extends DataObject>, DataObject>
- implements DataModificationTransaction {
-
- private final Object identifier;
-
- private TransactionStatus status;
- private ListenerRegistry<DataTransactionListener> listeners;
-
- final DataBrokerImpl broker;
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier<? extends DataObject>, DataObject>
+ implements DataModificationTransaction {
+ private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+
+
+
public DataTransactionImpl(DataBrokerImpl dataBroker) {
super(dataBroker);
- identifier = new Object();
- broker = dataBroker;
- status = TransactionStatus.NEW;
- listeners = new ListenerRegistry<>();
- }
-
- @Override
- public Future<RpcResult<TransactionStatus>> commit() {
- return broker.commit(this);
- }
-
- @Override
- public DataObject readConfigurationData(
- org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
- return broker.readConfigurationData(path);
- }
-
- @Override
- public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- return broker.readOperationalData(path);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((broker == null) ? 0 : broker.hashCode());
- result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- DataTransactionImpl other = (DataTransactionImpl) obj;
- if (broker == null) {
- if (other.broker != null)
- return false;
- } else if (!broker.equals(other.broker))
- return false;
- if (identifier == null) {
- if (other.identifier != null)
- return false;
- } else if (!identifier.equals(other.identifier))
- return false;
- return true;
- }
-
- @Override
- public TransactionStatus getStatus() {
- return status;
- }
-
- @Override
- public Object getIdentifier() {
- return identifier;
}
@Override
return listeners.register(listener);
}
- public void changeStatus(TransactionStatus status) {
- this.status = status;
- Iterable<ListenerRegistration<DataTransactionListener>> listenersToNotify = listeners.getListeners();
- for (ListenerRegistration<DataTransactionListener> listenerRegistration : listenersToNotify) {
+ protected void onStatusChange(TransactionStatus status) {
+ for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
listenerRegistration.getInstance().onStatusUpdated(this, status);
}
}
-}
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+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.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.base.Preconditions;
+
+public class BindingIndependentDataServiceConnector implements //
+ RuntimeDataProvider, //
+ DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
+
+ private BindingIndependentMappingService mappingService;
+
+ private DataBrokerService biDataService;
+
+ private DataProviderService baDataService;
+
+ @Override
+ public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ // TODO Auto-generated method stub
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+ CompositeNode result = biDataService.readOperationalData(biPath);
+ return mappingService.dataObjectFromDataDom(path, result);
+ }
+
+ @Override
+ public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+ CompositeNode result = biDataService.readConfigurationData(biPath);
+ return mappingService.dataObjectFromDataDom(path, result);
+ }
+
+ @Override
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+
+ DataModificationTransaction translated = translateTransaction(modification);
+ return new WrappedTransaction(translated, modification);
+ }
+
+ private DataModificationTransaction translateTransaction(
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
+ DataModificationTransaction target = biDataService.beginTransaction();
+ for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
+ .entrySet()) {
+ Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+ .toDataDom(entry);
+ target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+ }
+ for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
+ .entrySet()) {
+ Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+ .toDataDom(entry);
+ target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+ }
+ for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+ target.removeConfigurationData(biEntry);
+ }
+ for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+ target.removeOperationalData(biEntry);
+ }
+ return target;
+ }
+
+ private class WrappedTransaction implements
+ DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+ private DataModificationTransaction backing;
+ private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+ public WrappedTransaction(DataModificationTransaction backing,
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+ this.backing = backing;
+ this.modification = modification;
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+ return modification;
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ Future<RpcResult<TransactionStatus>> result = backing.commit();
+ try {
+ RpcResult<TransactionStatus> biresult = result.get();
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("", e);
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("", e);
+ }
+ return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // backing.cancel();
+ return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ }
+
+ }
+
+ public DataBrokerService getBiDataService() {
+ return biDataService;
+ }
+
+ public void setBiDataService(DataBrokerService biDataService) {
+ this.biDataService = biDataService;
+ }
+
+ public DataProviderService getBaDataService() {
+ return baDataService;
+ }
+
+ public void setBaDataService(DataProviderService baDataService) {
+ this.baDataService = baDataService;
+ }
+
+ public void start() {
+ baDataService.registerDataReader(ROOT, this);
+ baDataService.registerCommitHandler(ROOT, this);
+ }
+
+ public void setMappingService(BindingIndependentMappingService mappingService) {
+ this.mappingService = mappingService;
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface BindingIndependentMappingService {
+
+ CompositeNode toDataDom(DataObject data);
+
+ Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+ Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry);
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
+
+ DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class BindingIndependentRpcConnector {
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext
+import java.util.List
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import java.util.Map
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import org.opendaylight.yangtools.binding.generator.util.Types
+import java.util.HashMap
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import java.util.Collections
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import org.opendaylight.yangtools.yang.model.util.ExtendedType
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+
+class BindingMapping {
+
+ val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
+ val Map<Type, SchemaNode> typeToSchemaNode = new HashMap();
+
+ def QName getSchemaNode(Class<?> cls) {
+ val ref = Types.typeForClass(cls);
+ return typeToSchemaNode.get(ref)?.QName;
+ }
+
+ def void updateBinding(SchemaContext schemaContext, ModuleContext moduleBindingContext) {
+ updateBindingFor(moduleBindingContext.childNodes, schemaContext);
+
+ }
+
+ def org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+ InstanceIdentifier<? extends DataObject> obj) {
+ val pathArguments = obj.path;
+ var Class<? extends DataObject> parent;
+ val dataDomArgs = new ArrayList<PathArgument>();
+ for (pathArgument : pathArguments) {
+ dataDomArgs.add(pathArgument.toDataDomPathArgument(parent));
+ parent = pathArgument.type;
+ }
+
+ return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(dataDomArgs);
+ }
+
+
+
+ def DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> identifier, CompositeNode node) {
+ if (node == null) {
+ return null;
+ }
+ val targetClass = identifier.targetType;
+ val classLoader = targetClass.classLoader;
+ val ref = Types.typeForClass(targetClass);
+ val targetType = typeToDefinition.get(ref);
+ val targetSchema = typeToSchemaNode.get(ref);
+ return node.toDataObject(classLoader, targetType.toInstance, targetSchema);
+
+ }
+
+ def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
+ val Class rawType = argument.type;
+ val ref = Types.typeForClass(rawType);
+ val schemaType = typeToSchemaNode.get(ref);
+ val qname = schemaType.QName
+
+ val Object key = argument.key;
+ val predicates = key.toPredicates(schemaType as ListSchemaNode);
+
+ return new NodeIdentifierWithPredicates(qname, predicates);
+ }
+
+ def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+ val ref = Types.typeForClass(argument.type);
+ val qname = typeToSchemaNode.get(ref).QName
+ return new NodeIdentifier(qname);
+ }
+
+ def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+ val keyDefinitions = node.keyDefinition;
+ val map = new HashMap<QName, Object>();
+ for (keydef : keyDefinitions) {
+ val keyNode = node.getDataChildByName(keydef) as LeafSchemaNode;
+ val value = identifier.getSimpleValue(keydef, keyNode.type);
+ map.put(keydef, value.value);
+ }
+ return map;
+ }
+
+ def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+ for (entry : map.entrySet) {
+ val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+ typeToDefinition.put(entry.value, entry.value);
+ typeToSchemaNode.put(entry.value, schemaNode)
+ }
+ }
+
+ def CompositeNode toCompositeNode(DataContainer data) {
+ val type = data.implementedInterface;
+ val typeRef = Types.typeForClass(type);
+ val schemaNode = typeToSchemaNode.get(typeRef);
+ val generatedType = typeToDefinition.get(typeRef);
+
+ return data.toDataDom(schemaNode, generatedType);
+ }
+
+ private def dispatch CompositeNode toDataDom(DataContainer data, ContainerSchemaNode node,
+ GeneratedTypeBuilder builder) {
+ val subnodes = data.toDataDomComponents(node);
+ return new CompositeNodeTOImpl(node.QName, null, subnodes);
+ }
+
+ private def dispatch CompositeNode toDataDom(DataContainer data, NotificationDefinition node,
+ GeneratedTypeBuilder builder) {
+ val subnodes = data.toDataDomComponents(node);
+ return new CompositeNodeTOImpl(node.QName, null, subnodes);
+ }
+
+ private def dispatch CompositeNode toDataDom(DataContainer data, ListSchemaNode node,
+ GeneratedTypeBuilder builder) {
+ val subnodes = data.toDataDomComponents(node);
+ return new CompositeNodeTOImpl(node.QName, null, subnodes);
+ }
+
+ private def List<Node<?>> toDataDomComponents(DataContainer data, DataNodeContainer node) {
+ val subnodes = new ArrayList<Node<?>>();
+ for (childNode : node.childNodes) {
+ val value = childNode.dataDomFromParent(data);
+ if (value !== null) {
+ subnodes.addAll(value);
+ }
+ }
+ return subnodes;
+ }
+
+ private def List<Node<?>> dataDomFromParent(DataSchemaNode node, DataContainer container) {
+ if (node.augmenting) {
+ return Collections.emptyList();
+ }
+ return dataDomFromParentImpl(node, container);
+ }
+
+ private def dispatch List<Node<?>> dataDomFromParentImpl(LeafSchemaNode node, DataContainer container) {
+ val value = container.getSimpleValue(node.QName, node.type);
+ if (value !== null) {
+ return Collections.<Node<?>>singletonList(value);
+ }
+ return Collections.emptyList();
+ }
+
+ private def dispatch List<Node<?>> dataDomFromParentImpl(LeafListSchemaNode node, DataContainer container) {
+ val values = container.getSimpleValues(node);
+ if (values !== null) {
+ //val it = new ArrayList<Node<?>>();
+ //for (value : values) {
+ //}
+
+ }
+ return Collections.emptyList();
+ }
+
+ def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
+ return Collections.emptyList();
+ }
+
+ private def dispatch List<Node<?>> dataDomFromParentImpl(ListSchemaNode node, DataContainer container) {
+ val qname = node.QName;
+ val values = container.<List>getValue(qname, List) as List<? extends DataContainer>;
+ if (values === null) {
+ return Collections.emptyList;
+ }
+ val it = new ArrayList<Node<?>>();
+ for (value : values) {
+ add(value.toCompositeNode());
+ }
+
+ return it;
+ }
+
+ private def dispatch List<Node<?>> dataDomFromParentImpl(ChoiceNode node, DataContainer container) {
+ }
+
+ private def dispatch List<Node<?>> serializeValueImpl(List<?> list, GeneratedTypeBuilder builder,
+ ListSchemaNode node) {
+ val it = new ArrayList<Node<?>>();
+ for (value : list) {
+
+ val serVal = value.serializeValueImpl(builder, node);
+ if (serVal !== null) {
+ addAll(serVal);
+ }
+ }
+ return it;
+ }
+
+ private def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
+ getSimpleValue(container, name, type.baseType);
+ }
+
+ private def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
+ val value = container.getValue(name, String);
+ if(value === null) return null;
+ return new SimpleNodeTOImpl(name, null, value);
+ }
+
+ private def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
+ val value = container.getValue(name, Object);
+ if(value === null) return null;
+ return new SimpleNodeTOImpl(name, null, value);
+ }
+
+ private def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
+ val value = container.getValue(name, Boolean);
+ if(value === null) return null;
+ return new SimpleNodeTOImpl(name, null, value);
+ }
+
+ private def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
+ val Object value = container.getValue(name, Object); //Constants.BYTES_CLASS);
+ if(value === null) return null;
+ return new SimpleNodeTOImpl(name, null, value);
+ }
+
+ private def <T> T getValue(Object object, QName node, Class<T> type) {
+ val methodName = BindingGeneratorImpl.getterMethodName(node.localName, Types.typeForClass(type));
+ var clz = object.class;
+ if (object instanceof DataContainer) {
+ clz = (object as DataContainer).implementedInterface;
+ }
+ val method = clz.getMethod(methodName);
+ if (method === null) {
+ return null;
+ }
+ val value = method.invoke(object);
+ if (value === null) {
+ return null;
+ }
+ if (type.isAssignableFrom(value.class)) {
+ return value as T;
+ }
+ return value.getEncapsulatedValue(type);
+ }
+
+ private def <T> T getEncapsulatedValue(Object value, Class<T> type) {
+ val method = value.class.getMethod("getValue");
+ if (method !== null && type.isAssignableFrom(method.returnType)) {
+ return method.invoke(value) as T;
+ }
+ return null;
+ }
+
+ private def dispatch List<Node<?>> serializeValueImpl(DataContainer data, GeneratedTypeBuilder builder,
+ SchemaNode node) {
+ return Collections.<Node<?>>singletonList(data.toDataDom(node, builder));
+ }
+
+ private def dispatch List<Node<?>> serializeValueImpl(Object object, GeneratedTypeBuilder builder,
+ SchemaNode node) {
+ }
+
+ def DataObject toDataObject(CompositeNode node, ClassLoader loader, GeneratedType type, SchemaNode schema) {
+
+ // Nasty reflection hack (for now)
+ val builderClass = loader.loadClass(type.builderFQN);
+ val builder = builderClass.newInstance;
+ val buildMethod = builderClass.getMethod("build");
+
+ node.fillDataObject(builder, loader, type, schema);
+
+ return buildMethod.invoke(builder) as DataObject;
+ }
+
+ def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+ ListSchemaNode schema) {
+
+ if (schema.keyDefinition !== null && !schema.keyDefinition.empty) {
+
+ val value = node.keyToBindingKey(loader, type, schema);
+ builder.setProperty("key", value);
+ }
+ }
+
+ def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+ ContainerSchemaNode schema) {
+ }
+
+
+ def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
+ val keyClass = loader.loadClass(type.keyFQN);
+ val constructor = keyClass.constructors.get(0);
+ val keyType = type.keyTypeProperties;
+ val args = new ArrayList();
+ for (key : schema.keyDefinition) {
+ val keyProperty = keyType.get(BindingGeneratorUtil.parseToClassName(key.localName));
+ val domKeyValue = node.getFirstSimpleByName(key);
+ val keyValue = domKeyValue.deserializeSimpleValue(loader, keyProperty.returnType,
+ schema.getDataChildByName(key));
+ args.add(keyValue);
+ }
+ return ClassLoaderUtils.construct(constructor, args);
+ }
+
+ def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ LeafSchemaNode node2) {
+ deserializeSimpleValueImpl(node, loader, type, node2.type);
+ }
+
+ def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ LeafListSchemaNode node2) {
+ deserializeSimpleValueImpl(node, loader, type, node2.type);
+ }
+
+ def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ ExtendedType definition) {
+ deserializeSimpleValueImpl(node, loader, type, definition.baseType);
+ }
+
+ def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ StringTypeDefinition definition) {
+ if (type instanceof GeneratedTransferObject) {
+ val cls = loader.getClassForType(type);
+ val const = cls.getConstructor(String);
+ val str = String.valueOf(node.value);
+ return const.newInstance(str);
+ }
+ return node.value;
+ }
+
+ def Class<?> getClassForType(ClassLoader loader, Type type) {
+ loader.loadClass(type.fullyQualifiedName);
+ }
+
+ def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+ TypeDefinition definition) {
+ throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ }
+
+ def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
+ val method = FluentIterable.from(type.methodDefinitions).findFirst[name == "getKey"]
+ val key = method.returnType as GeneratedTransferObject;
+ val ret = new HashMap<String, GeneratedProperty>();
+ for (prop : key.properties) {
+ ret.put(prop.name, prop);
+ }
+ return ret;
+ }
+
+ def void setProperty(Object object, String property, Object value) {
+ val cls = object.class;
+ val valMethod = cls.getMethod("set" + property.toFirstUpper, value.class);
+ if (valMethod != null)
+ valMethod.invoke(object, value);
+ }
+
+ def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
+
+ def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
+
+}
+
+@Data
+class PropertyCapture {
+
+ @Property
+ val Type returnType;
+ @Property
+ val String name;
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Broker, Broker> {
+
+ BindingIndependentDataServiceConnector dataConnector;
+ BindingIndependentMappingService mappingService;
+
+ private final DataProviderService baDataService;
+ private BundleContext context;
+
+ private ServiceTracker<Broker, Broker> brokerTracker;
+
+ public ConnectorActivator(DataProviderService dataService, BundleContext context) {
+ baDataService = dataService;
+ this.context = context;
+ brokerTracker = new ServiceTracker<>(context, Broker.class, this);
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+
+ MappingServiceImpl mappingImpl = new MappingServiceImpl();
+ mappingImpl.setSchemaService(session.getService(SchemaService.class));
+ mappingImpl.start();
+
+ mappingService = mappingImpl;
+ dataConnector = new BindingIndependentDataServiceConnector();
+ dataConnector.setBaDataService(baDataService);
+ dataConnector.setBiDataService(session.getService(DataBrokerService.class));
+ dataConnector.setMappingService(mappingService);
+ dataConnector.start();
+ }
+
+ @Override
+ public Broker addingService(ServiceReference<Broker> reference) {
+ Broker br= context.getService(reference);
+ br.registerProvider(this, context);
+ return br;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<Broker> reference, Broker service) {
+ // NOOP
+ }
+
+ @Override
+ public void removedService(ServiceReference<Broker> reference, Broker service) {
+ // NOOP
+ }
+
+ public void start() {
+ brokerTracker.open();
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class Constants {
+ public static final Class<byte[]> BYTES_CLASS = byte[].class;
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import java.util.Collections
+import java.util.Map.Entry
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.AbstractMap.SimpleEntry
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+class MappingServiceImpl implements SchemaServiceListener, BindingIndependentMappingService {
+
+ var extension BindingMapping mapping = new BindingMapping;
+
+ @Property
+ BindingGeneratorImpl binding;
+
+ @Property
+ SchemaService schemaService;
+
+ override onGlobalContextUpdated(SchemaContext arg0) {
+ recreateBindingContext(arg0);
+ }
+
+ def recreateBindingContext(SchemaContext schemaContext) {
+ val newBinding = new BindingGeneratorImpl();
+ newBinding.generateTypes(schemaContext);
+ val newMapping = new BindingMapping();
+ for (entry : newBinding.moduleContexts.entrySet) {
+ val module = entry.key;
+ val context = entry.value;
+
+ newMapping.updateBinding(schemaContext, context);
+ }
+ mapping = newMapping
+ }
+
+ override CompositeNode toDataDom(DataObject data) {
+ mapping.toCompositeNode(data);
+ }
+
+ override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+ Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+ val key = mapping.toDataDom(entry.key);
+ val data = mapping.toCompositeNode(entry.value);
+ return new SimpleEntry(key, data);
+ }
+
+ override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+ InstanceIdentifier<? extends DataObject> path) {
+ return mapping.toDataDom(path);
+ }
+
+ override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) {
+ return mapping.dataObjectFromDataDom(path,result);
+ }
+
+ public def void start() {
+ schemaService.registerSchemaServiceListener(this);
+ recreateBindingContext(schemaService.globalContext);
+ }
+}
-package org.opendaylight.controller.sal.binding.impl.osgi;
+package org.opendaylight.controller.sal.binding.impl.util;
import java.util.concurrent.Callable;
+
import static com.google.common.base.Preconditions.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.opendaylight.yangtools.yang.binding.Identifier;
+
public class ClassLoaderUtils {
public static <V> V withClassLoader(ClassLoader cls,Callable<V> function) throws Exception {
throw new Exception(e);
}
}
+
+ public static Object construct(Constructor<? extends Object> constructor, ArrayList<Object> objects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Object[] initargs = objects.toArray(new Object[]{});
+ return constructor.newInstance(initargs);
+ }
}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+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.NodeBuilder;
+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.RpcResult;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class BrokerIntegrationTest {
+
+ DataBrokerService biDataService;
+ DataProviderService baDataService;
+ private MappingServiceImpl mappingServiceImpl;
+ private MappingServiceImpl mappingService;
+ private DataBrokerImpl baDataImpl;
+ private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
+ private ListeningExecutorService executor;
+ private BindingIndependentDataServiceConnector connectorServiceImpl;
+ private HashMapDataStore dataStore;
+
+
+ @Before
+ public void setUp() {
+ executor = MoreExecutors.sameThreadExecutor();
+ baDataImpl = new DataBrokerImpl();
+ baDataService = baDataImpl;
+ baDataImpl.setExecutor(executor);
+
+ biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
+ biDataService = biDataImpl;
+ biDataImpl.setExecutor(executor);
+
+ dataStore = new HashMapDataStore();
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
+ biDataImpl.registerConfigurationReader(treeRoot, dataStore);
+ biDataImpl.registerOperationalReader(treeRoot, dataStore);
+ biDataImpl.registerCommitHandler(treeRoot, dataStore);
+
+ mappingServiceImpl = new MappingServiceImpl();
+ mappingService = mappingServiceImpl;
+
+
+ connectorServiceImpl = new BindingIndependentDataServiceConnector();
+ connectorServiceImpl.setBaDataService(baDataService);
+ connectorServiceImpl.setBiDataService(biDataService);
+ connectorServiceImpl.setMappingService(mappingServiceImpl);
+ connectorServiceImpl.start();
+
+ String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+ "node-inventory.yang" };
+
+ mappingService.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+ }
+
+ @Test
+ public void simpleModifyOperation() throws Exception {
+
+ DataModificationTransaction transaction = baDataService.beginTransaction();
+ assertNotNull(transaction);
+
+ NodeRef node1 = createNodeRef("0");
+ DataObject node = baDataService.readConfigurationData(node1.getValue());
+ assertNull(node);
+ Node nodeData1 = createNode("0");
+
+ transaction.putConfigurationData(node1.getValue(), nodeData1);
+ Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
+ assertNotNull(commitResult);
+
+ RpcResult<TransactionStatus> result = commitResult.get();
+
+ assertNotNull(result);
+ assertNotNull(result.getResult());
+ assertEquals(TransactionStatus.COMMITED, result.getResult());
+
+ Node readedData = (Node) baDataService.readConfigurationData(node1.getValue());
+ assertNotNull(readedData);
+ assertEquals(nodeData1.getKey(), readedData.getKey());
+
+
+ DataModificationTransaction transaction2 = baDataService.beginTransaction();
+ assertNotNull(transaction);
+
+ transaction2.removeConfigurationData(node1.getValue());
+
+ Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
+ assertNotNull(commitResult2);
+
+ RpcResult<TransactionStatus> result2 = commitResult2.get();
+
+ assertNotNull(result2);
+ assertNotNull(result2.getResult());
+ assertEquals(TransactionStatus.COMMITED, result2.getResult());
+
+ DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());
+ assertNull(readedData2);
+ }
+
+ private static NodeRef createNodeRef(String string) {
+ NodeKey key = new NodeKey(new NodeId(string));
+ InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
+ .toInstance();
+ return new NodeRef(path);
+ }
+
+ private static Node createNode(String string) {
+ NodeBuilder ret = new NodeBuilder();
+ ret.setId(new NodeId(string));
+ ret.setKey(new NodeKey(ret.getId()));
+ return ret.build();
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+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.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+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.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class MappingServiceTest {
+
+ private static final QName NODES = QName.create("urn:opendaylight:inventory", "2013-08-19", "nodes");
+ private static final QName NODE = QName.create(NODES,"node");
+ private static final QName ID = QName.create(NODES,"id");
+
+ BindingIndependentMappingService service;
+ private MappingServiceImpl impl;
+
+ @Before
+ public void setUp() {
+ impl = new MappingServiceImpl();
+ service = impl;
+ }
+
+ @Test
+ public void baDataToBiData() throws Exception {
+
+ String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+ "node-inventory.yang" };
+
+ SchemaContext ctx = getContext(yangFiles);
+
+ impl.onGlobalContextUpdated(ctx);
+
+ NodesBuilder nodes = new NodesBuilder();
+
+ List<Node> nodeList = new ArrayList<>();
+ nodeList.add(createChildNode("foo"));
+ nodeList.add(createChildNode("bar"));
+
+ nodes.setNode(nodeList);
+ Nodes nodesTO = nodes.build();
+ CompositeNode xmlNodes = service.toDataDom(nodesTO);
+ assertNotNull(xmlNodes);
+ List<CompositeNode> invNodes = xmlNodes.getCompositesByName(NODE);
+ assertNotNull(invNodes);
+ assertEquals(2, invNodes.size());
+ }
+
+ @Test
+ public void instanceIdentifierTest() throws Exception {
+
+ String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+ "node-inventory.yang" };
+ SchemaContext ctx = getContext(yangFiles);
+ impl.onGlobalContextUpdated(ctx);
+
+ NodeKey nodeKey = new NodeKey(new NodeId("foo"));
+ InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).child(Node.class, nodeKey).toInstance();
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier result = service.toDataDom(path);
+ assertNotNull(result);
+ assertEquals(2, result.getPath().size());
+ }
+
+ public static SchemaContext getContext(String[] yangFiles) {
+
+ ClassLoader loader = MappingServiceTest.class.getClassLoader();
+
+ List<InputStream> streams = new ArrayList<>();
+ for (String string : yangFiles) {
+ InputStream stream = loader.getResourceAsStream("META-INF/yang/" + string);
+ streams.add(stream);
+
+ }
+ YangParserImpl parser = new YangParserImpl();
+
+ Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+ return parser.resolveSchemaContext(modules);
+ }
+
+ private Node createChildNode(String id) {
+ NodeBuilder node = new NodeBuilder();
+ NodeId nodeId = new NodeId(id);
+
+ node.setId(nodeId);
+ node.setKey(new NodeKey(nodeId));
+
+ FlowCapableNodeBuilder aug = new FlowCapableNodeBuilder();
+ aug.setManufacturer(id);
+ node.addAugmentation(FlowCapableNode.class, aug.build());
+
+ return node.build();
+ }
+
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator-plugin</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-manager</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+ <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+ <version>4.0</version>
+ </dependency>
</dependencies>
</project>
mavenBundle(CONTROLLER, "sal-common-api").versionAsInProject(), //
mavenBundle(CONTROLLER, "sal-common-impl").versionAsInProject(), //
+ mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
mavenBundle("com.google.guava", "guava").versionAsInProject(), //
mavenBundle(YANGTOOLS + ".thirdparty", "xtend-lib-osgi").versionAsInProject() //
);
mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
mavenBundle("org.javassist", "javassist").versionAsInProject(), //
- mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject() //
- );
+ mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+
+ mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+
+
+ mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+
+
+ mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+ mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+ mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+
+ mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject() //
+ );
}
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.Broker;
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.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
+import com.google.inject.Inject;
+
public class DataServiceTest extends AbstractTest {
protected DataBrokerService consumerDataService;
+
+
+ @Inject
+ Broker broker2;
@Before
public void setUp() throws Exception {
assertNotNull(result.getResult());
assertEquals(TransactionStatus.COMMITED, result.getResult());
- DataObject readedData = consumerDataService.readConfigurationData(node1.getValue());
+ Node readedData = (Node) consumerDataService.readConfigurationData(node1.getValue());
assertNotNull(readedData);
- assertEquals(nodeData1, readedData);
+ assertEquals(nodeData1.getKey(), readedData.getKey());
DataModificationTransaction transaction2 = consumerDataService.beginTransaction();
private static Node createNode(String string) {
NodeBuilder ret = new NodeBuilder();
- ret.setId(new NodeId(string));
+ NodeId id = new NodeId(string);
+ ret.setKey(new NodeKey(id));
+ ret.setId(id);
return ret.build();
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-common-impl</artifactId>
- <packaging>bundle</packaging>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>sal-common-impl</artifactId>
+ <packaging>bundle</packaging>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-api</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>org.eclipse.xtend.lib</artifactId>
+ </dependency>
+ </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.opendaylight.controller.md.sal.common.impl,
- org.opendaylight.controller.md.sal.common.impl.*
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.opendaylight.controller.md.sal.common.impl,
+ org.opendaylight.controller.md.sal.common.impl.*
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.xtend</groupId>
+ <artifactId>xtend-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
</project>
@Override
public D readOperationalData(P path) {
FluentIterable<D> dataBits = FluentIterable //
- .from(getReaders(configReaders, path)).transform(operationalRead(path));
+ .from(getReaders(operationalReaders, path)).transform(operationalRead(path));
return merge(path,dataBits);
}
return new Function<DataReader<P, D>, D>() {
@Override
public D apply(DataReader<P, D> input) {
- return input.readConfigurationData(path);
+ return input.readOperationalData(path);
}
};
}
--- /dev/null
+package org.opendaylight.controller.md.sal.common.impl.service
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import com.google.common.collect.Multimap
+import static com.google.common.base.Preconditions.*;
+import java.util.List
+import com.google.common.collect.HashMultimap
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Callable
+import org.opendaylight.yangtools.yang.common.RpcResult
+import java.util.Collections
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import java.util.ArrayList
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import java.util.Arrays
+import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
+import org.opendaylight.controller.md.sal.common.api.data.DataModificationTransactionFactory
+import org.opendaylight.controller.md.sal.common.api.data.DataChangePublisher
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener
+import org.opendaylight.controller.sal.common.util.Rpcs
+import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.concepts.Path
+import org.slf4j.LoggerFactory
+
+abstract class AbstractDataBroker<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> implements
+DataModificationTransactionFactory<P, D>, //
+DataReader<P, D>, //
+DataChangePublisher<P, D, DCL>, //
+DataProvisionService<P,D> {
+
+ @Property
+ var ExecutorService executor;
+
+ @Property
+ var AbstractDataReadRouter<P,D> dataReadRouter;
+
+ Multimap<P, DataChangeListenerRegistration<P,D,DCL>> listeners = HashMultimap.create();
+ Multimap<P, DataCommitHandlerRegistration<P,D>> commitHandlers = HashMultimap.create();
+
+
+ public new() {
+
+ }
+
+ override final readConfigurationData(P path) {
+ return dataReadRouter.readConfigurationData(path);
+ }
+
+ override final readOperationalData(P path) {
+ return dataReadRouter.readOperationalData(path);
+ }
+
+ override final registerCommitHandler(P path,
+ DataCommitHandler<P, D> commitHandler) {
+ val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
+ commitHandlers.put(path,registration)
+ return registration;
+ }
+
+ override final def registerDataChangeListener(P path, DCL listener) {
+ val reg = new DataChangeListenerRegistration(path, listener, this);
+ listeners.put(path, reg);
+ return reg;
+ }
+
+ final def registerDataReader(P path,DataReader<P,D> reader) {
+
+ val confReg = dataReadRouter.registerConfigurationReader(path,reader);
+ val dataReg = dataReadRouter.registerOperationalReader(path,reader);
+
+ return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
+ }
+
+ protected final def removeListener(DataChangeListenerRegistration<P,D,DCL> registration) {
+ listeners.remove(registration.path, registration);
+ }
+
+ protected final def removeCommitHandler(DataCommitHandlerRegistration<P,D> registration) {
+ commitHandlers.remove(registration.path, registration);
+ }
+
+ protected final def getActiveCommitHandlers() {
+ return commitHandlers.entries.map[ value.instance].toSet
+ }
+
+ package final def Future<RpcResult<TransactionStatus>> commit(AbstractDataTransaction<P,D> transaction) {
+ checkNotNull(transaction);
+ transaction.changeStatus(TransactionStatus.SUBMITED);
+ val task = new TwoPhaseCommit(transaction, this);
+ return executor.submit(task);
+ }
+
+}
+
+package class DataChangeListenerRegistration<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> extends AbstractObjectRegistration<DCL> implements ListenerRegistration<DCL> {
+
+ AbstractDataBroker<P,D,DCL> dataBroker;
+
+ @Property
+ val P path;
+
+ new(P path, DCL instance, AbstractDataBroker<P,D,DCL> broker) {
+ super(instance)
+ dataBroker = broker;
+ _path = path;
+ }
+
+ override protected removeRegistration() {
+ dataBroker.removeListener(this);
+ dataBroker = null;
+ }
+
+}
+
+package class DataCommitHandlerRegistration<P extends Path<P>,D>
+extends AbstractObjectRegistration<DataCommitHandler<P, D>> {
+
+ AbstractDataBroker<P,D,?> dataBroker;
+
+ @Property
+ val P path;
+
+ new(P path, DataCommitHandler<P, D> instance,
+ AbstractDataBroker<P,D,?> broker) {
+ super(instance)
+ dataBroker = broker;
+ _path = path;
+ }
+
+ override protected removeRegistration() {
+ dataBroker.removeCommitHandler(this);
+ dataBroker = null;
+ }
+
+}
+
+package class TwoPhaseCommit<P extends Path<P>,D> implements Callable<RpcResult<TransactionStatus>> {
+
+ private static val log = LoggerFactory.getLogger(TwoPhaseCommit);
+
+ val AbstractDataTransaction<P,D> transaction;
+ val AbstractDataBroker<P,D,?> dataBroker;
+
+ new(AbstractDataTransaction<P,D> transaction, AbstractDataBroker<P,D,?> broker) {
+ this.transaction = transaction;
+ this.dataBroker = broker;
+ }
+
+ override call() throws Exception {
+
+ val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.activeCommitHandlers;
+
+ // requesting commits
+ val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();
+ try {
+ for (handler : commitHandlers) {
+ handlerTransactions.add(handler.requestCommit(transaction));
+ }
+ } catch (Exception e) {
+ log.error("Request Commit failded",e);
+ return rollback(handlerTransactions,e);
+ }
+ val List<RpcResult<Void>> results = new ArrayList();
+ try {
+ for (subtransaction : handlerTransactions) {
+ results.add(subtransaction.finish());
+ }
+ } catch (Exception e) {
+ log.error("Finish Commit failed",e);
+ return rollback(handlerTransactions,e);
+ }
+
+ return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
+ }
+
+ def rollback(List<DataCommitTransaction<P, D>> transactions,Exception e) {
+ for (transaction : transactions) {
+ transaction.rollback()
+ }
+ // FIXME return encountered error.
+ return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
+ }
+}
+
+public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {
+
+ @Property
+ private val Object identifier;
+
+
+ var TransactionStatus status;
+
+
+ var AbstractDataBroker<P, D, ?> broker;
+
+ protected new (AbstractDataBroker<P,D,?> dataBroker) {
+ super(dataBroker);
+ _identifier = new Object();
+ broker = dataBroker;
+ status = TransactionStatus.NEW;
+ //listeners = new ListenerRegistry<>();
+ }
+
+ override commit() {
+ return broker.commit(this);
+ }
+
+ override readConfigurationData(P path) {
+ return broker.readConfigurationData(path);
+ }
+
+ override readOperationalData(P path) {
+ return broker.readOperationalData(path);
+ }
+
+ override hashCode() {
+ return identifier.hashCode;
+ }
+
+ override equals(Object obj) {
+ if (this === obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ val other = (obj as AbstractDataTransaction<P,D>) ;
+ if (broker == null) {
+ if (other.broker != null)
+ return false;
+ } else if (!broker.equals(other.broker))
+ return false;
+ if (identifier == null) {
+ if (other.identifier != null)
+ return false;
+ } else if (!identifier.equals(other.identifier))
+ return false;
+ return true;
+ }
+
+ override TransactionStatus getStatus() {
+ return status;
+ }
+
+
+ protected abstract def void onStatusChange(TransactionStatus status);
+
+ public def changeStatus(TransactionStatus status) {
+ this.status = status;
+ onStatusChange(status);
+ }
+
+}
package org.opendaylight.controller.sal.core.api.mount;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
-public interface MountProvisionInstance extends MountInstance, NotificationPublishService, RpcProvisionRegistry {
+public interface MountProvisionInstance extends //
+ MountInstance,//
+ NotificationPublishService, //
+ RpcProvisionRegistry,//
+ DataProviderService {
}
*/
package org.opendaylight.controller.sal.core.api.mount;
+import org.opendaylight.controller.sal.core.api.BrokerService;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-public interface MountService {
+public interface MountService extends BrokerService {
MountInstance getMountPoint(InstanceIdentifier path);
}
<artifactId>sal-common-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>0.5.9-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-impl</artifactId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
import org.opendaylight.controller.sal.core.api.data.DataProviderService;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class BrokerActivator implements BundleActivator {
+ private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance();
BrokerImpl broker;
private ServiceRegistration<Broker> brokerReg;
private ServiceRegistration<SchemaService> schemaReg;
private ServiceRegistration<DataProviderService> dataProviderReg;
private SchemaServiceImpl schemaService;
private DataBrokerImpl dataService;
+ private MountPointManagerImpl mountService;
+ private ServiceRegistration<MountService> mountReg;
+ private ServiceRegistration<MountProvisionService> mountProviderReg;
+ private HashMapDataStore hashMapStore;
@Override
public void start(BundleContext context) throws Exception {
Hashtable<String, String> emptyProperties = new Hashtable<String, String>();
broker = new BrokerImpl();
broker.setBundleContext(context);
- brokerReg = context.registerService(Broker.class, broker, emptyProperties);
+
schemaService = new SchemaServiceImpl();
schemaService.setContext(context);
schemaReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String, String>());
dataService = new DataBrokerImpl();
+ dataService.setExecutor(broker.getExecutor());
+
dataReg = context.registerService(DataBrokerService.class, dataService, emptyProperties);
dataProviderReg = context.registerService(DataProviderService.class, dataService, emptyProperties);
+ hashMapStore = new HashMapDataStore();
+
+ dataService.registerConfigurationReader(ROOT, hashMapStore);
+ dataService.registerCommitHandler(ROOT, hashMapStore);
+ dataService.registerOperationalReader(ROOT, hashMapStore);
+ mountService = new MountPointManagerImpl();
+ mountService.setDataBroker(dataService);
+
+ mountReg = context.registerService(MountService.class, mountService, emptyProperties);
+ mountProviderReg = context.registerService(MountProvisionService.class, mountService, emptyProperties);
+
+ brokerReg = context.registerService(Broker.class, broker, emptyProperties);
}
@Override
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
+import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
+ DataProviderService {
+
+ public DataBrokerImpl() {
+ setDataReadRouter(new DataReaderRouter());
+ }
+
+ @Override
+ public DataTransactionImpl beginTransaction() {
+ return new DataTransactionImpl(this);
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return getDataReadRouter().registerConfigurationReader(path, reader);
+ }
+
+ @Override
+ public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
+ InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+ return getDataReadRouter().registerOperationalReader(path, reader);
+ }
+
+ @Deprecated
+ @Override
+ public void addValidator(DataStoreIdentifier store, DataValidator validator) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Deprecated
+ @Override
+ public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Deprecated
+ @Override
+ public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Deprecated
+ @Override
+ public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.sal.dom.broker
-
-import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.controller.sal.common.DataStoreIdentifier
-import org.opendaylight.controller.sal.core.api.data.DataProviderService.DataRefresher
-import org.opendaylight.controller.sal.core.api.data.DataValidator
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-
-class DataBrokerImpl implements DataProviderService {
-
- val readRouter = new DataReaderRouter();
-
- override addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
- // NOOP
- }
-
- override addValidator(DataStoreIdentifier store, DataValidator validator) {
- // NOOP
- }
-
- override beginTransaction() {
- // NOOP
- }
-
- override readConfigurationData(InstanceIdentifier path) {
- readRouter.readConfigurationData(path)
- }
-
- override readOperationalData(InstanceIdentifier path) {
- readRouter.readOperationalData(path)
- }
-
- override registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
- readRouter.registerConfigurationReader(path, reader);
- }
-
- override registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
- readRouter.registerOperationalReader(path, reader);
- }
-
- override removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
- // NOOP
- }
-
- override removeValidator(DataStoreIdentifier store, DataValidator validator) {
- // NOOP
- }
-
- override registerDataChangeListener(InstanceIdentifier path, DataChangeListener listener) {
- // NOOP
- }
-
- override registerCommitHandler(InstanceIdentifier path,
- DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
- // NOOP
- }
-
-}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier, CompositeNode>
+ implements DataModificationTransaction {
+ private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+
+
+
+ public DataTransactionImpl(DataBrokerImpl dataBroker) {
+ super(dataBroker);
+ }
+
+ @Override
+ public ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener) {
+ return listeners.register(listener);
+ }
+
+ protected void onStatusChange(TransactionStatus status) {
+ for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
+ listenerRegistration.getInstance().onStatusUpdated(this, status);
+ }
+ }
+}
\ No newline at end of file
package org.opendaylight.controller.sal.dom.broker;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
import org.opendaylight.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.data.api.InstanceIdentifier.PathArgument;
public class MountPointImpl implements MountProvisionInstance {
- final RpcRouter rpcs;
- final DataReaderRouter dataReader;
- final NotificationRouter notificationRouter;
+ private final RpcRouter rpcs;
+ private final DataReaderRouter dataReader;
+ private final NotificationRouter notificationRouter;
+ private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
+
+
+ private final InstanceIdentifier mountPath;
public MountPointImpl(InstanceIdentifier path) {
+ this.mountPath = path;
rpcs = new RpcRouterImpl("");
dataReader = new DataReaderRouter();
notificationRouter = new NotificationRouterImpl();
+ readWrapper = new ReadWrapper();
+ }
+
+ public InstanceIdentifier getMountPath() {
+ return mountPath;
+ }
+
+ public DataReader<InstanceIdentifier, CompositeNode> getReadWrapper() {
+ return readWrapper;
}
@Override
@Override
public void sendNotification(CompositeNode notification) {
publish(notification);
+ }
+
+ @Override
+ public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
+ InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+ // NOOP
+ }
+
+ @Override
+ public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+ // NOOP
+ }
+
+ @Override
+ public void addValidator(DataStoreIdentifier store, DataValidator validator) {
+ // NOOP
+ }
+ @Override
+ public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+ // NOOP
+ }
+
+ class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
+
+
+ private InstanceIdentifier shortenPath(InstanceIdentifier path) {
+ InstanceIdentifier ret = null;
+ if(mountPath.contains(path)) {
+ List<PathArgument> newArgs = path.getPath().subList(mountPath.getPath().size(), path.getPath().size());
+ ret = new InstanceIdentifier(newArgs);
+ }
+ return ret;
+ }
+
+ @Override
+ public CompositeNode readConfigurationData(InstanceIdentifier path) {
+ InstanceIdentifier newPath = shortenPath(path);
+ if(newPath == null) {
+ return null;
+ }
+ return MountPointImpl.this.readConfigurationData(newPath);
+ }
+ @Override
+ public CompositeNode readOperationalData(InstanceIdentifier path) {
+ InstanceIdentifier newPath = shortenPath(path);
+ if(newPath == null) {
+ return null;
+ }
+ return MountPointImpl.this.readOperationalData(newPath);
+ }
}
}
import java.util.concurrent.ConcurrentMap
import java.util.concurrent.ConcurrentHashMap
import static com.google.common.base.Preconditions.*;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService
class MountPointManagerImpl implements MountProvisionService {
+ @Property
+ DataProviderService dataBroker;
+
ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
override createMountPoint(InstanceIdentifier path) {
checkState(!mounts.containsKey(path),"Mount already created");
val mount = new MountPointImpl(path);
+ registerMountPoint(mount);
mounts.put(path,mount);
+ return mount;
+ }
+
+ def registerMountPoint(MountPointImpl impl) {
+ dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
+ dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
+
}
override getMountPoint(InstanceIdentifier path) {
mounts.get(path);
}
-
-
}
import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
- return data.iterator.next
+ val iterator = data.iterator;
+ if(iterator.hasNext) {
+ return data.iterator.next
+ }
+ return null;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import java.util.Map
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import java.util.Map.Entry
+import java.util.HashSet
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+
+class DataUtils {
+
+ static def CompositeNode read(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
+ val root = map.get(path);
+ val childs = map.getChilds(path);
+ if(root === null && childs.empty) {
+ return null;
+ }
+
+ return merge(path, root, childs);
+ }
+
+ static def CompositeNode merge(InstanceIdentifier path, CompositeNode node,
+ HashSet<Entry<InstanceIdentifier, CompositeNode>> entries) {
+ val it = new ArrayList<Node<?>>();
+ val qname = path.path.last.nodeType;
+ if (node != null) {
+ addAll(node.children);
+ }
+ for (entry : entries) {
+ val nesting = entry.key.path.size - path.path.size;
+ if (nesting === 1) {
+ add(entry.value);
+ }
+ }
+ return new CompositeNodeTOImpl(qname, null, it);
+ }
+
+ static def getChilds(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
+ val it = new HashSet<Entry<InstanceIdentifier, CompositeNode>>();
+ for (entry : map.entrySet) {
+ if (path.contains(entry.key)) {
+ add(entry);
+ }
+ }
+ return it;
+ }
+
+}
-package org.opendaylight.controller.sal.binding.impl
+package org.opendaylight.controller.sal.dom.broker.impl
import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
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.RpcResult
import java.util.concurrent.ConcurrentHashMap
import org.opendaylight.controller.sal.common.util.Rpcs
import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import static extension org.opendaylight.controller.sal.dom.broker.impl.DataUtils.*;
class HashMapDataStore //
implements //
-RuntimeDataProvider, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataReader<InstanceIdentifier, CompositeNode>, DataCommitHandler<InstanceIdentifier, CompositeNode> {
- val Map<InstanceIdentifier<? extends DataObject>,DataObject> configuration = new ConcurrentHashMap();
- val Map<InstanceIdentifier<? extends DataObject>,DataObject> operational = new ConcurrentHashMap();
+ val Map<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap();
+ val Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap();
-
- override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
- configuration.get(path);
+ override readConfigurationData(InstanceIdentifier path) {
+ configuration.read(path);
}
- override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- operational.get(path);
+ override readOperationalData(InstanceIdentifier path) {
+ operational.read(path);
}
+
+
- override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
- return new HashMapDataStoreTransaction(modification,this);
+
+ override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
+ return new HashMapDataStoreTransaction(modification, this);
}
-
+
def RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
- return Rpcs.getRpcResult(true,null,Collections.emptySet);
+ return Rpcs.getRpcResult(true, null, Collections.emptySet);
}
-
+
def RpcResult<Void> finish(HashMapDataStoreTransaction transaction) {
val modification = transaction.modification;
configuration.putAll(modification.updatedConfigurationData);
operational.putAll(modification.updatedOperationalData);
-
- for(removal : modification.removedConfigurationData) {
+
+ for (removal : modification.removedConfigurationData) {
configuration.remove(removal);
}
- for(removal : modification.removedOperationalData) {
+ for (removal : modification.removedOperationalData) {
operational.remove(removal);
}
- return Rpcs.getRpcResult(true,null,Collections.emptySet);
+ return Rpcs.getRpcResult(true, null, Collections.emptySet);
}
}
class HashMapDataStoreTransaction implements //
-DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataCommitTransaction<InstanceIdentifier, CompositeNode> {
@Property
- val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification
+ val DataModification<InstanceIdentifier, CompositeNode> modification
@Property
val HashMapDataStore datastore;
-
-
+
new(
- DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modify,
+ DataModification<InstanceIdentifier, CompositeNode> modify,
HashMapDataStore store
) {
_modification = modify;
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.osgi;
+
+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.yang.data.api.InstanceIdentifier;
+import org.osgi.framework.ServiceReference;
+
+public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountProvisionService> implements MountProvisionService{
+
+
+ public MountProviderServiceProxy(ServiceReference<MountProvisionService> ref, MountProvisionService delegate) {
+ super(ref, delegate);
+ }
+
+ public MountProvisionInstance getMountPoint(InstanceIdentifier path) {
+ return getDelegate().getMountPoint(path);
+ }
+
+ public MountProvisionInstance createMountPoint(InstanceIdentifier path) {
+ return getDelegate().createMountPoint(path);
+ }
+
+ public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
+ return getDelegate().createOrGetMountPoint(path);
+ }
+}
import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService
import org.opendaylight.controller.sal.core.api.notify.NotificationService
import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
class ProxyFactory {
new NotificationServiceProxy(ref as ServiceReference<NotificationService>, service);
}
+ private static def dispatch createProxyImpl(ServiceReference<?> ref, MountProvisionService service) {
+ new MountProviderServiceProxy(ref as ServiceReference<MountProvisionService>, service);
+ }
+
+
private static def dispatch createProxyImpl(ServiceReference<?> ref, SchemaService service) {
new SchemaServiceProxy(ref as ServiceReference<SchemaService>, service);
}
<version>1.0-SNAPSHOT</version>
</parent>
<properties>
- <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+ <netconf.version>0.2.3-SNAPSHOT</netconf.version>
</properties>
<artifactId>sal-netconf-connector</artifactId>
<scm>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-client</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>${netconf.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-impl</artifactId>
<version>0.5.9-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-broker-impl</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>test</scope>
+ <type>jar</type>
+ </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependencies>
<packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.opendaylight.controller.sal.connect.netconf.NetconfProvider</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class InventoryUtils {
+
+ private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory");
+ private static final Date INVENTORY_REVISION = date();
+ public static final QName INVENTORY_NODES = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "nodes");
+ public static final QName INVENTORY_NODE = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "node");
+ public static final QName INVENTORY_ID = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "id");
+
+ public static final InstanceIdentifier INVENTORY_PATH = InstanceIdentifier.builder().node(INVENTORY_NODES)
+ .toInstance();
+ public static final QName NETCONF_INVENTORY_MOUNT = null;
+
+
+
+ private static Date date() {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ return formatter.parse("2013-08-19");
+ } catch (ParseException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+
+}
--- /dev/null
+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 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.util.Collections
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import org.opendaylight.yangtools.concepts.Registration
+
+class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation {
+
+ var NetconfClient client;
+
+ @Property
+ var InetSocketAddress socketAddress;
+
+ @Property
+ val MountProvisionInstance mountInstance;
+
+ @Property
+ val InstanceIdentifier path;
+
+ Registration<DataReader<InstanceIdentifier,CompositeNode>> operReaderReg
+
+ Registration<DataReader<InstanceIdentifier,CompositeNode>> confReaderReg
+
+ public new(MountProvisionInstance mount,InstanceIdentifier path) {
+ _mountInstance = mount;
+ _path = path;
+ }
+
+ def start(NetconfClientDispatcher dispatcher) {
+ client = new NetconfClient("sal-netconf-connector", socketAddress, dispatcher);
+
+ confReaderReg = mountInstance.registerConfigurationReader(path,this);
+ operReaderReg = mountInstance.registerOperationalReader(path,this);
+ }
+
+ override readConfigurationData(InstanceIdentifier path) {
+ val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, path.toFilterStructure()));
+ val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
+ return data?.findNode(path) as CompositeNode;
+ }
+
+ override readOperationalData(InstanceIdentifier path) {
+ val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure()));
+ val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
+ return data?.findNode(path) as CompositeNode;
+ }
+
+ override getSupportedRpcs() {
+ Collections.emptySet;
+ }
+
+ override invokeRpc(QName rpc, CompositeNode input) {
+ val message = rpc.toRpcMessage(input);
+ val result = client.sendMessage(message);
+ return result.toRpcResult();
+ }
+
+ def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
+
+ var Node<?> current = node;
+ for (arg : identifier.path) {
+ if (current instanceof SimpleNode<?>) {
+ return null;
+ } else if (current instanceof CompositeNode) {
+ val currentComposite = (current as CompositeNode);
+
+ current = currentComposite.getFirstCompositeByName(arg.nodeType);
+ if (current == null) {
+ current = currentComposite.getFirstSimpleByName(arg.nodeType);
+ }
+ if (current == null) {
+ return null;
+ }
+ }
+ }
+ return current;
+ }
+
+ public def stop() {
+ confReaderReg?.close()
+ operReaderReg?.close()
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf
+
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
+import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.QName
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils.*;
+
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
+import java.util.Map
+import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import java.io.OptionalDataException
+import com.google.common.base.Optional
+import java.net.SocketAddress
+import java.net.InetSocketAddress
+
+class NetconfDeviceManager {
+
+ val Map<InstanceIdentifier, NetconfDevice> devices = new ConcurrentHashMap;
+
+ var ProviderSession session;
+
+ @Property
+ var DataProviderService dataService;
+
+ @Property
+ var MountProvisionService mountService;
+
+ val nodeUpdateListener = new NetconfInventoryListener(this);
+
+
+ @Property
+ var NetconfClientDispatcher dispatcher;
+
+ def void start() {
+ dataService?.registerDataChangeListener(INVENTORY_PATH, nodeUpdateListener);
+ if(dispatcher == null) {
+ dispatcher = new NetconfClientDispatcher(Optional.absent);
+ }
+ }
+
+ def netconfNodeAdded(InstanceIdentifier path, CompositeNode node) {
+ val address = node.endpointAddress;
+ val port = Integer.parseInt(node.endpointPort);
+ netconfNodeAdded(path,new InetSocketAddress(address,port))
+
+ }
+
+ def netconfNodeAdded(InstanceIdentifier path, InetSocketAddress address) {
+
+ val mountPointPath = path;
+ val mountPoint = mountService.createOrGetMountPoint(mountPointPath);
+ val localPath = InstanceIdentifier.builder().toInstance;
+ val netconfDevice = new NetconfDevice(mountPoint,localPath);
+ netconfDevice.setSocketAddress(address);
+ netconfDevice.start(dispatcher);
+ }
+
+ def netconfNodeRemoved(InstanceIdentifier path) {
+
+ }
+
+}
+
+class NetconfInventoryListener implements DataChangeListener {
+
+ val NetconfDeviceManager manager;
+
+ new(NetconfDeviceManager manager) {
+ this.manager = manager;
+ }
+
+ override onDataChanged(DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
+
+ //manager.netconfNodeAdded(path, change);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class NetconfInventoryUtils {
+
+
+ public static final QName NETCONF_MOUNT = null;
+ public static final QName NETCONF_ENDPOINT = null;
+ public static final QName NETCONF_ENDPOINT_ADDRESS = null;
+ public static final QName NETCONF_ENDPOINT_PORT = null;
+
+
+ public static String getEndpointAddress(CompositeNode node) {
+ return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_ADDRESS).getValue().toString();
+ }
+
+ public static String getEndpointPort(CompositeNode node) {
+ return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_PORT).getValue().toString();
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf
+
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import java.net.URI
+import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.NodeUtils
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import java.util.concurrent.atomic.AtomicInteger
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+import org.opendaylight.controller.sal.common.util.Rpcs
+
+class NetconfMapping {
+
+ public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
+ public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf");
+ public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc");
+ public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get");
+ public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config");
+ public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply");
+ public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok");
+ public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data");
+
+
+ static val messageId = new AtomicInteger(0);
+
+
+
+ static def Node<?> toFilterStructure(InstanceIdentifier identifier) {
+ var Node<?> previous = null;
+ for (component : identifier.path.reverse) {
+ val Node<?> current = component.toNode(previous);
+ previous = current;
+ }
+ return previous;
+ }
+
+ static def dispatch Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
+ val list = new ArrayList<Node<?>>();
+ for( arg : argument.keyValues.entrySet) {
+ list.add = new SimpleNodeTOImpl(arg.key,null,arg.value);
+ }
+ return new CompositeNodeTOImpl(argument.nodeType,null,list)
+ }
+
+ static def dispatch Node<?> toNode(PathArgument argument, Node<?> node) {
+ if(node != null) {
+ return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node));
+ } else {
+ return new SimpleNodeTOImpl(argument.nodeType,null,null);
+ }
+ }
+
+ static def CompositeNode toCompositeNode(NetconfMessage message) {
+ return message.toRpcResult().result;
+ }
+
+ static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
+ val rpcPayload = wrap(NETCONF_RPC_QNAME,node);
+ val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
+ w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement);
+ return new NetconfMessage(w3cPayload);
+ }
+
+ static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
+ val rawRpc = message.document.toCompositeNode() as CompositeNode;
+ //rawRpc.
+
+ return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet());
+ }
+
+
+ static def wrap(QName name,Node<?> node) {
+ if(node != null) {
+ return new CompositeNodeTOImpl(name,null,Collections.singletonList(node));
+ }
+ else {
+ return new CompositeNodeTOImpl(name,null,Collections.emptyList());
+ }
+ }
+
+
+ public static def Node<?> toCompositeNode(Document document) {
+ return XmlDocumentUtils.toCompositeNode(document) as Node<?>
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Hashtable;
+
+import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.osgi.framework.BundleContext;
+
+public class NetconfProvider extends AbstractProvider {
+
+ private NetconfDeviceManager netconfDeviceManager;
+
+ @Override
+ protected void startImpl(BundleContext context) {
+ netconfDeviceManager = new NetconfDeviceManager();
+ context.registerService(NetconfDeviceManager.class, netconfDeviceManager, new Hashtable<String,String>());
+ }
+
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+ MountProvisionService mountService = session.getService(MountProvisionService.class);
+
+
+ netconfDeviceManager.setMountService(mountService);
+ netconfDeviceManager.start();
+ }
+
+ @Override
+ protected void stopImpl(BundleContext context) {
+
+ }
+}
--- /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;
+
+public class XmlDocumentUtils {
+
+ public static CompositeNode toCompositeNode(Document doc) {
+ return (CompositeNode) 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 = false;
+ 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 (value.matches(".*\\w.*")) {
+ isSimpleObject = true;
+ break;
+ }
+ }
+ }
+
+ if (isSimpleObject) {
+ return new SimpleNodeTOImpl<>(qname, null, value);
+ }
+ return new CompositeNodeTOImpl(qname, null, values);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.connector.netconf.test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.*;
+import io.netty.channel.ChannelFuture;
+import io.netty.util.HashedWheelTimer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClient;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
+import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.dom.broker.DataBrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
+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.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+public class MountTest extends AbstractConfigTest {
+
+ private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
+ private static final InetSocketAddress tlsAddress = new InetSocketAddress("127.0.0.1", 12024);
+ private static final URI NETCONF_MONITORING_NS = URI.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring");
+
+ private static final QName NETCONF_MONITORING = new QName(NETCONF_MONITORING_NS, new Date(2010,10,04), "ietf-netconf-monitoring");
+ private static final QName NETCONF_MONITORING_STATE = new QName(NETCONF_MONITORING,"netconf-state");
+
+
+ private NetconfMessage getConfig, getConfigCandidate, editConfig, closeSession;
+ private DefaultCommitNotificationProducer commitNot;
+ private NetconfServerDispatcher dispatch;
+ private DataProviderService dataBroker;
+ private MountPointManagerImpl mountManager;
+ private NetconfDeviceManager netconfManager;
+
+ private static QName CONFIG_MODULES = new QName(
+ URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+ private static QName CONFIG_SERVICES = new QName(
+ URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+
+ private NetconfClient createSession(final InetSocketAddress address, NetconfClientDispatcher dispatcher) throws InterruptedException {
+ final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, dispatcher);
+ return netconfClient;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+ new ModuleFactory[0])));
+
+ loadMessages();
+
+ NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+ factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+
+ commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
+
+ dispatch = createDispatcher(Optional.<SSLContext> absent(), factoriesListener);
+ ChannelFuture s = dispatch.createServer(tcpAddress);
+ s.await();
+
+ dataBroker = new DataBrokerImpl();
+ mountManager = new MountPointManagerImpl();
+ mountManager.setDataBroker(dataBroker);
+ netconfManager = new NetconfDeviceManager();
+
+ netconfManager.setMountService(mountManager);
+ netconfManager.setDataService(dataBroker);
+ netconfManager.start();
+
+ try (NetconfClient netconfClient = createSession(tcpAddress, netconfManager.getDispatcher())) {
+ // send edit_config.xml
+ final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument();
+ assertNotNull(rpcReply);
+ }
+ }
+
+
+ protected List<ModuleFactory> getModuleFactories() {
+ return getModuleFactoriesS();
+ }
+
+ static List<ModuleFactory> getModuleFactoriesS() {
+ return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(),
+ new NetconfTestImplModuleFactory());
+ }
+
+ private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
+ this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml");
+ this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+ this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml");
+ this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml");
+ }
+
+ private NetconfServerDispatcher createDispatcher(Optional<SSLContext> sslC,
+ NetconfOperationServiceFactoryListenerImpl factoriesListener) {
+ SessionIdProvider idProvider = new SessionIdProvider();
+ NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+ new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+
+ NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+ factoriesListener, commitNot, idProvider);
+
+ return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory);
+ }
+
+ private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
+ final Collection<InputStream> yangDependencies = getBasicYangs();
+ return new HardcodedYangStoreService(yangDependencies);
+ }
+
+ private Collection<InputStream> getBasicYangs() throws IOException {
+ List<String> paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang",
+ "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang",
+ "/META-INF/yang/ietf-inet-types.yang");
+ final Collection<InputStream> yangDependencies = new ArrayList<>();
+ for (String path : paths) {
+ final InputStream is = Preconditions
+ .checkNotNull(getClass().getResourceAsStream(path), path + " not found");
+ yangDependencies.add(is);
+ }
+ return yangDependencies;
+ }
+
+ @Test
+ public void test() {
+ // MountProvisionInstance mount =
+ // Mockito.mock(MountProvisionInstance.class);
+ InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
+ .node(InventoryUtils.INVENTORY_NODE).toInstance();
+ netconfManager.netconfNodeAdded(path, tcpAddress);
+ InstanceIdentifier mountPointPath = path;
+ MountProvisionInstance mountPoint = mountManager.getMountPoint(mountPointPath);
+
+ CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES)
+ .toInstance());
+ assertNotNull(data);
+ assertEquals(CONFIG_MODULES, data.getNodeType());
+
+ CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance());
+ assertNotNull(data2);
+
+ InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance();
+
+ CompositeNode data3 = dataBroker.readOperationalData(fullPath);
+ assertNotNull(data3);
+ assertEquals(CONFIG_MODULES, data.getNodeType());
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.rest.api;
+
+public class Draft02 {
+ public static class MediaTypes {
+ public static final String API = "application/yang.api";
+ public static final String DATASTORE = "application/yang.datastore";
+ public static final String DATA = "application/yang.data";
+ public static final String OPERATION = "application/yang.operation";
+ public static final String PATCH = "application/yang.patch";
+ public static final String PATCH_STATUS = "application/yang.patch-status";
+ public static final String STREAM = "application/yang.stream";
+ }
+
+ public static class Paths {
+
+ }
+}
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
/**
* Section 5 for details on each URI.
* <ul>
* <li><b>/restconf</b> - {@link #getRoot()}
- * <ul><li><b>/datastore</b> - {@link #readAllData()}
+ * <ul><li><b>/config</b>
+ * <li><b>/operational</b> - {@link #readAllData()} - Added in Draft02
+ * <li><b>/datastore</b> - {@link #readAllData()}
* <ul>
* <li>/(top-level-data-nodes) (config=true or false)
* </ul>
* </ul>
*/
@Path("/")
-public interface RestconfService {
+public interface RestconfService extends RestconfServiceLegacy {
public static final String XML = "+xml";
public static final String JSON = "+json";
@GET
public Object getRoot();
+
@GET
- @Path("/datastore")
+ @Path("/modules")
@Produces({API+JSON,API+XML})
- public Object readAllData();
+ public StructuredData getModules();
+ @POST
+ @Path("/operations/{identifier}")
+ @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
+ public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+
+
@GET
- @Path("/datastore/{identifier:.+}")
- @Produces({API+JSON,API+XML})
- public StructuredData readData(@PathParam("identifier") String identifier);
+ @Path("/config/{identifier:.+}")
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+ public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
+
+
@PUT
- @Path("/datastore/{identifier:.+}")
+ @Path("/config/{identifier:.+}")
@Produces({API+JSON,API+XML})
- public Object createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+ public RpcResult<TransactionStatus> createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
@POST
- @Path("/datastore/{identifier:.+}")
+ @Path("/config/{identifier:.+}")
@Produces({API+JSON,API+XML})
- public Object updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+ public RpcResult<TransactionStatus> updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
@GET
- @Path("/modules")
+ @Path("/operational/{identifier:.+}")
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+ public StructuredData readOperationalData(@PathParam("identifier") String identifier);
+
+ @PUT
+ @Path("/operational/{identifier:.+}")
@Produces({API+JSON,API+XML})
- public Object getModules();
+ public RpcResult<TransactionStatus> createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
@POST
- @Path("/operations/{identifier}")
+ @Path("/operational/{identifier:.+}")
@Produces({API+JSON,API+XML})
- public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+ public RpcResult<TransactionStatus> updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
+
+
}
--- /dev/null
+package org.opendaylight.controller.sal.rest.api;
+
+import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RestconfServiceLegacy {
+
+ public static final String XML = "+xml";
+ public static final String JSON = "+json";
+
+ @Deprecated
+ @GET
+ @Path("/datastore")
+ @Produces({API+JSON,API+XML})
+ public StructuredData readAllData();
+
+ @Deprecated
+ @GET
+ @Path("/datastore/{identifier:.+}")
+ @Produces({API+JSON,API+XML})
+ public StructuredData readData(@PathParam("identifier") String identifier);
+
+ @Deprecated
+ @PUT
+ @Path("/datastore/{identifier:.+}")
+ @Produces({API+JSON,API+XML})
+ public RpcResult<TransactionStatus> createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+
+ @Deprecated
+ @POST
+ @Path("/datastore/{identifier:.+}")
+ @Produces({API+JSON,API+XML})
+ public RpcResult<TransactionStatus> updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+
+}
return future.get;
}
- def commitConfigurationDataUpdate(InstanceIdentifier path, CompositeNode payload) {
+ def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
val transaction = dataService.beginTransaction;
transaction.putConfigurationData(path, payload);
return transaction.commit()
}
- def commitConfigurationDataCreate(InstanceIdentifier path, CompositeNode payload) {
+ def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
val transaction = dataService.beginTransaction;
- transaction.putConfigurationData(path, payload);
+ transaction.putOperationalData(path, payload);
return transaction.commit()
}
import static com.google.common.base.Preconditions.*
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
+import java.util.concurrent.ConcurrentHashMap
class ControllerContext implements SchemaServiceListener {
private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
+ private val Map<QName,RpcDefinition> qnameToRpc = new ConcurrentHashMap();
+
private new() {
if (INSTANCE != null) {
}
}
- public def QName toRpcQName(String name) {
+ public def QName toQName(String name) {
+ val module = name.toModuleName;
+ val node = name.toNodeName;
+ val namespace = moduleNameToUri.get(module);
+ return new QName(namespace,null,node);
}
override onGlobalContextUpdated(SchemaContext context) {
this.schemas = context;
+ for(operation : context.operations) {
+ val qname = new QName(operation.QName.namespace,null,operation.QName.localName);
+ qnameToRpc.put(qname,operation);
+ }
+ }
+
+ def ContainerSchemaNode getRpcOutputSchema(QName name) {
+ qnameToRpc.get(name)?.output;
}
}
override readAllData() {
// return broker.readOperationalData("".toInstanceIdentifier.getInstanceIdentifier);
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ throw new UnsupportedOperationException("Reading all data is currently not supported.")
}
override getModules() {
}
override getRoot() {
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
-
+ return null;
}
override readData(String identifier) {
}
override createConfigurationData(String identifier, CompositeNode payload) {
-// return broker.commitConfigurationDataCreate(identifier.toInstanceIdentifier.getInstanceIdentifier, payload);
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val identifierWithSchemaNode = identifier.toInstanceIdentifier
+ return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
}
override updateConfigurationData(String identifier, CompositeNode payload) {
-// return broker.commitConfigurationDataCreate(identifier.toInstanceIdentifier.getInstanceIdentifier, payload);
- throw new UnsupportedOperationException("TODO: auto-generated method stub")
+ val identifierWithSchemaNode = identifier.toInstanceIdentifier
+ return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
}
override invokeRpc(String identifier, CompositeNode payload) {
- val rpcResult = broker.invokeRpc(identifier.toRpcQName, payload);
- return new StructuredData(rpcResult.result, identifier.toInstanceIdentifier.getSchemaNode)
+ val rpc = identifier.toQName;
+ val rpcResult = broker.invokeRpc(rpc, payload);
+ val schema = controllerContext.getRpcOutputSchema(rpc);
+ return new StructuredData(rpcResult.result, schema);
+ }
+
+ override readConfigurationData(String identifier) {
+ val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+ val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
+ return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ }
+
+ override readOperationalData(String identifier) {
+ val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+ val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
+ return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+ }
+
+ override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
+ updateConfigurationData(identifier,payload);
+ }
+
+ override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
+ createConfigurationData(identifier,payload);
+ }
+
+ override createOperationalData(String identifier, CompositeNode payload) {
+ val identifierWithSchemaNode = identifier.toInstanceIdentifier
+ return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+ }
+
+ override updateOperationalData(String identifier, CompositeNode payload) {
+ val identifierWithSchemaNode = identifier.toInstanceIdentifier
+ return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>sal-zeromq-connector</artifactId>
+ <packaging>bundle</packaging>
- <artifactId>sal-zeromq-connector</artifactId>
- <packaging>bundle</packaging>
+ <properties>
+ <scala.version>2.10.3</scala.version>
+ </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>
- org.opendaylight.controller.sal.connector.api,
- org.opendaylight.controller.sal.core.api,
- org.opendaylight.yangtools.concepts;version="[0.1,1)",
- org.opendaylight.yangtools.yang.common;version="[0.5,1)",
- org.opendaylight.yangtools.yang.data.api;version="[0.5,1)",
- org.zeromq;version="[0.3,1)"
- </Import-Package>
- <Bundle-Activator>org.opendaylight.controller.sal.connector.zeromq.Activator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-connector-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.opendaylight.controller.sal.connector.api,
+ org.opendaylight.controller.sal.core.api,
+ org.opendaylight.yangtools.concepts;version="[0.1,1)",
+ org.opendaylight.yangtools.yang.common;version="[0.5,1)",
+ org.opendaylight.yangtools.yang.data.api;version="[0.5,1)",
+ org.zeromq;version="[0.3,1)"
+ </Import-Package>
+ <Bundle-Activator>org.opendaylight.controller.sal.connector.remoterpc.router.zeromq.Activator</Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.jeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>0.3.0-SNAPSHOT</version>
- </dependency>
+ <plugin>
+ <groupId>net.alchim31.maven</groupId>
+ <artifactId>scala-maven-plugin</artifactId>
+ <version>3.1.6</version>
+ <configuration>
+ <recompileMode>incremental</recompileMode>
+ <args>
+ <arg>-target:jvm-1.7</arg>
+ </args>
+ <javacArgs>
+ <javacArg>-source</javacArg><javacArg>1.7</javacArg>
+ <javacArg>-target</javacArg><javacArg>1.7</javacArg>
+ </javacArgs>
+ </configuration>
+ <executions>
+ <execution>
+ <id>scala-compile</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>scala-test-compile</id>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
- </dependencies>
- <repositories>
- <repository>
- <id>sonatype-nexus-snapshots</id>
- <url>https://oss.sonatype.org/content/repositories/snapshots</url>
- <releases>
- <enabled>false</enabled>
- </releases>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- </repository>
- </repositories>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scala-library</artifactId>
+ <version>${scala.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.northbound</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-connector-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jeromq</groupId>
+ <artifactId>jeromq</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ </dependency>
+
+ </dependencies>
+ <repositories>
+ <repository>
+ <id>sonatype-nexus-snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
</project>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface RouteChange<I, R> {
+
+ Map<I, Set<R>> getRemovals();
+ Map<I, Set<R>> getAnnouncements();
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import java.util.EventListener;
+
+public interface RouteChangeListener extends EventListener {
+
+ public void onRouteChanged(RouteChange<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> change);
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import java.util.Set;
+
+public interface RoutingTable<I,R> {
+
+ /**
+ * Adds a network address for the route. If address for route
+ * exists, appends the address to the list
+ *
+ * @param routeId route identifier
+ * @param route network address
+ */
+ public void addRoute(I routeId, R route);
+
+ /**
+ * Adds a network address for the route. If the route already exists,
+ * it throws. This method would be used when registering a global service.
+ *
+ * @param routeId route identifier
+ * @param route network address
+ * @throws DuplicateRouteException
+ */
+ public void addGlobalRoute(I routeId, R route) throws DuplicateRouteException;
+
+ /**
+ * Removes the network address for the route from routing table. If only
+ * one network address existed, remove the route as well.
+ * @param routeId
+ * @param route
+ */
+ public void removeRoute(I routeId, R route);
+
+ /**
+ * Returns a set of network addresses associated with this route
+ * @param routeId
+ * @return
+ */
+ public Set<R> getRoutes(I routeId);
+
+ /**
+ * Returns only one address from the list of network addresses
+ * associated with the route. The algorithm to determine that
+ * one address is upto the implementer
+ * @param route
+ * @return
+ */
+ public R getARoute(I routeId);
+
+ public void registerRouteChangeListener(RouteChangeListener listener);
+
+ public class DuplicateRouteException extends Exception {}
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
+
+import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends AbstractProvider {
+
+ ZeroMqRpcRouter router;
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+ router = ZeroMqRpcRouter.getInstance();
+ router.setBrokerSession(session);
+ router.start();
+ }
+
+ @Override
+ protected void stopImpl(BundleContext context) {
+ router.stop();
+ }
+
+}
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
import org.codehaus.jackson.map.ObjectMapper;
import org.opendaylight.controller.sal.connector.api.RpcRouter;
import java.io.*;
-import java.util.Arrays;
public class Message implements Serializable {
- public enum MessageType {
- ANNOUNCE((byte) 0),
+ public static enum MessageType {
+ ANNOUNCE((byte) 0), //TODO: Remove announce, add rpc registration and deregistration
HEARTBEAT((byte) 1),
REQUEST((byte) 2),
RESPONSE((byte) 3);
return o.readObject();
}
- public static byte[] toJsonBytes(Message m){
+ public static byte[] toJsonBytes(Message m) throws IOException {
ObjectMapper o = new ObjectMapper();
- try {
- System.out.println(o.writeValueAsString(m));
- return o.writeValueAsBytes(m);
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- return null;
+ return o.writeValueAsBytes(m);
}
- public static Message fromJsonBytes(byte [] bytes){
+ public static Message fromJsonBytes(byte [] bytes) throws IOException {
ObjectMapper o = new ObjectMapper();
- Message m = null;
- try {
- m = o.readValue(bytes, Message.class);
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- return m;
+ return o.readValue(bytes, Message.class);
}
public static class Response extends Message implements RpcRouter.RpcReply {
}
}
+ /**
+ * Builds a {@link Message} object
+ */
+ public static class MessageBuilder{
+
+ private Message message;
+
+ public MessageBuilder(){
+ message = new Message();
+ }
+
+
+ public MessageBuilder type(MessageType type){
+ message.setType(type);
+ return this;
+ }
+
+ public MessageBuilder sender(String sender){
+ message.setSender(sender);
+ return this;
+ }
+
+ public MessageBuilder route(RpcRouter.RouteIdentifier route){
+ message.setRoute(route);
+ return this;
+ }
+
+ public MessageBuilder payload(Object obj){
+ message.setPayload(obj);
+ return this;
+ }
+
+ public Message build(){
+ return message;
+ }
+ }
}
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
import org.opendaylight.controller.sal.connector.api.RpcRouter;
import org.opendaylight.yangtools.yang.common.QName;
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
import org.opendaylight.controller.sal.connector.api.RpcRouter;
import org.opendaylight.yangtools.yang.common.QName;
import java.io.Serializable;
-/**
- * Created with IntelliJ IDEA.
- * User: abhishk2
- * Date: 10/25/13
- * Time: 12:32 PM
- * To change this template use File | Settings | File Templates.
- */
public class RpcRequestImpl implements RpcRouter.RpcRequest<QName, QName, InstanceIdentifier, Object>,Serializable {
private RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier;
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.controller.sal.connector.remoterpc.router.zeromq.Message.MessageType;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+/**
+ * ZeroMq based implementation of RpcRouter
+ * TODO:
+ * 1. Make it multi VM aware
+ * 2. Make rpc request handling async and non-blocking. Note zmq socket is not thread safe
+ * 3. sendRpc() should use connection pooling
+ * 4. Read properties from config file using existing(?) ODL properties framework
+ */
+public class ZeroMqRpcRouter implements RpcRouter<QName, QName, InstanceIdentifier, Object> {
+
+ private ExecutorService serverPool;
+ private static ExecutorService handlersPool;
+
+ private Map<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
+
+ private ProviderSession brokerSession;
+
+ private ZMQ.Context context;
+ private ZMQ.Socket publisher;
+ private ZMQ.Socket subscriber;
+ private ZMQ.Socket replySocket;
+
+ private static ZeroMqRpcRouter _instance = new ZeroMqRpcRouter();
+
+ private final RpcFacade facade = new RpcFacade();
+ private final RpcListener listener = new RpcListener();
+
+ private final String localIp = getLocalIpAddress();
+
+ private String pubPort = System.getProperty("pub.port");// port on which announcements are sent
+ private String subPort = System.getProperty("sub.port");// other controller's pub port
+ private String pubIp = System.getProperty("pub.ip"); // other controller's ip
+ private String rpcPort = System.getProperty("rpc.port");// port on which RPC messages are received
+
+ private Logger _logger = LoggerFactory.getLogger(ZeroMqRpcRouter.class);
+
+ //Prevent instantiation
+ private ZeroMqRpcRouter() {
+ }
+
+ public static ZeroMqRpcRouter getInstance() {
+ return _instance;
+ }
+
+ public void start() {
+ context = ZMQ.context(2);
+ publisher = context.socket(ZMQ.PUB);
+ int ret = publisher.bind("tcp://*:" + pubPort);
+ // serverPool = Executors.newSingleThreadExecutor();
+ serverPool = Executors.newCachedThreadPool();
+ handlersPool = Executors.newCachedThreadPool();
+ routingTable = new ConcurrentHashMap<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
+
+ // Start listening for announce and rpc messages
+ serverPool.execute(receive());
+
+ brokerSession.addRpcRegistrationListener(listener);
+
+ Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
+ for (QName rpc : currentlySupported) {
+ listener.onRpcImplementationAdded(rpc);
+ }
+
+ }
+
+ public void stop() {
+ if (handlersPool != null)
+ handlersPool.shutdown();
+ if (serverPool != null)
+ serverPool.shutdown();
+ if (publisher != null) {
+ publisher.setLinger(0);
+ publisher.close();
+ }
+ if (replySocket != null) {
+ replySocket.setLinger(0);
+ replySocket.close();
+ }
+ if (subscriber != null) {
+ subscriber.setLinger(0);
+ subscriber.close();
+ }
+ if (context != null)
+ context.term();
+
+ }
+
+ private Runnable receive() {
+ return new Runnable() {
+ public void run() {
+ try {
+ // Bind to RPC reply socket
+ replySocket = context.socket(ZMQ.REP);
+ replySocket.bind("tcp://*:" + rpcPort);
+
+ // Bind to publishing controller
+ subscriber = context.socket(ZMQ.SUB);
+ String pubAddress = "tcp://" + pubIp + ":" + subPort;
+ subscriber.connect(pubAddress);
+ _logger.debug("{} Subscribing at[{}]", Thread.currentThread().getName(), pubAddress);
+
+ //subscribe for announcements
+ //TODO: Message type would be changed. Update this
+ subscriber.subscribe(Message.serialize(Message.MessageType.ANNOUNCE));
+
+ // Poller enables listening on multiple sockets using a single thread
+ ZMQ.Poller poller = new ZMQ.Poller(2);
+ poller.register(replySocket, ZMQ.Poller.POLLIN);
+ poller.register(subscriber, ZMQ.Poller.POLLIN);
+
+ //TODO: Add code to restart the thread after exception
+ while (!Thread.currentThread().isInterrupted()) {
+
+ poller.poll();
+
+ if (poller.pollin(0)) {
+ handleRpcCall();
+ }
+ if (poller.pollin(1)) {
+ handleAnnouncement();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ replySocket.setLinger(0);
+ replySocket.close();
+ subscriber.setLinger(0);
+ subscriber.close();
+ }
+ };
+ }
+
+ /**
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ private void handleAnnouncement() throws IOException, ClassNotFoundException {
+
+ _logger.info("Announcement received");
+ Message.MessageType topic = (MessageType) Message.deserialize(subscriber.recv());
+
+ if (subscriber.hasReceiveMore()) {
+ try {
+ Message m = (Message) Message.deserialize(subscriber.recv());
+ _logger.debug("Announcement message [{}]", m);
+
+ // TODO: check on msg type or topic. Both
+ // should be same. Need to normalize.
+ if (Message.MessageType.ANNOUNCE == m.getType())
+ updateRoutingTable(m);
+ } catch (IOException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ /**
+ * @throws InterruptedException
+ * @throws ExecutionException
+ */
+ private void handleRpcCall() throws InterruptedException, ExecutionException {
+ try {
+ Message request = parseMessage(replySocket);
+
+ _logger.debug("Received rpc request [{}]", request);
+
+ // Call broker to process the message then reply
+ Future<RpcResult<CompositeNode>> rpc = brokerSession.rpc(
+ (QName) request.getRoute().getType(), (CompositeNode) request.getPayload());
+
+ RpcResult<CompositeNode> result = rpc.get();
+
+ Message response = new Message.MessageBuilder()
+ .type(MessageType.RESPONSE)
+ .sender(localIp + ":" + rpcPort)
+ .route(request.getRoute())
+ //.payload(result) TODO: enable and test
+ .build();
+
+ replySocket.send(Message.serialize(response));
+
+ _logger.debug("Sent rpc response [{}]", response);
+
+ } catch (IOException ex) {
+ //TODO: handle exception and send error codes to caller
+ ex.printStackTrace();
+ }
+ }
+
+
+ @Override
+ public Future<RpcReply<Object>> sendRpc(
+ final RpcRequest<QName, QName, InstanceIdentifier, Object> input) {
+
+ return handlersPool.submit(new Callable<RpcReply<Object>>() {
+
+ @Override
+ public RpcReply<Object> call() {
+ ZMQ.Socket requestSocket = context.socket(ZMQ.REQ);
+
+ // TODO pick the ip and port from routing table based on routing identifier
+ requestSocket.connect("tcp://" + pubIp + ":5554");
+
+ Message requestMessage = new Message.MessageBuilder()
+ .type(MessageType.REQUEST)
+ .sender(localIp + ":" + rpcPort)
+ .route(input.getRoutingInformation())
+ .payload(input.getPayload())
+ .build();
+
+ _logger.debug("Sending rpc request [{}]", requestMessage);
+
+ RpcReply<Object> reply = null;
+
+ try {
+
+ requestSocket.send(Message.serialize(requestMessage));
+ final Message response = parseMessage(requestSocket);
+
+ _logger.debug("Received response [{}]", response);
+
+ reply = new RpcReply<Object>() {
+
+ @Override
+ public Object getPayload() {
+ return response.getPayload();
+ }
+ };
+ } catch (IOException ex) {
+ // TODO: Pass exception back to the caller
+ ex.printStackTrace();
+ }
+
+ return reply;
+ }
+ });
+ }
+
+ /**
+ * TODO: Remove this implementation and use RoutingTable implementation to send announcements
+ * Publishes a notice to other controllers in the cluster
+ *
+ * @param notice
+ */
+ public void publish(final Message notice) {
+ Runnable task = new Runnable() {
+ public void run() {
+
+ try {
+
+ publisher.sendMore(Message.serialize(Message.MessageType.ANNOUNCE));
+ publisher.send(Message.serialize(notice));
+ _logger.debug("Announcement sent [{}]", notice);
+ } catch (IOException ex) {
+ _logger.error("Error in sending announcement [{}]", notice);
+ ex.printStackTrace();
+ }
+ }
+ };
+ handlersPool.execute(task);
+ }
+
+ /**
+ * Finds IPv4 address of the local VM
+ * TODO: This method is non-deterministic. There may be more than one IPv4 address. Cant say which
+ * address will be returned. Read IP from a property file or enhance the code to make it deterministic.
+ * Should we use IP or hostname?
+ *
+ * @return
+ */
+ private String getLocalIpAddress() {
+ String hostAddress = null;
+ Enumeration e = null;
+ try {
+ e = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e1) {
+ e1.printStackTrace();
+ }
+ while (e.hasMoreElements()) {
+
+ NetworkInterface n = (NetworkInterface) e.nextElement();
+
+ Enumeration ee = n.getInetAddresses();
+ while (ee.hasMoreElements()) {
+ InetAddress i = (InetAddress) ee.nextElement();
+ if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
+ hostAddress = i.getHostAddress();
+ }
+ }
+ return hostAddress;
+
+ }
+
+ /**
+ * TODO: Change to use external routing table implementation
+ *
+ * @param msg
+ */
+ private void updateRoutingTable(Message msg) {
+ routingTable.put(msg.getRoute(), msg.getSender());
+ RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> route = msg.getRoute();
+
+ // Currently only registers rpc implementation.
+ // TODO: do registration for instance based routing
+ QName rpcType = route.getType();
+ RpcRegistration registration = brokerSession.addRpcImplementation(rpcType, facade);
+ _logger.debug("Routing table updated");
+ }
+
+ /**
+ * @param socket
+ * @return
+ */
+ private Message parseMessage(ZMQ.Socket socket) {
+
+ Message msg = null;
+ try {
+ byte[] bytes = socket.recv();
+ _logger.debug("Received bytes:[{}]", bytes.length);
+ msg = (Message) Message.deserialize(bytes);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ return msg;
+ }
+
+ private class RpcFacade implements RpcImplementation {
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+
+ RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+ routeId.setType(rpc);
+
+ RpcRequestImpl request = new RpcRequestImpl();
+ request.setRouteIdentifier(routeId);
+ request.setPayload(input);
+
+ final Future<RpcReply<Object>> ret = sendRpc(request);
+
+ //TODO: Review result handling
+ RpcResult<CompositeNode> result = new RpcResult<CompositeNode>() {
+ @Override
+ public boolean isSuccessful() {
+ try {
+ ret.get();
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public CompositeNode getResult() {
+ return null;
+ }
+
+ @Override
+ public Collection<RpcError> getErrors() {
+ return Collections.EMPTY_LIST;
+ }
+ };
+ return result;
+ }
+ }
+
+ /**
+ * Listener for rpc registrations
+ */
+ private class RpcListener implements RpcRegistrationListener {
+
+ @Override
+ public void onRpcImplementationAdded(QName name) {
+
+ _logger.debug("Announcing registration for [{}]", name);
+ RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+ routeId.setType(name);
+
+ //TODO: Make notice immutable and change message type
+ Message notice = new Message.MessageBuilder()
+ .type(MessageType.ANNOUNCE)
+ .sender("tcp://" + localIp + ":" + rpcPort)
+ .route(routeId)
+ .build();
+
+ publish(notice);
+ }
+
+ @Override
+ public void onRpcImplementationRemoved(QName name) {
+ // TODO: send a rpc-deregistrtation notice
+
+ }
+ }
+
+ public void setBrokerSession(ProviderSession session) {
+ this.brokerSession = session;
+
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.osgi.framework.BundleContext;
-
-public class Activator extends AbstractProvider {
-
- ZeroMqRpcRouter router;
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
- router = ZeroMqRpcRouter.getInstance();
- router.setBrokerSession(session);
- router.start();
- }
-
- @Override
- protected void stopImpl(BundleContext context) {
- router.stop();
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-
-import java.io.Serializable;
-
-/**
- * Created with IntelliJ IDEA.
- * User: abhishk2
- * Date: 10/24/13
- * Time: 4:25 PM
- * To change this template use File | Settings | File Templates.
- */
-public class RpcReplyImpl implements RpcRouter.RpcReply<Object>,Serializable {
-
- private Object payload;
-
- @Override
- public Object getPayload() {
- return payload; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void setPayload(Object payload){
- this.payload = payload;
- }
-}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-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.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.*;
-import java.util.concurrent.*;
-
-public class ZeroMqRpcRouter implements RpcRouter<QName, QName, InstanceIdentifier, Object> {
-
- private ExecutorService serverPool;
- private static ExecutorService handlersPool;
-
- private Map<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
-
- private ProviderSession brokerSession;
-
- private ZMQ.Context context;
- private ZMQ.Socket publisher;
- private ZMQ.Socket subscriber;
- private ZMQ.Socket replySocket;
-
- private static ZeroMqRpcRouter _instance = new ZeroMqRpcRouter();
-
- private final RpcFacade facade = new RpcFacade();
- private final RpcListener listener = new RpcListener();
-
- private String pubPort = System.getProperty("pub.port");//port on which announcements are sent
- private String subPort = System.getProperty("sub.port");//other controller's pub port
- private String pubIp = System.getProperty("pub.ip"); //other controller's ip
- private String rpcPort = System.getProperty("rpc.port");//port on which RPC messages are received
-
-
- private ZeroMqRpcRouter() {
- }
-
- public static ZeroMqRpcRouter getInstance() {
- return _instance;
- }
-
- public void start() {
- context = ZMQ.context(2);
- serverPool = Executors.newSingleThreadExecutor();
- handlersPool = Executors.newCachedThreadPool();
- routingTable = new ConcurrentHashMap<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
-
- // Start listening for announce and rpc messages
- serverPool.execute(receive());
-
-
- brokerSession.addRpcRegistrationListener(listener);
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- for(QName rpc : currentlySupported) {
- listener.onRpcImplementationAdded(rpc);
- }
-
-
- }
-
- public void stop() {
- if (handlersPool != null) handlersPool.shutdown();
- if (serverPool != null) serverPool.shutdown();
- if (publisher != null) {
- publisher.setLinger(0);
- publisher.close();
- }
- if (replySocket != null) {
- replySocket.setLinger(0);
- replySocket.close();
- }
- if (subscriber != null) {
- subscriber.setLinger(0);
- subscriber.close();
- }
- if (context != null) context.term();
-
-
- }
-
- private Runnable receive() {
- return new Runnable() {
- public void run() {
- try {
- // Bind to RPC reply socket
- replySocket = context.socket(ZMQ.REP);
- replySocket.bind("tcp://*:" + rpcPort);
-
- // Bind to publishing controller
- subscriber = context.socket(ZMQ.SUB);
- subscriber.connect("tcp://" + pubIp + ":" + subPort);
- System.out.println("Subscribing at[" + "tcp://" + pubIp + ":" + subPort + "]");
-
- subscriber.subscribe(Message.serialize(Message.MessageType.ANNOUNCE));
-
- // Initialize poll set
- ZMQ.Poller poller = new ZMQ.Poller(2);
- poller.register(replySocket, ZMQ.Poller.POLLIN);
- poller.register(subscriber, ZMQ.Poller.POLLIN);
-
- while (!Thread.currentThread().isInterrupted()) {
-
- poller.poll(250);
- //TODO: Fix this
- if (poller.pollin(0)) {
- //receive rpc request and reply
- try {
- Message req = parseMessage(replySocket);
- Message resp = new Message();
- //Call broker to process the message then reply
- Future<RpcResult<CompositeNode>> rpc = brokerSession.rpc((QName) req.getRoute().getType(), (CompositeNode) req.getPayload());
- RpcResult<CompositeNode> result = rpc.get();
- resp.setType(Message.MessageType.RESPONSE);
- resp.setSender(getLocalIpAddress() + ":" + rpcPort);
- resp.setRoute(req.getRoute());
- resp.setPayload(result.isSuccessful());
- replySocket.send(Message.serialize(resp));
-
- } catch (IOException ex) {// | ClassNotFoundException ex) {
- System.out.println("Rpc request could not be handled" + ex);
- }
- }
- if (poller.pollin(1)) {
- //get subscription and update routing table
- //try {
- Message.MessageType topic = (Message.MessageType)Message.deserialize(subscriber.recv());
- System.out.println("Topic:[" + topic + "]");
-
- if (subscriber.hasReceiveMore()) {
- try {
- Message m = (Message) Message.deserialize(subscriber.recv());
- System.out.println(m);
- //TODO: check on msg type or topic. Both should be same. Need to normalize.
- if (Message.MessageType.ANNOUNCE == m.getType()) updateRoutingTable(m);
- } catch (IOException | ClassNotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
-//
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- replySocket.setLinger(0);
- replySocket.close();
- subscriber.setLinger(0);
- subscriber.close();
- }
- };
- }
-
- private void updateRoutingTable(Message msg) {
- routingTable.put(msg.getRoute(), msg.getSender());
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> route = msg.getRoute();
- QName rpcType = route.getType();
- System.out.println("Routing Table\n" + routingTable);
-
- RpcRegistration registration = brokerSession.addRpcImplementation(rpcType, facade);
- }
-
- private Message parseMessage(ZMQ.Socket socket) {
- //Message m = new Message();
- //socket.setReceiveBufferSize(40000);
- Message msg = null;
- try {
- byte[] bytes = socket.recv();
- System.out.println("Received bytes:[" + bytes.length + "]");
- msg = (Message) Message.deserialize(bytes);
- } catch (Throwable t) {
- System.out.println("Caught exception");
- t.printStackTrace();
- }
- return msg;
- /*m.setType((Message.MessageType) Message.deserialize(socket.recv()));
-
- if (socket.hasReceiveMore()) {
- m.setSender((String) Message.deserialize(socket.recv()));
- }
- if (socket.hasReceiveMore()) {
- m.setRoute((RouteIdentifier) Message.deserialize(socket.recv()));
- }
- if (socket.hasReceiveMore()) {
- m.setPayload(Message.deserialize(socket.recv()));
- }
- return m;*/
- }
-
- @Override
- public Future<RpcReply<Object>> sendRpc(final RpcRequest<QName, QName, InstanceIdentifier, Object> input) {
-
- return handlersPool.submit(new Callable<RpcReply<Object>>() {
-
- @Override
- public RpcReply<Object> call() {
- ZMQ.Socket requestSocket = context.socket(ZMQ.REQ);
- Message req = new Message();
- Message resp = null;
- RpcReplyImpl reply = new RpcReplyImpl();
- requestSocket.connect((String) routingTable.get(input.getRoutingInformation().getRoute()));
-
- req.setType(Message.MessageType.REQUEST);
- req.setSender(getLocalIpAddress() + ":" + rpcPort);
- req.setRoute(input.getRoutingInformation());
- req.setPayload(input.getPayload());
- try {
- requestSocket.send(Message.serialize(req));
- resp = parseMessage(requestSocket);
- reply.setPayload(resp.getPayload());
- } catch (IOException ex) {//| ClassNotFoundException ex) {
- //Log and ignore
- System.out.println("Error in RPC send. Input could not be serialized[" + input + "]");
- }
-
- return reply;
- }
- });
- }
-
- public void publish(final Message message) {
- Runnable task = new Runnable() {
- public void run() {
- // Bind to publishing port
- publisher = context.socket(ZMQ.PUB);
- publisher.bind("tcp://*:" + pubPort);
- System.out.println("Publisher started at port[" + pubPort + "]");
- try {
- Message outMessage = new Message();
- outMessage.setType(Message.MessageType.ANNOUNCE);
- outMessage.setSender("tcp://" + getLocalIpAddress() + ":" + rpcPort);
- outMessage.setRoute(message.getRoute());
-
- System.out.println("Sending announcement[" + outMessage + "]");
- publisher.sendMore(Message.serialize(Message.MessageType.ANNOUNCE));
- publisher.send(Message.serialize(outMessage));
-
- } catch (IOException ex) {
- //Log and ignore
- System.out.println("Error in publishing");
- ex.printStackTrace();
- }
- System.out.println("Published message[" + message + "]");
- publisher.close();
- }
- };
- handlersPool.execute(task);
- }
-
- private String getLocalIpAddress() {
- String hostAddress = null;
- Enumeration e = null;
- try {
- e = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e1) {
- e1.printStackTrace();
- }
- while (e.hasMoreElements()) {
-
- NetworkInterface n = (NetworkInterface) e.nextElement();
- Enumeration ee = n.getInetAddresses();
- while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
- if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
- hostAddress = i.getHostAddress();
- }
- }
-
- return hostAddress;
-
-
- }
-
-
- private class RpcFacade implements RpcImplementation {
-
-
- @Override
- public Set<QName> getSupportedRpcs() {
- return Collections.emptySet();
- }
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
-
- RpcRequestImpl request = new RpcRequestImpl();
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setContext(null);
- routeId.setRoute(null);
- routeId.setType(rpc);
-
- request.setRouteIdentifier(routeId);
- request.setPayload(input);
- // Create message
-
- Future<org.opendaylight.controller.sal.connector.api.RpcRouter.RpcReply<Object>> ret = sendRpc(request);
-
- return null;
- }
- }
-
- private class RpcListener implements RpcRegistrationListener {
-
- @Override
- public void onRpcImplementationAdded(QName name) {
-
- Message msg = new Message();
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(name);
- msg.setRoute(routeId);
- publish(msg);
- }
-
- @Override
- public void onRpcImplementationRemoved(QName name) {
- // TODO Auto-generated method stub
-
- }
- }
-
- public void setBrokerSession(ProviderSession session) {
- this.brokerSession = session;
-
- }
-
-}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-manager</artifactId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+ <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+ <version>4.0</version>
+ </dependency>
</dependencies>
</project>
public static final String ODL = "org.opendaylight.controller";
public static final String YANG = "org.opendaylight.yangtools";
+ public static final String CONTROLLER = "org.opendaylight.controller";
+ public static final String YANGTOOLS = "org.opendaylight.yangtools";
+
+
public static final String SAMPLE = "org.opendaylight.controller.samples";
@Test
mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
- mavenBundle(ODL, "sal-binding-api").versionAsInProject(), //
- mavenBundle(ODL, "sal-binding-config").versionAsInProject(),
- mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject(), //
mavenBundle(ODL, "sal-common").versionAsInProject(), //
mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
mavenBundle(ODL, "config-api").versionAsInProject(), //
mavenBundle(ODL, "config-manager").versionAsInProject(), //
mavenBundle("commons-io", "commons-io").versionAsInProject(),
+ mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
+ mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), //
+ mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
+ mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
+ mavenBundle("org.javassist", "javassist").versionAsInProject(), //
+ mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+
+ mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+
+
+ mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+ mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+ mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+
+
+ mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+ mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+ mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+
+ mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
mavenBundle(SAMPLE, "sample-toaster").versionAsInProject(), //
mavenBundle(SAMPLE, "sample-toaster-consumer").versionAsInProject(), //
<spring.version>3.1.3.RELEASE</spring.version>
<jersey.version>1.17</jersey.version>
<spring-security.version>3.1.3.RELEASE</spring-security.version>
+ <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+ <config.version>0.2.2-SNAPSHOT</config.version>
</properties>
<build>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-netconf-connector</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-it</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.thirdparty</groupId>
+ <artifactId>exificient</artifactId>
+ <version>0.9.2</version>
+ </dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-container-native</artifactId>
<version>${exam.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>4.0.10.Final</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-link-mvn</artifactId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
<version>7.0.42</version>
</dependency>
+
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-manager</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-util</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-store-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-store-impl</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>logback-config</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-file-adapter</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-api</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-impl</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-util</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-mapping-api</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-netconf-connector</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-persister-impl</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
</dependencies>
</project>
package org.opendaylight.controller.test.restconf.it;
+import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.CoreOptions.maven;
+import java.net.InetSocketAddress;
+import java.net.URI;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
+import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
+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.controller.test.sal.binding.it.TestHelper;
+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.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
public static final String YANG = "org.opendaylight.yangtools";
public static final String SAMPLE = "org.opendaylight.controller.samples";
+ private static QName CONFIG_MODULES = new QName(
+ URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+ private static QName CONFIG_SERVICES = new QName(
+ URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+ @Inject
+ BundleContext context;
+
+ @Inject
+ MountProvisionService mountService;
+
+ @Inject
+ DataBrokerService dataBroker;
+
+ @Inject
+ NetconfDeviceManager netconfManager;
+
@Test
public void properInitialized() throws Exception {
- Thread.sleep(30*60*1000); // Waiting for services to get wired.
- assertTrue(true);
- // assertTrue(consumer.createToast(WhiteBread.class, 5));
+ Map<QName, String> arg = Collections.singletonMap(InventoryUtils.INVENTORY_ID, "foo");
- }
+ InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
+ .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance();
- // @Inject
- // BindingAwareBroker broker;
+ netconfManager.netconfNodeAdded(path, new InetSocketAddress("127.0.0.1", 8383));
- // @Inject
- // ToastConsumer consumer;
+
+ InstanceIdentifier mountPointPath = path;
+
+ /** We retrive a mountpoint **/
+ MountProvisionInstance mountPoint = mountService.getMountPoint(mountPointPath);
+ CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES)
+ .toInstance());
+ assertNotNull(data);
+ assertEquals(CONFIG_MODULES, data.getNodeType());
- @Inject
- BundleContext ctx;
+ CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance());
+ assertNotNull(data2);
+
+ InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance();
+
+ CompositeNode data3 = dataBroker.readOperationalData(fullPath);
+ assertNotNull(data3);
+ assertEquals(CONFIG_MODULES, data.getNodeType());
+
+ //Thread.sleep(30 * 60 * 1000); // Waiting for services to get wired.
+ //assertTrue(true);
+ // assertTrue(consumer.createToast(WhiteBread.class, 5));
+ }
@Configuration
public Option[] config() {
mdSalCoreBundles(),
baseModelBundles(),
flowCapableModelBundles(),
+ configMinumumBundles(),
// mavenBundle(ODL,
// "sal-binding-broker-impl").versionAsInProject().update(), //
// mavenBundle(SAMPLE,
// "zeromq-test-provider").versionAsInProject(), //
mavenBundle(ODL, "sal-rest-connector").versionAsInProject(), //
+ mavenBundle(ODL, "sal-netconf-connector").versionAsInProject(), //
mavenBundle(YANG, "concepts").versionAsInProject(),
mavenBundle(YANG, "yang-binding").versionAsInProject(), //
mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
mavenBundle(YANG, "yang-parser-api").versionAsInProject(),
mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
+
mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), //
mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
mavenBundle("com.google.guava", "guava").versionAsInProject(), //
// earlier.
systemProperty("osgi.bundles.defaultStartLevel").value("4"),
+ systemProperty("netconf.tcp.address").value("127.0.0.1"),
+ systemProperty("netconf.tcp.port").value("8383"),
+
// Set the systemPackages (used by clustering)
systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
+
+ mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.xerces", "2.11.0_1"),
+ mavenBundle("org.eclipse.birt.runtime.3_7_1", "org.apache.xml.resolver", "1.2.0"),
+
mavenBundle("org.slf4j", "jcl-over-slf4j").versionAsInProject(),
mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(),
mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(),
// mavenBundle("commons-fileupload",
// "commons-fileupload").versionAsInProject(),
+ mavenBundle("io.netty", "netty-handler").versionAsInProject(),
+ mavenBundle("io.netty", "netty-codec").versionAsInProject(),
+ mavenBundle("io.netty", "netty-buffer").versionAsInProject(),
+ mavenBundle("io.netty", "netty-transport").versionAsInProject(),
+ mavenBundle("io.netty", "netty-common").versionAsInProject(),
+
+ mavenBundle(ODL, "config-api").versionAsInProject(),
+ mavenBundle(ODL, "config-manager").versionAsInProject(),
+ mavenBundle(ODL, "config-util").versionAsInProject(),
+ mavenBundle(ODL, "yang-jmx-generator").versionAsInProject(),
+ mavenBundle(ODL, "yang-store-api").versionAsInProject(),
+ mavenBundle(ODL, "yang-store-impl").versionAsInProject(),
+ mavenBundle(ODL, "logback-config").versionAsInProject(),
+ mavenBundle(ODL, "config-persister-api").versionAsInProject(),
+ // mavenBundle(ODL,"config-persister-file-adapter").versionAsInProject(),
+ mavenBundle(ODL, "netconf-api").versionAsInProject(),
+ mavenBundle(ODL, "netconf-impl").versionAsInProject(),
+ mavenBundle(ODL, "netconf-client").versionAsInProject(),
+ mavenBundle(ODL, "netconf-util").versionAsInProject(),
+ mavenBundle(ODL + ".thirdparty", "ganymed", "1.0-SNAPSHOT"),
+ mavenBundle(ODL, "netconf-mapping-api").versionAsInProject(),
+ mavenBundle(ODL, "config-netconf-connector").versionAsInProject(),
+ mavenBundle(ODL, "config-persister-impl").versionAsInProject(),
+
+ mavenBundle("org.opendaylight.bgpcep", "framework").versionAsInProject(),
+ mavenBundle("org.opendaylight.bgpcep", "util").versionAsInProject(),
+ mavenBundle(YANG, "binding-generator-spi").versionAsInProject(), //
+ mavenBundle(YANG, "binding-model-api").versionAsInProject(), //
+ mavenBundle(YANG, "binding-generator-util").versionAsInProject(),
+ mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
+ mavenBundle(YANG, "binding-type-provider").versionAsInProject(),
+
+ mavenBundle("org.opendaylight.controller.thirdparty", "exificient", "0.9.2"),
+
mavenBundle("equinoxSDK381", "javax.servlet").versionAsInProject(),
mavenBundle("equinoxSDK381", "javax.servlet.jsp").versionAsInProject(),
mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(),
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>config-netconf-connector</artifactId>
<name>${project.artifactId}</name>
Element response = get();
- System.err.println(XmlUtil.toString(response));
-
assertEquals(2, getElementsSize(response, "instance"));
assertEquals(2, getElementsSize(response, "asdf"));
assertEquals(5, getElementsSize(response, "inner-running-data"));
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>config-persister-impl</artifactId>
<name>${project.artifactId}</name>
javax.management,
javax.xml.parsers,
org.opendaylight.controller.config.persist.api,
- org.opendaylight.controller.config.stat,
org.opendaylight.controller.config.persist.api.storage,
org.opendaylight.controller.netconf.api,
org.opendaylight.controller.netconf.api.jmx,
import com.google.common.base.Optional;
import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(NoOpStorageAdapter.class);
@Override
- public void setProperties(ConfigProvider configProvider) {
- logger.debug("setProperties called with {}", configProvider);
+ public void setProperties(BundleContext bundleContext) {
+ logger.debug("setProperties called with {}", bundleContext);
}
@Override
import com.google.common.base.Optional;
import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
import java.io.IOException;
this.storage = storage;
}
- public static Optional<PersisterImpl> createFromProperties(ConfigProvider configProvider) {
- String storageAdapterClass = configProvider.getProperty(STORAGE_ADAPTER_CLASS_PROP);
+ public static Optional<PersisterImpl> createFromProperties(BundleContext bundleContext) {
+ String storageAdapterClass = bundleContext.getProperty(STORAGE_ADAPTER_CLASS_PROP);
StorageAdapter storage;
if (storageAdapterClass == null || storageAdapterClass.equals("")) {
return Optional.absent();
try {
storage = StorageAdapter.class.cast(resolveClass(storageAdapterClass, StorageAdapter.class).newInstance());
- storage.setProperties(configProvider);
+ storage.setProperties(bundleContext);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new IllegalArgumentException("Unable to instantiate storage adapter from " + storageAdapterClass, e);
import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
import org.opendaylight.controller.netconf.persist.impl.NoOpStorageAdapter;
import org.opendaylight.controller.netconf.persist.impl.PersisterImpl;
-import org.opendaylight.controller.config.stat.ConfigProvider;
import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.TLSConfiguration;
import org.osgi.framework.BundleActivator;
public void start(BundleContext context) throws Exception {
logger.debug("ConfigPersister activator started");
- ConfigProvider configProvider = new ConfigProvider.ConfigProviderImpl(context);
- Optional<PersisterImpl> maybePersister = PersisterImpl.createFromProperties(configProvider);
+ Optional<PersisterImpl> maybePersister = PersisterImpl.createFromProperties(context);
if (maybePersister.isPresent() == false) {
throw new IllegalStateException("No persister is defined in " + PersisterImpl.STORAGE_ADAPTER_CLASS_PROP
+ " property. For noop persister use " + NoOpStorageAdapter.class.getCanonicalName()
+ " . Persister is not operational");
}
- Optional<TLSConfiguration> maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(configProvider);
- Optional<InetSocketAddress> maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(configProvider);
+ Optional<TLSConfiguration> maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context);
+ Optional<InetSocketAddress> maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context);
InetSocketAddress address;
if (maybeTLSConfiguration.isPresent()) {
import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
import org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
import java.io.File;
import java.io.IOException;
public class PersisterImplTest {
@Mock
- ConfigProvider mockedConfigProvider;
+ BundleContext mockedContext;
@Before
public void setUpMocks() {
@Test
public void testFromProperties() throws Exception {
- doReturn(MockAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+ doReturn(MockAdapter.class.getName()).when(mockedContext).getProperty(
PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
- PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedConfigProvider).get();
+ PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedContext).get();
persisterImpl.persistConfig(null);
persisterImpl.loadLastConfig();
persisterImpl.persistConfig(null);
@Test
public void testFromProperties2() throws Exception {
- mockedConfigProvider = mock(ConfigProvider.class);
- doReturn(FileStorageAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+ mockedContext = mock(BundleContext.class);
+ doReturn(FileStorageAdapter.class.getName()).when(mockedContext).getProperty(
PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
doReturn("target" + File.separator + "generated-test-sources" + File.separator + "testFile").when(
- mockedConfigProvider).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
- doReturn("mockedConfigProvider").when(mockedConfigProvider).toString();
- doReturn(null).when(mockedConfigProvider).getProperty("numberOfBackups");
+ mockedContext).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
+ doReturn("mockedContext").when(mockedContext).toString();
+ doReturn(null).when(mockedContext).getProperty("numberOfBackups");
- PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedConfigProvider).get();
+ PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedContext).get();
assertTrue(persisterImpl.getStorage() instanceof FileStorageAdapter);
}
@Test
public void testFromProperties3() throws Exception {
- mockedConfigProvider = mock(ConfigProvider.class);
- doReturn(FileStorageAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+ mockedContext = mock(BundleContext.class);
+ doReturn(FileStorageAdapter.class.getName()).when(mockedContext).getProperty(
PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
doReturn("target" + File.separator + "generated-test-sources" + File.separator + "testFile").when(
- mockedConfigProvider).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
- doReturn("mockedConfigProvider").when(mockedConfigProvider).toString();
- doReturn("0").when(mockedConfigProvider).getProperty("numberOfBackups");
+ mockedContext).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
+ doReturn("mockedContext").when(mockedContext).toString();
+ doReturn("0").when(mockedContext).getProperty("numberOfBackups");
try {
- PersisterImpl.createFromProperties(mockedConfigProvider).get();
+ PersisterImpl.createFromProperties(mockedContext).get();
fail();
} catch (RuntimeException e) {
assertThat(
static int props = 0;
@Override
- public void setProperties(ConfigProvider configProvider) {
+ public void setProperties(BundleContext configProvider) {
props++;
}
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-api</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>netconf-client</artifactId>
<name>${project.artifactId}</name>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-impl</artifactId>
org.w3c.dom,
org.xml.sax,
org.opendaylight.controller.netconf.util.messages,
- org.opendaylight.controller.config.stat,
com.siemens.ct.exi.exceptions
</Import-Package>
</instructions>
import com.google.common.base.Optional;
import io.netty.util.HashedWheelTimer;
-import org.opendaylight.controller.config.stat.ConfigProvider;
import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
@Override
public void start(final BundleContext context) throws Exception {
- final ConfigProvider configProvider = new ConfigProvider.ConfigProviderImpl(context);
- maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(configProvider);
- maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(configProvider);
+ maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context);
+ maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context);
if (maybeTCPAddress.isPresent() == false && maybeTLSConfiguration.isPresent() == false) {
throw new IllegalStateException("TCP nor TLS is configured, netconf not available.");
}
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>netconf-it</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>netconf-mapping-api</artifactId>
<parent>
<artifactId>netconf-subsystem</artifactId>
<groupId>org.opendaylight.controller</groupId>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
</parent>
<artifactId>netconf-util</artifactId>
<name>${project.artifactId}</name>
org.opendaylight.controller.netconf.util.handler,
</Export-Package>
<Import-Package>
- org.opendaylight.controller.config.stat,
com.google.common.base,
com.google.common.collect,
ch.ethz.ssh2,
package org.opendaylight.controller.netconf.util.osgi;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Optional;
+import org.opendaylight.protocol.util.SSLUtil;
+import org.osgi.framework.BundleContext;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.InetSocketAddress;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-
-import org.opendaylight.controller.config.stat.ConfigProvider;
-import org.opendaylight.protocol.util.SSLUtil;
-
-import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
public class NetconfConfigUtil {
private static final String PREFIX_PROP = "netconf.";
private static final String NETCONF_TLS_KEYSTORE_PROP = PREFIX_PROP + InfixProp.tls + ".keystore";
private static final String NETCONF_TLS_KEYSTORE_PASSWORD_PROP = NETCONF_TLS_KEYSTORE_PROP + ".password";
- public static Optional<InetSocketAddress> extractTCPNetconfAddress(ConfigProvider configProvider) {
- return extractSomeNetconfAddress(configProvider, InfixProp.tcp);
+ public static Optional<InetSocketAddress> extractTCPNetconfAddress(BundleContext context) {
+ return extractSomeNetconfAddress(context, InfixProp.tcp);
}
- public static Optional<TLSConfiguration> extractTLSConfiguration(ConfigProvider configProvider) {
- Optional<InetSocketAddress> address = extractSomeNetconfAddress(configProvider, InfixProp.tls);
+ public static Optional<TLSConfiguration> extractTLSConfiguration(BundleContext context) {
+ Optional<InetSocketAddress> address = extractSomeNetconfAddress(context, InfixProp.tls);
if (address.isPresent()) {
- String keystoreFileName = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PROP);
+ String keystoreFileName = context.getProperty(NETCONF_TLS_KEYSTORE_PROP);
File keystoreFile = new File(keystoreFileName);
checkState(keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead(),
"Keystore file %s does not exist or is not readable file", keystoreFileName);
keystoreFile = keystoreFile.getAbsoluteFile();
- String keystorePassword = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
+ String keystorePassword = context.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
checkNotNull(keystoreFileName, "Property %s must be defined for tls netconf server",
NETCONF_TLS_KEYSTORE_PROP);
keystorePassword = keystorePassword != null ? keystorePassword : "";
}
/**
- * @param configProvider
+ * @param context
* from which properties are being read.
* @param infixProp
* either tcp or tls
* @throws IllegalStateException
* if address or port are invalid
*/
- private static Optional<InetSocketAddress> extractSomeNetconfAddress(ConfigProvider configProvider,
+ private static Optional<InetSocketAddress> extractSomeNetconfAddress(BundleContext context,
InfixProp infixProp) {
- String address = configProvider.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
+ String address = context.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
if (address == null) {
return Optional.absent();
}
String portKey = PREFIX_PROP + infixProp + PORT_SUFFIX_PROP;
- String portString = configProvider.getProperty(portKey);
+ String portString = context.getProperty(portKey);
checkNotNull(portString, "Netconf port must be specified in properties file with " + portKey);
try {
int port = Integer.valueOf(portString);
<relativePath>../commons/opendaylight</relativePath>
</parent>
- <version>0.2.2-SNAPSHOT</version>
+ <version>0.2.3-SNAPSHOT</version>
<artifactId>netconf-subsystem</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.util.Hashtable;\r
-import java.util.Dictionary;\r
-import org.apache.felix.dm.Component;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;\r
-\r
-public class Activator extends ComponentActivatorAbstractBase {\r
- protected static final Logger logger = LoggerFactory\r
- .getLogger(Activator.class);\r
-\r
- /**\r
- * Function called when the activator starts just after some\r
- * initializations are done by the\r
- * ComponentActivatorAbstractBase.\r
- *\r
- */\r
- public void init() {\r
-\r
- }\r
-\r
- /**\r
- * Function called when the activator stops just before the\r
- * cleanup done by ComponentActivatorAbstractBase\r
- *\r
- */\r
- public void destroy() {\r
-\r
- }\r
-\r
- /**\r
- * Function that is used to communicate to dependency manager the\r
- * list of known implementations for services inside a container\r
- *\r
- *\r
- * @return An array containing all the CLASS objects that will be\r
- * instantiated in order to get an fully working implementation\r
- * Object\r
- */\r
- public Object[] getImplementations() {\r
- Object[] res = { NeutronFloatingIPInterface.class,\r
- NeutronRouterInterface.class,\r
- NeutronPortInterface.class,\r
- NeutronSubnetInterface.class,\r
- NeutronNetworkInterface.class };\r
- return res;\r
- }\r
-\r
- /**\r
- * Function that is called when configuration of the dependencies\r
- * is required.\r
- *\r
- * @param c dependency manager Component object, used for\r
- * configuring the dependencies exported and imported\r
- * @param imp Implementation class that is being configured,\r
- * needed as long as the same routine can configure multiple\r
- * implementations\r
- * @param containerName The containerName being configured, this allow\r
- * also optional per-container different behavior if needed, usually\r
- * should not be the case though.\r
- */\r
- public void configureInstance(Component c, Object imp, String containerName) {\r
- if (imp.equals(NeutronFloatingIPInterface.class)) {\r
- // export the service\r
- c.setInterface(\r
- new String[] { INeutronFloatingIPCRUD.class.getName() }, null);\r
- Dictionary<String, String> props = new Hashtable<String, String>();\r
- props.put("salListenerName", "neutron");\r
- c.add(createContainerServiceDependency(containerName)\r
- .setService(IClusterContainerServices.class)\r
- .setCallbacks("setClusterContainerService",\r
- "unsetClusterContainerService").setRequired(true));\r
- }\r
- if (imp.equals(NeutronRouterInterface.class)) {\r
- // export the service\r
- c.setInterface(\r
- new String[] { INeutronRouterCRUD.class.getName() }, null);\r
- Dictionary<String, String> props = new Hashtable<String, String>();\r
- props.put("salListenerName", "neutron");\r
- c.add(createContainerServiceDependency(containerName)\r
- .setService(IClusterContainerServices.class)\r
- .setCallbacks("setClusterContainerService",\r
- "unsetClusterContainerService").setRequired(true));\r
- }\r
- if (imp.equals(NeutronPortInterface.class)) {\r
- // export the service\r
- c.setInterface(\r
- new String[] { INeutronPortCRUD.class.getName() }, null);\r
- Dictionary<String, String> props = new Hashtable<String, String>();\r
- props.put("salListenerName", "neutron");\r
- c.add(createContainerServiceDependency(containerName)\r
- .setService(IClusterContainerServices.class)\r
- .setCallbacks("setClusterContainerService",\r
- "unsetClusterContainerService").setRequired(true));\r
- }\r
- if (imp.equals(NeutronSubnetInterface.class)) {\r
- // export the service\r
- c.setInterface(\r
- new String[] { INeutronSubnetCRUD.class.getName() }, null);\r
- Dictionary<String, String> props = new Hashtable<String, String>();\r
- props.put("salListenerName", "neutron");\r
- c.add(createContainerServiceDependency(containerName)\r
- .setService(IClusterContainerServices.class)\r
- .setCallbacks("setClusterContainerService",\r
- "unsetClusterContainerService").setRequired(true));\r
- }\r
- if (imp.equals(NeutronNetworkInterface.class)) {\r
- // export the service\r
- c.setInterface(\r
- new String[] { INeutronNetworkCRUD.class.getName() }, null);\r
- Dictionary<String, String> props = new Hashtable<String, String>();\r
- props.put("salListenerName", "neutron");\r
- c.add(createContainerServiceDependency(containerName)\r
- .setService(IClusterContainerServices.class)\r
- .setCallbacks("setClusterContainerService",\r
- "unsetClusterContainerService").setRequired(true));\r
- }\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+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.networkconfig.neutron.INeutronFloatingIPCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+
+public class Activator extends ComponentActivatorAbstractBase {
+ protected static final Logger logger = LoggerFactory
+ .getLogger(Activator.class);
+
+ /**
+ * Function called when the activator starts just after some
+ * initializations are done by the
+ * ComponentActivatorAbstractBase.
+ *
+ */
+ public void init() {
+
+ }
+
+ /**
+ * Function called when the activator stops just before the
+ * cleanup done by ComponentActivatorAbstractBase
+ *
+ */
+ public void destroy() {
+
+ }
+
+ /**
+ * Function that is used to communicate to dependency manager the
+ * list of known implementations for services inside a container
+ *
+ *
+ * @return An array containing all the CLASS objects that will be
+ * instantiated in order to get an fully working implementation
+ * Object
+ */
+ public Object[] getImplementations() {
+ Object[] res = { NeutronFloatingIPInterface.class,
+ NeutronRouterInterface.class,
+ NeutronPortInterface.class,
+ NeutronSubnetInterface.class,
+ NeutronNetworkInterface.class };
+ return res;
+ }
+
+ /**
+ * Function that is called when configuration of the dependencies
+ * is required.
+ *
+ * @param c dependency manager Component object, used for
+ * configuring the dependencies exported and imported
+ * @param imp Implementation class that is being configured,
+ * needed as long as the same routine can configure multiple
+ * implementations
+ * @param containerName The containerName being configured, this allow
+ * also optional per-container different behavior if needed, usually
+ * should not be the case though.
+ */
+ 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);
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("salListenerName", "neutron");
+ c.add(createContainerServiceDependency(containerName)
+ .setService(IClusterContainerServices.class)
+ .setCallbacks("setClusterContainerService",
+ "unsetClusterContainerService").setRequired(true));
+ }
+ if (imp.equals(NeutronRouterInterface.class)) {
+ // export the service
+ c.setInterface(
+ new String[] { INeutronRouterCRUD.class.getName() }, null);
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("salListenerName", "neutron");
+ c.add(createContainerServiceDependency(containerName)
+ .setService(IClusterContainerServices.class)
+ .setCallbacks("setClusterContainerService",
+ "unsetClusterContainerService").setRequired(true));
+ }
+ if (imp.equals(NeutronPortInterface.class)) {
+ // export the service
+ c.setInterface(
+ new String[] { INeutronPortCRUD.class.getName() }, null);
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("salListenerName", "neutron");
+ c.add(createContainerServiceDependency(containerName)
+ .setService(IClusterContainerServices.class)
+ .setCallbacks("setClusterContainerService",
+ "unsetClusterContainerService").setRequired(true));
+ }
+ if (imp.equals(NeutronSubnetInterface.class)) {
+ // export the service
+ c.setInterface(
+ new String[] { INeutronSubnetCRUD.class.getName() }, null);
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("salListenerName", "neutron");
+ c.add(createContainerServiceDependency(containerName)
+ .setService(IClusterContainerServices.class)
+ .setCallbacks("setClusterContainerService",
+ "unsetClusterContainerService").setRequired(true));
+ }
+ if (imp.equals(NeutronNetworkInterface.class)) {
+ // export the service
+ c.setInterface(
+ new String[] { INeutronNetworkCRUD.class.getName() }, null);
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("salListenerName", "neutron");
+ c.add(createContainerServiceDependency(containerName)
+ .setService(IClusterContainerServices.class)
+ .setCallbacks("setClusterContainerService",
+ "unsetClusterContainerService").setRequired(true));
+ }
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {\r
- private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);\r
- private String containerName = null;\r
-\r
- private IClusterContainerServices clusterContainerService = null;\r
- private ConcurrentMap<String, NeutronFloatingIP> floatingIPDB;\r
-\r
- // methods needed for creating caches\r
-\r
- void setClusterContainerService(IClusterContainerServices s) {\r
- logger.debug("Cluster Service set");\r
- this.clusterContainerService = s;\r
- }\r
-\r
- void unsetClusterContainerService(IClusterContainerServices s) {\r
- if (this.clusterContainerService == s) {\r
- logger.debug("Cluster Service removed!");\r
- this.clusterContainerService = null;\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void allocateCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't create cache");\r
- return;\r
- }\r
- logger.debug("Creating Cache for Neutron FloatingIPs");\r
- try {\r
- // neutron caches\r
- this.clusterContainerService.createCache("neutronFloatingIPs",\r
- EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
- } catch (CacheConfigException cce) {\r
- logger.error("Cache couldn't be created for Neutron - check cache mode");\r
- } catch (CacheExistException cce) {\r
- logger.error("Cache for Neutron already exists, destroy and recreate");\r
- }\r
- logger.debug("Cache successfully created for NeutronFloatingIps");\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "deprecation" })\r
- private void retrieveCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
- return;\r
- }\r
-\r
- logger.debug("Retrieving cache for Neutron FloatingIPs");\r
- floatingIPDB = (ConcurrentMap<String, NeutronFloatingIP>) this.clusterContainerService\r
- .getCache("neutronFloatingIPs");\r
- if (floatingIPDB == null) {\r
- logger.error("Cache couldn't be retrieved for Neutron FloatingIPs");\r
- }\r
- logger.debug("Cache was successfully retrieved for Neutron FloatingIPs");\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void destroyCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterMger, can't destroy cache");\r
- return;\r
- }\r
- logger.debug("Destroying Cache for HostTracker");\r
- this.clusterContainerService.destroyCache("neutronFloatingIPs");\r
- }\r
-\r
- private void startUp() {\r
- allocateCache();\r
- retrieveCache();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when all the required\r
- * dependencies are satisfied\r
- *\r
- */\r
- void init(Component c) {\r
- Dictionary<?, ?> props = c.getServiceProperties();\r
- if (props != null) {\r
- this.containerName = (String) props.get("containerName");\r
- logger.debug("Running containerName: {}", this.containerName);\r
- } else {\r
- // In the Global instance case the containerName is empty\r
- this.containerName = "";\r
- }\r
- startUp();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when at least one dependency\r
- * become unsatisfied or when the component is shutting down because for\r
- * example bundle is being stopped.\r
- *\r
- */\r
- void destroy() {\r
- destroyCache();\r
- }\r
-\r
- /**\r
- * Function called by dependency manager after "init ()" is called and after\r
- * the services provided by the class are registered in the service registry\r
- *\r
- */\r
- void start() {\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager before the services exported by\r
- * the component are unregistered, this will be followed by a "destroy ()"\r
- * calls\r
- *\r
- */\r
- void stop() {\r
- }\r
-\r
- // this method uses reflection to update an object from it's delta.\r
-\r
- private boolean overwrite(Object target, Object delta) {\r
- Method[] methods = target.getClass().getMethods();\r
-\r
- for(Method toMethod: methods){\r
- if(toMethod.getDeclaringClass().equals(target.getClass())\r
- && toMethod.getName().startsWith("set")){\r
-\r
- String toName = toMethod.getName();\r
- String fromName = toName.replace("set", "get");\r
-\r
- try {\r
- Method fromMethod = delta.getClass().getMethod(fromName);\r
- Object value = fromMethod.invoke(delta, (Object[])null);\r
- if(value != null){\r
- toMethod.invoke(target, value);\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- // IfNBFloatingIPCRUD interface methods\r
-\r
- public boolean floatingIPExists(String uuid) {\r
- return floatingIPDB.containsKey(uuid);\r
- }\r
-\r
- public NeutronFloatingIP getFloatingIP(String uuid) {\r
- if (!floatingIPExists(uuid))\r
- return null;\r
- return floatingIPDB.get(uuid);\r
- }\r
-\r
- public List<NeutronFloatingIP> getAllFloatingIPs() {\r
- Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();\r
- for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {\r
- NeutronFloatingIP floatingip = entry.getValue();\r
- allIPs.add(floatingip);\r
- }\r
- logger.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());\r
- List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
- ans.addAll(allIPs);\r
- return ans;\r
- }\r
-\r
- public boolean addFloatingIP(NeutronFloatingIP input) {\r
- INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
- INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
- if (floatingIPExists(input.getID()))\r
- return false;\r
- //if floating_ip_address isn't there, allocate from the subnet pool\r
- NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(input.getFloatingNetworkUUID()).getSubnets().get(0));\r
- if (input.getFloatingIPAddress() == null)\r
- input.setFloatingIPAddress(subnet.getLowAddr());\r
- subnet.allocateIP(input.getFloatingIPAddress());\r
-\r
- //if port_id is there, bind port to this floating ip\r
- if (input.getPortUUID() != null) {\r
- NeutronPort port = portCRUD.getPort(input.getPortUUID());\r
- port.addFloatingIP(input.getFixedIPAddress(), input);\r
- }\r
-\r
- floatingIPDB.putIfAbsent(input.getID(), input);\r
- return true;\r
- }\r
-\r
- public boolean removeFloatingIP(String uuid) {\r
- INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
- INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
- if (!floatingIPExists(uuid))\r
- return false;\r
- NeutronFloatingIP floatIP = getFloatingIP(uuid);\r
- //if floating_ip_address isn't there, allocate from the subnet pool\r
- NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(floatIP.getFloatingNetworkUUID()).getSubnets().get(0));\r
- subnet.releaseIP(floatIP.getFloatingIPAddress());\r
- if (floatIP.getPortUUID() != null) {\r
- NeutronPort port = portCRUD.getPort(floatIP.getPortUUID());\r
- port.removeFloatingIP(floatIP.getFixedIPAddress());\r
- }\r
- floatingIPDB.remove(uuid);\r
- return true;\r
- }\r
-\r
- public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {\r
- INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
- if (!floatingIPExists(uuid))\r
- return false;\r
- NeutronFloatingIP target = floatingIPDB.get(uuid);\r
- if (target.getPortUUID() != null) {\r
- NeutronPort port = portCRUD.getPort(target.getPortUUID());\r
- port.removeFloatingIP(target.getFixedIPAddress());\r
- }\r
-\r
- //if port_id is there, bind port to this floating ip\r
- if (delta.getPortUUID() != null) {\r
- NeutronPort port = portCRUD.getPort(delta.getPortUUID());\r
- port.addFloatingIP(delta.getFixedIPAddress(), delta);\r
- }\r
-\r
- target.setPortUUID(delta.getPortUUID());\r
- target.setFixedIPAddress(delta.getFixedIPAddress());\r
- return true;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+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.networkconfig.neutron.INeutronFloatingIPCRUD;
+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.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+ private String containerName = null;
+
+ private IClusterContainerServices clusterContainerService = null;
+ private ConcurrentMap<String, NeutronFloatingIP> floatingIPDB;
+
+ // methods needed for creating caches
+
+ void setClusterContainerService(IClusterContainerServices s) {
+ logger.debug("Cluster Service set");
+ this.clusterContainerService = s;
+ }
+
+ void unsetClusterContainerService(IClusterContainerServices s) {
+ if (this.clusterContainerService == s) {
+ logger.debug("Cluster Service removed!");
+ this.clusterContainerService = null;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void allocateCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't create cache");
+ return;
+ }
+ logger.debug("Creating Cache for Neutron FloatingIPs");
+ try {
+ // neutron caches
+ this.clusterContainerService.createCache("neutronFloatingIPs",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ logger.error("Cache couldn't be created for Neutron - check cache mode");
+ } catch (CacheExistException cce) {
+ logger.error("Cache for Neutron already exists, destroy and recreate");
+ }
+ logger.debug("Cache successfully created for NeutronFloatingIps");
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't retrieve cache");
+ return;
+ }
+
+ logger.debug("Retrieving cache for Neutron FloatingIPs");
+ floatingIPDB = (ConcurrentMap<String, NeutronFloatingIP>) this.clusterContainerService
+ .getCache("neutronFloatingIPs");
+ if (floatingIPDB == null) {
+ logger.error("Cache couldn't be retrieved for Neutron FloatingIPs");
+ }
+ logger.debug("Cache was successfully retrieved for Neutron FloatingIPs");
+ }
+
+ @SuppressWarnings("deprecation")
+ private void destroyCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterMger, can't destroy cache");
+ return;
+ }
+ logger.debug("Destroying Cache for HostTracker");
+ this.clusterContainerService.destroyCache("neutronFloatingIPs");
+ }
+
+ private void startUp() {
+ allocateCache();
+ retrieveCache();
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ Dictionary<?, ?> props = c.getServiceProperties();
+ if (props != null) {
+ this.containerName = (String) props.get("containerName");
+ logger.debug("Running containerName: {}", this.containerName);
+ } else {
+ // In the Global instance case the containerName is empty
+ this.containerName = "";
+ }
+ startUp();
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ destroyCache();
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ }
+
+ // this method uses reflection to update an object from it's delta.
+
+ private boolean overwrite(Object target, Object delta) {
+ Method[] methods = target.getClass().getMethods();
+
+ for(Method toMethod: methods){
+ if(toMethod.getDeclaringClass().equals(target.getClass())
+ && toMethod.getName().startsWith("set")){
+
+ String toName = toMethod.getName();
+ String fromName = toName.replace("set", "get");
+
+ try {
+ Method fromMethod = delta.getClass().getMethod(fromName);
+ Object value = fromMethod.invoke(delta, (Object[])null);
+ if(value != null){
+ toMethod.invoke(target, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // IfNBFloatingIPCRUD interface methods
+
+ public boolean floatingIPExists(String uuid) {
+ return floatingIPDB.containsKey(uuid);
+ }
+
+ public NeutronFloatingIP getFloatingIP(String uuid) {
+ if (!floatingIPExists(uuid))
+ return null;
+ return floatingIPDB.get(uuid);
+ }
+
+ public List<NeutronFloatingIP> getAllFloatingIPs() {
+ Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
+ for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {
+ NeutronFloatingIP floatingip = entry.getValue();
+ allIPs.add(floatingip);
+ }
+ logger.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());
+ List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+ ans.addAll(allIPs);
+ return ans;
+ }
+
+ public boolean addFloatingIP(NeutronFloatingIP input) {
+ INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+ INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+ if (floatingIPExists(input.getID()))
+ return false;
+ //if floating_ip_address isn't there, allocate from the subnet pool
+ NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(input.getFloatingNetworkUUID()).getSubnets().get(0));
+ if (input.getFloatingIPAddress() == null)
+ input.setFloatingIPAddress(subnet.getLowAddr());
+ subnet.allocateIP(input.getFloatingIPAddress());
+
+ //if port_id is there, bind port to this floating ip
+ if (input.getPortUUID() != null) {
+ NeutronPort port = portCRUD.getPort(input.getPortUUID());
+ port.addFloatingIP(input.getFixedIPAddress(), input);
+ }
+
+ floatingIPDB.putIfAbsent(input.getID(), input);
+ return true;
+ }
+
+ public boolean removeFloatingIP(String uuid) {
+ INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+ INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+ if (!floatingIPExists(uuid))
+ return false;
+ NeutronFloatingIP floatIP = getFloatingIP(uuid);
+ //if floating_ip_address isn't there, allocate from the subnet pool
+ NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(floatIP.getFloatingNetworkUUID()).getSubnets().get(0));
+ subnet.releaseIP(floatIP.getFloatingIPAddress());
+ if (floatIP.getPortUUID() != null) {
+ NeutronPort port = portCRUD.getPort(floatIP.getPortUUID());
+ port.removeFloatingIP(floatIP.getFixedIPAddress());
+ }
+ floatingIPDB.remove(uuid);
+ return true;
+ }
+
+ public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
+ INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+ if (!floatingIPExists(uuid))
+ return false;
+ NeutronFloatingIP target = floatingIPDB.get(uuid);
+ if (target.getPortUUID() != null) {
+ NeutronPort port = portCRUD.getPort(target.getPortUUID());
+ port.removeFloatingIP(target.getFixedIPAddress());
+ }
+
+ //if port_id is there, bind port to this floating ip
+ if (delta.getPortUUID() != null) {
+ NeutronPort port = portCRUD.getPort(delta.getPortUUID());
+ port.addFloatingIP(delta.getFixedIPAddress(), delta);
+ }
+
+ target.setPortUUID(delta.getPortUUID());
+ target.setFixedIPAddress(delta.getFixedIPAddress());
+ return true;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronNetworkInterface implements INeutronNetworkCRUD {\r
- private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);\r
- private String containerName = null;\r
-\r
- private ConcurrentMap<String, NeutronNetwork> networkDB;\r
- private IClusterContainerServices clusterContainerService = null;\r
-\r
- // methods needed for creating caches\r
-\r
- void setClusterContainerService(IClusterContainerServices s) {\r
- logger.debug("Cluster Service set");\r
- this.clusterContainerService = s;\r
- }\r
-\r
- void unsetClusterContainerService(IClusterContainerServices s) {\r
- if (this.clusterContainerService == s) {\r
- logger.debug("Cluster Service removed!");\r
- this.clusterContainerService = null;\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void allocateCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't create cache");\r
- return;\r
- }\r
- logger.debug("Creating Cache for Neutron Networks");\r
- try {\r
- // neutron caches\r
- this.clusterContainerService.createCache("neutronNetworks",\r
- EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
- } catch (CacheConfigException cce) {\r
- logger.error("Cache couldn't be created for Neutron Networks - check cache mode");\r
- } catch (CacheExistException cce) {\r
- logger.error("Cache for Neutron Networks already exists, destroy and recreate");\r
- }\r
- logger.debug("Cache successfully created for Neutron Networks");\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "deprecation" })\r
- private void retrieveCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
- return;\r
- }\r
- logger.debug("Retrieving cache for Neutron Networks");\r
- networkDB = (ConcurrentMap<String, NeutronNetwork>) this.clusterContainerService.getCache("neutronNetworks");\r
- if (networkDB == null) {\r
- logger.error("Cache couldn't be retrieved for Neutron Networks");\r
- }\r
- logger.debug("Cache was successfully retrieved for Neutron Networks");\r
- }\r
-\r
- private void startUp() {\r
- allocateCache();\r
- retrieveCache();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when all the required\r
- * dependencies are satisfied\r
- *\r
- */\r
- void init(Component c) {\r
- Dictionary<?, ?> props = c.getServiceProperties();\r
- if (props != null) {\r
- this.containerName = (String) props.get("containerName");\r
- logger.debug("Running containerName: {}", this.containerName);\r
- } else {\r
- // In the Global instance case the containerName is empty\r
- this.containerName = "";\r
- }\r
- startUp();\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void destroyCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterMger, can't destroy cache");\r
- return;\r
- }\r
- logger.debug("Destroying Cache for Neutron Networks");\r
- this.clusterContainerService.destroyCache("Neutron Networks");\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when at least one dependency\r
- * become unsatisfied or when the component is shutting down because for\r
- * example bundle is being stopped.\r
- *\r
- */\r
- void destroy() {\r
- destroyCache();\r
- }\r
-\r
- /**\r
- * Function called by dependency manager after "init ()" is called and after\r
- * the services provided by the class are registered in the service registry\r
- *\r
- */\r
- void start() {\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager before the services exported by\r
- * the component are unregistered, this will be followed by a "destroy ()"\r
- * calls\r
- *\r
- */\r
- void stop() {\r
- }\r
-\r
- // this method uses reflection to update an object from it's delta.\r
-\r
- private boolean overwrite(Object target, Object delta) {\r
- Method[] methods = target.getClass().getMethods();\r
-\r
- for(Method toMethod: methods){\r
- if(toMethod.getDeclaringClass().equals(target.getClass())\r
- && toMethod.getName().startsWith("set")){\r
-\r
- String toName = toMethod.getName();\r
- String fromName = toName.replace("set", "get");\r
-\r
- try {\r
- Method fromMethod = delta.getClass().getMethod(fromName);\r
- Object value = fromMethod.invoke(delta, (Object[])null);\r
- if(value != null){\r
- toMethod.invoke(target, value);\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- // IfNBNetworkCRUD methods\r
-\r
- public boolean networkExists(String uuid) {\r
- return networkDB.containsKey(uuid);\r
- }\r
-\r
- public NeutronNetwork getNetwork(String uuid) {\r
- if (!networkExists(uuid))\r
- return null;\r
- return networkDB.get(uuid);\r
- }\r
-\r
- public List<NeutronNetwork> getAllNetworks() {\r
- Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();\r
- for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {\r
- NeutronNetwork network = entry.getValue();\r
- allNetworks.add(network);\r
- }\r
- logger.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());\r
- List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
- ans.addAll(allNetworks);\r
- return ans;\r
- }\r
-\r
- public boolean addNetwork(NeutronNetwork input) {\r
- if (networkExists(input.getID()))\r
- return false;\r
- networkDB.putIfAbsent(input.getID(), input);\r
- //TODO: add code to find INeutronNetworkAware services and call newtorkCreated on them\r
- return true;\r
- }\r
-\r
- public boolean removeNetwork(String uuid) {\r
- if (!networkExists(uuid))\r
- return false;\r
- networkDB.remove(uuid);\r
- //TODO: add code to find INeutronNetworkAware services and call newtorkDeleted on them\r
- return true;\r
- }\r
-\r
- public boolean updateNetwork(String uuid, NeutronNetwork delta) {\r
- if (!networkExists(uuid))\r
- return false;\r
- NeutronNetwork target = networkDB.get(uuid);\r
- return overwrite(target, delta);\r
- }\r
-\r
- public boolean networkInUse(String netUUID) {\r
- if (!networkExists(netUUID))\r
- return true;\r
- NeutronNetwork target = networkDB.get(netUUID);\r
- if (target.getPortsOnNetwork().size() > 0)\r
- return true;\r
- return false;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+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.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronNetworkInterface implements INeutronNetworkCRUD {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+ private String containerName = null;
+
+ private ConcurrentMap<String, NeutronNetwork> networkDB;
+ private IClusterContainerServices clusterContainerService = null;
+
+ // methods needed for creating caches
+
+ void setClusterContainerService(IClusterContainerServices s) {
+ logger.debug("Cluster Service set");
+ this.clusterContainerService = s;
+ }
+
+ void unsetClusterContainerService(IClusterContainerServices s) {
+ if (this.clusterContainerService == s) {
+ logger.debug("Cluster Service removed!");
+ this.clusterContainerService = null;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void allocateCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't create cache");
+ return;
+ }
+ logger.debug("Creating Cache for Neutron Networks");
+ try {
+ // neutron caches
+ this.clusterContainerService.createCache("neutronNetworks",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ logger.error("Cache couldn't be created for Neutron Networks - check cache mode");
+ } catch (CacheExistException cce) {
+ logger.error("Cache for Neutron Networks already exists, destroy and recreate");
+ }
+ logger.debug("Cache successfully created for Neutron Networks");
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't retrieve cache");
+ return;
+ }
+ logger.debug("Retrieving cache for Neutron Networks");
+ networkDB = (ConcurrentMap<String, NeutronNetwork>) this.clusterContainerService.getCache("neutronNetworks");
+ if (networkDB == null) {
+ logger.error("Cache couldn't be retrieved for Neutron Networks");
+ }
+ logger.debug("Cache was successfully retrieved for Neutron Networks");
+ }
+
+ private void startUp() {
+ allocateCache();
+ retrieveCache();
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ Dictionary<?, ?> props = c.getServiceProperties();
+ if (props != null) {
+ this.containerName = (String) props.get("containerName");
+ logger.debug("Running containerName: {}", this.containerName);
+ } else {
+ // In the Global instance case the containerName is empty
+ this.containerName = "";
+ }
+ startUp();
+ }
+
+ @SuppressWarnings("deprecation")
+ private void destroyCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterMger, can't destroy cache");
+ return;
+ }
+ logger.debug("Destroying Cache for Neutron Networks");
+ this.clusterContainerService.destroyCache("Neutron Networks");
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ destroyCache();
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ }
+
+ // this method uses reflection to update an object from it's delta.
+
+ private boolean overwrite(Object target, Object delta) {
+ Method[] methods = target.getClass().getMethods();
+
+ for(Method toMethod: methods){
+ if(toMethod.getDeclaringClass().equals(target.getClass())
+ && toMethod.getName().startsWith("set")){
+
+ String toName = toMethod.getName();
+ String fromName = toName.replace("set", "get");
+
+ try {
+ Method fromMethod = delta.getClass().getMethod(fromName);
+ Object value = fromMethod.invoke(delta, (Object[])null);
+ if(value != null){
+ toMethod.invoke(target, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // IfNBNetworkCRUD methods
+
+ public boolean networkExists(String uuid) {
+ return networkDB.containsKey(uuid);
+ }
+
+ public NeutronNetwork getNetwork(String uuid) {
+ if (!networkExists(uuid))
+ return null;
+ return networkDB.get(uuid);
+ }
+
+ public List<NeutronNetwork> getAllNetworks() {
+ Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
+ for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {
+ NeutronNetwork network = entry.getValue();
+ allNetworks.add(network);
+ }
+ logger.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());
+ List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+ ans.addAll(allNetworks);
+ return ans;
+ }
+
+ public boolean addNetwork(NeutronNetwork input) {
+ if (networkExists(input.getID()))
+ return false;
+ networkDB.putIfAbsent(input.getID(), input);
+ //TODO: add code to find INeutronNetworkAware services and call newtorkCreated on them
+ return true;
+ }
+
+ public boolean removeNetwork(String uuid) {
+ if (!networkExists(uuid))
+ return false;
+ networkDB.remove(uuid);
+ //TODO: add code to find INeutronNetworkAware services and call newtorkDeleted on them
+ return true;
+ }
+
+ public boolean updateNetwork(String uuid, NeutronNetwork delta) {
+ if (!networkExists(uuid))
+ return false;
+ NeutronNetwork target = networkDB.get(uuid);
+ return overwrite(target, delta);
+ }
+
+ public boolean networkInUse(String netUUID) {
+ if (!networkExists(netUUID))
+ return true;
+ NeutronNetwork target = networkDB.get(netUUID);
+ if (target.getPortsOnNetwork().size() > 0)
+ return true;
+ return false;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronPortInterface implements INeutronPortCRUD {\r
- private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);\r
- private String containerName = null;\r
-\r
- private IClusterContainerServices clusterContainerService = null;\r
- private ConcurrentMap<String, NeutronPort> portDB;\r
-\r
- // methods needed for creating caches\r
-\r
- void setClusterContainerService(IClusterContainerServices s) {\r
- logger.debug("Cluster Service set");\r
- clusterContainerService = s;\r
- }\r
-\r
- void unsetClusterContainerService(IClusterContainerServices s) {\r
- if (clusterContainerService == s) {\r
- logger.debug("Cluster Service removed!");\r
- clusterContainerService = null;\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void allocateCache() {\r
- if (clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't create cache");\r
- return;\r
- }\r
- logger.debug("Creating Cache for OpenDOVE");\r
- try {\r
- // neutron caches\r
- clusterContainerService.createCache("neutronPorts",\r
- EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
- } catch (CacheConfigException cce) {\r
- logger.error("Cache couldn't be created for OpenDOVE - check cache mode");\r
- } catch (CacheExistException cce) {\r
- logger.error("Cache for OpenDOVE already exists, destroy and recreate");\r
- }\r
- logger.debug("Cache successfully created for OpenDOVE");\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "deprecation" })\r
- private void retrieveCache() {\r
- if (clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
- return;\r
- }\r
-\r
- logger.debug("Retrieving cache for Neutron Ports");\r
- portDB = (ConcurrentMap<String, NeutronPort>) clusterContainerService\r
- .getCache("neutronPorts");\r
- if (portDB == null) {\r
- logger.error("Cache couldn't be retrieved for Neutron Ports");\r
- }\r
- logger.debug("Cache was successfully retrieved for Neutron Ports");\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void destroyCache() {\r
- if (clusterContainerService == null) {\r
- logger.error("un-initialized clusterMger, can't destroy cache");\r
- return;\r
- }\r
- logger.debug("Destroying Cache for HostTracker");\r
- clusterContainerService.destroyCache("neutronPorts");\r
- }\r
-\r
- private void startUp() {\r
- allocateCache();\r
- retrieveCache();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when all the required\r
- * dependencies are satisfied\r
- *\r
- */\r
- void init(Component c) {\r
- Dictionary<?, ?> props = c.getServiceProperties();\r
- if (props != null) {\r
- containerName = (String) props.get("containerName");\r
- logger.debug("Running containerName: {}", containerName);\r
- } else {\r
- // In the Global instance case the containerName is empty\r
- containerName = "";\r
- }\r
- startUp();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when at least one dependency\r
- * become unsatisfied or when the component is shutting down because for\r
- * example bundle is being stopped.\r
- *\r
- */\r
- void destroy() {\r
- destroyCache();\r
- }\r
-\r
- /**\r
- * Function called by dependency manager after "init ()" is called and after\r
- * the services provided by the class are registered in the service registry\r
- *\r
- */\r
- void start() {\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager before the services exported by\r
- * the component are unregistered, this will be followed by a "destroy ()"\r
- * calls\r
- *\r
- */\r
- void stop() {\r
- }\r
-\r
- // this method uses reflection to update an object from it's delta.\r
-\r
- private boolean overwrite(Object target, Object delta) {\r
- Method[] methods = target.getClass().getMethods();\r
-\r
- for(Method toMethod: methods){\r
- if(toMethod.getDeclaringClass().equals(target.getClass())\r
- && toMethod.getName().startsWith("set")){\r
-\r
- String toName = toMethod.getName();\r
- String fromName = toName.replace("set", "get");\r
-\r
- try {\r
- Method fromMethod = delta.getClass().getMethod(fromName);\r
- Object value = fromMethod.invoke(delta, (Object[])null);\r
- if(value != null){\r
- toMethod.invoke(target, value);\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- // IfNBPortCRUD methods\r
-\r
- @Override\r
- public boolean portExists(String uuid) {\r
- return portDB.containsKey(uuid);\r
- }\r
-\r
- @Override\r
- public NeutronPort getPort(String uuid) {\r
- if (!portExists(uuid)) {\r
- return null;\r
- }\r
- return portDB.get(uuid);\r
- }\r
-\r
- @Override\r
- public List<NeutronPort> getAllPorts() {\r
- Set<NeutronPort> allPorts = new HashSet<NeutronPort>();\r
- for (Entry<String, NeutronPort> entry : portDB.entrySet()) {\r
- NeutronPort port = entry.getValue();\r
- allPorts.add(port);\r
- }\r
- logger.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());\r
- List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
- ans.addAll(allPorts);\r
- return ans;\r
- }\r
-\r
- @Override\r
- public boolean addPort(NeutronPort input) {\r
- if (portExists(input.getID())) {\r
- return false;\r
- }\r
- portDB.putIfAbsent(input.getID(), input);\r
- // if there are no fixed IPs, allocate one for each subnet in the network\r
- INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (input.getFixedIPs().size() == 0) {\r
- List<Neutron_IPs> list = input.getFixedIPs();\r
- Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();\r
- while (subnetIterator.hasNext()) {\r
- NeutronSubnet subnet = subnetIterator.next();\r
- if (subnet.getNetworkUUID().equals(input.getNetworkUUID())) {\r
- list.add(new Neutron_IPs(subnet.getID()));\r
- }\r
- }\r
- }\r
- Iterator<Neutron_IPs> fixedIPIterator = input.getFixedIPs().iterator();\r
- while (fixedIPIterator.hasNext()) {\r
- Neutron_IPs ip = fixedIPIterator.next();\r
- NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
- if (ip.getIpAddress() == null) {\r
- ip.setIpAddress(subnet.getLowAddr());\r
- }\r
- if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {\r
- subnet.allocateIP(ip.getIpAddress());\r
- }\r
- else {\r
- subnet.setGatewayIPAllocated();\r
- }\r
- subnet.addPort(input);\r
- }\r
- INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
- NeutronNetwork network = networkIf.getNetwork(input.getNetworkUUID());\r
- network.addPort(input);\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean removePort(String uuid) {\r
- if (!portExists(uuid)) {\r
- return false;\r
- }\r
- NeutronPort port = getPort(uuid);\r
- portDB.remove(uuid);\r
- INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
- INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-\r
- NeutronNetwork network = networkCRUD.getNetwork(port.getNetworkUUID());\r
- network.removePort(port);\r
- Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();\r
- while (fixedIPIterator.hasNext()) {\r
- Neutron_IPs ip = fixedIPIterator.next();\r
- NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
- if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {\r
- subnet.releaseIP(ip.getIpAddress());\r
- }\r
- else {\r
- subnet.resetGatewayIPAllocated();\r
- }\r
- subnet.removePort(port);\r
- }\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean updatePort(String uuid, NeutronPort delta) {\r
- if (!portExists(uuid)) {\r
- return false;\r
- }\r
- NeutronPort target = portDB.get(uuid);\r
- // remove old Fixed_IPs\r
- if (delta.getFixedIPs() != null) {\r
- NeutronPort port = getPort(uuid);\r
- INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- for (Neutron_IPs ip: port.getFixedIPs()) {\r
- NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
- subnet.releaseIP(ip.getIpAddress());\r
- }\r
-\r
- // allocate new Fixed_IPs\r
- for (Neutron_IPs ip: delta.getFixedIPs()) {\r
- NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
- if (ip.getIpAddress() == null) {\r
- ip.setIpAddress(subnet.getLowAddr());\r
- }\r
- subnet.allocateIP(ip.getIpAddress());\r
- }\r
- }\r
- return overwrite(target, delta);\r
- }\r
-\r
- @Override\r
- public boolean macInUse(String macAddress) {\r
- List<NeutronPort> ports = getAllPorts();\r
- Iterator<NeutronPort> portIterator = ports.iterator();\r
- while (portIterator.hasNext()) {\r
- NeutronPort port = portIterator.next();\r
- if (macAddress.equalsIgnoreCase(port.getMacAddress())) {\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
-\r
- @Override\r
- public NeutronPort getGatewayPort(String subnetUUID) {\r
- INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- NeutronSubnet subnet = systemCRUD.getSubnet(subnetUUID);\r
- Iterator<NeutronPort> portIterator = getAllPorts().iterator();\r
- while (portIterator.hasNext()) {\r
- NeutronPort port = portIterator.next();\r
- List<Neutron_IPs> fixedIPs = port.getFixedIPs();\r
- if (fixedIPs.size() == 1) {\r
- if (subnet.getGatewayIP().equals(fixedIPs.get(0).getIpAddress())) {\r
- return port;\r
- }\r
- }\r
- }\r
- return null;\r
- }\r
-\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+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.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+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.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronPortInterface implements INeutronPortCRUD {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);
+ private String containerName = null;
+
+ private IClusterContainerServices clusterContainerService = null;
+ private ConcurrentMap<String, NeutronPort> portDB;
+
+ // methods needed for creating caches
+
+ void setClusterContainerService(IClusterContainerServices s) {
+ logger.debug("Cluster Service set");
+ clusterContainerService = s;
+ }
+
+ void unsetClusterContainerService(IClusterContainerServices s) {
+ if (clusterContainerService == s) {
+ logger.debug("Cluster Service removed!");
+ clusterContainerService = null;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void allocateCache() {
+ if (clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't create cache");
+ return;
+ }
+ logger.debug("Creating Cache for OpenDOVE");
+ try {
+ // neutron caches
+ clusterContainerService.createCache("neutronPorts",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ logger.error("Cache couldn't be created for OpenDOVE - check cache mode");
+ } catch (CacheExistException cce) {
+ logger.error("Cache for OpenDOVE already exists, destroy and recreate");
+ }
+ logger.debug("Cache successfully created for OpenDOVE");
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCache() {
+ if (clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't retrieve cache");
+ return;
+ }
+
+ logger.debug("Retrieving cache for Neutron Ports");
+ portDB = (ConcurrentMap<String, NeutronPort>) clusterContainerService
+ .getCache("neutronPorts");
+ if (portDB == null) {
+ logger.error("Cache couldn't be retrieved for Neutron Ports");
+ }
+ logger.debug("Cache was successfully retrieved for Neutron Ports");
+ }
+
+ @SuppressWarnings("deprecation")
+ private void destroyCache() {
+ if (clusterContainerService == null) {
+ logger.error("un-initialized clusterMger, can't destroy cache");
+ return;
+ }
+ logger.debug("Destroying Cache for HostTracker");
+ clusterContainerService.destroyCache("neutronPorts");
+ }
+
+ private void startUp() {
+ allocateCache();
+ retrieveCache();
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ Dictionary<?, ?> props = c.getServiceProperties();
+ if (props != null) {
+ containerName = (String) props.get("containerName");
+ logger.debug("Running containerName: {}", containerName);
+ } else {
+ // In the Global instance case the containerName is empty
+ containerName = "";
+ }
+ startUp();
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ destroyCache();
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ }
+
+ // this method uses reflection to update an object from it's delta.
+
+ private boolean overwrite(Object target, Object delta) {
+ Method[] methods = target.getClass().getMethods();
+
+ for(Method toMethod: methods){
+ if(toMethod.getDeclaringClass().equals(target.getClass())
+ && toMethod.getName().startsWith("set")){
+
+ String toName = toMethod.getName();
+ String fromName = toName.replace("set", "get");
+
+ try {
+ Method fromMethod = delta.getClass().getMethod(fromName);
+ Object value = fromMethod.invoke(delta, (Object[])null);
+ if(value != null){
+ toMethod.invoke(target, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // IfNBPortCRUD methods
+
+ @Override
+ public boolean portExists(String uuid) {
+ return portDB.containsKey(uuid);
+ }
+
+ @Override
+ public NeutronPort getPort(String uuid) {
+ if (!portExists(uuid)) {
+ return null;
+ }
+ return portDB.get(uuid);
+ }
+
+ @Override
+ public List<NeutronPort> getAllPorts() {
+ Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
+ for (Entry<String, NeutronPort> entry : portDB.entrySet()) {
+ NeutronPort port = entry.getValue();
+ allPorts.add(port);
+ }
+ logger.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());
+ List<NeutronPort> ans = new ArrayList<NeutronPort>();
+ ans.addAll(allPorts);
+ return ans;
+ }
+
+ @Override
+ public boolean addPort(NeutronPort input) {
+ if (portExists(input.getID())) {
+ return false;
+ }
+ portDB.putIfAbsent(input.getID(), input);
+ // if there are no fixed IPs, allocate one for each subnet in the network
+ INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (input.getFixedIPs().size() == 0) {
+ List<Neutron_IPs> list = input.getFixedIPs();
+ Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();
+ while (subnetIterator.hasNext()) {
+ NeutronSubnet subnet = subnetIterator.next();
+ if (subnet.getNetworkUUID().equals(input.getNetworkUUID())) {
+ list.add(new Neutron_IPs(subnet.getID()));
+ }
+ }
+ }
+ Iterator<Neutron_IPs> fixedIPIterator = input.getFixedIPs().iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+ if (ip.getIpAddress() == null) {
+ ip.setIpAddress(subnet.getLowAddr());
+ }
+ if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {
+ subnet.allocateIP(ip.getIpAddress());
+ }
+ else {
+ subnet.setGatewayIPAllocated();
+ }
+ subnet.addPort(input);
+ }
+ INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+ NeutronNetwork network = networkIf.getNetwork(input.getNetworkUUID());
+ network.addPort(input);
+ return true;
+ }
+
+ @Override
+ public boolean removePort(String uuid) {
+ if (!portExists(uuid)) {
+ return false;
+ }
+ NeutronPort port = getPort(uuid);
+ portDB.remove(uuid);
+ INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+ INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+
+ NeutronNetwork network = networkCRUD.getNetwork(port.getNetworkUUID());
+ network.removePort(port);
+ Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+ if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {
+ subnet.releaseIP(ip.getIpAddress());
+ }
+ else {
+ subnet.resetGatewayIPAllocated();
+ }
+ subnet.removePort(port);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePort(String uuid, NeutronPort delta) {
+ if (!portExists(uuid)) {
+ return false;
+ }
+ NeutronPort target = portDB.get(uuid);
+ // remove old Fixed_IPs
+ if (delta.getFixedIPs() != null) {
+ NeutronPort port = getPort(uuid);
+ INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ for (Neutron_IPs ip: port.getFixedIPs()) {
+ NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+ subnet.releaseIP(ip.getIpAddress());
+ }
+
+ // allocate new Fixed_IPs
+ for (Neutron_IPs ip: delta.getFixedIPs()) {
+ NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+ if (ip.getIpAddress() == null) {
+ ip.setIpAddress(subnet.getLowAddr());
+ }
+ subnet.allocateIP(ip.getIpAddress());
+ }
+ }
+ return overwrite(target, delta);
+ }
+
+ @Override
+ public boolean macInUse(String macAddress) {
+ List<NeutronPort> ports = getAllPorts();
+ Iterator<NeutronPort> portIterator = ports.iterator();
+ while (portIterator.hasNext()) {
+ NeutronPort port = portIterator.next();
+ if (macAddress.equalsIgnoreCase(port.getMacAddress())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public NeutronPort getGatewayPort(String subnetUUID) {
+ INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ NeutronSubnet subnet = systemCRUD.getSubnet(subnetUUID);
+ Iterator<NeutronPort> portIterator = getAllPorts().iterator();
+ while (portIterator.hasNext()) {
+ NeutronPort port = portIterator.next();
+ List<Neutron_IPs> fixedIPs = port.getFixedIPs();
+ if (fixedIPs.size() == 1) {
+ if (subnet.getGatewayIP().equals(fixedIPs.get(0).getIpAddress())) {
+ return port;
+ }
+ }
+ }
+ return null;
+ }
+
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronRouterInterface implements INeutronRouterCRUD {\r
- private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);\r
- private String containerName = null;\r
-\r
- private IClusterContainerServices clusterContainerService = null;\r
- private ConcurrentMap<String, NeutronRouter> routerDB;\r
- // methods needed for creating caches\r
-\r
- void setClusterContainerService(IClusterContainerServices s) {\r
- logger.debug("Cluster Service set");\r
- this.clusterContainerService = s;\r
- }\r
-\r
- void unsetClusterContainerService(IClusterContainerServices s) {\r
- if (this.clusterContainerService == s) {\r
- logger.debug("Cluster Service removed!");\r
- this.clusterContainerService = null;\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void allocateCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't create cache");\r
- return;\r
- }\r
- logger.debug("Creating Cache for Neutron Routers");\r
- try {\r
- // neutron caches\r
- this.clusterContainerService.createCache("neutronRouters",\r
- EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
- } catch (CacheConfigException cce) {\r
- logger.error("Cache couldn't be created for Neutron Routers - check cache mode");\r
- } catch (CacheExistException cce) {\r
- logger.error("Cache for Neutron Routers already exists, destroy and recreate");\r
- }\r
- logger.debug("Cache successfully created for Neutron Routers");\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "deprecation" })\r
- private void retrieveCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
- return;\r
- }\r
-\r
- logger.debug("Retrieving cache for Neutron Routers");\r
- routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService\r
- .getCache("neutronRouters");\r
- if (routerDB == null) {\r
- logger.error("Cache couldn't be retrieved for Neutron Routers");\r
- }\r
- logger.debug("Cache was successfully retrieved for Neutron Routers");\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void destroyCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterMger, can't destroy cache");\r
- return;\r
- }\r
- logger.debug("Destroying Cache for HostTracker");\r
- this.clusterContainerService.destroyCache("neutronRouters");\r
- }\r
-\r
- private void startUp() {\r
- allocateCache();\r
- retrieveCache();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when all the required\r
- * dependencies are satisfied\r
- *\r
- */\r
- void init(Component c) {\r
- Dictionary<?, ?> props = c.getServiceProperties();\r
- if (props != null) {\r
- this.containerName = (String) props.get("containerName");\r
- logger.debug("Running containerName: {}", this.containerName);\r
- } else {\r
- // In the Global instance case the containerName is empty\r
- this.containerName = "";\r
- }\r
- startUp();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when at least one dependency\r
- * become unsatisfied or when the component is shutting down because for\r
- * example bundle is being stopped.\r
- *\r
- */\r
- void destroy() {\r
- destroyCache();\r
- }\r
-\r
- /**\r
- * Function called by dependency manager after "init ()" is called and after\r
- * the services provided by the class are registered in the service registry\r
- *\r
- */\r
- void start() {\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager before the services exported by\r
- * the component are unregistered, this will be followed by a "destroy ()"\r
- * calls\r
- *\r
- */\r
- void stop() {\r
- }\r
-\r
- // this method uses reflection to update an object from it's delta.\r
-\r
- private boolean overwrite(Object target, Object delta) {\r
- Method[] methods = target.getClass().getMethods();\r
-\r
- for(Method toMethod: methods){\r
- if(toMethod.getDeclaringClass().equals(target.getClass())\r
- && toMethod.getName().startsWith("set")){\r
-\r
- String toName = toMethod.getName();\r
- String fromName = toName.replace("set", "get");\r
-\r
- try {\r
- Method fromMethod = delta.getClass().getMethod(fromName);\r
- Object value = fromMethod.invoke(delta, (Object[])null);\r
- if(value != null){\r
- toMethod.invoke(target, value);\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
-\r
- // IfNBRouterCRUD Interface methods\r
-\r
- public boolean routerExists(String uuid) {\r
- return routerDB.containsKey(uuid);\r
- }\r
-\r
- public NeutronRouter getRouter(String uuid) {\r
- if (!routerExists(uuid))\r
- return null;\r
- return routerDB.get(uuid);\r
- }\r
-\r
- public List<NeutronRouter> getAllRouters() {\r
- Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();\r
- for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {\r
- NeutronRouter router = entry.getValue();\r
- allRouters.add(router);\r
- }\r
- logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());\r
- List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
- ans.addAll(allRouters);\r
- return ans;\r
- }\r
-\r
- public boolean addRouter(NeutronRouter input) {\r
- if (routerExists(input.getID()))\r
- return false;\r
- routerDB.putIfAbsent(input.getID(), input);\r
- return true;\r
- }\r
-\r
- public boolean removeRouter(String uuid) {\r
- if (!routerExists(uuid))\r
- return false;\r
- routerDB.remove(uuid);\r
- return true;\r
- }\r
-\r
- public boolean updateRouter(String uuid, NeutronRouter delta) {\r
- if (!routerExists(uuid))\r
- return false;\r
- NeutronRouter target = routerDB.get(uuid);\r
- return overwrite(target, delta);\r
- }\r
-\r
- public boolean routerInUse(String routerUUID) {\r
- if (!routerExists(routerUUID))\r
- return true;\r
- NeutronRouter target = routerDB.get(routerUUID);\r
- return (target.getInterfaces().size() > 0);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+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.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronRouterInterface implements INeutronRouterCRUD {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
+ private String containerName = null;
+
+ private IClusterContainerServices clusterContainerService = null;
+ private ConcurrentMap<String, NeutronRouter> routerDB;
+ // methods needed for creating caches
+
+ void setClusterContainerService(IClusterContainerServices s) {
+ logger.debug("Cluster Service set");
+ this.clusterContainerService = s;
+ }
+
+ void unsetClusterContainerService(IClusterContainerServices s) {
+ if (this.clusterContainerService == s) {
+ logger.debug("Cluster Service removed!");
+ this.clusterContainerService = null;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void allocateCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't create cache");
+ return;
+ }
+ logger.debug("Creating Cache for Neutron Routers");
+ try {
+ // neutron caches
+ this.clusterContainerService.createCache("neutronRouters",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ logger.error("Cache couldn't be created for Neutron Routers - check cache mode");
+ } catch (CacheExistException cce) {
+ logger.error("Cache for Neutron Routers already exists, destroy and recreate");
+ }
+ logger.debug("Cache successfully created for Neutron Routers");
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't retrieve cache");
+ return;
+ }
+
+ logger.debug("Retrieving cache for Neutron Routers");
+ routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService
+ .getCache("neutronRouters");
+ if (routerDB == null) {
+ logger.error("Cache couldn't be retrieved for Neutron Routers");
+ }
+ logger.debug("Cache was successfully retrieved for Neutron Routers");
+ }
+
+ @SuppressWarnings("deprecation")
+ private void destroyCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterMger, can't destroy cache");
+ return;
+ }
+ logger.debug("Destroying Cache for HostTracker");
+ this.clusterContainerService.destroyCache("neutronRouters");
+ }
+
+ private void startUp() {
+ allocateCache();
+ retrieveCache();
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ Dictionary<?, ?> props = c.getServiceProperties();
+ if (props != null) {
+ this.containerName = (String) props.get("containerName");
+ logger.debug("Running containerName: {}", this.containerName);
+ } else {
+ // In the Global instance case the containerName is empty
+ this.containerName = "";
+ }
+ startUp();
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ destroyCache();
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ }
+
+ // this method uses reflection to update an object from it's delta.
+
+ private boolean overwrite(Object target, Object delta) {
+ Method[] methods = target.getClass().getMethods();
+
+ for(Method toMethod: methods){
+ if(toMethod.getDeclaringClass().equals(target.getClass())
+ && toMethod.getName().startsWith("set")){
+
+ String toName = toMethod.getName();
+ String fromName = toName.replace("set", "get");
+
+ try {
+ Method fromMethod = delta.getClass().getMethod(fromName);
+ Object value = fromMethod.invoke(delta, (Object[])null);
+ if(value != null){
+ toMethod.invoke(target, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+
+ // IfNBRouterCRUD Interface methods
+
+ public boolean routerExists(String uuid) {
+ return routerDB.containsKey(uuid);
+ }
+
+ public NeutronRouter getRouter(String uuid) {
+ if (!routerExists(uuid))
+ return null;
+ return routerDB.get(uuid);
+ }
+
+ public List<NeutronRouter> getAllRouters() {
+ Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
+ for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
+ NeutronRouter router = entry.getValue();
+ allRouters.add(router);
+ }
+ logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());
+ List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+ ans.addAll(allRouters);
+ return ans;
+ }
+
+ public boolean addRouter(NeutronRouter input) {
+ if (routerExists(input.getID()))
+ return false;
+ routerDB.putIfAbsent(input.getID(), input);
+ return true;
+ }
+
+ public boolean removeRouter(String uuid) {
+ if (!routerExists(uuid))
+ return false;
+ routerDB.remove(uuid);
+ return true;
+ }
+
+ public boolean updateRouter(String uuid, NeutronRouter delta) {
+ if (!routerExists(uuid))
+ return false;
+ NeutronRouter target = routerDB.get(uuid);
+ return overwrite(target, delta);
+ }
+
+ public boolean routerInUse(String routerUUID) {
+ if (!routerExists(routerUUID))
+ return true;
+ NeutronRouter target = routerDB.get(routerUUID);
+ return (target.getInterfaces().size() > 0);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronSubnetInterface implements INeutronSubnetCRUD {\r
- private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);\r
- private String containerName = null;\r
-\r
- private IClusterContainerServices clusterContainerService = null;\r
- private ConcurrentMap<String, NeutronSubnet> subnetDB;\r
-\r
- // methods needed for creating caches\r
-\r
- void setClusterContainerService(IClusterContainerServices s) {\r
- logger.debug("Cluster Service set");\r
- this.clusterContainerService = s;\r
- }\r
-\r
- void unsetClusterContainerService(IClusterContainerServices s) {\r
- if (this.clusterContainerService == s) {\r
- logger.debug("Cluster Service removed!");\r
- this.clusterContainerService = null;\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void allocateCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't create cache");\r
- return;\r
- }\r
- logger.debug("Creating Cache for Neutron Subnets");\r
- try {\r
- // neutron caches\r
- this.clusterContainerService.createCache("neutronSubnets",\r
- EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
- } catch (CacheConfigException cce) {\r
- logger.error("Cache couldn't be created for Neutron Subnets - check cache mode");\r
- } catch (CacheExistException cce) {\r
- logger.error("Cache for Neutron Subnets already exists, destroy and recreate");\r
- }\r
- logger.debug("Cache successfully created for Neutron Subnets");\r
- }\r
-\r
- @SuppressWarnings({ "unchecked", "deprecation" })\r
- private void retrieveCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
- return;\r
- }\r
-\r
- logger.debug("Retrieving cache for Neutron Subnets");\r
- subnetDB = (ConcurrentMap<String, NeutronSubnet>) this.clusterContainerService\r
- .getCache("neutronSubnets");\r
- if (subnetDB == null) {\r
- logger.error("Cache couldn't be retrieved for Neutron Subnets");\r
- }\r
- logger.debug("Cache was successfully retrieved for Neutron Subnets");\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private void destroyCache() {\r
- if (this.clusterContainerService == null) {\r
- logger.error("un-initialized clusterMger, can't destroy cache");\r
- return;\r
- }\r
- logger.debug("Destroying Cache for HostTracker");\r
- this.clusterContainerService.destroyCache("neutronSubnets");\r
- }\r
-\r
- private void startUp() {\r
- allocateCache();\r
- retrieveCache();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when all the required\r
- * dependencies are satisfied\r
- *\r
- */\r
- void init(Component c) {\r
- Dictionary<?, ?> props = c.getServiceProperties();\r
- if (props != null) {\r
- this.containerName = (String) props.get("containerName");\r
- logger.debug("Running containerName: {}", this.containerName);\r
- } else {\r
- // In the Global instance case the containerName is empty\r
- this.containerName = "";\r
- }\r
- startUp();\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager when at least one dependency\r
- * become unsatisfied or when the component is shutting down because for\r
- * example bundle is being stopped.\r
- *\r
- */\r
- void destroy() {\r
- destroyCache();\r
- }\r
-\r
- /**\r
- * Function called by dependency manager after "init ()" is called and after\r
- * the services provided by the class are registered in the service registry\r
- *\r
- */\r
- void start() {\r
- }\r
-\r
- /**\r
- * Function called by the dependency manager before the services exported by\r
- * the component are unregistered, this will be followed by a "destroy ()"\r
- * calls\r
- *\r
- */\r
- void stop() {\r
- }\r
-\r
- // this method uses reflection to update an object from it's delta.\r
-\r
- private boolean overwrite(Object target, Object delta) {\r
- Method[] methods = target.getClass().getMethods();\r
-\r
- for(Method toMethod: methods){\r
- if(toMethod.getDeclaringClass().equals(target.getClass())\r
- && toMethod.getName().startsWith("set")){\r
-\r
- String toName = toMethod.getName();\r
- String fromName = toName.replace("set", "get");\r
-\r
- try {\r
- Method fromMethod = delta.getClass().getMethod(fromName);\r
- Object value = fromMethod.invoke(delta, (Object[])null);\r
- if(value != null){\r
- toMethod.invoke(target, value);\r
- }\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- return false;\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
-\r
-\r
- // IfNBSubnetCRUD methods\r
-\r
- public boolean subnetExists(String uuid) {\r
- return subnetDB.containsKey(uuid);\r
- }\r
-\r
- public NeutronSubnet getSubnet(String uuid) {\r
- if (!subnetExists(uuid))\r
- return null;\r
- return subnetDB.get(uuid);\r
- }\r
-\r
- public List<NeutronSubnet> getAllSubnets() {\r
- Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();\r
- for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {\r
- NeutronSubnet subnet = entry.getValue();\r
- allSubnets.add(subnet);\r
- }\r
- logger.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());\r
- List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
- ans.addAll(allSubnets);\r
- return ans;\r
- }\r
-\r
- public boolean addSubnet(NeutronSubnet input) {\r
- String id = input.getID();\r
- if (subnetExists(id))\r
- return false;\r
- subnetDB.putIfAbsent(id, input);\r
- INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
- NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());\r
- targetNet.addSubnet(id);\r
- return true;\r
- }\r
-\r
- public boolean removeSubnet(String uuid) {\r
- if (!subnetExists(uuid))\r
- return false;\r
- NeutronSubnet target = subnetDB.get(uuid);\r
- INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
- NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());\r
- targetNet.removeSubnet(uuid);\r
- subnetDB.remove(uuid);\r
- return true;\r
- }\r
-\r
- public boolean updateSubnet(String uuid, NeutronSubnet delta) {\r
- if (!subnetExists(uuid))\r
- return false;\r
- NeutronSubnet target = subnetDB.get(uuid);\r
- return overwrite(target, delta);\r
- }\r
-\r
- public boolean subnetInUse(String subnetUUID) {\r
- if (!subnetExists(subnetUUID))\r
- return true;\r
- NeutronSubnet target = subnetDB.get(subnetUUID);\r
- return (target.getPortsInSubnet().size() > 0);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+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.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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronSubnetInterface implements INeutronSubnetCRUD {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+ private String containerName = null;
+
+ private IClusterContainerServices clusterContainerService = null;
+ private ConcurrentMap<String, NeutronSubnet> subnetDB;
+
+ // methods needed for creating caches
+
+ void setClusterContainerService(IClusterContainerServices s) {
+ logger.debug("Cluster Service set");
+ this.clusterContainerService = s;
+ }
+
+ void unsetClusterContainerService(IClusterContainerServices s) {
+ if (this.clusterContainerService == s) {
+ logger.debug("Cluster Service removed!");
+ this.clusterContainerService = null;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private void allocateCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't create cache");
+ return;
+ }
+ logger.debug("Creating Cache for Neutron Subnets");
+ try {
+ // neutron caches
+ this.clusterContainerService.createCache("neutronSubnets",
+ EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+ } catch (CacheConfigException cce) {
+ logger.error("Cache couldn't be created for Neutron Subnets - check cache mode");
+ } catch (CacheExistException cce) {
+ logger.error("Cache for Neutron Subnets already exists, destroy and recreate");
+ }
+ logger.debug("Cache successfully created for Neutron Subnets");
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ private void retrieveCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterContainerService, can't retrieve cache");
+ return;
+ }
+
+ logger.debug("Retrieving cache for Neutron Subnets");
+ subnetDB = (ConcurrentMap<String, NeutronSubnet>) this.clusterContainerService
+ .getCache("neutronSubnets");
+ if (subnetDB == null) {
+ logger.error("Cache couldn't be retrieved for Neutron Subnets");
+ }
+ logger.debug("Cache was successfully retrieved for Neutron Subnets");
+ }
+
+ @SuppressWarnings("deprecation")
+ private void destroyCache() {
+ if (this.clusterContainerService == null) {
+ logger.error("un-initialized clusterMger, can't destroy cache");
+ return;
+ }
+ logger.debug("Destroying Cache for HostTracker");
+ this.clusterContainerService.destroyCache("neutronSubnets");
+ }
+
+ private void startUp() {
+ allocateCache();
+ retrieveCache();
+ }
+
+ /**
+ * Function called by the dependency manager when all the required
+ * dependencies are satisfied
+ *
+ */
+ void init(Component c) {
+ Dictionary<?, ?> props = c.getServiceProperties();
+ if (props != null) {
+ this.containerName = (String) props.get("containerName");
+ logger.debug("Running containerName: {}", this.containerName);
+ } else {
+ // In the Global instance case the containerName is empty
+ this.containerName = "";
+ }
+ startUp();
+ }
+
+ /**
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
+ *
+ */
+ void destroy() {
+ destroyCache();
+ }
+
+ /**
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
+ *
+ */
+ void start() {
+ }
+
+ /**
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
+ *
+ */
+ void stop() {
+ }
+
+ // this method uses reflection to update an object from it's delta.
+
+ private boolean overwrite(Object target, Object delta) {
+ Method[] methods = target.getClass().getMethods();
+
+ for(Method toMethod: methods){
+ if(toMethod.getDeclaringClass().equals(target.getClass())
+ && toMethod.getName().startsWith("set")){
+
+ String toName = toMethod.getName();
+ String fromName = toName.replace("set", "get");
+
+ try {
+ Method fromMethod = delta.getClass().getMethod(fromName);
+ Object value = fromMethod.invoke(delta, (Object[])null);
+ if(value != null){
+ toMethod.invoke(target, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+
+ // IfNBSubnetCRUD methods
+
+ public boolean subnetExists(String uuid) {
+ return subnetDB.containsKey(uuid);
+ }
+
+ public NeutronSubnet getSubnet(String uuid) {
+ if (!subnetExists(uuid))
+ return null;
+ return subnetDB.get(uuid);
+ }
+
+ public List<NeutronSubnet> getAllSubnets() {
+ Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
+ for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {
+ NeutronSubnet subnet = entry.getValue();
+ allSubnets.add(subnet);
+ }
+ logger.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
+ List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+ ans.addAll(allSubnets);
+ return ans;
+ }
+
+ public boolean addSubnet(NeutronSubnet input) {
+ String id = input.getID();
+ if (subnetExists(id))
+ return false;
+ subnetDB.putIfAbsent(id, input);
+ INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+ NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());
+ targetNet.addSubnet(id);
+ return true;
+ }
+
+ public boolean removeSubnet(String uuid) {
+ if (!subnetExists(uuid))
+ return false;
+ NeutronSubnet target = subnetDB.get(uuid);
+ INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+ NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());
+ targetNet.removeSubnet(uuid);
+ subnetDB.remove(uuid);
+ return true;
+ }
+
+ public boolean updateSubnet(String uuid, NeutronSubnet delta) {
+ if (!subnetExists(uuid))
+ return false;
+ NeutronSubnet target = subnetDB.get(uuid);
+ return overwrite(target, delta);
+ }
+
+ public boolean subnetInUse(String subnetUUID) {
+ if (!subnetExists(subnetUUID))
+ return true;
+ NeutronSubnet target = subnetDB.get(subnetUUID);
+ return (target.getPortsInSubnet().size() > 0);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronFloatingIPAware {\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified floatingIP can be created\r
- *\r
- * @param floatingIP\r
- * instance of proposed new Neutron FloatingIP object\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the create operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canCreateFloatingIP(NeutronFloatingIP floatingIP);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a floatingIP has been created\r
- *\r
- * @param floatingIP\r
- * instance of new Neutron FloatingIP object\r
- * @return void\r
- */\r
- public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified\r
- * delta\r
- *\r
- * @param delta\r
- * updates to the floatingIP object using patch semantics\r
- * @param floatingIP\r
- * instance of the Neutron FloatingIP object to be updated\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the update operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a floatingIP has been updated\r
- *\r
- * @param floatingIP\r
- * instance of modified Neutron FloatingIP object\r
- * @return void\r
- */\r
- public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified floatingIP can be deleted\r
- *\r
- * @param floatingIP\r
- * instance of the Neutron FloatingIP object to be deleted\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the delete operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDeleteFloatingIP(NeutronFloatingIP floatingIP);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a floatingIP has been deleted\r
- *\r
- * @param floatingIP\r
- * instance of deleted Neutron FloatingIP object\r
- * @return void\r
- */\r
- public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement
+ *
+ */
+
+public interface INeutronFloatingIPAware {
+
+ /**
+ * Services provide this interface method to indicate if the specified floatingIP can be created
+ *
+ * @param floatingIP
+ * instance of proposed new Neutron FloatingIP object
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the create operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canCreateFloatingIP(NeutronFloatingIP floatingIP);
+
+ /**
+ * Services provide this interface method for taking action after a floatingIP has been created
+ *
+ * @param floatingIP
+ * instance of new Neutron FloatingIP object
+ * @return void
+ */
+ public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);
+
+ /**
+ * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified
+ * delta
+ *
+ * @param delta
+ * updates to the floatingIP object using patch semantics
+ * @param floatingIP
+ * instance of the Neutron FloatingIP object to be updated
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the update operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);
+
+ /**
+ * Services provide this interface method for taking action after a floatingIP has been updated
+ *
+ * @param floatingIP
+ * instance of modified Neutron FloatingIP object
+ * @return void
+ */
+ public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);
+
+ /**
+ * Services provide this interface method to indicate if the specified floatingIP can be deleted
+ *
+ * @param floatingIP
+ * instance of the Neutron FloatingIP object to be deleted
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the delete operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDeleteFloatingIP(NeutronFloatingIP floatingIP);
+
+ /**
+ * Services provide this interface method for taking action after a floatingIP has been deleted
+ *
+ * @param floatingIP
+ * instance of deleted Neutron FloatingIP object
+ * @return void
+ */
+ public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB FloatingIP objects\r
- *\r
- */\r
-\r
-public interface INeutronFloatingIPCRUD {\r
- /**\r
- * Applications call this interface method to determine if a particular\r
- * FloatingIP object exists\r
- *\r
- * @param uuid\r
- * UUID of the FloatingIP object\r
- * @return boolean\r
- */\r
-\r
- public boolean floatingIPExists(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return if a particular\r
- * FloatingIP object exists\r
- *\r
- * @param uuid\r
- * UUID of the FloatingIP object\r
- * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP.OpenStackFloatingIPs}\r
- * OpenStack FloatingIP class\r
- */\r
-\r
- public NeutronFloatingIP getFloatingIP(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return all FloatingIP objects\r
- *\r
- * @return a Set of OpenStackFloatingIPs objects\r
- */\r
-\r
- public List<NeutronFloatingIP> getAllFloatingIPs();\r
-\r
- /**\r
- * Applications call this interface method to add a FloatingIP object to the\r
- * concurrent map\r
- *\r
- * @param input\r
- * OpenStackFloatingIP object\r
- * @return boolean on whether the object was added or not\r
- */\r
-\r
- public boolean addFloatingIP(NeutronFloatingIP input);\r
-\r
- /**\r
- * Applications call this interface method to remove a FloatingIP object to the\r
- * concurrent map\r
- *\r
- * @param uuid\r
- * identifier for the FloatingIP object\r
- * @return boolean on whether the object was removed or not\r
- */\r
-\r
- public boolean removeFloatingIP(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to edit a FloatingIP object\r
- *\r
- * @param uuid\r
- * identifier of the FloatingIP object\r
- * @param delta\r
- * OpenStackFloatingIP object containing changes to apply\r
- * @return boolean on whether the object was updated or not\r
- */\r
-\r
- public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB FloatingIP objects
+ *
+ */
+
+public interface INeutronFloatingIPCRUD {
+ /**
+ * Applications call this interface method to determine if a particular
+ * FloatingIP object exists
+ *
+ * @param uuid
+ * UUID of the FloatingIP object
+ * @return boolean
+ */
+
+ public boolean floatingIPExists(String uuid);
+
+ /**
+ * Applications call this interface method to return if a particular
+ * FloatingIP object exists
+ *
+ * @param uuid
+ * UUID of the FloatingIP object
+ * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP.OpenStackFloatingIPs}
+ * OpenStack FloatingIP class
+ */
+
+ public NeutronFloatingIP getFloatingIP(String uuid);
+
+ /**
+ * Applications call this interface method to return all FloatingIP objects
+ *
+ * @return a Set of OpenStackFloatingIPs objects
+ */
+
+ public List<NeutronFloatingIP> getAllFloatingIPs();
+
+ /**
+ * Applications call this interface method to add a FloatingIP object to the
+ * concurrent map
+ *
+ * @param input
+ * OpenStackFloatingIP object
+ * @return boolean on whether the object was added or not
+ */
+
+ public boolean addFloatingIP(NeutronFloatingIP input);
+
+ /**
+ * Applications call this interface method to remove a FloatingIP object to the
+ * concurrent map
+ *
+ * @param uuid
+ * identifier for the FloatingIP object
+ * @return boolean on whether the object was removed or not
+ */
+
+ public boolean removeFloatingIP(String uuid);
+
+ /**
+ * Applications call this interface method to edit a FloatingIP object
+ *
+ * @param uuid
+ * identifier of the FloatingIP object
+ * @param delta
+ * OpenStackFloatingIP object containing changes to apply
+ * @return boolean on whether the object was updated or not
+ */
+
+ public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronNetworkAware {\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified network can be created\r
- *\r
- * @param network\r
- * instance of proposed new Neutron Network object\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the create operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canCreateNetwork(NeutronNetwork network);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a network has been created\r
- *\r
- * @param network\r
- * instance of new Neutron Network object\r
- * @return void\r
- */\r
- public void neutronNetworkCreated(NeutronNetwork network);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified network can be changed using the specified\r
- * delta\r
- *\r
- * @param delta\r
- * updates to the network object using patch semantics\r
- * @param network\r
- * instance of the Neutron Network object to be updated\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the update operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a network has been updated\r
- *\r
- * @param network\r
- * instance of modified Neutron Network object\r
- * @return void\r
- */\r
- public void neutronNetworkUpdated(NeutronNetwork network);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified network can be deleted\r
- *\r
- * @param network\r
- * instance of the Neutron Network object to be deleted\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the delete operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDeleteNetwork(NeutronNetwork network);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a network has been deleted\r
- *\r
- * @param network\r
- * instance of deleted Neutron Network object\r
- * @return void\r
- */\r
- public void neutronNetworkDeleted(NeutronNetwork network);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement
+ *
+ */
+
+public interface INeutronNetworkAware {
+
+ /**
+ * Services provide this interface method to indicate if the specified network can be created
+ *
+ * @param network
+ * instance of proposed new Neutron Network object
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the create operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canCreateNetwork(NeutronNetwork network);
+
+ /**
+ * Services provide this interface method for taking action after a network has been created
+ *
+ * @param network
+ * instance of new Neutron Network object
+ * @return void
+ */
+ public void neutronNetworkCreated(NeutronNetwork network);
+
+ /**
+ * Services provide this interface method to indicate if the specified network can be changed using the specified
+ * delta
+ *
+ * @param delta
+ * updates to the network object using patch semantics
+ * @param network
+ * instance of the Neutron Network object to be updated
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the update operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);
+
+ /**
+ * Services provide this interface method for taking action after a network has been updated
+ *
+ * @param network
+ * instance of modified Neutron Network object
+ * @return void
+ */
+ public void neutronNetworkUpdated(NeutronNetwork network);
+
+ /**
+ * Services provide this interface method to indicate if the specified network can be deleted
+ *
+ * @param network
+ * instance of the Neutron Network object to be deleted
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the delete operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDeleteNetwork(NeutronNetwork network);
+
+ /**
+ * Services provide this interface method for taking action after a network has been deleted
+ *
+ * @param network
+ * instance of deleted Neutron Network object
+ * @return void
+ */
+ public void neutronNetworkDeleted(NeutronNetwork network);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB network objects\r
- *\r
- */\r
-\r
-public interface INeutronNetworkCRUD {\r
- /**\r
- * Applications call this interface method to determine if a particular\r
- * Network object exists\r
- *\r
- * @param uuid\r
- * UUID of the Network object\r
- * @return boolean\r
- */\r
-\r
- public boolean networkExists(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return if a particular\r
- * Network object exists\r
- *\r
- * @param uuid\r
- * UUID of the Network object\r
- * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronNetwork.OpenStackNetworks}\r
- * OpenStack Network class\r
- */\r
-\r
- public NeutronNetwork getNetwork(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return all Network objects\r
- *\r
- * @return List of OpenStackNetworks objects\r
- */\r
-\r
- public List<NeutronNetwork> getAllNetworks();\r
-\r
- /**\r
- * Applications call this interface method to add a Network object to the\r
- * concurrent map\r
- *\r
- * @param input\r
- * OpenStackNetwork object\r
- * @return boolean on whether the object was added or not\r
- */\r
-\r
- public boolean addNetwork(NeutronNetwork input);\r
-\r
- /**\r
- * Applications call this interface method to remove a Network object to the\r
- * concurrent map\r
- *\r
- * @param uuid\r
- * identifier for the network object\r
- * @return boolean on whether the object was removed or not\r
- */\r
-\r
- public boolean removeNetwork(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to edit a Network object\r
- *\r
- * @param uuid\r
- * identifier of the network object\r
- * @param delta\r
- * OpenStackNetwork object containing changes to apply\r
- * @return boolean on whether the object was updated or not\r
- */\r
-\r
- public boolean updateNetwork(String uuid, NeutronNetwork delta);\r
-\r
- /**\r
- * Applications call this interface method to determine if a Network object\r
- * is use\r
- *\r
- * @param netUUID\r
- * identifier of the network object\r
- *\r
- * @return boolean on whether the network is in use or not\r
- */\r
-\r
- public boolean networkInUse(String netUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB network objects
+ *
+ */
+
+public interface INeutronNetworkCRUD {
+ /**
+ * Applications call this interface method to determine if a particular
+ * Network object exists
+ *
+ * @param uuid
+ * UUID of the Network object
+ * @return boolean
+ */
+
+ public boolean networkExists(String uuid);
+
+ /**
+ * Applications call this interface method to return if a particular
+ * Network object exists
+ *
+ * @param uuid
+ * UUID of the Network object
+ * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronNetwork.OpenStackNetworks}
+ * OpenStack Network class
+ */
+
+ public NeutronNetwork getNetwork(String uuid);
+
+ /**
+ * Applications call this interface method to return all Network objects
+ *
+ * @return List of OpenStackNetworks objects
+ */
+
+ public List<NeutronNetwork> getAllNetworks();
+
+ /**
+ * Applications call this interface method to add a Network object to the
+ * concurrent map
+ *
+ * @param input
+ * OpenStackNetwork object
+ * @return boolean on whether the object was added or not
+ */
+
+ public boolean addNetwork(NeutronNetwork input);
+
+ /**
+ * Applications call this interface method to remove a Network object to the
+ * concurrent map
+ *
+ * @param uuid
+ * identifier for the network object
+ * @return boolean on whether the object was removed or not
+ */
+
+ public boolean removeNetwork(String uuid);
+
+ /**
+ * Applications call this interface method to edit a Network object
+ *
+ * @param uuid
+ * identifier of the network object
+ * @param delta
+ * OpenStackNetwork object containing changes to apply
+ * @return boolean on whether the object was updated or not
+ */
+
+ public boolean updateNetwork(String uuid, NeutronNetwork delta);
+
+ /**
+ * Applications call this interface method to determine if a Network object
+ * is use
+ *
+ * @param netUUID
+ * identifier of the network object
+ *
+ * @return boolean on whether the network is in use or not
+ */
+
+ public boolean networkInUse(String netUUID);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronPortAware {\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified port can be created\r
- *\r
- * @param port\r
- * instance of proposed new Neutron Port object\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the create operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canCreatePort(NeutronPort port);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a port has been created\r
- *\r
- * @param port\r
- * instance of new Neutron Port object\r
- * @return void\r
- */\r
- public void neutronPortCreated(NeutronPort port);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified port can be changed using the specified\r
- * delta\r
- *\r
- * @param delta\r
- * updates to the port object using patch semantics\r
- * @param port\r
- * instance of the Neutron Port object to be updated\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the update operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canUpdatePort(NeutronPort delta, NeutronPort original);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a port has been updated\r
- *\r
- * @param port\r
- * instance of modified Neutron Port object\r
- * @return void\r
- */\r
- public void neutronPortUpdated(NeutronPort port);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified port can be deleted\r
- *\r
- * @param port\r
- * instance of the Neutron Port object to be deleted\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the delete operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDeletePort(NeutronPort port);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a port has been deleted\r
- *\r
- * @param port\r
- * instance of deleted Port Network object\r
- * @return void\r
- */\r
- public void neutronPortDeleted(NeutronPort port);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement
+ *
+ */
+
+public interface INeutronPortAware {
+
+ /**
+ * Services provide this interface method to indicate if the specified port can be created
+ *
+ * @param port
+ * instance of proposed new Neutron Port object
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the create operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canCreatePort(NeutronPort port);
+
+ /**
+ * Services provide this interface method for taking action after a port has been created
+ *
+ * @param port
+ * instance of new Neutron Port object
+ * @return void
+ */
+ public void neutronPortCreated(NeutronPort port);
+
+ /**
+ * Services provide this interface method to indicate if the specified port can be changed using the specified
+ * delta
+ *
+ * @param delta
+ * updates to the port object using patch semantics
+ * @param port
+ * instance of the Neutron Port object to be updated
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the update operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canUpdatePort(NeutronPort delta, NeutronPort original);
+
+ /**
+ * Services provide this interface method for taking action after a port has been updated
+ *
+ * @param port
+ * instance of modified Neutron Port object
+ * @return void
+ */
+ public void neutronPortUpdated(NeutronPort port);
+
+ /**
+ * Services provide this interface method to indicate if the specified port can be deleted
+ *
+ * @param port
+ * instance of the Neutron Port object to be deleted
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the delete operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDeletePort(NeutronPort port);
+
+ /**
+ * Services provide this interface method for taking action after a port has been deleted
+ *
+ * @param port
+ * instance of deleted Port Network object
+ * @return void
+ */
+ public void neutronPortDeleted(NeutronPort port);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Port objects\r
- *\r
- */\r
-\r
-public interface INeutronPortCRUD {\r
- /**\r
- * Applications call this interface method to determine if a particular\r
- * Port object exists\r
- *\r
- * @param uuid\r
- * UUID of the Port object\r
- * @return boolean\r
- */\r
-\r
- public boolean portExists(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return if a particular\r
- * Port object exists\r
- *\r
- * @param uuid\r
- * UUID of the Port object\r
- * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronPort.OpenStackPorts}\r
- * OpenStack Port class\r
- */\r
-\r
- public NeutronPort getPort(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return all Port objects\r
- *\r
- * @return List of OpenStackPorts objects\r
- */\r
-\r
- public List<NeutronPort> getAllPorts();\r
-\r
- /**\r
- * Applications call this interface method to add a Port object to the\r
- * concurrent map\r
- *\r
- * @param input\r
- * OpenStackPort object\r
- * @return boolean on whether the object was added or not\r
- */\r
-\r
- public boolean addPort(NeutronPort input);\r
-\r
- /**\r
- * Applications call this interface method to remove a Port object to the\r
- * concurrent map\r
- *\r
- * @param uuid\r
- * identifier for the Port object\r
- * @return boolean on whether the object was removed or not\r
- */\r
-\r
- public boolean removePort(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to edit a Port object\r
- *\r
- * @param uuid\r
- * identifier of the Port object\r
- * @param delta\r
- * OpenStackPort object containing changes to apply\r
- * @return boolean on whether the object was updated or not\r
- */\r
-\r
- public boolean updatePort(String uuid, NeutronPort delta);\r
-\r
- /**\r
- * Applications call this interface method to see if a MAC address is in use\r
- *\r
- * @param macAddress\r
- * mac Address to be tested\r
- * @return boolean on whether the macAddress is already associated with a\r
- * port or not\r
- */\r
-\r
- public boolean macInUse(String macAddress);\r
-\r
- /**\r
- * Applications call this interface method to retrieve the port associated with\r
- * the gateway address of a subnet\r
- *\r
- * @param subnetUUID\r
- * identifier of the subnet\r
- * @return OpenStackPorts object if the port exists and null if it does not\r
- */\r
-\r
- public NeutronPort getGatewayPort(String subnetUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Port objects
+ *
+ */
+
+public interface INeutronPortCRUD {
+ /**
+ * Applications call this interface method to determine if a particular
+ * Port object exists
+ *
+ * @param uuid
+ * UUID of the Port object
+ * @return boolean
+ */
+
+ public boolean portExists(String uuid);
+
+ /**
+ * Applications call this interface method to return if a particular
+ * Port object exists
+ *
+ * @param uuid
+ * UUID of the Port object
+ * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronPort.OpenStackPorts}
+ * OpenStack Port class
+ */
+
+ public NeutronPort getPort(String uuid);
+
+ /**
+ * Applications call this interface method to return all Port objects
+ *
+ * @return List of OpenStackPorts objects
+ */
+
+ public List<NeutronPort> getAllPorts();
+
+ /**
+ * Applications call this interface method to add a Port object to the
+ * concurrent map
+ *
+ * @param input
+ * OpenStackPort object
+ * @return boolean on whether the object was added or not
+ */
+
+ public boolean addPort(NeutronPort input);
+
+ /**
+ * Applications call this interface method to remove a Port object to the
+ * concurrent map
+ *
+ * @param uuid
+ * identifier for the Port object
+ * @return boolean on whether the object was removed or not
+ */
+
+ public boolean removePort(String uuid);
+
+ /**
+ * Applications call this interface method to edit a Port object
+ *
+ * @param uuid
+ * identifier of the Port object
+ * @param delta
+ * OpenStackPort object containing changes to apply
+ * @return boolean on whether the object was updated or not
+ */
+
+ public boolean updatePort(String uuid, NeutronPort delta);
+
+ /**
+ * Applications call this interface method to see if a MAC address is in use
+ *
+ * @param macAddress
+ * mac Address to be tested
+ * @return boolean on whether the macAddress is already associated with a
+ * port or not
+ */
+
+ public boolean macInUse(String macAddress);
+
+ /**
+ * Applications call this interface method to retrieve the port associated with
+ * the gateway address of a subnet
+ *
+ * @param subnetUUID
+ * identifier of the subnet
+ * @return OpenStackPorts object if the port exists and null if it does not
+ */
+
+ public NeutronPort getGatewayPort(String subnetUUID);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronRouterAware {\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified router can be created\r
- *\r
- * @param router\r
- * instance of proposed new Neutron Router object\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the create operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canCreateRouter(NeutronRouter router);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a router has been created\r
- *\r
- * @param router\r
- * instance of new Neutron Router object\r
- * @return void\r
- */\r
- public void neutronRouterCreated(NeutronRouter router);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified router can be changed using the specified\r
- * delta\r
- *\r
- * @param delta\r
- * updates to the router object using patch semantics\r
- * @param router\r
- * instance of the Neutron Router object to be updated\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the update operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canUpdateRouter(NeutronRouter delta, NeutronRouter original);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a router has been updated\r
- *\r
- * @param router\r
- * instance of modified Neutron Router object\r
- * @return void\r
- */\r
- public void neutronRouterUpdated(NeutronRouter router);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified router can be deleted\r
- *\r
- * @param router\r
- * instance of the Neutron Router object to be deleted\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the delete operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDeleteRouter(NeutronRouter router);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a router has been deleted\r
- *\r
- * @param router\r
- * instance of deleted Router Network object\r
- * @return void\r
- */\r
- public void neutronRouterDeleted(NeutronRouter router);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified interface can be attached to the specified route\r
- *\r
- * @param router\r
- * instance of the base Neutron Router object\r
- * @param routerInterface\r
- * instance of the NeutronRouter_Interface to be attached to the router\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the attach operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
- /**\r
- * Services provide this interface method for taking action after an interface has been added to a router\r
- *\r
- * @param router\r
- * instance of the base Neutron Router object\r
- * @param routerInterface\r
- * instance of the NeutronRouter_Interface being attached to the router\r
- * @return void\r
- */\r
- public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified interface can be detached from the specified router\r
- *\r
- * @param router\r
- * instance of the base Neutron Router object\r
- * @param routerInterface\r
- * instance of the NeutronRouter_Interface to be detached to the router\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the detach operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
- /**\r
- * Services provide this interface method for taking action after an interface has been removed from a router\r
- *\r
- * @param router\r
- * instance of the base Neutron Router object\r
- * @param routerInterface\r
- * instance of the NeutronRouter_Interface being detached from the router\r
- * @return void\r
- */\r
- public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement
+ *
+ */
+
+public interface INeutronRouterAware {
+
+ /**
+ * Services provide this interface method to indicate if the specified router can be created
+ *
+ * @param router
+ * instance of proposed new Neutron Router object
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the create operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canCreateRouter(NeutronRouter router);
+
+ /**
+ * Services provide this interface method for taking action after a router has been created
+ *
+ * @param router
+ * instance of new Neutron Router object
+ * @return void
+ */
+ public void neutronRouterCreated(NeutronRouter router);
+
+ /**
+ * Services provide this interface method to indicate if the specified router can be changed using the specified
+ * delta
+ *
+ * @param delta
+ * updates to the router object using patch semantics
+ * @param router
+ * instance of the Neutron Router object to be updated
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the update operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canUpdateRouter(NeutronRouter delta, NeutronRouter original);
+
+ /**
+ * Services provide this interface method for taking action after a router has been updated
+ *
+ * @param router
+ * instance of modified Neutron Router object
+ * @return void
+ */
+ public void neutronRouterUpdated(NeutronRouter router);
+
+ /**
+ * Services provide this interface method to indicate if the specified router can be deleted
+ *
+ * @param router
+ * instance of the Neutron Router object to be deleted
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the delete operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDeleteRouter(NeutronRouter router);
+
+ /**
+ * Services provide this interface method for taking action after a router has been deleted
+ *
+ * @param router
+ * instance of deleted Router Network object
+ * @return void
+ */
+ public void neutronRouterDeleted(NeutronRouter router);
+
+ /**
+ * Services provide this interface method to indicate if the specified interface can be attached to the specified route
+ *
+ * @param router
+ * instance of the base Neutron Router object
+ * @param routerInterface
+ * instance of the NeutronRouter_Interface to be attached to the router
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the attach operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+ /**
+ * Services provide this interface method for taking action after an interface has been added to a router
+ *
+ * @param router
+ * instance of the base Neutron Router object
+ * @param routerInterface
+ * instance of the NeutronRouter_Interface being attached to the router
+ * @return void
+ */
+ public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+ /**
+ * Services provide this interface method to indicate if the specified interface can be detached from the specified router
+ *
+ * @param router
+ * instance of the base Neutron Router object
+ * @param routerInterface
+ * instance of the NeutronRouter_Interface to be detached to the router
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the detach operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+ /**
+ * Services provide this interface method for taking action after an interface has been removed from a router
+ *
+ * @param router
+ * instance of the base Neutron Router object
+ * @param routerInterface
+ * instance of the NeutronRouter_Interface being detached from the router
+ * @return void
+ */
+ public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Router objects\r
- *\r
- */\r
-\r
-public interface INeutronRouterCRUD {\r
- /**\r
- * Applications call this interface method to determine if a particular\r
- * Router object exists\r
- *\r
- * @param uuid\r
- * UUID of the Router object\r
- * @return boolean\r
- */\r
-\r
- public boolean routerExists(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return if a particular\r
- * Router object exists\r
- *\r
- * @param uuid\r
- * UUID of the Router object\r
- * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronRouter.OpenStackRouters}\r
- * OpenStack Router class\r
- */\r
-\r
- public NeutronRouter getRouter(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return all Router objects\r
- *\r
- * @return List of OpenStackRouters objects\r
- */\r
-\r
- public List<NeutronRouter> getAllRouters();\r
-\r
- /**\r
- * Applications call this interface method to add a Router object to the\r
- * concurrent map\r
- *\r
- * @param input\r
- * OpenStackRouter object\r
- * @return boolean on whether the object was added or not\r
- */\r
-\r
- public boolean addRouter(NeutronRouter input);\r
-\r
- /**\r
- * Applications call this interface method to remove a Router object to the\r
- * concurrent map\r
- *\r
- * @param uuid\r
- * identifier for the Router object\r
- * @return boolean on whether the object was removed or not\r
- */\r
-\r
- public boolean removeRouter(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to edit a Router object\r
- *\r
- * @param uuid\r
- * identifier of the Router object\r
- * @param delta\r
- * OpenStackRouter object containing changes to apply\r
- * @return boolean on whether the object was updated or not\r
- */\r
-\r
- public boolean updateRouter(String uuid, NeutronRouter delta);\r
-\r
- /**\r
- * Applications call this interface method to check if a router is in use\r
- *\r
- * @param uuid\r
- * identifier of the Router object\r
- * @return boolean on whether the router is in use or not\r
- */\r
-\r
- public boolean routerInUse(String routerUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Router objects
+ *
+ */
+
+public interface INeutronRouterCRUD {
+ /**
+ * Applications call this interface method to determine if a particular
+ * Router object exists
+ *
+ * @param uuid
+ * UUID of the Router object
+ * @return boolean
+ */
+
+ public boolean routerExists(String uuid);
+
+ /**
+ * Applications call this interface method to return if a particular
+ * Router object exists
+ *
+ * @param uuid
+ * UUID of the Router object
+ * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronRouter.OpenStackRouters}
+ * OpenStack Router class
+ */
+
+ public NeutronRouter getRouter(String uuid);
+
+ /**
+ * Applications call this interface method to return all Router objects
+ *
+ * @return List of OpenStackRouters objects
+ */
+
+ public List<NeutronRouter> getAllRouters();
+
+ /**
+ * Applications call this interface method to add a Router object to the
+ * concurrent map
+ *
+ * @param input
+ * OpenStackRouter object
+ * @return boolean on whether the object was added or not
+ */
+
+ public boolean addRouter(NeutronRouter input);
+
+ /**
+ * Applications call this interface method to remove a Router object to the
+ * concurrent map
+ *
+ * @param uuid
+ * identifier for the Router object
+ * @return boolean on whether the object was removed or not
+ */
+
+ public boolean removeRouter(String uuid);
+
+ /**
+ * Applications call this interface method to edit a Router object
+ *
+ * @param uuid
+ * identifier of the Router object
+ * @param delta
+ * OpenStackRouter object containing changes to apply
+ * @return boolean on whether the object was updated or not
+ */
+
+ public boolean updateRouter(String uuid, NeutronRouter delta);
+
+ /**
+ * Applications call this interface method to check if a router is in use
+ *
+ * @param uuid
+ * identifier of the Router object
+ * @return boolean on whether the router is in use or not
+ */
+
+ public boolean routerInUse(String routerUUID);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronSubnetAware {\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified subnet can be created\r
- *\r
- * @param subnet\r
- * instance of proposed new Neutron Subnet object\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the create operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canCreateSubnet(NeutronSubnet subnet);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a subnet has been created\r
- *\r
- * @param subnet\r
- * instance of new Neutron Subnet object\r
- * @return void\r
- */\r
- public void neutronSubnetCreated(NeutronSubnet subnet);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified subnet can be changed using the specified\r
- * delta\r
- *\r
- * @param delta\r
- * updates to the subnet object using patch semantics\r
- * @param subnet\r
- * instance of the Neutron Subnet object to be updated\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the update operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a subnet has been updated\r
- *\r
- * @param subnet\r
- * instance of modified Neutron Subnet object\r
- * @return void\r
- */\r
- public void neutronSubnetUpdated(NeutronSubnet subnet);\r
-\r
- /**\r
- * Services provide this interface method to indicate if the specified subnet can be deleted\r
- *\r
- * @param subnet\r
- * instance of the Subnet Router object to be deleted\r
- * @return integer\r
- * the return value is understood to be a HTTP status code. A return value outside of 200 through 299\r
- * results in the delete operation being interrupted and the returned status value reflected in the\r
- * HTTP response.\r
- */\r
- public int canDeleteSubnet(NeutronSubnet subnet);\r
-\r
- /**\r
- * Services provide this interface method for taking action after a subnet has been deleted\r
- *\r
- * @param subnet\r
- * instance of deleted Router Subnet object\r
- * @return void\r
- */\r
- public void neutronSubnetDeleted(NeutronSubnet subnet);\r
-\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement
+ *
+ */
+
+public interface INeutronSubnetAware {
+
+ /**
+ * Services provide this interface method to indicate if the specified subnet can be created
+ *
+ * @param subnet
+ * instance of proposed new Neutron Subnet object
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the create operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canCreateSubnet(NeutronSubnet subnet);
+
+ /**
+ * Services provide this interface method for taking action after a subnet has been created
+ *
+ * @param subnet
+ * instance of new Neutron Subnet object
+ * @return void
+ */
+ public void neutronSubnetCreated(NeutronSubnet subnet);
+
+ /**
+ * Services provide this interface method to indicate if the specified subnet can be changed using the specified
+ * delta
+ *
+ * @param delta
+ * updates to the subnet object using patch semantics
+ * @param subnet
+ * instance of the Neutron Subnet object to be updated
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the update operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);
+
+ /**
+ * Services provide this interface method for taking action after a subnet has been updated
+ *
+ * @param subnet
+ * instance of modified Neutron Subnet object
+ * @return void
+ */
+ public void neutronSubnetUpdated(NeutronSubnet subnet);
+
+ /**
+ * Services provide this interface method to indicate if the specified subnet can be deleted
+ *
+ * @param subnet
+ * instance of the Subnet Router object to be deleted
+ * @return integer
+ * the return value is understood to be a HTTP status code. A return value outside of 200 through 299
+ * results in the delete operation being interrupted and the returned status value reflected in the
+ * HTTP response.
+ */
+ public int canDeleteSubnet(NeutronSubnet subnet);
+
+ /**
+ * Services provide this interface method for taking action after a subnet has been deleted
+ *
+ * @param subnet
+ * instance of deleted Router Subnet object
+ * @return void
+ */
+ public void neutronSubnetDeleted(NeutronSubnet subnet);
+
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Subnet objects\r
- *\r
- */\r
-\r
-public interface INeutronSubnetCRUD {\r
- /**\r
- * Applications call this interface method to determine if a particular\r
- * Subnet object exists\r
- *\r
- * @param uuid\r
- * UUID of the Subnet object\r
- * @return boolean\r
- */\r
-\r
- public boolean subnetExists(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return if a particular\r
- * Subnet object exists\r
- *\r
- * @param uuid\r
- * UUID of the Subnet object\r
- * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSubnet.OpenStackSubnets}\r
- * OpenStack Subnet class\r
- */\r
-\r
- public NeutronSubnet getSubnet(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to return all Subnet objects\r
- *\r
- * @return List of OpenStackSubnets objects\r
- */\r
-\r
- public List<NeutronSubnet> getAllSubnets();\r
-\r
- /**\r
- * Applications call this interface method to add a Subnet object to the\r
- * concurrent map\r
- *\r
- * @param input\r
- * OpenStackSubnet object\r
- * @return boolean on whether the object was added or not\r
- */\r
-\r
- public boolean addSubnet(NeutronSubnet input);\r
-\r
- /**\r
- * Applications call this interface method to remove a Subnet object to the\r
- * concurrent map\r
- *\r
- * @param uuid\r
- * identifier for the Subnet object\r
- * @return boolean on whether the object was removed or not\r
- */\r
-\r
- public boolean removeSubnet(String uuid);\r
-\r
- /**\r
- * Applications call this interface method to edit a Subnet object\r
- *\r
- * @param uuid\r
- * identifier of the Subnet object\r
- * @param delta\r
- * OpenStackSubnet object containing changes to apply\r
- * @return boolean on whether the object was updated or not\r
- */\r
-\r
- public boolean updateSubnet(String uuid, NeutronSubnet delta);\r
-\r
- /**\r
- * Applications call this interface method to determine if a Subnet object\r
- * is use\r
- *\r
- * @param subnetUUID\r
- * identifier of the subnet object\r
- *\r
- * @return boolean on whether the subnet is in use or not\r
- */\r
-\r
- public boolean subnetInUse(String subnetUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Subnet objects
+ *
+ */
+
+public interface INeutronSubnetCRUD {
+ /**
+ * Applications call this interface method to determine if a particular
+ * Subnet object exists
+ *
+ * @param uuid
+ * UUID of the Subnet object
+ * @return boolean
+ */
+
+ public boolean subnetExists(String uuid);
+
+ /**
+ * Applications call this interface method to return if a particular
+ * Subnet object exists
+ *
+ * @param uuid
+ * UUID of the Subnet object
+ * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSubnet.OpenStackSubnets}
+ * OpenStack Subnet class
+ */
+
+ public NeutronSubnet getSubnet(String uuid);
+
+ /**
+ * Applications call this interface method to return all Subnet objects
+ *
+ * @return List of OpenStackSubnets objects
+ */
+
+ public List<NeutronSubnet> getAllSubnets();
+
+ /**
+ * Applications call this interface method to add a Subnet object to the
+ * concurrent map
+ *
+ * @param input
+ * OpenStackSubnet object
+ * @return boolean on whether the object was added or not
+ */
+
+ public boolean addSubnet(NeutronSubnet input);
+
+ /**
+ * Applications call this interface method to remove a Subnet object to the
+ * concurrent map
+ *
+ * @param uuid
+ * identifier for the Subnet object
+ * @return boolean on whether the object was removed or not
+ */
+
+ public boolean removeSubnet(String uuid);
+
+ /**
+ * Applications call this interface method to edit a Subnet object
+ *
+ * @param uuid
+ * identifier of the Subnet object
+ * @param delta
+ * OpenStackSubnet object containing changes to apply
+ * @return boolean on whether the object was updated or not
+ */
+
+ public boolean updateSubnet(String uuid, NeutronSubnet delta);
+
+ /**
+ * Applications call this interface method to determine if a Subnet object
+ * is use
+ *
+ * @param subnetUUID
+ * identifier of the subnet object
+ *
+ * @return boolean on whether the subnet is in use or not
+ */
+
+ public boolean subnetInUse(String subnetUUID);
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-public class NeutronCRUDInterfaces {\r
-\r
- public static INeutronNetworkCRUD getINeutronNetworkCRUD(Object o) {\r
- INeutronNetworkCRUD answer = (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, o);\r
- return answer;\r
- }\r
-\r
- public static INeutronSubnetCRUD getINeutronSubnetCRUD(Object o) {\r
- INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, o);\r
- return answer;\r
- }\r
-\r
- public static INeutronPortCRUD getINeutronPortCRUD(Object o) {\r
- INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, o);\r
- return answer;\r
- }\r
-\r
- public static INeutronRouterCRUD getINeutronRouterCRUD(Object o) {\r
- INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getGlobalInstance(INeutronRouterCRUD.class, o);\r
- return answer;\r
- }\r
-\r
- public static INeutronFloatingIPCRUD getINeutronFloatingIPCRUD(Object o) {\r
- INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);\r
- return answer;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+public class NeutronCRUDInterfaces {
+
+ public static INeutronNetworkCRUD getINeutronNetworkCRUD(Object o) {
+ INeutronNetworkCRUD answer = (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, o);
+ return answer;
+ }
+
+ public static INeutronSubnetCRUD getINeutronSubnetCRUD(Object o) {
+ INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, o);
+ return answer;
+ }
+
+ public static INeutronPortCRUD getINeutronPortCRUD(Object o) {
+ INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, o);
+ return answer;
+ }
+
+ public static INeutronRouterCRUD getINeutronRouterCRUD(Object o) {
+ INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getGlobalInstance(INeutronRouterCRUD.class, o);
+ return answer;
+ }
+
+ public static INeutronFloatingIPCRUD getINeutronFloatingIPCRUD(Object o) {
+ INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);
+ return answer;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronFloatingIP {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement (name="id")\r
- String floatingIPUUID;\r
-\r
- @XmlElement (name="floating_network_id")\r
- String floatingNetworkUUID;\r
-\r
- @XmlElement (name="port_id")\r
- String portUUID;\r
-\r
- @XmlElement (name="fixed_ip_address")\r
- String fixedIPAddress;\r
-\r
- @XmlElement (name="floating_ip_address")\r
- String floatingIPAddress;\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantUUID;\r
-\r
- public NeutronFloatingIP() {\r
- }\r
-\r
- public String getID() { return floatingIPUUID; }\r
-\r
- public String getFloatingIPUUID() {\r
- return floatingIPUUID;\r
- }\r
-\r
- public void setFloatingIPUUID(String floatingIPUUID) {\r
- this.floatingIPUUID = floatingIPUUID;\r
- }\r
-\r
- public String getFloatingNetworkUUID() {\r
- return floatingNetworkUUID;\r
- }\r
-\r
- public void setFloatingNetworkUUID(String floatingNetworkUUID) {\r
- this.floatingNetworkUUID = floatingNetworkUUID;\r
- }\r
-\r
- public String getPortUUID() {\r
- return portUUID;\r
- }\r
-\r
- public void setPortUUID(String portUUID) {\r
- this.portUUID = portUUID;\r
- }\r
-\r
- public String getFixedIPAddress() {\r
- return fixedIPAddress;\r
- }\r
-\r
- public void setFixedIPAddress(String fixedIPAddress) {\r
- this.fixedIPAddress = fixedIPAddress;\r
- }\r
-\r
- public String getFloatingIPAddress() {\r
- return floatingIPAddress;\r
- }\r
-\r
- public void setFloatingIPAddress(String floatingIPAddress) {\r
- this.floatingIPAddress = floatingIPAddress;\r
- }\r
-\r
- public String getTenantUUID() {\r
- return tenantUUID;\r
- }\r
-\r
- public void setTenantUUID(String tenantUUID) {\r
- this.tenantUUID = tenantUUID;\r
- }\r
-\r
- /**\r
- * This method copies selected fields from the object and returns them\r
- * as a new object, suitable for marshaling.\r
- *\r
- * @param fields\r
- * List of attributes to be extracted\r
- * @return an OpenStackFloatingIPs object with only the selected fields\r
- * populated\r
- */\r
-\r
- public NeutronFloatingIP extractFields(List<String> fields) {\r
- NeutronFloatingIP ans = new NeutronFloatingIP();\r
- Iterator<String> i = fields.iterator();\r
- while (i.hasNext()) {\r
- String s = i.next();\r
- if (s.equals("id"))\r
- ans.setFloatingIPUUID(this.getFloatingIPUUID());\r
- if (s.equals("floating_network_id"))\r
- ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());\r
- if (s.equals("port_id"))\r
- ans.setPortUUID(this.getPortUUID());\r
- if (s.equals("fixed_ip_address"))\r
- ans.setFixedIPAddress(this.getFixedIPAddress());\r
- if (s.equals("floating_ip_address"))\r
- ans.setFloatingIPAddress(this.getFloatingIPAddress());\r
- if (s.equals("tenant_id"))\r
- ans.setTenantUUID(this.getTenantUUID());\r
- }\r
- return ans;\r
- }\r
-\r
- public void initDefaults() {\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+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;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFloatingIP {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement (name="id")
+ String floatingIPUUID;
+
+ @XmlElement (name="floating_network_id")
+ String floatingNetworkUUID;
+
+ @XmlElement (name="port_id")
+ String portUUID;
+
+ @XmlElement (name="fixed_ip_address")
+ String fixedIPAddress;
+
+ @XmlElement (name="floating_ip_address")
+ String floatingIPAddress;
+
+ @XmlElement (name="tenant_id")
+ String tenantUUID;
+
+ public NeutronFloatingIP() {
+ }
+
+ public String getID() { return floatingIPUUID; }
+
+ public String getFloatingIPUUID() {
+ return floatingIPUUID;
+ }
+
+ public void setFloatingIPUUID(String floatingIPUUID) {
+ this.floatingIPUUID = floatingIPUUID;
+ }
+
+ public String getFloatingNetworkUUID() {
+ return floatingNetworkUUID;
+ }
+
+ public void setFloatingNetworkUUID(String floatingNetworkUUID) {
+ this.floatingNetworkUUID = floatingNetworkUUID;
+ }
+
+ public String getPortUUID() {
+ return portUUID;
+ }
+
+ public void setPortUUID(String portUUID) {
+ this.portUUID = portUUID;
+ }
+
+ public String getFixedIPAddress() {
+ return fixedIPAddress;
+ }
+
+ public void setFixedIPAddress(String fixedIPAddress) {
+ this.fixedIPAddress = fixedIPAddress;
+ }
+
+ public String getFloatingIPAddress() {
+ return floatingIPAddress;
+ }
+
+ public void setFloatingIPAddress(String floatingIPAddress) {
+ this.floatingIPAddress = floatingIPAddress;
+ }
+
+ public String getTenantUUID() {
+ return tenantUUID;
+ }
+
+ public void setTenantUUID(String tenantUUID) {
+ this.tenantUUID = tenantUUID;
+ }
+
+ /**
+ * This method copies selected fields from the object and returns them
+ * as a new object, suitable for marshaling.
+ *
+ * @param fields
+ * List of attributes to be extracted
+ * @return an OpenStackFloatingIPs object with only the selected fields
+ * populated
+ */
+
+ public NeutronFloatingIP extractFields(List<String> fields) {
+ NeutronFloatingIP ans = new NeutronFloatingIP();
+ Iterator<String> i = fields.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (s.equals("id")) {
+ ans.setFloatingIPUUID(this.getFloatingIPUUID());
+ }
+ if (s.equals("floating_network_id")) {
+ ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());
+ }
+ if (s.equals("port_id")) {
+ ans.setPortUUID(this.getPortUUID());
+ }
+ if (s.equals("fixed_ip_address")) {
+ ans.setFixedIPAddress(this.getFixedIPAddress());
+ }
+ if (s.equals("floating_ip_address")) {
+ ans.setFloatingIPAddress(this.getFloatingIPAddress());
+ }
+ if (s.equals("tenant_id")) {
+ ans.setTenantUUID(this.getTenantUUID());
+ }
+ }
+ return ans;
+ }
+
+ public void initDefaults() {
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement(name = "network")\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronNetwork {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement (name="id")\r
- String networkUUID; // network UUID\r
-\r
- @XmlElement (name="name")\r
- String networkName; // name\r
-\r
- @XmlElement (defaultValue="true", name="admin_state_up")\r
- Boolean adminStateUp; // admin state up (true/false)\r
-\r
- @XmlElement (defaultValue="false", name="shared")\r
- Boolean shared; // shared network or not\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantID; // tenant for this network\r
-\r
- @XmlElement (defaultValue="false", namespace="router", name="external")\r
- Boolean routerExternal; // network external or not\r
-\r
- @XmlElement (defaultValue="flat", namespace="provider", name="network_type")\r
- String providerNetworkType; // provider network type (flat or vlan)\r
-\r
- @XmlElement (namespace="provider", name="physical_network")\r
- String providerPhysicalNetwork; // provider physical network (name)\r
-\r
- @XmlElement (namespace="provider", name="segmentation_id")\r
- String providerSegmentationID; // provide segmentation ID (vlan ID)\r
-\r
- @XmlElement (name="status")\r
- String status; // status (read-only)\r
-\r
- @XmlElement (name="subnets")\r
- List<String> subnets; // subnets (read-only)\r
-\r
- /* This attribute lists the ports associated with an instance\r
- * which is needed for determining if that instance can be deleted\r
- */\r
-\r
- List<NeutronPort> myPorts;\r
-\r
- public NeutronNetwork() {\r
- myPorts = new ArrayList<NeutronPort>();\r
- }\r
-\r
- public void initDefaults() {\r
- subnets = new ArrayList<String>();\r
- if (this.status == null)\r
- this.status = "ACTIVE";\r
- if (this.adminStateUp == null)\r
- this.adminStateUp = true;\r
- if (this.shared == null)\r
- this.shared = false;\r
- if (this.routerExternal == null)\r
- this.routerExternal = false;\r
- if (this.providerNetworkType == null)\r
- this.providerNetworkType = "flat";\r
- }\r
-\r
- public String getID() { return networkUUID; }\r
-\r
- public String getNetworkUUID() {\r
- return networkUUID;\r
- }\r
-\r
- public void setNetworkUUID(String networkUUID) {\r
- this.networkUUID = networkUUID;\r
- }\r
-\r
- public String getNetworkName() {\r
- return networkName;\r
- }\r
-\r
- public void setNetworkName(String networkName) {\r
- this.networkName = networkName;\r
- }\r
-\r
- public boolean isAdminStateUp() {\r
- return adminStateUp;\r
- }\r
-\r
- public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
- public void setAdminStateUp(boolean newValue) {\r
- this.adminStateUp = newValue;\r
- }\r
-\r
- public boolean isShared() { return shared; }\r
-\r
- public Boolean getShared() { return shared; }\r
-\r
- public void setShared(boolean newValue) {\r
- this.shared = newValue;\r
- }\r
-\r
- public String getTenantID() {\r
- return tenantID;\r
- }\r
-\r
- public void setTenantID(String tenantID) {\r
- this.tenantID = tenantID;\r
- }\r
-\r
- public boolean isRouterExternal() { return routerExternal; }\r
-\r
- public Boolean getRouterExternal() { return routerExternal; }\r
-\r
- public void setRouterExternal(boolean newValue) {\r
- this.routerExternal = newValue;\r
- }\r
-\r
- public String getProviderNetworkType() {\r
- return providerNetworkType;\r
- }\r
-\r
- public void setProviderNetworkType(String providerNetworkType) {\r
- this.providerNetworkType = providerNetworkType;\r
- }\r
-\r
- public String getProviderPhysicalNetwork() {\r
- return providerPhysicalNetwork;\r
- }\r
-\r
- public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {\r
- this.providerPhysicalNetwork = providerPhysicalNetwork;\r
- }\r
-\r
- public String getProviderSegmentationID() {\r
- return providerSegmentationID;\r
- }\r
-\r
- public void setProviderSegmentationID(String providerSegmentationID) {\r
- this.providerSegmentationID = providerSegmentationID;\r
- }\r
-\r
- public String getStatus() {\r
- return status;\r
- }\r
-\r
- public void setStatus(String status) {\r
- this.status = status;\r
- }\r
-\r
- public List<String> getSubnets() {\r
- return subnets;\r
- }\r
-\r
- public void setSubnets(List<String> subnets) {\r
- this.subnets = subnets;\r
- }\r
-\r
- public void addSubnet(String uuid) {\r
- this.subnets.add(uuid);\r
- }\r
-\r
- public void removeSubnet(String uuid) {\r
- this.subnets.remove(uuid);\r
- }\r
-\r
- public List<NeutronPort> getPortsOnNetwork() {\r
- return myPorts;\r
- }\r
-\r
- public void addPort(NeutronPort port) {\r
- myPorts.add(port);\r
- }\r
-\r
- public void removePort(NeutronPort port) {\r
- myPorts.remove(port);\r
- }\r
-\r
- /**\r
- * This method copies selected fields from the object and returns them\r
- * as a new object, suitable for marshaling.\r
- *\r
- * @param fields\r
- * List of attributes to be extracted\r
- * @return an OpenStackNetworks object with only the selected fields\r
- * populated\r
- */\r
-\r
- public NeutronNetwork extractFields(List<String> fields) {\r
- NeutronNetwork ans = new NeutronNetwork();\r
- Iterator<String> i = fields.iterator();\r
- while (i.hasNext()) {\r
- String s = i.next();\r
- if (s.equals("id"))\r
- ans.setNetworkUUID(this.getNetworkUUID());\r
- if (s.equals("name"))\r
- ans.setNetworkName(this.getNetworkName());\r
- if (s.equals("admin_state_up"))\r
- ans.setAdminStateUp(this.adminStateUp);\r
- if (s.equals("status"))\r
- ans.setStatus(this.getStatus());\r
- if (s.equals("subnets")) {\r
- List<String> subnetList = new ArrayList<String>();\r
- subnetList.addAll(this.getSubnets());\r
- ans.setSubnets(subnetList);\r
- }\r
- if (s.equals("shared"))\r
- ans.setShared(this.shared);\r
- if (s.equals("tenant_id"))\r
- ans.setTenantID(this.getTenantID());\r
- }\r
- return ans;\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.ArrayList;
+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;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "network")
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronNetwork {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement (name="id")
+ String networkUUID; // network UUID
+
+ @XmlElement (name="name")
+ String networkName; // name
+
+ @XmlElement (defaultValue="true", name="admin_state_up")
+ Boolean adminStateUp; // admin state up (true/false)
+
+ @XmlElement (defaultValue="false", name="shared")
+ Boolean shared; // shared network or not
+
+ @XmlElement (name="tenant_id")
+ String tenantID; // tenant for this network
+
+ @XmlElement (defaultValue="false", namespace="router", name="external")
+ Boolean routerExternal; // network external or not
+
+ @XmlElement (defaultValue="flat", namespace="provider", name="network_type")
+ String providerNetworkType; // provider network type (flat or vlan)
+
+ @XmlElement (namespace="provider", name="physical_network")
+ String providerPhysicalNetwork; // provider physical network (name)
+
+ @XmlElement (namespace="provider", name="segmentation_id")
+ String providerSegmentationID; // provide segmentation ID (vlan ID)
+
+ @XmlElement (name="status")
+ String status; // status (read-only)
+
+ @XmlElement (name="subnets")
+ List<String> subnets; // subnets (read-only)
+
+ /* This attribute lists the ports associated with an instance
+ * which is needed for determining if that instance can be deleted
+ */
+
+ List<NeutronPort> myPorts;
+
+ public NeutronNetwork() {
+ myPorts = new ArrayList<NeutronPort>();
+ }
+
+ public void initDefaults() {
+ subnets = new ArrayList<String>();
+ if (status == null) {
+ status = "ACTIVE";
+ }
+ if (adminStateUp == null) {
+ adminStateUp = true;
+ }
+ if (shared == null) {
+ shared = false;
+ }
+ if (routerExternal == null) {
+ routerExternal = false;
+ }
+ if (providerNetworkType == null) {
+ providerNetworkType = "flat";
+ }
+ }
+
+ public String getID() { return networkUUID; }
+
+ public String getNetworkUUID() {
+ return networkUUID;
+ }
+
+ public void setNetworkUUID(String networkUUID) {
+ this.networkUUID = networkUUID;
+ }
+
+ public String getNetworkName() {
+ return networkName;
+ }
+
+ public void setNetworkName(String networkName) {
+ this.networkName = networkName;
+ }
+
+ public boolean isAdminStateUp() {
+ return adminStateUp;
+ }
+
+ public Boolean getAdminStateUp() { return adminStateUp; }
+
+ public void setAdminStateUp(boolean newValue) {
+ adminStateUp = newValue;
+ }
+
+ public boolean isShared() { return shared; }
+
+ public Boolean getShared() { return shared; }
+
+ public void setShared(boolean newValue) {
+ shared = newValue;
+ }
+
+ public String getTenantID() {
+ return tenantID;
+ }
+
+ public void setTenantID(String tenantID) {
+ this.tenantID = tenantID;
+ }
+
+ public boolean isRouterExternal() { return routerExternal; }
+
+ public Boolean getRouterExternal() { return routerExternal; }
+
+ public void setRouterExternal(boolean newValue) {
+ routerExternal = newValue;
+ }
+
+ public String getProviderNetworkType() {
+ return providerNetworkType;
+ }
+
+ public void setProviderNetworkType(String providerNetworkType) {
+ this.providerNetworkType = providerNetworkType;
+ }
+
+ public String getProviderPhysicalNetwork() {
+ return providerPhysicalNetwork;
+ }
+
+ public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {
+ this.providerPhysicalNetwork = providerPhysicalNetwork;
+ }
+
+ public String getProviderSegmentationID() {
+ return providerSegmentationID;
+ }
+
+ public void setProviderSegmentationID(String providerSegmentationID) {
+ this.providerSegmentationID = providerSegmentationID;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public List<String> getSubnets() {
+ return subnets;
+ }
+
+ public void setSubnets(List<String> subnets) {
+ this.subnets = subnets;
+ }
+
+ public void addSubnet(String uuid) {
+ subnets.add(uuid);
+ }
+
+ public void removeSubnet(String uuid) {
+ subnets.remove(uuid);
+ }
+
+ public List<NeutronPort> getPortsOnNetwork() {
+ return myPorts;
+ }
+
+ public void addPort(NeutronPort port) {
+ myPorts.add(port);
+ }
+
+ public void removePort(NeutronPort port) {
+ myPorts.remove(port);
+ }
+
+ /**
+ * This method copies selected fields from the object and returns them
+ * as a new object, suitable for marshaling.
+ *
+ * @param fields
+ * List of attributes to be extracted
+ * @return an OpenStackNetworks object with only the selected fields
+ * populated
+ */
+
+ public NeutronNetwork extractFields(List<String> fields) {
+ NeutronNetwork ans = new NeutronNetwork();
+ Iterator<String> i = fields.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (s.equals("id")) {
+ ans.setNetworkUUID(this.getNetworkUUID());
+ }
+ if (s.equals("name")) {
+ ans.setNetworkName(this.getNetworkName());
+ }
+ if (s.equals("admin_state_up")) {
+ ans.setAdminStateUp(adminStateUp);
+ }
+ if (s.equals("status")) {
+ ans.setStatus(this.getStatus());
+ }
+ if (s.equals("subnets")) {
+ List<String> subnetList = new ArrayList<String>();
+ subnetList.addAll(this.getSubnets());
+ ans.setSubnets(subnetList);
+ }
+ if (s.equals("shared")) {
+ ans.setShared(shared);
+ }
+ if (s.equals("tenant_id")) {
+ ans.setTenantID(this.getTenantID());
+ }
+ }
+ return ans;
+ }
+
+}
+
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronPort {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement (name="id")\r
- String portUUID;\r
-\r
- @XmlElement (name="network_id")\r
- String networkUUID;\r
-\r
- @XmlElement (name="name")\r
- String name;\r
-\r
- @XmlElement (defaultValue="true", name="admin_state_up")\r
- Boolean adminStateUp;\r
-\r
- @XmlElement (name="status")\r
- String status;\r
-\r
- @XmlElement (name="mac_address")\r
- String macAddress;\r
-\r
- @XmlElement (name="fixed_ips")\r
- List<Neutron_IPs> fixedIPs;\r
-\r
- @XmlElement (name="device_id")\r
- String deviceID;\r
-\r
- @XmlElement (name="device_owner")\r
- String deviceOwner;\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantID;\r
-\r
- // TODO: add security groups\r
- // @XmlElement (name="security_groups")\r
- // List<String> securityGroups;\r
-\r
- /* this attribute stores the floating IP address assigned to\r
- * each fixed IP address\r
- */\r
-\r
- HashMap<String, NeutronFloatingIP> floatingIPMap;\r
-\r
- public NeutronPort() {\r
- floatingIPMap = new HashMap<String, NeutronFloatingIP>();\r
- }\r
-\r
- public String getID() { return portUUID; }\r
-\r
- public String getPortUUID() {\r
- return portUUID;\r
- }\r
-\r
- public void setPortUUID(String portUUID) {\r
- this.portUUID = portUUID;\r
- }\r
-\r
- public String getNetworkUUID() {\r
- return networkUUID;\r
- }\r
-\r
- public void setNetworkUUID(String networkUUID) {\r
- this.networkUUID = networkUUID;\r
- }\r
-\r
- public String getName() {\r
- return name;\r
- }\r
-\r
- public void setName(String name) {\r
- this.name = name;\r
- }\r
-\r
- public boolean isAdminStateUp() {\r
- if (adminStateUp == null)\r
- return true;\r
- return adminStateUp;\r
- }\r
-\r
- public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
- public void setAdminStateUp(Boolean newValue) {\r
- this.adminStateUp = newValue;\r
- }\r
-\r
- public String getStatus() {\r
- return status;\r
- }\r
-\r
- public void setStatus(String status) {\r
- this.status = status;\r
- }\r
-\r
- public String getMacAddress() {\r
- return macAddress;\r
- }\r
-\r
- public void setMacAddress(String macAddress) {\r
- this.macAddress = macAddress;\r
- }\r
-\r
- public List<Neutron_IPs> getFixedIPs() {\r
- return fixedIPs;\r
- }\r
-\r
- public void setFixedIPs(List<Neutron_IPs> fixedIPs) {\r
- this.fixedIPs = fixedIPs;\r
- }\r
-\r
- public String getDeviceID() {\r
- return deviceID;\r
- }\r
-\r
- public void setDeviceID(String deviceID) {\r
- this.deviceID = deviceID;\r
- }\r
-\r
- public String getDeviceOwner() {\r
- return deviceOwner;\r
- }\r
-\r
- public void setDeviceOwner(String deviceOwner) {\r
- this.deviceOwner = deviceOwner;\r
- }\r
-\r
- public String getTenantID() {\r
- return tenantID;\r
- }\r
-\r
- public void setTenantID(String tenantID) {\r
- this.tenantID = tenantID;\r
- }\r
-\r
- public NeutronFloatingIP getFloatingIP(String key) {\r
- if (!floatingIPMap.containsKey(key))\r
- return null;\r
- return floatingIPMap.get(key);\r
- }\r
-\r
- public void removeFloatingIP(String key) {\r
- floatingIPMap.remove(key);\r
- }\r
-\r
- public void addFloatingIP(String key, NeutronFloatingIP floatingIP) {\r
- if (!floatingIPMap.containsKey(key))\r
- floatingIPMap.put(key, floatingIP);\r
- }\r
-\r
- /**\r
- * This method copies selected fields from the object and returns them\r
- * as a new object, suitable for marshaling.\r
- *\r
- * @param fields\r
- * List of attributes to be extracted\r
- * @return an OpenStackPorts object with only the selected fields\r
- * populated\r
- */\r
-\r
- public NeutronPort extractFields(List<String> fields) {\r
- NeutronPort ans = new NeutronPort();\r
- Iterator<String> i = fields.iterator();\r
- while (i.hasNext()) {\r
- String s = i.next();\r
- if (s.equals("id"))\r
- ans.setPortUUID(this.getPortUUID());\r
- if (s.equals("network_id"))\r
- ans.setNetworkUUID(this.getNetworkUUID());\r
- if (s.equals("name"))\r
- ans.setName(this.getName());\r
- if (s.equals("admin_state_up"))\r
- ans.setAdminStateUp(this.getAdminStateUp());\r
- if (s.equals("status"))\r
- ans.setStatus(this.getStatus());\r
- if (s.equals("mac_address"))\r
- ans.setMacAddress(this.getMacAddress());\r
- if (s.equals("fixed_ips")) {\r
- List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();\r
- fixedIPs.addAll(this.getFixedIPs());\r
- ans.setFixedIPs(fixedIPs);\r
- }\r
- if (s.equals("device_id")) {\r
- ans.setDeviceID(this.getDeviceID());\r
- }\r
- if (s.equals("device_owner")) {\r
- ans.setDeviceOwner(this.getDeviceOwner());\r
- }\r
- if (s.equals("tenant_id"))\r
- ans.setTenantID(this.getTenantID());\r
- }\r
- return ans;\r
- }\r
-\r
- public void initDefaults() {\r
- adminStateUp = true;\r
- if (status == null)\r
- status = "ACTIVE";\r
- if (fixedIPs == null)\r
- fixedIPs = new ArrayList<Neutron_IPs>();\r
- }\r
-\r
- /**\r
- * This method checks to see if the port has a floating IPv4 address\r
- * associated with the supplied fixed IPv4 address\r
- *\r
- * @param fixedIP\r
- * fixed IPv4 address in dotted decimal format\r
- * @return a boolean indicating if there is a floating IPv4 address bound\r
- * to the fixed IPv4 address\r
- */\r
-\r
- public boolean isBoundToFloatingIP(String fixedIP) {\r
- return floatingIPMap.containsKey(fixedIP);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.ArrayList;
+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;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronPort {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement (name="id")
+ String portUUID;
+
+ @XmlElement (name="network_id")
+ String networkUUID;
+
+ @XmlElement (name="name")
+ String name;
+
+ @XmlElement (defaultValue="true", name="admin_state_up")
+ Boolean adminStateUp;
+
+ @XmlElement (name="status")
+ String status;
+
+ @XmlElement (name="mac_address")
+ String macAddress;
+
+ @XmlElement (name="fixed_ips")
+ List<Neutron_IPs> fixedIPs;
+
+ @XmlElement (name="device_id")
+ String deviceID;
+
+ @XmlElement (name="device_owner")
+ String deviceOwner;
+
+ @XmlElement (name="tenant_id")
+ String tenantID;
+
+ // TODO: add security groups
+ // @XmlElement (name="security_groups")
+ // List<String> securityGroups;
+
+ /* this attribute stores the floating IP address assigned to
+ * each fixed IP address
+ */
+
+ HashMap<String, NeutronFloatingIP> floatingIPMap;
+
+ public NeutronPort() {
+ floatingIPMap = new HashMap<String, NeutronFloatingIP>();
+ }
+
+ public String getID() { return portUUID; }
+
+ public String getPortUUID() {
+ return portUUID;
+ }
+
+ public void setPortUUID(String portUUID) {
+ this.portUUID = portUUID;
+ }
+
+ public String getNetworkUUID() {
+ return networkUUID;
+ }
+
+ public void setNetworkUUID(String networkUUID) {
+ this.networkUUID = networkUUID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isAdminStateUp() {
+ if (adminStateUp == null) {
+ return true;
+ }
+ return adminStateUp;
+ }
+
+ public Boolean getAdminStateUp() { return adminStateUp; }
+
+ public void setAdminStateUp(Boolean newValue) {
+ adminStateUp = newValue;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getMacAddress() {
+ return macAddress;
+ }
+
+ public void setMacAddress(String macAddress) {
+ this.macAddress = macAddress;
+ }
+
+ public List<Neutron_IPs> getFixedIPs() {
+ return fixedIPs;
+ }
+
+ public void setFixedIPs(List<Neutron_IPs> fixedIPs) {
+ this.fixedIPs = fixedIPs;
+ }
+
+ public String getDeviceID() {
+ return deviceID;
+ }
+
+ public void setDeviceID(String deviceID) {
+ this.deviceID = deviceID;
+ }
+
+ public String getDeviceOwner() {
+ return deviceOwner;
+ }
+
+ public void setDeviceOwner(String deviceOwner) {
+ this.deviceOwner = deviceOwner;
+ }
+
+ public String getTenantID() {
+ return tenantID;
+ }
+
+ public void setTenantID(String tenantID) {
+ this.tenantID = tenantID;
+ }
+
+ public NeutronFloatingIP getFloatingIP(String key) {
+ if (!floatingIPMap.containsKey(key)) {
+ return null;
+ }
+ return floatingIPMap.get(key);
+ }
+
+ public void removeFloatingIP(String key) {
+ floatingIPMap.remove(key);
+ }
+
+ public void addFloatingIP(String key, NeutronFloatingIP floatingIP) {
+ if (!floatingIPMap.containsKey(key)) {
+ floatingIPMap.put(key, floatingIP);
+ }
+ }
+
+ /**
+ * This method copies selected fields from the object and returns them
+ * as a new object, suitable for marshaling.
+ *
+ * @param fields
+ * List of attributes to be extracted
+ * @return an OpenStackPorts object with only the selected fields
+ * populated
+ */
+
+ public NeutronPort extractFields(List<String> fields) {
+ NeutronPort ans = new NeutronPort();
+ Iterator<String> i = fields.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (s.equals("id")) {
+ ans.setPortUUID(this.getPortUUID());
+ }
+ if (s.equals("network_id")) {
+ ans.setNetworkUUID(this.getNetworkUUID());
+ }
+ if (s.equals("name")) {
+ ans.setName(this.getName());
+ }
+ if (s.equals("admin_state_up")) {
+ ans.setAdminStateUp(this.getAdminStateUp());
+ }
+ if (s.equals("status")) {
+ ans.setStatus(this.getStatus());
+ }
+ if (s.equals("mac_address")) {
+ ans.setMacAddress(this.getMacAddress());
+ }
+ if (s.equals("fixed_ips")) {
+ List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();
+ fixedIPs.addAll(this.getFixedIPs());
+ ans.setFixedIPs(fixedIPs);
+ }
+ if (s.equals("device_id")) {
+ ans.setDeviceID(this.getDeviceID());
+ }
+ if (s.equals("device_owner")) {
+ ans.setDeviceOwner(this.getDeviceOwner());
+ }
+ if (s.equals("tenant_id")) {
+ ans.setTenantID(this.getTenantID());
+ }
+ }
+ return ans;
+ }
+
+ public void initDefaults() {
+ adminStateUp = true;
+ if (status == null) {
+ status = "ACTIVE";
+ }
+ if (fixedIPs == null) {
+ fixedIPs = new ArrayList<Neutron_IPs>();
+ }
+ }
+
+ /**
+ * This method checks to see if the port has a floating IPv4 address
+ * associated with the supplied fixed IPv4 address
+ *
+ * @param fixedIP
+ * fixed IPv4 address in dotted decimal format
+ * @return a boolean indicating if there is a floating IPv4 address bound
+ * to the fixed IPv4 address
+ */
+
+ public boolean isBoundToFloatingIP(String fixedIP) {
+ return floatingIPMap.containsKey(fixedIP);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouter {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
- @XmlElement (name="id")\r
- String routerUUID;\r
-\r
- @XmlElement (name="name")\r
- String name;\r
-\r
- @XmlElement (defaultValue="true", name="admin_state_up")\r
- Boolean adminStateUp;\r
-\r
- @XmlElement (name="status")\r
- String status;\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantID;\r
-\r
- @XmlElement (name="external_gateway_info")\r
- NeutronRouter_NetworkReference externalGatewayInfo;\r
-\r
- /* Holds a map of OpenStackRouterInterfaces by subnet UUID\r
- * used for internal mapping to DOVE\r
- */\r
- HashMap<String, NeutronRouter_Interface> interfaces;\r
-\r
- public NeutronRouter() {\r
- interfaces = new HashMap<String, NeutronRouter_Interface>();\r
- }\r
-\r
- public String getID() { return routerUUID; }\r
-\r
- public String getRouterUUID() {\r
- return routerUUID;\r
- }\r
-\r
- public void setRouterUUID(String routerUUID) {\r
- this.routerUUID = routerUUID;\r
- }\r
-\r
- public String getName() {\r
- return name;\r
- }\r
-\r
- public void setName(String name) {\r
- this.name = name;\r
- }\r
-\r
- public boolean isAdminStateUp() {\r
- if (adminStateUp == null)\r
- return true;\r
- return adminStateUp;\r
- }\r
-\r
- public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
- public void setAdminStateUp(Boolean newValue) {\r
- this.adminStateUp = newValue;\r
- }\r
-\r
- public String getStatus() {\r
- return status;\r
- }\r
-\r
- public void setStatus(String status) {\r
- this.status = status;\r
- }\r
-\r
- public String getTenantID() {\r
- return tenantID;\r
- }\r
-\r
- public void setTenantID(String tenantID) {\r
- this.tenantID = tenantID;\r
- }\r
-\r
- public NeutronRouter_NetworkReference getExternalGatewayInfo() {\r
- return externalGatewayInfo;\r
- }\r
-\r
- public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {\r
- this.externalGatewayInfo = externalGatewayInfo;\r
- }\r
-\r
- /**\r
- * This method copies selected fields from the object and returns them\r
- * as a new object, suitable for marshaling.\r
- *\r
- * @param fields\r
- * List of attributes to be extracted\r
- * @return an OpenStackRouters object with only the selected fields\r
- * populated\r
- */\r
-\r
- public NeutronRouter extractFields(List<String> fields) {\r
- NeutronRouter ans = new NeutronRouter();\r
- Iterator<String> i = fields.iterator();\r
- while (i.hasNext()) {\r
- String s = i.next();\r
- if (s.equals("id"))\r
- ans.setRouterUUID(this.getRouterUUID());\r
- if (s.equals("name"))\r
- ans.setName(this.getName());\r
- if (s.equals("admin_state_up"))\r
- ans.setAdminStateUp(this.getAdminStateUp());\r
- if (s.equals("status"))\r
- ans.setStatus(this.getStatus());\r
- if (s.equals("tenant_id"))\r
- ans.setTenantID(this.getTenantID());\r
- if (s.equals("external_gateway_info")) {\r
- ans.setExternalGatewayInfo(this.getExternalGatewayInfo());\r
- }\r
- }\r
- return ans;\r
- }\r
-\r
- public HashMap<String, NeutronRouter_Interface> getInterfaces() {\r
- return interfaces;\r
- }\r
-\r
- public void addInterface(String s, NeutronRouter_Interface i) {\r
- interfaces.put(s, i);\r
- }\r
-\r
- public void removeInterface(String s) {\r
- interfaces.remove(s);\r
- }\r
-\r
- public void initDefaults() {\r
- adminStateUp = true;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+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;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+ @XmlElement (name="id")
+ String routerUUID;
+
+ @XmlElement (name="name")
+ String name;
+
+ @XmlElement (defaultValue="true", name="admin_state_up")
+ Boolean adminStateUp;
+
+ @XmlElement (name="status")
+ String status;
+
+ @XmlElement (name="tenant_id")
+ String tenantID;
+
+ @XmlElement (name="external_gateway_info")
+ NeutronRouter_NetworkReference externalGatewayInfo;
+
+ /* Holds a map of OpenStackRouterInterfaces by subnet UUID
+ * used for internal mapping to DOVE
+ */
+ HashMap<String, NeutronRouter_Interface> interfaces;
+
+ public NeutronRouter() {
+ interfaces = new HashMap<String, NeutronRouter_Interface>();
+ }
+
+ public String getID() { return routerUUID; }
+
+ public String getRouterUUID() {
+ return routerUUID;
+ }
+
+ public void setRouterUUID(String routerUUID) {
+ this.routerUUID = routerUUID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isAdminStateUp() {
+ if (adminStateUp == null) {
+ return true;
+ }
+ return adminStateUp;
+ }
+
+ public Boolean getAdminStateUp() { return adminStateUp; }
+
+ public void setAdminStateUp(Boolean newValue) {
+ adminStateUp = newValue;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getTenantID() {
+ return tenantID;
+ }
+
+ public void setTenantID(String tenantID) {
+ this.tenantID = tenantID;
+ }
+
+ public NeutronRouter_NetworkReference getExternalGatewayInfo() {
+ return externalGatewayInfo;
+ }
+
+ public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {
+ this.externalGatewayInfo = externalGatewayInfo;
+ }
+
+ /**
+ * This method copies selected fields from the object and returns them
+ * as a new object, suitable for marshaling.
+ *
+ * @param fields
+ * List of attributes to be extracted
+ * @return an OpenStackRouters object with only the selected fields
+ * populated
+ */
+
+ public NeutronRouter extractFields(List<String> fields) {
+ NeutronRouter ans = new NeutronRouter();
+ Iterator<String> i = fields.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (s.equals("id")) {
+ ans.setRouterUUID(this.getRouterUUID());
+ }
+ if (s.equals("name")) {
+ ans.setName(this.getName());
+ }
+ if (s.equals("admin_state_up")) {
+ ans.setAdminStateUp(this.getAdminStateUp());
+ }
+ if (s.equals("status")) {
+ ans.setStatus(this.getStatus());
+ }
+ if (s.equals("tenant_id")) {
+ ans.setTenantID(this.getTenantID());
+ }
+ if (s.equals("external_gateway_info")) {
+ ans.setExternalGatewayInfo(this.getExternalGatewayInfo());
+ }
+ }
+ return ans;
+ }
+
+ public HashMap<String, NeutronRouter_Interface> getInterfaces() {
+ return interfaces;
+ }
+
+ public void addInterface(String s, NeutronRouter_Interface i) {
+ interfaces.put(s, i);
+ }
+
+ public void removeInterface(String s) {
+ interfaces.remove(s);
+ }
+
+ public void initDefaults() {
+ adminStateUp = true;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronRouter_Interface {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement (name="subnet_id")\r
- String subnetUUID;\r
-\r
- @XmlElement (name="port_id")\r
- String portUUID;\r
-\r
- @XmlElement (name="id")\r
- String id;\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantID;\r
-\r
- public NeutronRouter_Interface() {\r
- }\r
-\r
- public NeutronRouter_Interface(String subnetUUID, String portUUID) {\r
- this.subnetUUID = subnetUUID;\r
- this.portUUID = portUUID;\r
- }\r
-\r
- public String getSubnetUUID() {\r
- return subnetUUID;\r
- }\r
-\r
- public void setSubnetUUID(String subnetUUID) {\r
- this.subnetUUID = subnetUUID;\r
- }\r
-\r
- public String getPortUUID() {\r
- return portUUID;\r
- }\r
-\r
- public void setPortUUID(String portUUID) {\r
- this.portUUID = portUUID;\r
- }\r
-\r
- public void setID(String id) {\r
- this.id = id;\r
- }\r
-\r
- public void setTenantID(String tenantID) {\r
- this.tenantID = tenantID;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronRouter_Interface {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement (name="subnet_id")
+ String subnetUUID;
+
+ @XmlElement (name="port_id")
+ String portUUID;
+
+ @XmlElement (name="id")
+ String id;
+
+ @XmlElement (name="tenant_id")
+ String tenantID;
+
+ public NeutronRouter_Interface() {
+ }
+
+ public NeutronRouter_Interface(String subnetUUID, String portUUID) {
+ this.subnetUUID = subnetUUID;
+ this.portUUID = portUUID;
+ }
+
+ public String getSubnetUUID() {
+ return subnetUUID;
+ }
+
+ public void setSubnetUUID(String subnetUUID) {
+ this.subnetUUID = subnetUUID;
+ }
+
+ public String getPortUUID() {
+ return portUUID;
+ }
+
+ public void setPortUUID(String portUUID) {
+ this.portUUID = portUUID;
+ }
+
+ public void setID(String id) {
+ this.id = id;
+ }
+
+ public void setTenantID(String tenantID) {
+ this.tenantID = tenantID;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouter_NetworkReference {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="network_id")\r
- String networkID;\r
-\r
- public NeutronRouter_NetworkReference() {\r
- }\r
-\r
- public String getNetworkID() {\r
- return networkID;\r
- }\r
-\r
- public void setNetworkID(String networkID) {\r
- this.networkID = networkID;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter_NetworkReference {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="network_id")
+ String networkID;
+
+ public NeutronRouter_NetworkReference() {
+ }
+
+ public String getNetworkID() {
+ return networkID;
+ }
+
+ public void setNetworkID(String networkID) {
+ this.networkID = networkID;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.apache.commons.net.util.SubnetUtils;\r
-import org.apache.commons.net.util.SubnetUtils.SubnetInfo;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronSubnet {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement (name="id")\r
- String subnetUUID;\r
-\r
- @XmlElement (name="network_id")\r
- String networkUUID;\r
-\r
- @XmlElement (name="name")\r
- String name;\r
-\r
- @XmlElement (defaultValue="4", name="ip_version")\r
- Integer ipVersion;\r
-\r
- @XmlElement (name="cidr")\r
- String cidr;\r
-\r
- @XmlElement (name="gateway_ip")\r
- String gatewayIP;\r
-\r
- @XmlElement (name="dns_nameservers")\r
- List<String> dnsNameservers;\r
-\r
- @XmlElement (name="allocation_pools")\r
- List<NeutronSubnet_IPAllocationPool> allocationPools;\r
-\r
- @XmlElement (name="host_routes")\r
- List<NeutronSubnet_HostRoute> hostRoutes;\r
-\r
- @XmlElement (defaultValue="true", name="enable_dhcp")\r
- Boolean enableDHCP;\r
-\r
- @XmlElement (name="tenant_id")\r
- String tenantID;\r
-\r
- /* stores the OpenStackPorts associated with an instance\r
- * used to determine if that instance can be deleted.\r
- */\r
- List<NeutronPort> myPorts;\r
-\r
- boolean gatewayIPAssigned;\r
-\r
- public NeutronSubnet() {\r
- myPorts = new ArrayList<NeutronPort>();\r
- }\r
-\r
- public String getID() { return subnetUUID; }\r
-\r
- public String getSubnetUUID() {\r
- return subnetUUID;\r
- }\r
-\r
- public void setSubnetUUID(String subnetUUID) {\r
- this.subnetUUID = subnetUUID;\r
- }\r
-\r
- public String getNetworkUUID() {\r
- return networkUUID;\r
- }\r
-\r
- public void setNetworkUUID(String networkUUID) {\r
- this.networkUUID = networkUUID;\r
- }\r
-\r
- public String getName() {\r
- return name;\r
- }\r
-\r
- public void setName(String name) {\r
- this.name = name;\r
- }\r
-\r
- public Integer getIpVersion() {\r
- return ipVersion;\r
- }\r
-\r
- public void setIpVersion(Integer ipVersion) {\r
- this.ipVersion = ipVersion;\r
- }\r
-\r
- public String getCidr() {\r
- return cidr;\r
- }\r
-\r
- public void setCidr(String cidr) {\r
- this.cidr = cidr;\r
- }\r
-\r
- public String getGatewayIP() {\r
- return gatewayIP;\r
- }\r
-\r
- public void setGatewayIP(String gatewayIP) {\r
- this.gatewayIP = gatewayIP;\r
- }\r
-\r
- public List<String> getDnsNameservers() {\r
- return dnsNameservers;\r
- }\r
-\r
- public void setDnsNameservers(List<String> dnsNameservers) {\r
- this.dnsNameservers = dnsNameservers;\r
- }\r
-\r
- public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {\r
- return allocationPools;\r
- }\r
-\r
- public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {\r
- this.allocationPools = allocationPools;\r
- }\r
-\r
- public List<NeutronSubnet_HostRoute> getHostRoutes() {\r
- return hostRoutes;\r
- }\r
-\r
- public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {\r
- this.hostRoutes = hostRoutes;\r
- }\r
-\r
- public boolean isEnableDHCP() {\r
- if (enableDHCP == null) {\r
- return true;\r
- }\r
- return enableDHCP;\r
- }\r
-\r
- public Boolean getEnableDHCP() { return enableDHCP; }\r
-\r
- public void setEnableDHCP(Boolean newValue) {\r
- enableDHCP = newValue;\r
- }\r
-\r
- public String getTenantID() {\r
- return tenantID;\r
- }\r
-\r
- public void setTenantID(String tenantID) {\r
- this.tenantID = tenantID;\r
- }\r
-\r
- /**\r
- * This method copies selected fields from the object and returns them\r
- * as a new object, suitable for marshaling.\r
- *\r
- * @param fields\r
- * List of attributes to be extracted\r
- * @return an OpenStackSubnets object with only the selected fields\r
- * populated\r
- */\r
-\r
- public NeutronSubnet extractFields(List<String> fields) {\r
- NeutronSubnet ans = new NeutronSubnet();\r
- Iterator<String> i = fields.iterator();\r
- while (i.hasNext()) {\r
- String s = i.next();\r
- if (s.equals("id")) {\r
- ans.setSubnetUUID(this.getSubnetUUID());\r
- }\r
- if (s.equals("network_id")) {\r
- ans.setNetworkUUID(this.getNetworkUUID());\r
- }\r
- if (s.equals("name")) {\r
- ans.setName(this.getName());\r
- }\r
- if (s.equals("ip_version")) {\r
- ans.setIpVersion(this.getIpVersion());\r
- }\r
- if (s.equals("cidr")) {\r
- ans.setCidr(this.getCidr());\r
- }\r
- if (s.equals("gateway_ip")) {\r
- ans.setGatewayIP(this.getGatewayIP());\r
- }\r
- if (s.equals("dns_nameservers")) {\r
- List<String> nsList = new ArrayList<String>();\r
- nsList.addAll(this.getDnsNameservers());\r
- ans.setDnsNameservers(nsList);\r
- }\r
- if (s.equals("allocation_pools")) {\r
- List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
- aPools.addAll(this.getAllocationPools());\r
- ans.setAllocationPools(aPools);\r
- }\r
- if (s.equals("host_routes")) {\r
- List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
- hRoutes.addAll(this.getHostRoutes());\r
- ans.setHostRoutes(hRoutes);\r
- }\r
- if (s.equals("enable_dhcp")) {\r
- ans.setEnableDHCP(this.getEnableDHCP());\r
- }\r
- if (s.equals("tenant_id")) {\r
- ans.setTenantID(this.getTenantID());\r
- }\r
- }\r
- return ans;\r
- }\r
-\r
- /* test to see if the cidr address used to define this subnet\r
- * is a valid network address (an necessary condition when creating\r
- * a new subnet)\r
- */\r
- public boolean isValidCIDR() {\r
- try {\r
- SubnetUtils util = new SubnetUtils(cidr);\r
- SubnetInfo info = util.getInfo();\r
- if (!info.getNetworkAddress().equals(info.getAddress())) {\r
- return false;\r
- }\r
- } catch (Exception e) {\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- /* test to see if the gateway IP specified overlaps with specified\r
- * allocation pools (an error condition when creating a new subnet\r
- * or assigning a gateway IP)\r
- */\r
- public boolean gatewayIP_Pool_overlap() {\r
- Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
- while (i.hasNext()) {\r
- NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(gatewayIP)) {\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
-\r
- public boolean initDefaults() {\r
- if (enableDHCP == null) {\r
- enableDHCP = true;\r
- }\r
- if (ipVersion == null) {\r
- ipVersion = 4;\r
- }\r
- gatewayIPAssigned = false;\r
- dnsNameservers = new ArrayList<String>();\r
- allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
- hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
- try {\r
- SubnetUtils util = new SubnetUtils(cidr);\r
- SubnetInfo info = util.getInfo();\r
- if (gatewayIP == null) {\r
- gatewayIP = info.getLowAddress();\r
- }\r
- if (allocationPools.size() < 1) {\r
- NeutronSubnet_IPAllocationPool source =\r
- new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
- info.getHighAddress());\r
- allocationPools = source.splitPool(gatewayIP);\r
- }\r
- } catch (Exception e) {\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- public List<NeutronPort> getPortsInSubnet() {\r
- return myPorts;\r
- }\r
-\r
- public void addPort(NeutronPort port) {\r
- myPorts.add(port);\r
- }\r
-\r
- public void removePort(NeutronPort port) {\r
- myPorts.remove(port);\r
- }\r
-\r
- /* this method tests to see if the supplied IPv4 address\r
- * is valid for this subnet or not\r
- */\r
- public boolean isValidIP(String ipAddress) {\r
- try {\r
- SubnetUtils util = new SubnetUtils(cidr);\r
- SubnetInfo info = util.getInfo();\r
- return info.isInRange(ipAddress);\r
- } catch (Exception e) {\r
- return false;\r
- }\r
- }\r
-\r
- /* test to see if the supplied IPv4 address is part of one of the\r
- * available allocation pools or not\r
- */\r
- public boolean isIPInUse(String ipAddress) {\r
- if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {\r
- return false;\r
- }\r
- Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
- while (i.hasNext()) {\r
- NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (pool.contains(ipAddress)) {\r
- return false;\r
- }\r
- }\r
- return true;\r
- }\r
-\r
- /* method to get the lowest available address of the subnet.\r
- * go through all the allocation pools and keep the lowest of their\r
- * low addresses.\r
- */\r
- public String getLowAddr() {\r
- String ans = null;\r
- Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
- while (i.hasNext()) {\r
- NeutronSubnet_IPAllocationPool pool = i.next();\r
- if (ans == null) {\r
- ans = pool.getPoolStart();\r
- }\r
- else\r
- if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
- NeutronSubnet_IPAllocationPool.convert(ans)) {\r
- ans = pool.getPoolStart();\r
- }\r
- }\r
- return ans;\r
- }\r
-\r
- /*\r
- * allocate the parameter address. Because this uses an iterator to\r
- * check the instance's list of allocation pools and we want to modify\r
- * pools while the iterator is being used, it is necessary to\r
- * build a new list of allocation pools and replace the list when\r
- * finished (otherwise a split will cause undefined iterator behavior.\r
- */\r
- public void allocateIP(String ipAddress) {\r
- Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
- List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>(); // we have to modify a separate list\r
- while (i.hasNext()) {\r
- NeutronSubnet_IPAllocationPool pool = i.next();\r
- /* if the pool contains a single address element and we are allocating it\r
- * then we don't need to copy the pool over. Otherwise, we need to possibly\r
- * split the pool and add both pieces to the new list\r
- */\r
- if (!(pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&\r
- pool.getPoolStart().equalsIgnoreCase(ipAddress))) {\r
- if (pool.contains(ipAddress)) {\r
- List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
- newList.addAll(pools);\r
- } else {\r
- newList.add(pool);\r
- }\r
- }\r
- }\r
- allocationPools = newList;\r
- }\r
-\r
- /*\r
- * release an IP address back to the subnet. Although an iterator\r
- * is used, the list is not modified until the iterator is complete, so\r
- * an extra list is not necessary.\r
- */\r
- public void releaseIP(String ipAddress) {\r
- NeutronSubnet_IPAllocationPool lPool = null;\r
- NeutronSubnet_IPAllocationPool hPool = null;\r
- Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
- long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
- //look for lPool where ipAddr - 1 is high address\r
- //look for hPool where ipAddr + 1 is low address\r
- while (i.hasNext()) {\r
- NeutronSubnet_IPAllocationPool pool = i.next();\r
- long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
- long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
- if (sIP+1 == lIP) {\r
- hPool = pool;\r
- }\r
- if (sIP-1 == hIP) {\r
- lPool = pool;\r
- }\r
- }\r
- //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
- if (lPool == null && hPool == null) {\r
- allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
- }\r
- //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
- if (lPool == null && hPool != null) {\r
- hPool.setPoolStart(ipAddress);\r
- }\r
- //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
- if (lPool != null && hPool == null) {\r
- lPool.setPoolEnd(ipAddress);\r
- }\r
- //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
- // where low address = lPool.low address and high address = hPool.high Address\r
- if (lPool != null && hPool != null) {\r
- allocationPools.remove(lPool);\r
- allocationPools.remove(hPool);\r
- allocationPools.add(new NeutronSubnet_IPAllocationPool(\r
- lPool.getPoolStart(), hPool.getPoolEnd()));\r
- }\r
- }\r
-\r
- public void setGatewayIPAllocated() {\r
- gatewayIPAssigned = true;\r
- }\r
-\r
- public void resetGatewayIPAllocated() {\r
- gatewayIPAssigned = false;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.ArrayList;
+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;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnet {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement (name="id")
+ String subnetUUID;
+
+ @XmlElement (name="network_id")
+ String networkUUID;
+
+ @XmlElement (name="name")
+ String name;
+
+ @XmlElement (defaultValue="4", name="ip_version")
+ Integer ipVersion;
+
+ @XmlElement (name="cidr")
+ String cidr;
+
+ @XmlElement (name="gateway_ip")
+ String gatewayIP;
+
+ @XmlElement (name="dns_nameservers")
+ List<String> dnsNameservers;
+
+ @XmlElement (name="allocation_pools")
+ List<NeutronSubnet_IPAllocationPool> allocationPools;
+
+ @XmlElement (name="host_routes")
+ List<NeutronSubnet_HostRoute> hostRoutes;
+
+ @XmlElement (defaultValue="true", name="enable_dhcp")
+ Boolean enableDHCP;
+
+ @XmlElement (name="tenant_id")
+ String tenantID;
+
+ /* stores the OpenStackPorts associated with an instance
+ * used to determine if that instance can be deleted.
+ */
+ List<NeutronPort> myPorts;
+
+ boolean gatewayIPAssigned;
+
+ public NeutronSubnet() {
+ myPorts = new ArrayList<NeutronPort>();
+ }
+
+ public String getID() { return subnetUUID; }
+
+ public String getSubnetUUID() {
+ return subnetUUID;
+ }
+
+ public void setSubnetUUID(String subnetUUID) {
+ this.subnetUUID = subnetUUID;
+ }
+
+ public String getNetworkUUID() {
+ return networkUUID;
+ }
+
+ public void setNetworkUUID(String networkUUID) {
+ this.networkUUID = networkUUID;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getIpVersion() {
+ return ipVersion;
+ }
+
+ public void setIpVersion(Integer ipVersion) {
+ this.ipVersion = ipVersion;
+ }
+
+ public String getCidr() {
+ return cidr;
+ }
+
+ public void setCidr(String cidr) {
+ this.cidr = cidr;
+ }
+
+ public String getGatewayIP() {
+ return gatewayIP;
+ }
+
+ public void setGatewayIP(String gatewayIP) {
+ this.gatewayIP = gatewayIP;
+ }
+
+ public List<String> getDnsNameservers() {
+ return dnsNameservers;
+ }
+
+ public void setDnsNameservers(List<String> dnsNameservers) {
+ this.dnsNameservers = dnsNameservers;
+ }
+
+ public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {
+ return allocationPools;
+ }
+
+ public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {
+ this.allocationPools = allocationPools;
+ }
+
+ public List<NeutronSubnet_HostRoute> getHostRoutes() {
+ return hostRoutes;
+ }
+
+ public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {
+ this.hostRoutes = hostRoutes;
+ }
+
+ public boolean isEnableDHCP() {
+ if (enableDHCP == null) {
+ return true;
+ }
+ return enableDHCP;
+ }
+
+ public Boolean getEnableDHCP() { return enableDHCP; }
+
+ public void setEnableDHCP(Boolean newValue) {
+ enableDHCP = newValue;
+ }
+
+ public String getTenantID() {
+ return tenantID;
+ }
+
+ public void setTenantID(String tenantID) {
+ this.tenantID = tenantID;
+ }
+
+ /**
+ * This method copies selected fields from the object and returns them
+ * as a new object, suitable for marshaling.
+ *
+ * @param fields
+ * List of attributes to be extracted
+ * @return an OpenStackSubnets object with only the selected fields
+ * populated
+ */
+
+ public NeutronSubnet extractFields(List<String> fields) {
+ NeutronSubnet ans = new NeutronSubnet();
+ Iterator<String> i = fields.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (s.equals("id")) {
+ ans.setSubnetUUID(this.getSubnetUUID());
+ }
+ if (s.equals("network_id")) {
+ ans.setNetworkUUID(this.getNetworkUUID());
+ }
+ if (s.equals("name")) {
+ ans.setName(this.getName());
+ }
+ if (s.equals("ip_version")) {
+ ans.setIpVersion(this.getIpVersion());
+ }
+ if (s.equals("cidr")) {
+ ans.setCidr(this.getCidr());
+ }
+ if (s.equals("gateway_ip")) {
+ ans.setGatewayIP(this.getGatewayIP());
+ }
+ if (s.equals("dns_nameservers")) {
+ List<String> nsList = new ArrayList<String>();
+ nsList.addAll(this.getDnsNameservers());
+ ans.setDnsNameservers(nsList);
+ }
+ if (s.equals("allocation_pools")) {
+ List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
+ aPools.addAll(this.getAllocationPools());
+ ans.setAllocationPools(aPools);
+ }
+ if (s.equals("host_routes")) {
+ List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+ hRoutes.addAll(this.getHostRoutes());
+ ans.setHostRoutes(hRoutes);
+ }
+ if (s.equals("enable_dhcp")) {
+ ans.setEnableDHCP(this.getEnableDHCP());
+ }
+ if (s.equals("tenant_id")) {
+ ans.setTenantID(this.getTenantID());
+ }
+ }
+ return ans;
+ }
+
+ /* test to see if the cidr address used to define this subnet
+ * is a valid network address (an necessary condition when creating
+ * a new subnet)
+ */
+ public boolean isValidCIDR() {
+ try {
+ SubnetUtils util = new SubnetUtils(cidr);
+ SubnetInfo info = util.getInfo();
+ if (!info.getNetworkAddress().equals(info.getAddress())) {
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ /* test to see if the gateway IP specified overlaps with specified
+ * allocation pools (an error condition when creating a new subnet
+ * or assigning a gateway IP)
+ */
+ public boolean gatewayIP_Pool_overlap() {
+ Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ if (pool.contains(gatewayIP)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean initDefaults() {
+ if (enableDHCP == null) {
+ enableDHCP = true;
+ }
+ if (ipVersion == null) {
+ ipVersion = 4;
+ }
+ gatewayIPAssigned = false;
+ dnsNameservers = new ArrayList<String>();
+ allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
+ hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+ try {
+ SubnetUtils util = new SubnetUtils(cidr);
+ SubnetInfo info = util.getInfo();
+ if (gatewayIP == null) {
+ gatewayIP = info.getLowAddress();
+ }
+ if (allocationPools.size() < 1) {
+ NeutronSubnet_IPAllocationPool source =
+ new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
+ info.getHighAddress());
+ allocationPools = source.splitPool(gatewayIP);
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ public List<NeutronPort> getPortsInSubnet() {
+ return myPorts;
+ }
+
+ public void addPort(NeutronPort port) {
+ myPorts.add(port);
+ }
+
+ public void removePort(NeutronPort port) {
+ myPorts.remove(port);
+ }
+
+ /* this method tests to see if the supplied IPv4 address
+ * is valid for this subnet or not
+ */
+ public boolean isValidIP(String ipAddress) {
+ try {
+ SubnetUtils util = new SubnetUtils(cidr);
+ SubnetInfo info = util.getInfo();
+ return info.isInRange(ipAddress);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /* test to see if the supplied IPv4 address is part of one of the
+ * available allocation pools or not
+ */
+ public boolean isIPInUse(String ipAddress) {
+ if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {
+ return false;
+ }
+ Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ if (pool.contains(ipAddress)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /* method to get the lowest available address of the subnet.
+ * go through all the allocation pools and keep the lowest of their
+ * low addresses.
+ */
+ public String getLowAddr() {
+ String ans = null;
+ Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ if (ans == null) {
+ ans = pool.getPoolStart();
+ }
+ else
+ if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <
+ NeutronSubnet_IPAllocationPool.convert(ans)) {
+ ans = pool.getPoolStart();
+ }
+ }
+ return ans;
+ }
+
+ /*
+ * allocate the parameter address. Because this uses an iterator to
+ * check the instance's list of allocation pools and we want to modify
+ * pools while the iterator is being used, it is necessary to
+ * build a new list of allocation pools and replace the list when
+ * finished (otherwise a split will cause undefined iterator behavior.
+ */
+ public void allocateIP(String ipAddress) {
+ Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+ List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>(); // we have to modify a separate list
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ /* if the pool contains a single address element and we are allocating it
+ * then we don't need to copy the pool over. Otherwise, we need to possibly
+ * split the pool and add both pieces to the new list
+ */
+ if (!(pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&
+ pool.getPoolStart().equalsIgnoreCase(ipAddress))) {
+ if (pool.contains(ipAddress)) {
+ List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);
+ newList.addAll(pools);
+ } else {
+ newList.add(pool);
+ }
+ }
+ }
+ allocationPools = newList;
+ }
+
+ /*
+ * release an IP address back to the subnet. Although an iterator
+ * is used, the list is not modified until the iterator is complete, so
+ * an extra list is not necessary.
+ */
+ public void releaseIP(String ipAddress) {
+ NeutronSubnet_IPAllocationPool lPool = null;
+ NeutronSubnet_IPAllocationPool hPool = null;
+ Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+ long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
+ //look for lPool where ipAddr - 1 is high address
+ //look for hPool where ipAddr + 1 is low address
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());
+ long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());
+ if (sIP+1 == lIP) {
+ hPool = pool;
+ }
+ if (sIP-1 == hIP) {
+ lPool = pool;
+ }
+ }
+ //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high
+ if (lPool == null && hPool == null) {
+ allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));
+ }
+ //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr
+ if (lPool == null && hPool != null) {
+ hPool.setPoolStart(ipAddress);
+ }
+ //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr
+ if (lPool != null && hPool == null) {
+ lPool.setPoolEnd(ipAddress);
+ }
+ //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool
+ // where low address = lPool.low address and high address = hPool.high Address
+ if (lPool != null && hPool != null) {
+ allocationPools.remove(lPool);
+ allocationPools.remove(hPool);
+ allocationPools.add(new NeutronSubnet_IPAllocationPool(
+ lPool.getPoolStart(), hPool.getPoolEnd()));
+ }
+ }
+
+ public void setGatewayIPAllocated() {
+ gatewayIPAssigned = true;
+ }
+
+ public void resetGatewayIPAllocated() {
+ gatewayIPAssigned = false;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronSubnet_HostRoute {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="destination")\r
- String destination;\r
-\r
- @XmlElement(name="nexthop")\r
- String nextHop;\r
-\r
- public NeutronSubnet_HostRoute() { }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnet_HostRoute {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="destination")
+ String destination;
+
+ @XmlElement(name="nexthop")
+ String nextHop;
+
+ public NeutronSubnet_HostRoute() { }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronSubnet_IPAllocationPool {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="start")\r
- String poolStart;\r
-\r
- @XmlElement(name="end")\r
- String poolEnd;\r
-\r
- public NeutronSubnet_IPAllocationPool() { }\r
-\r
- public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {\r
- poolStart = lowAddress;\r
- poolEnd = highAddress;\r
- }\r
-\r
- public String getPoolStart() {\r
- return poolStart;\r
- }\r
-\r
- public void setPoolStart(String poolStart) {\r
- this.poolStart = poolStart;\r
- }\r
-\r
- public String getPoolEnd() {\r
- return poolEnd;\r
- }\r
-\r
- public void setPoolEnd(String poolEnd) {\r
- this.poolEnd = poolEnd;\r
- }\r
-\r
- /**\r
- * This method determines if this allocation pool contains the\r
- * input IPv4 address\r
- *\r
- * @param inputString\r
- * IPv4 address in dotted decimal format\r
- * @returns a boolean on whether the pool contains the address or not\r
- */\r
-\r
- public boolean contains(String inputString) {\r
- long inputIP = convert(inputString);\r
- long startIP = convert(poolStart);\r
- long endIP = convert(poolEnd);\r
- return (inputIP >= startIP && inputIP <= endIP);\r
- }\r
-\r
- /**\r
- * This static method converts the supplied IPv4 address to a long\r
- * integer for comparison\r
- *\r
- * @param inputString\r
- * IPv4 address in dotted decimal format\r
- * @returns high-endian representation of the IPv4 address as a long\r
- */\r
-\r
- static long convert(String inputString) {\r
- long ans = 0;\r
- String[] parts = inputString.split("\\.");\r
- for (String part: parts) {\r
- ans <<= 8;\r
- ans |= Integer.parseInt(part);\r
- }\r
- return ans;\r
- }\r
-\r
- /**\r
- * This static method converts the supplied high-ending long back\r
- * into a dotted decimal representation of an IPv4 address\r
- *\r
- * @param l\r
- * high-endian representation of the IPv4 address as a long\r
- * @returns IPv4 address in dotted decimal format\r
- */\r
- static String longtoIP(long l) {\r
- int i;\r
- String[] parts = new String[4];\r
- for (i=0; i<4; i++) {\r
- parts[3-i] = String.valueOf(l & 255);\r
- l >>= 8;\r
- }\r
- return join(parts,".");\r
- }\r
-\r
- /*\r
- * helper routine used by longtoIP\r
- */\r
- public static String join(String r[],String d)\r
- {\r
- if (r.length == 0) return "";\r
- StringBuilder sb = new StringBuilder();\r
- int i;\r
- for(i=0;i<r.length-1;i++) {\r
- sb.append(r[i]+d);\r
- }\r
- return sb.toString()+r[i];\r
- }\r
-\r
- /*\r
- * This method splits the current instance by removing the supplied\r
- * parameter.\r
- *\r
- * If the parameter is either the low or high address,\r
- * then that member is adjusted and a list containing just this instance\r
- * is returned.\r
- *\r
- * If the parameter is in the middle of the pool, then\r
- * create two new instances, one ranging from low to parameter-1\r
- * the other ranging from parameter+1 to high\r
- */\r
- public List<NeutronSubnet_IPAllocationPool> splitPool(String ipAddress) {\r
- List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
- long gIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
- long sIP = NeutronSubnet_IPAllocationPool.convert(poolStart);\r
- long eIP = NeutronSubnet_IPAllocationPool.convert(poolEnd);\r
- long i;\r
- NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();\r
- boolean poolStarted = false;\r
- for (i=sIP; i<=eIP; i++) {\r
- if (i == sIP) {\r
- if (i != gIP) {\r
- p.setPoolStart(poolStart);\r
- poolStarted = true;\r
- }\r
- }\r
- if (i == eIP) {\r
- if (i != gIP) {\r
- p.setPoolEnd(poolEnd);\r
- } else {\r
- p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
- }\r
- ans.add(p);\r
- }\r
- if (i != sIP && i != eIP) {\r
- if (i != gIP) {\r
- if (!poolStarted) {\r
- p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));\r
- poolStarted = true;\r
- }\r
- } else {\r
- p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
- poolStarted = false;\r
- ans.add(p);\r
- p = new NeutronSubnet_IPAllocationPool();\r
- }\r
- }\r
- }\r
- return ans;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnet_IPAllocationPool {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="start")
+ String poolStart;
+
+ @XmlElement(name="end")
+ String poolEnd;
+
+ public NeutronSubnet_IPAllocationPool() { }
+
+ public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {
+ poolStart = lowAddress;
+ poolEnd = highAddress;
+ }
+
+ public String getPoolStart() {
+ return poolStart;
+ }
+
+ public void setPoolStart(String poolStart) {
+ this.poolStart = poolStart;
+ }
+
+ public String getPoolEnd() {
+ return poolEnd;
+ }
+
+ public void setPoolEnd(String poolEnd) {
+ this.poolEnd = poolEnd;
+ }
+
+ /**
+ * This method determines if this allocation pool contains the
+ * input IPv4 address
+ *
+ * @param inputString
+ * IPv4 address in dotted decimal format
+ * @returns a boolean on whether the pool contains the address or not
+ */
+
+ public boolean contains(String inputString) {
+ long inputIP = convert(inputString);
+ long startIP = convert(poolStart);
+ long endIP = convert(poolEnd);
+ return (inputIP >= startIP && inputIP <= endIP);
+ }
+
+ /**
+ * This static method converts the supplied IPv4 address to a long
+ * integer for comparison
+ *
+ * @param inputString
+ * IPv4 address in dotted decimal format
+ * @returns high-endian representation of the IPv4 address as a long
+ */
+
+ static long convert(String inputString) {
+ long ans = 0;
+ String[] parts = inputString.split("\\.");
+ for (String part: parts) {
+ ans <<= 8;
+ ans |= Integer.parseInt(part);
+ }
+ return ans;
+ }
+
+ /**
+ * This static method converts the supplied high-ending long back
+ * into a dotted decimal representation of an IPv4 address
+ *
+ * @param l
+ * high-endian representation of the IPv4 address as a long
+ * @returns IPv4 address in dotted decimal format
+ */
+ static String longtoIP(long l) {
+ int i;
+ String[] parts = new String[4];
+ for (i=0; i<4; i++) {
+ parts[3-i] = String.valueOf(l & 255);
+ l >>= 8;
+ }
+ return join(parts,".");
+ }
+
+ /*
+ * helper routine used by longtoIP
+ */
+ public static String join(String r[],String d)
+ {
+ if (r.length == 0) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ int i;
+ for(i=0;i<r.length-1;i++) {
+ sb.append(r[i]+d);
+ }
+ return sb.toString()+r[i];
+ }
+
+ /*
+ * This method splits the current instance by removing the supplied
+ * parameter.
+ *
+ * If the parameter is either the low or high address,
+ * then that member is adjusted and a list containing just this instance
+ * is returned.
+ *
+ * If the parameter is in the middle of the pool, then
+ * create two new instances, one ranging from low to parameter-1
+ * the other ranging from parameter+1 to high
+ */
+ public List<NeutronSubnet_IPAllocationPool> splitPool(String ipAddress) {
+ List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();
+ long gIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
+ long sIP = NeutronSubnet_IPAllocationPool.convert(poolStart);
+ long eIP = NeutronSubnet_IPAllocationPool.convert(poolEnd);
+ long i;
+ NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();
+ boolean poolStarted = false;
+ for (i=sIP; i<=eIP; i++) {
+ if (i == sIP) {
+ if (i != gIP) {
+ p.setPoolStart(poolStart);
+ poolStarted = true;
+ }
+ }
+ if (i == eIP) {
+ if (i != gIP) {
+ p.setPoolEnd(poolEnd);
+ } else {
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+ }
+ ans.add(p);
+ }
+ if (i != sIP && i != eIP) {
+ if (i != gIP) {
+ if (!poolStarted) {
+ p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));
+ poolStarted = true;
+ }
+ } else {
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+ poolStarted = false;
+ ans.add(p);
+ p = new NeutronSubnet_IPAllocationPool();
+ }
+ }
+ }
+ return ans;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class Neutron_IPs {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="ip_address")\r
- String ipAddress;\r
-\r
- @XmlElement(name="subnet_id")\r
- String subnetUUID;\r
-\r
- public Neutron_IPs() { }\r
-\r
- public Neutron_IPs(String uuid) {\r
- this.subnetUUID = uuid;\r
- }\r
-\r
- public String getIpAddress() {\r
- return ipAddress;\r
- }\r
-\r
- public void setIpAddress(String ipAddress) {\r
- this.ipAddress = ipAddress;\r
- }\r
-\r
- public String getSubnetUUID() {\r
- return subnetUUID;\r
- }\r
-\r
- public void setSubnetUUID(String subnetUUID) {\r
- this.subnetUUID = subnetUUID;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Neutron_IPs {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="ip_address")
+ String ipAddress;
+
+ @XmlElement(name="subnet_id")
+ String subnetUUID;
+
+ public Neutron_IPs() { }
+
+ public Neutron_IPs(String uuid) {
+ subnetUUID = uuid;
+ }
+
+ public String getIpAddress() {
+ return ipAddress;
+ }
+
+ public void setIpAddress(String ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ public String getSubnetUUID() {
+ return subnetUUID;
+ }
+
+ public void setSubnetUUID(String subnetUUID) {
+ this.subnetUUID = subnetUUID;
+ }
+}
JSONTokener jt = new JSONTokener(result);
JSONObject json = new JSONObject(jt);
JSONArray subnetConfigs = json.getJSONArray("subnetConfig");
- Assert.assertEquals(subnetConfigs.length(), 0);
+ Assert.assertEquals(subnetConfigs.length(), 1); // should only get the default subnet
// Test GET subnet1 expecting 404
result = getJsonResult(baseURL + "default/subnet/" + name1);
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronFloatingIPRequest {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="floatingip")\r
- NeutronFloatingIP singletonFloatingIP;\r
-\r
- @XmlElement(name="floatingips")\r
- List<NeutronFloatingIP> bulkRequest;\r
-\r
- NeutronFloatingIPRequest() {\r
- }\r
-\r
- NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {\r
- bulkRequest = bulk;\r
- singletonFloatingIP = null;\r
- }\r
-\r
- NeutronFloatingIPRequest(NeutronFloatingIP singleton) {\r
- bulkRequest = null;\r
- singletonFloatingIP = singleton;\r
- }\r
-\r
- public NeutronFloatingIP getSingleton() {\r
- return singletonFloatingIP;\r
- }\r
-\r
- public boolean isSingleton() {\r
- return (singletonFloatingIP != null);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronFloatingIPRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="floatingip")
+ NeutronFloatingIP singletonFloatingIP;
+
+ @XmlElement(name="floatingips")
+ List<NeutronFloatingIP> bulkRequest;
+
+ NeutronFloatingIPRequest() {
+ }
+
+ NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {
+ bulkRequest = bulk;
+ singletonFloatingIP = null;
+ }
+
+ NeutronFloatingIPRequest(NeutronFloatingIP singleton) {
+ bulkRequest = null;
+ singletonFloatingIP = singleton;
+ }
+
+ public NeutronFloatingIP getSingleton() {
+ return singletonFloatingIP;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFloatingIP != null);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/floatingips")\r
-public class NeutronFloatingIPsNorthbound {\r
-\r
- private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {\r
- return o.extractFields(fields);\r
- }\r
-\r
- /**\r
- * Returns a list of all FloatingIPs */\r
-\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response listFloatingIPs(\r
- // return fields\r
- @QueryParam("fields") List<String> fields,\r
- // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
- @QueryParam("id") String queryID,\r
- @QueryParam("floating_network_id") String queryFloatingNetworkId,\r
- @QueryParam("port_id") String queryPortId,\r
- @QueryParam("fixed_ip_address") String queryFixedIPAddress,\r
- @QueryParam("floating_ip_address") String queryFloatingIPAddress,\r
- @QueryParam("tenant_id") String queryTenantID,\r
- // pagination\r
- @QueryParam("limit") String limit,\r
- @QueryParam("marker") String marker,\r
- @QueryParam("page_reverse") String pageReverse\r
- // sorting not supported\r
- ) {\r
- INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();\r
- List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
- Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();\r
- while (i.hasNext()) {\r
- NeutronFloatingIP oSS = i.next();\r
- //match filters: TODO provider extension and router extension\r
- if ((queryID == null || queryID.equals(oSS.getID())) &&\r
- (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&\r
- (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&\r
- (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&\r
- (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&\r
- (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {\r
- if (fields.size() > 0)\r
- ans.add(extractFields(oSS,fields));\r
- else\r
- ans.add(oSS);\r
- }\r
- }\r
- //TODO: apply pagination to results\r
- return Response.status(200).entity(\r
- new NeutronFloatingIPRequest(ans)).build();\r
- }\r
-\r
- /**\r
- * Returns a specific FloatingIP */\r
-\r
- @Path("{floatingipUUID}")\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response showFloatingIP(\r
- @PathParam("floatingipUUID") String floatingipUUID,\r
- // return fields\r
- @QueryParam("fields") List<String> fields ) {\r
- INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
- return Response.status(404).build();\r
- if (fields.size() > 0) {\r
- NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);\r
- return Response.status(200).entity(\r
- new NeutronFloatingIPRequest(extractFields(ans, fields))).build();\r
- } else\r
- return Response.status(200).entity(\r
- new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();\r
-\r
- }\r
-\r
- /**\r
- * Creates new FloatingIPs */\r
-\r
- @POST\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- @StatusCodes({\r
- @ResponseCode(code = 201, condition = "Created"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response createFloatingIPs(final NeutronFloatingIPRequest input) {\r
- INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (input.isSingleton()) {\r
- NeutronFloatingIP singleton = input.getSingleton();\r
- // check existence of id in cache and return badrequest if exists\r
- if (floatingIPInterface.floatingIPExists(singleton.getID()))\r
- return Response.status(400).build();\r
- // check if the external network is specified, exists, and is an external network\r
- String externalNetworkUUID = singleton.getFloatingNetworkUUID();\r
- if (externalNetworkUUID == null)\r
- return Response.status(400).build();\r
- if (!networkInterface.networkExists(externalNetworkUUID))\r
- return Response.status(400).build();\r
- NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);\r
- if (!externNetwork.isRouterExternal())\r
- return Response.status(400).build();\r
- // if floating IP is specified, make sure it can come from the network\r
- String floatingIP = singleton.getFloatingIPAddress();\r
- if (floatingIP != null) {\r
- if (externNetwork.getSubnets().size() > 1)\r
- return Response.status(400).build();\r
- NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
- if (!externSubnet.isValidIP(floatingIP))\r
- return Response.status(400).build();\r
- if (externSubnet.isIPInUse(floatingIP))\r
- return Response.status(409).build();\r
- }\r
- // if port_id is specified, then check that the port exists and has at least one IP\r
- String port_id = singleton.getPortUUID();\r
- if (port_id != null) {\r
- String fixedIP = null; // used for the fixedIP calculation\r
- if (!portInterface.portExists(port_id))\r
- return Response.status(404).build();\r
- NeutronPort port = portInterface.getPort(port_id);\r
- if (port.getFixedIPs().size() < 1)\r
- return Response.status(400).build();\r
- // if there is more than one fixed IP then check for fixed_ip_address\r
- // and that it is in the list of port addresses\r
- if (port.getFixedIPs().size() > 1) {\r
- fixedIP = singleton.getFixedIPAddress();\r
- if (fixedIP == null)\r
- return Response.status(400).build();\r
- Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
- boolean validFixedIP = false;\r
- while (i.hasNext() && !validFixedIP) {\r
- Neutron_IPs ip = i.next();\r
- if (ip.getIpAddress().equals(fixedIP))\r
- validFixedIP = true;\r
- }\r
- if (!validFixedIP)\r
- return Response.status(400).build();\r
- } else {\r
- fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
- if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
- return Response.status(400).build();\r
- }\r
- //lastly check that this fixed IP address isn't already used\r
- if (port.isBoundToFloatingIP(fixedIP))\r
- return Response.status(409).build();\r
- singleton.setFixedIPAddress(fixedIP);\r
- }\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- int status = service.canCreateFloatingIP(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- floatingIPInterface.addFloatingIP(singleton);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- service.neutronFloatingIPCreated(singleton);\r
- }\r
- }\r
- } else {\r
- return Response.status(400).build();\r
- }\r
- return Response.status(201).entity(input).build();\r
- }\r
-\r
- /**\r
- * Updates a FloatingIP */\r
-\r
- @Path("{floatingipUUID}")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response updateFloatingIP(\r
- @PathParam("floatingipUUID") String floatingipUUID,\r
- NeutronFloatingIPRequest input\r
- ) {\r
- INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
- return Response.status(404).build();\r
-\r
- NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);\r
- if (!input.isSingleton())\r
- return Response.status(400).build();\r
- NeutronFloatingIP singleton = input.getSingleton();\r
- if (singleton.getID() != null)\r
- return Response.status(400).build();\r
-\r
- NeutronNetwork externNetwork = networkInterface.getNetwork(\r
- sourceFloatingIP.getFloatingNetworkUUID());\r
-\r
- // if floating IP is specified, make sure it can come from the network\r
- String floatingIP = singleton.getFloatingIPAddress();\r
- if (floatingIP != null) {\r
- if (externNetwork.getSubnets().size() > 1)\r
- return Response.status(400).build();\r
- NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
- if (!externSubnet.isValidIP(floatingIP))\r
- return Response.status(400).build();\r
- if (externSubnet.isIPInUse(floatingIP))\r
- return Response.status(409).build();\r
- }\r
-\r
- // if port_id is specified, then check that the port exists and has at least one IP\r
- String port_id = singleton.getPortUUID();\r
- if (port_id != null) {\r
- String fixedIP = null; // used for the fixedIP calculation\r
- if (!portInterface.portExists(port_id))\r
- return Response.status(404).build();\r
- NeutronPort port = portInterface.getPort(port_id);\r
- if (port.getFixedIPs().size() < 1)\r
- return Response.status(400).build();\r
- // if there is more than one fixed IP then check for fixed_ip_address\r
- // and that it is in the list of port addresses\r
- if (port.getFixedIPs().size() > 1) {\r
- fixedIP = singleton.getFixedIPAddress();\r
- if (fixedIP == null)\r
- return Response.status(400).build();\r
- Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
- boolean validFixedIP = false;\r
- while (i.hasNext() && !validFixedIP) {\r
- Neutron_IPs ip = i.next();\r
- if (ip.getIpAddress().equals(fixedIP))\r
- validFixedIP = true;\r
- }\r
- if (!validFixedIP)\r
- return Response.status(400).build();\r
- } else {\r
- fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
- if (singleton.getFixedIPAddress() != null &&\r
- !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
- return Response.status(400).build();\r
- }\r
- //lastly check that this fixed IP address isn't already used\r
- if (port.isBoundToFloatingIP(fixedIP))\r
- return Response.status(409).build();\r
- singleton.setFixedIPAddress(fixedIP);\r
- }\r
- NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- int status = service.canUpdateFloatingIP(singleton, target);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);\r
- target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- service.neutronFloatingIPUpdated(target);\r
- }\r
- }\r
- return Response.status(200).entity(\r
- new NeutronFloatingIPRequest(target)).build();\r
-\r
- }\r
-\r
- /**\r
- * Deletes a FloatingIP */\r
-\r
- @Path("{floatingipUUID}")\r
- @DELETE\r
- @StatusCodes({\r
- @ResponseCode(code = 204, condition = "No Content"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response deleteFloatingIP(\r
- @PathParam("floatingipUUID") String floatingipUUID) {\r
- INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
- return Response.status(404).build();\r
- // TODO: need to undo port association if it exists\r
- NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- int status = service.canDeleteFloatingIP(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- floatingIPInterface.removeFloatingIP(floatingipUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
- service.neutronFloatingIPDeleted(singleton);\r
- }\r
- }\r
- return Response.status(204).build();\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;
+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.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+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.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/floatingips")
+public class NeutronFloatingIPsNorthbound {
+
+ private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all FloatingIPs */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listFloatingIPs(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("floating_network_id") String queryFloatingNetworkId,
+ @QueryParam("port_id") String queryPortId,
+ @QueryParam("fixed_ip_address") String queryFixedIPAddress,
+ @QueryParam("floating_ip_address") String queryFloatingIPAddress,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();
+ List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+ Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();
+ while (i.hasNext()) {
+ NeutronFloatingIP oSS = i.next();
+ //match filters: TODO provider extension and router extension
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&
+ (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&
+ (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&
+ (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();
+
+ }
+
+ /**
+ * Creates new FloatingIPs */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createFloatingIPs(final NeutronFloatingIPRequest input) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronFloatingIP singleton = input.getSingleton();
+ // check existence of id in cache and return badrequest if exists
+ if (floatingIPInterface.floatingIPExists(singleton.getID()))
+ return Response.status(400).build();
+ // check if the external network is specified, exists, and is an external network
+ String externalNetworkUUID = singleton.getFloatingNetworkUUID();
+ if (externalNetworkUUID == null)
+ return Response.status(400).build();
+ if (!networkInterface.networkExists(externalNetworkUUID))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ // if floating IP is specified, make sure it can come from the network
+ String floatingIP = singleton.getFloatingIPAddress();
+ if (floatingIP != null) {
+ if (externNetwork.getSubnets().size() > 1)
+ return Response.status(400).build();
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ return Response.status(400).build();
+ if (externSubnet.isIPInUse(floatingIP))
+ return Response.status(409).build();
+ }
+ // if port_id is specified, then check that the port exists and has at least one IP
+ String port_id = singleton.getPortUUID();
+ if (port_id != null) {
+ String fixedIP = null; // used for the fixedIP calculation
+ if (!portInterface.portExists(port_id))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ return Response.status(400).build();
+ // if there is more than one fixed IP then check for fixed_ip_address
+ // and that it is in the list of port addresses
+ if (port.getFixedIPs().size() > 1) {
+ fixedIP = singleton.getFixedIPAddress();
+ if (fixedIP == null)
+ return Response.status(400).build();
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ return Response.status(400).build();
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ return Response.status(400).build();
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ return Response.status(409).build();
+ singleton.setFixedIPAddress(fixedIP);
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canCreateFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.addFloatingIP(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPCreated(singleton);
+ }
+ }
+ } else {
+ return Response.status(400).build();
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID,
+ NeutronFloatingIPRequest input
+ ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+
+ NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronFloatingIP singleton = input.getSingleton();
+ if (singleton.getID() != null)
+ return Response.status(400).build();
+
+ NeutronNetwork externNetwork = networkInterface.getNetwork(
+ sourceFloatingIP.getFloatingNetworkUUID());
+
+ // if floating IP is specified, make sure it can come from the network
+ String floatingIP = singleton.getFloatingIPAddress();
+ if (floatingIP != null) {
+ if (externNetwork.getSubnets().size() > 1)
+ return Response.status(400).build();
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ return Response.status(400).build();
+ if (externSubnet.isIPInUse(floatingIP))
+ return Response.status(409).build();
+ }
+
+ // if port_id is specified, then check that the port exists and has at least one IP
+ String port_id = singleton.getPortUUID();
+ if (port_id != null) {
+ String fixedIP = null; // used for the fixedIP calculation
+ if (!portInterface.portExists(port_id))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ return Response.status(400).build();
+ // if there is more than one fixed IP then check for fixed_ip_address
+ // and that it is in the list of port addresses
+ if (port.getFixedIPs().size() > 1) {
+ fixedIP = singleton.getFixedIPAddress();
+ if (fixedIP == null)
+ return Response.status(400).build();
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ return Response.status(400).build();
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null &&
+ !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ return Response.status(400).build();
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ return Response.status(409).build();
+ singleton.setFixedIPAddress(fixedIP);
+ }
+ NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canUpdateFloatingIP(singleton, target);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);
+ target = floatingIPInterface.getFloatingIP(floatingipUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPUpdated(target);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(target)).build();
+
+ }
+
+ /**
+ * Deletes a FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+ // TODO: need to undo port association if it exists
+ NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canDeleteFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.removeFloatingIP(floatingipUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronNetworkRequest {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="network")\r
- NeutronNetwork singletonNetwork;\r
-\r
- @XmlElement(name="networks")\r
- List<NeutronNetwork> bulkRequest;\r
-\r
- NeutronNetworkRequest() {\r
- }\r
-\r
- NeutronNetworkRequest(List<NeutronNetwork> bulk) {\r
- bulkRequest = bulk;\r
- singletonNetwork = null;\r
- }\r
-\r
- NeutronNetworkRequest(NeutronNetwork net) {\r
- singletonNetwork = net;\r
- }\r
-\r
- public NeutronNetwork getSingleton() {\r
- return singletonNetwork;\r
- }\r
-\r
- public boolean isSingleton() {\r
- return (singletonNetwork != null);\r
- }\r
-\r
- public List<NeutronNetwork> getBulk() {\r
- return bulkRequest;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronNetworkRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="network")
+ NeutronNetwork singletonNetwork;
+
+ @XmlElement(name="networks")
+ List<NeutronNetwork> bulkRequest;
+
+ NeutronNetworkRequest() {
+ }
+
+ NeutronNetworkRequest(List<NeutronNetwork> bulk) {
+ bulkRequest = bulk;
+ singletonNetwork = null;
+ }
+
+ NeutronNetworkRequest(NeutronNetwork net) {
+ singletonNetwork = net;
+ }
+
+ public NeutronNetwork getSingleton() {
+ return singletonNetwork;
+ }
+
+ public boolean isSingleton() {
+ return (singletonNetwork != null);
+ }
+
+ public List<NeutronNetwork> getBulk() {
+ return bulkRequest;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.codehaus.enunciate.jaxrs.TypeHint;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs for Network.<br>\r
- * This class provides REST APIs for managing open DOVE internals related to Networks\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/networks")\r
-public class NeutronNetworksNorthbound {\r
-\r
- private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {\r
- return o.extractFields(fields);\r
- }\r
-\r
- /**\r
- * Returns a list of all Networks */\r
-\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackNetworks.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized") })\r
- public Response listNetworks(\r
- // return fields\r
- @QueryParam("fields") List<String> fields,\r
- // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
- @QueryParam("id") String queryID,\r
- @QueryParam("name") String queryName,\r
- @QueryParam("admin_state_up") String queryAdminStateUp,\r
- @QueryParam("status") String queryStatus,\r
- @QueryParam("shared") String queryShared,\r
- @QueryParam("tenant_id") String queryTenantID,\r
- @QueryParam("router_external") String queryRouterExternal,\r
- @QueryParam("provider_network_type") String queryProviderNetworkType,\r
- @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,\r
- @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,\r
- // pagination\r
- @QueryParam("limit") String limit,\r
- @QueryParam("marker") String marker,\r
- @QueryParam("page_reverse") String pageReverse\r
- // sorting not supported\r
- ) {\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();\r
- List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
- Iterator<NeutronNetwork> i = allNetworks.iterator();\r
- while (i.hasNext()) {\r
- NeutronNetwork oSN = i.next();\r
- //match filters: TODO provider extension\r
- Boolean bAdminStateUp = null;\r
- Boolean bShared = null;\r
- Boolean bRouterExternal = null;\r
- if (queryAdminStateUp != null)\r
- bAdminStateUp = Boolean.valueOf(queryAdminStateUp);\r
- if (queryShared != null)\r
- bShared = Boolean.valueOf(queryShared);\r
- if (queryRouterExternal != null)\r
- bRouterExternal = Boolean.valueOf(queryRouterExternal);\r
- if ((queryID == null || queryID.equals(oSN.getID())) &&\r
- (queryName == null || queryName.equals(oSN.getNetworkName())) &&\r
- (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&\r
- (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&\r
- (bShared == null || bShared.booleanValue() == oSN.isShared()) &&\r
- (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&\r
- (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {\r
- if (fields.size() > 0)\r
- ans.add(extractFields(oSN,fields));\r
- else\r
- ans.add(oSN);\r
- }\r
- }\r
- //TODO: apply pagination to results\r
- return Response.status(200).entity(\r
- new NeutronNetworkRequest(ans)).build();\r
- }\r
-\r
- /**\r
- * Returns a specific Network */\r
-\r
- @Path("{netUUID}")\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackNetworks.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found") })\r
- public Response showNetwork(\r
- @PathParam("netUUID") String netUUID,\r
- // return fields\r
- @QueryParam("fields") List<String> fields\r
- ) {\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!networkInterface.networkExists(netUUID))\r
- return Response.status(404).build();\r
- if (fields.size() > 0) {\r
- NeutronNetwork ans = networkInterface.getNetwork(netUUID);\r
- return Response.status(200).entity(\r
- new NeutronNetworkRequest(extractFields(ans, fields))).build();\r
- } else\r
- return Response.status(200).entity(\r
- new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
- }\r
-\r
- /**\r
- * Creates new Networks */\r
- @POST\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- @TypeHint(NeutronNetwork.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 201, condition = "Created"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized") })\r
- public Response createNetworks(final NeutronNetworkRequest input) {\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (input.isSingleton()) {\r
- NeutronNetwork singleton = input.getSingleton();\r
-\r
- /*\r
- * network ID can't already exist\r
- */\r
- if (networkInterface.networkExists(singleton.getID()))\r
- return Response.status(400).build();\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- int status = service.canCreateNetwork(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
-\r
- // add network to cache\r
- networkInterface.addNetwork(singleton);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- service.neutronNetworkCreated(singleton);\r
- }\r
- }\r
-\r
- } else {\r
- List<NeutronNetwork> bulk = input.getBulk();\r
- Iterator<NeutronNetwork> i = bulk.iterator();\r
- HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
- while (i.hasNext()) {\r
- NeutronNetwork test = i.next();\r
-\r
- /*\r
- * network ID can't already exist, nor can there be an entry for this UUID\r
- * already in this bulk request\r
- */\r
- if (networkInterface.networkExists(test.getID()))\r
- return Response.status(400).build();\r
- if (testMap.containsKey(test.getID()))\r
- return Response.status(400).build();\r
- if (instances != null) {\r
- for (Object instance: instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- int status = service.canCreateNetwork(test);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- testMap.put(test.getID(),test);\r
- }\r
-\r
- // now that everything passed, add items to the cache\r
- i = bulk.iterator();\r
- while (i.hasNext()) {\r
- NeutronNetwork test = i.next();\r
- test.initDefaults();\r
- networkInterface.addNetwork(test);\r
- if (instances != null) {\r
- for (Object instance: instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- service.neutronNetworkCreated(test);\r
- }\r
- }\r
- }\r
- }\r
- return Response.status(201).entity(input).build();\r
- }\r
-\r
- /**\r
- * Updates a Network */\r
- @Path("{netUUID}")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackNetworks.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"), })\r
- public Response updateNetwork(\r
- @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input\r
- ) {\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * network has to exist and only a single delta is supported\r
- */\r
- if (!networkInterface.networkExists(netUUID))\r
- return Response.status(404).build();\r
- if (!input.isSingleton())\r
- return Response.status(400).build();\r
- NeutronNetwork delta = input.getSingleton();\r
-\r
- /*\r
- * transitions forbidden by Neutron\r
- */\r
- if (delta.getID() != null || delta.getTenantID() != null ||\r
- delta.getStatus() != null)\r
- return Response.status(400).build();\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- NeutronNetwork original = networkInterface.getNetwork(netUUID);\r
- int status = service.canUpdateNetwork(delta, original);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
-\r
- // update network object and return the modified object\r
- networkInterface.updateNetwork(netUUID, delta);\r
- NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- service.neutronNetworkUpdated(updatedSingleton);\r
- }\r
- }\r
- return Response.status(200).entity(\r
- new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
- }\r
-\r
- /**\r
- * Deletes a Network */\r
-\r
- @Path("{netUUID}")\r
- @DELETE\r
- @StatusCodes({\r
- @ResponseCode(code = 204, condition = "No Content"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Network In Use") })\r
- public Response deleteNetwork(\r
- @PathParam("netUUID") String netUUID) {\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * network has to exist and not be in use before it can be removed\r
- */\r
- if (!networkInterface.networkExists(netUUID))\r
- return Response.status(404).build();\r
- if (networkInterface.networkInUse(netUUID))\r
- return Response.status(409).build();\r
-\r
- NeutronNetwork singleton = networkInterface.getNetwork(netUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- int status = service.canDeleteNetwork(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- networkInterface.removeNetwork(netUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
- service.neutronNetworkDeleted(singleton);\r
- }\r
- }\r
- return Response.status(204).build();\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs for Network.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Networks
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/networks")
+public class NeutronNetworksNorthbound {
+
+ private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Networks */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized") })
+ public Response listNetworks(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("shared") String queryShared,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("router_external") String queryRouterExternal,
+ @QueryParam("provider_network_type") String queryProviderNetworkType,
+ @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
+ @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();
+ List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+ Iterator<NeutronNetwork> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronNetwork oSN = i.next();
+ //match filters: TODO provider extension
+ Boolean bAdminStateUp = null;
+ Boolean bShared = null;
+ Boolean bRouterExternal = null;
+ if (queryAdminStateUp != null)
+ bAdminStateUp = Boolean.valueOf(queryAdminStateUp);
+ if (queryShared != null)
+ bShared = Boolean.valueOf(queryShared);
+ if (queryRouterExternal != null)
+ bRouterExternal = Boolean.valueOf(queryRouterExternal);
+ if ((queryID == null || queryID.equals(oSN.getID())) &&
+ (queryName == null || queryName.equals(oSN.getNetworkName())) &&
+ (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&
+ (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&
+ (bShared == null || bShared.booleanValue() == oSN.isShared()) &&
+ (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&
+ (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSN,fields));
+ else
+ ans.add(oSN);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Network */
+
+ @Path("{netUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found") })
+ public Response showNetwork(
+ @PathParam("netUUID") String netUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronNetwork ans = networkInterface.getNetwork(netUUID);
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+ }
+
+ /**
+ * Creates new Networks */
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @TypeHint(NeutronNetwork.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized") })
+ public Response createNetworks(final NeutronNetworkRequest input) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronNetwork singleton = input.getSingleton();
+
+ /*
+ * network ID can't already exist
+ */
+ if (networkInterface.networkExists(singleton.getID()))
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // add network to cache
+ networkInterface.addNetwork(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkCreated(singleton);
+ }
+ }
+
+ } else {
+ List<NeutronNetwork> bulk = input.getBulk();
+ Iterator<NeutronNetwork> i = bulk.iterator();
+ HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronNetwork test = i.next();
+
+ /*
+ * network ID can't already exist, nor can there be an entry for this UUID
+ * already in this bulk request
+ */
+ if (networkInterface.networkExists(test.getID()))
+ return Response.status(400).build();
+ if (testMap.containsKey(test.getID()))
+ return Response.status(400).build();
+ if (instances != null) {
+ for (Object instance: instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(test);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ testMap.put(test.getID(),test);
+ }
+
+ // now that everything passed, add items to the cache
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronNetwork test = i.next();
+ test.initDefaults();
+ networkInterface.addNetwork(test);
+ if (instances != null) {
+ for (Object instance: instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Network */
+ @Path("{netUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"), })
+ public Response updateNetwork(
+ @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * network has to exist and only a single delta is supported
+ */
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronNetwork delta = input.getSingleton();
+
+ /*
+ * transitions forbidden by Neutron
+ */
+ if (delta.getID() != null || delta.getTenantID() != null ||
+ delta.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ NeutronNetwork original = networkInterface.getNetwork(netUUID);
+ int status = service.canUpdateNetwork(delta, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // update network object and return the modified object
+ networkInterface.updateNetwork(netUUID, delta);
+ NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkUpdated(updatedSingleton);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+ }
+
+ /**
+ * Deletes a Network */
+
+ @Path("{netUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Network In Use") })
+ public Response deleteNetwork(
+ @PathParam("netUUID") String netUUID) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * network has to exist and not be in use before it can be removed
+ */
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (networkInterface.networkInUse(netUUID))
+ return Response.status(409).build();
+
+ NeutronNetwork singleton = networkInterface.getNetwork(netUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canDeleteNetwork(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ networkInterface.removeNetwork(netUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import javax.ws.rs.core.Application;\r
-import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;\r
-\r
-\r
-/**\r
- * This class is an instance of javax.ws.rs.core.Application and is used to return the classes\r
- * that will be instantiated for JAXRS processing. This is necessary\r
- * because package scanning in jersey doesn't yet work in OSGi environment.\r
- *\r
- */\r
-public class NeutronNorthboundRSApplication extends Application {\r
- @Override\r
- public Set<Class<?>> getClasses() {\r
- Set<Class<?>> classes = new HashSet<Class<?>>();\r
-// northbound URIs\r
- classes.add(NeutronNetworksNorthbound.class);\r
- classes.add(NeutronSubnetsNorthbound.class);\r
- classes.add(NeutronPortsNorthbound.class);\r
- classes.add(NeutronRoutersNorthbound.class);\r
- classes.add(NeutronFloatingIPsNorthbound.class);\r
- return classes;\r
- }\r
-\r
- @Override\r
- public Set<Object> getSingletons() {\r
- MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();\r
-\r
- moxyJsonProvider.setAttributePrefix("@");\r
- moxyJsonProvider.setFormattedOutput(true);\r
- moxyJsonProvider.setIncludeRoot(false);\r
- moxyJsonProvider.setMarshalEmptyCollections(true);\r
- moxyJsonProvider.setValueWrapper("$");\r
-\r
- Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);\r
- namespacePrefixMapper.put("router", "router"); // FIXME: fill in with XSD\r
- namespacePrefixMapper.put("provider", "provider"); // FIXME: fill in with XSD\r
- moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);\r
- moxyJsonProvider.setNamespaceSeparator(':');\r
-\r
- HashSet<Object> set = new HashSet<Object>(1);\r
- set.add(moxyJsonProvider);\r
- return set;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Application;
+import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
+
+
+/**
+ * This class is an instance of javax.ws.rs.core.Application and is used to return the classes
+ * that will be instantiated for JAXRS processing. This is necessary
+ * because package scanning in jersey doesn't yet work in OSGi environment.
+ *
+ */
+public class NeutronNorthboundRSApplication extends Application {
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+// northbound URIs
+ classes.add(NeutronNetworksNorthbound.class);
+ classes.add(NeutronSubnetsNorthbound.class);
+ classes.add(NeutronPortsNorthbound.class);
+ classes.add(NeutronRoutersNorthbound.class);
+ classes.add(NeutronFloatingIPsNorthbound.class);
+ return classes;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
+
+ moxyJsonProvider.setAttributePrefix("@");
+ moxyJsonProvider.setFormattedOutput(true);
+ moxyJsonProvider.setIncludeRoot(false);
+ moxyJsonProvider.setMarshalEmptyCollections(true);
+ moxyJsonProvider.setValueWrapper("$");
+
+ Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
+ namespacePrefixMapper.put("router", "router"); // FIXME: fill in with XSD
+ namespacePrefixMapper.put("provider", "provider"); // FIXME: fill in with XSD
+ moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
+ moxyJsonProvider.setNamespaceSeparator(':');
+
+ HashSet<Object> set = new HashSet<Object>(1);
+ set.add(moxyJsonProvider);
+ return set;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronPortRequest {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="port")\r
- NeutronPort singletonPort;\r
-\r
- @XmlElement(name="ports")\r
- List<NeutronPort> bulkRequest;\r
-\r
- NeutronPortRequest() {\r
- }\r
-\r
- NeutronPortRequest(List<NeutronPort> bulk) {\r
- bulkRequest = bulk;\r
- singletonPort = null;\r
- }\r
-\r
- NeutronPortRequest(NeutronPort port) {\r
- singletonPort = port;\r
- }\r
-\r
- public NeutronPort getSingleton() {\r
- return singletonPort;\r
- }\r
-\r
- public boolean isSingleton() {\r
- return (singletonPort != null);\r
- }\r
-\r
- public List<NeutronPort> getBulk() {\r
- return bulkRequest;\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPortRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="port")
+ NeutronPort singletonPort;
+
+ @XmlElement(name="ports")
+ List<NeutronPort> bulkRequest;
+
+ NeutronPortRequest() {
+ }
+
+ NeutronPortRequest(List<NeutronPort> bulk) {
+ bulkRequest = bulk;
+ singletonPort = null;
+ }
+
+ NeutronPortRequest(NeutronPort port) {
+ singletonPort = port;
+ }
+
+ public NeutronPort getSingleton() {
+ return singletonPort;
+ }
+
+ public boolean isSingleton() {
+ return (singletonPort != null);
+ }
+
+ public List<NeutronPort> getBulk() {
+ return bulkRequest;
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/ports")\r
-public class NeutronPortsNorthbound {\r
-\r
- private NeutronPort extractFields(NeutronPort o, List<String> fields) {\r
- return o.extractFields(fields);\r
- }\r
-\r
- /**\r
- * Returns a list of all Ports */\r
-\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackPorts.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response listPorts(\r
- // return fields\r
- @QueryParam("fields") List<String> fields,\r
- // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
- @QueryParam("id") String queryID,\r
- @QueryParam("network_id") String queryNetworkID,\r
- @QueryParam("name") String queryName,\r
- @QueryParam("admin_state_up") String queryAdminStateUp,\r
- @QueryParam("status") String queryStatus,\r
- @QueryParam("mac_address") String queryMACAddress,\r
- @QueryParam("device_id") String queryDeviceID,\r
- @QueryParam("device_owner") String queryDeviceOwner,\r
- @QueryParam("tenant_id") String queryTenantID,\r
- // pagination\r
- @QueryParam("limit") String limit,\r
- @QueryParam("marker") String marker,\r
- @QueryParam("page_reverse") String pageReverse\r
- // sorting not supported\r
- ) {\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- List<NeutronPort> allPorts = portInterface.getAllPorts();\r
- List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
- Iterator<NeutronPort> i = allPorts.iterator();\r
- while (i.hasNext()) {\r
- NeutronPort oSS = i.next();\r
- if ((queryID == null || queryID.equals(oSS.getID())) &&\r
- (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
- (queryName == null || queryName.equals(oSS.getName())) &&\r
- (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
- (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
- (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&\r
- (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&\r
- (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&\r
- (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
- if (fields.size() > 0)\r
- ans.add(extractFields(oSS,fields));\r
- else\r
- ans.add(oSS);\r
- }\r
- }\r
- //TODO: apply pagination to results\r
- return Response.status(200).entity(\r
- new NeutronPortRequest(ans)).build();\r
- }\r
-\r
- /**\r
- * Returns a specific Port */\r
-\r
- @Path("{portUUID}")\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackPorts.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response showPort(\r
- @PathParam("portUUID") String portUUID,\r
- // return fields\r
- @QueryParam("fields") List<String> fields ) {\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!portInterface.portExists(portUUID))\r
- return Response.status(404).build();\r
- if (fields.size() > 0) {\r
- NeutronPort ans = portInterface.getPort(portUUID);\r
- return Response.status(200).entity(\r
- new NeutronPortRequest(extractFields(ans, fields))).build();\r
- } else\r
- return Response.status(200).entity(\r
- new NeutronPortRequest(portInterface.getPort(portUUID))).build();\r
- }\r
-\r
- /**\r
- * Creates new Ports */\r
-\r
- @POST\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackPorts.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 201, condition = "Created"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented"),\r
- @ResponseCode(code = 503, condition = "MAC generation failure") })\r
- public Response createPorts(final NeutronPortRequest input) {\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (input.isSingleton()) {\r
- NeutronPort singleton = input.getSingleton();\r
-\r
- /*\r
- * the port must be part of an existing network, must not already exist,\r
- * have a valid MAC and the MAC not be in use\r
- */\r
- if (singleton.getNetworkUUID() == null)\r
- return Response.status(400).build();\r
- if (portInterface.portExists(singleton.getID()))\r
- return Response.status(400).build();\r
- if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
- return Response.status(404).build();\r
- if (singleton.getMacAddress() == null ||\r
- !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
- return Response.status(400).build();\r
- if (portInterface.macInUse(singleton.getMacAddress()))\r
- return Response.status(409).build();\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- int status = service.canCreatePort(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- /*\r
- * if fixed IPs are specified, each one has to have an existing subnet ID\r
- * that is in the same scoping network as the port. In addition, if an IP\r
- * address is specified it has to be a valid address for the subnet and not\r
- * already in use\r
- */\r
- List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
- if (fixedIPs != null && fixedIPs.size() > 0) {\r
- Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
- while (fixedIPIterator.hasNext()) {\r
- Neutron_IPs ip = fixedIPIterator.next();\r
- if (ip.getSubnetUUID() == null)\r
- return Response.status(400).build();\r
- if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
- return Response.status(400).build();\r
- NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
- if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
- return Response.status(400).build();\r
- if (ip.getIpAddress() != null) {\r
- if (!subnet.isValidIP(ip.getIpAddress()))\r
- return Response.status(400).build();\r
- if (subnet.isIPInUse(ip.getIpAddress()))\r
- return Response.status(409).build();\r
- }\r
- }\r
- }\r
-\r
- // add the port to the cache\r
- portInterface.addPort(singleton);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- service.neutronPortCreated(singleton);\r
- }\r
- }\r
- } else {\r
- List<NeutronPort> bulk = input.getBulk();\r
- Iterator<NeutronPort> i = bulk.iterator();\r
- HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
- while (i.hasNext()) {\r
- NeutronPort test = i.next();\r
-\r
- /*\r
- * the port must be part of an existing network, must not already exist,\r
- * have a valid MAC and the MAC not be in use. Further the bulk request\r
- * can't already contain a new port with the same UUID\r
- */\r
- if (portInterface.portExists(test.getID()))\r
- return Response.status(400).build();\r
- if (testMap.containsKey(test.getID()))\r
- return Response.status(400).build();\r
- for (NeutronPort check : testMap.values()) {\r
- if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))\r
- return Response.status(409).build();\r
- for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {\r
- for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {\r
- if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))\r
- return Response.status(409).build();\r
- }\r
- }\r
- }\r
- testMap.put(test.getID(), test);\r
- if (!networkInterface.networkExists(test.getNetworkUUID()))\r
- return Response.status(404).build();\r
- if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
- return Response.status(400).build();\r
- if (portInterface.macInUse(test.getMacAddress()))\r
- return Response.status(409).build();\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- int status = service.canCreatePort(test);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- /*\r
- * if fixed IPs are specified, each one has to have an existing subnet ID\r
- * that is in the same scoping network as the port. In addition, if an IP\r
- * address is specified it has to be a valid address for the subnet and not\r
- * already in use (or be the gateway IP address of the subnet)\r
- */\r
- List<Neutron_IPs> fixedIPs = test.getFixedIPs();\r
- if (fixedIPs != null && fixedIPs.size() > 0) {\r
- Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
- while (fixedIPIterator.hasNext()) {\r
- Neutron_IPs ip = fixedIPIterator.next();\r
- if (ip.getSubnetUUID() == null)\r
- return Response.status(400).build();\r
- if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
- return Response.status(400).build();\r
- NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
- if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
- return Response.status(400).build();\r
- if (ip.getIpAddress() != null) {\r
- if (!subnet.isValidIP(ip.getIpAddress()))\r
- return Response.status(400).build();\r
- //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the\r
- //same bulk create\r
- if (subnet.isIPInUse(ip.getIpAddress()))\r
- return Response.status(409).build();\r
- }\r
- }\r
- }\r
- }\r
-\r
- //once everything has passed, then we can add to the cache\r
- i = bulk.iterator();\r
- while (i.hasNext()) {\r
- NeutronPort test = i.next();\r
- portInterface.addPort(test);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- service.neutronPortCreated(test);\r
- }\r
- }\r
- }\r
- }\r
- return Response.status(201).entity(input).build();\r
- }\r
-\r
- /**\r
- * Updates a Port */\r
-\r
- @Path("{portUUID}")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackPorts.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response updatePort(\r
- @PathParam("portUUID") String portUUID,\r
- NeutronPortRequest input\r
- ) {\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- // port has to exist and only a single delta is supported\r
- if (!portInterface.portExists(portUUID))\r
- return Response.status(404).build();\r
- NeutronPort target = portInterface.getPort(portUUID);\r
- if (!input.isSingleton())\r
- return Response.status(400).build();\r
- NeutronPort singleton = input.getSingleton();\r
- NeutronPort original = portInterface.getPort(portUUID);\r
-\r
- // deltas restricted by Neutron\r
- if (singleton.getID() != null || singleton.getTenantID() != null ||\r
- singleton.getStatus() != null)\r
- return Response.status(400).build();\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- int status = service.canUpdatePort(singleton, original);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
-\r
- // Verify the new fixed ips are valid\r
- List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
- if (fixedIPs != null && fixedIPs.size() > 0) {\r
- Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
- while (fixedIPIterator.hasNext()) {\r
- Neutron_IPs ip = fixedIPIterator.next();\r
- if (ip.getSubnetUUID() == null)\r
- return Response.status(400).build();\r
- if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
- return Response.status(400).build();\r
- NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
- if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
- return Response.status(400).build();\r
- if (ip.getIpAddress() != null) {\r
- if (!subnet.isValidIP(ip.getIpAddress()))\r
- return Response.status(400).build();\r
- if (subnet.isIPInUse(ip.getIpAddress()))\r
- return Response.status(409).build();\r
- }\r
- }\r
- }\r
-\r
-// TODO: Support change of security groups\r
- // update the port and return the modified object\r
- portInterface.updatePort(portUUID, singleton);\r
- NeutronPort updatedPort = portInterface.getPort(portUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- service.neutronPortUpdated(updatedPort);\r
- }\r
- }\r
- return Response.status(200).entity(\r
- new NeutronPortRequest(updatedPort)).build();\r
-\r
- }\r
-\r
- /**\r
- * Deletes a Port */\r
-\r
- @Path("{portUUID}")\r
- @DELETE\r
- @StatusCodes({\r
- @ResponseCode(code = 204, condition = "No Content"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response deletePort(\r
- @PathParam("portUUID") String portUUID) {\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- // port has to exist and not be owned by anyone. then it can be removed from the cache\r
- if (!portInterface.portExists(portUUID))\r
- return Response.status(404).build();\r
- NeutronPort port = portInterface.getPort(portUUID);\r
- if (port.getDeviceID() != null ||\r
- port.getDeviceOwner() != null)\r
- Response.status(403).build();\r
- NeutronPort singleton = portInterface.getPort(portUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- int status = service.canDeletePort(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- portInterface.removePort(portUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronPortAware service = (INeutronPortAware) instance;\r
- service.neutronPortDeleted(singleton);\r
- }\r
- }\r
- return Response.status(204).build();\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+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.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/ports")
+public class NeutronPortsNorthbound {
+
+ private NeutronPort extractFields(NeutronPort o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Ports */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listPorts(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("mac_address") String queryMACAddress,
+ @QueryParam("device_id") String queryDeviceID,
+ @QueryParam("device_owner") String queryDeviceOwner,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronPort> allPorts = portInterface.getAllPorts();
+ List<NeutronPort> ans = new ArrayList<NeutronPort>();
+ Iterator<NeutronPort> i = allPorts.iterator();
+ while (i.hasNext()) {
+ NeutronPort oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&
+ (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&
+ (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronPortRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Port */
+
+ @Path("{portUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showPort(
+ @PathParam("portUUID") String portUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronPort ans = portInterface.getPort(portUUID);
+ return Response.status(200).entity(
+ new NeutronPortRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronPortRequest(portInterface.getPort(portUUID))).build();
+ }
+
+ /**
+ * Creates new Ports */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented"),
+ @ResponseCode(code = 503, condition = "MAC generation failure") })
+ public Response createPorts(final NeutronPortRequest input) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronPort singleton = input.getSingleton();
+
+ /*
+ * the port must be part of an existing network, must not already exist,
+ * have a valid MAC and the MAC not be in use
+ */
+ if (singleton.getNetworkUUID() == null)
+ return Response.status(400).build();
+ if (portInterface.portExists(singleton.getID()))
+ return Response.status(400).build();
+ if (!networkInterface.networkExists(singleton.getNetworkUUID()))
+ return Response.status(404).build();
+ if (singleton.getMacAddress() == null ||
+ !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+ return Response.status(400).build();
+ if (portInterface.macInUse(singleton.getMacAddress()))
+ return Response.status(409).build();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use
+ */
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+
+ // add the port to the cache
+ portInterface.addPort(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronPort> bulk = input.getBulk();
+ Iterator<NeutronPort> i = bulk.iterator();
+ HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronPort test = i.next();
+
+ /*
+ * the port must be part of an existing network, must not already exist,
+ * have a valid MAC and the MAC not be in use. Further the bulk request
+ * can't already contain a new port with the same UUID
+ */
+ if (portInterface.portExists(test.getID()))
+ return Response.status(400).build();
+ if (testMap.containsKey(test.getID()))
+ return Response.status(400).build();
+ for (NeutronPort check : testMap.values()) {
+ if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))
+ return Response.status(409).build();
+ for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {
+ for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {
+ if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID()))
+ return Response.status(404).build();
+ if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+ return Response.status(400).build();
+ if (portInterface.macInUse(test.getMacAddress()))
+ return Response.status(409).build();
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(test);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use (or be the gateway IP address of the subnet)
+ */
+ List<Neutron_IPs> fixedIPs = test.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the
+ //same bulk create
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+ }
+
+ //once everything has passed, then we can add to the cache
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronPort test = i.next();
+ portInterface.addPort(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Port */
+
+ @Path("{portUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updatePort(
+ @PathParam("portUUID") String portUUID,
+ NeutronPortRequest input
+ ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // port has to exist and only a single delta is supported
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ NeutronPort target = portInterface.getPort(portUUID);
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronPort singleton = input.getSingleton();
+ NeutronPort original = portInterface.getPort(portUUID);
+
+ // deltas restricted by Neutron
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canUpdatePort(singleton, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // Verify the new fixed ips are valid
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+
+// TODO: Support change of security groups
+ // update the port and return the modified object
+ portInterface.updatePort(portUUID, singleton);
+ NeutronPort updatedPort = portInterface.getPort(portUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortUpdated(updatedPort);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronPortRequest(updatedPort)).build();
+
+ }
+
+ /**
+ * Deletes a Port */
+
+ @Path("{portUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deletePort(
+ @PathParam("portUUID") String portUUID) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // port has to exist and not be owned by anyone. then it can be removed from the cache
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(portUUID);
+ if (port.getDeviceID() != null ||
+ port.getDeviceOwner() != null)
+ Response.status(403).build();
+ NeutronPort singleton = portInterface.getPort(portUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canDeletePort(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ portInterface.removePort(portUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouterRequest {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="router")\r
- NeutronRouter singletonRouter;\r
-\r
- @XmlElement(name="routers")\r
- List<NeutronRouter> bulkRequest;\r
-\r
- NeutronRouterRequest() {\r
- }\r
-\r
- NeutronRouterRequest(List<NeutronRouter> bulk) {\r
- bulkRequest = bulk;\r
- singletonRouter = null;\r
- }\r
-\r
- NeutronRouterRequest(NeutronRouter router) {\r
- singletonRouter = router;\r
- }\r
-\r
- public List<NeutronRouter> getBulk() {\r
- return bulkRequest;\r
- }\r
-\r
- public NeutronRouter getSingleton() {\r
- return singletonRouter;\r
- }\r
-\r
- public boolean isSingleton() {\r
- return (singletonRouter != null);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouterRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="router")
+ NeutronRouter singletonRouter;
+
+ @XmlElement(name="routers")
+ List<NeutronRouter> bulkRequest;
+
+ NeutronRouterRequest() {
+ }
+
+ NeutronRouterRequest(List<NeutronRouter> bulk) {
+ bulkRequest = bulk;
+ singletonRouter = null;
+ }
+
+ NeutronRouterRequest(NeutronRouter router) {
+ singletonRouter = router;
+ }
+
+ public List<NeutronRouter> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronRouter getSingleton() {
+ return singletonRouter;
+ }
+
+ public boolean isSingleton() {
+ return (singletonRouter != null);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/routers")\r
-public class NeutronRoutersNorthbound {\r
-\r
- private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {\r
- return o.extractFields(fields);\r
- }\r
-\r
- /**\r
- * Returns a list of all Routers */\r
-\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouters.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response listRouters(\r
- // return fields\r
- @QueryParam("fields") List<String> fields,\r
- // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
- @QueryParam("id") String queryID,\r
- @QueryParam("name") String queryName,\r
- @QueryParam("admin_state_up") String queryAdminStateUp,\r
- @QueryParam("status") String queryStatus,\r
- @QueryParam("tenant_id") String queryTenantID,\r
- @QueryParam("external_gateway_info") String queryExternalGatewayInfo,\r
- // pagination\r
- @QueryParam("limit") String limit,\r
- @QueryParam("marker") String marker,\r
- @QueryParam("page_reverse") String pageReverse\r
- // sorting not supported\r
- ) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- List<NeutronRouter> allRouters = routerInterface.getAllRouters();\r
- List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
- Iterator<NeutronRouter> i = allRouters.iterator();\r
- while (i.hasNext()) {\r
- NeutronRouter oSS = i.next();\r
- if ((queryID == null || queryID.equals(oSS.getID())) &&\r
- (queryName == null || queryName.equals(oSS.getName())) &&\r
- (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
- (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
- (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&\r
- (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
- if (fields.size() > 0)\r
- ans.add(extractFields(oSS,fields));\r
- else\r
- ans.add(oSS);\r
- }\r
- }\r
- //TODO: apply pagination to results\r
- return Response.status(200).entity(\r
- new NeutronRouterRequest(ans)).build();\r
- }\r
-\r
- /**\r
- * Returns a specific Router */\r
-\r
- @Path("{routerUUID}")\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouters.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response showRouter(\r
- @PathParam("routerUUID") String routerUUID,\r
- // return fields\r
- @QueryParam("fields") List<String> fields) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!routerInterface.routerExists(routerUUID))\r
- return Response.status(404).build();\r
- if (fields.size() > 0) {\r
- NeutronRouter ans = routerInterface.getRouter(routerUUID);\r
- return Response.status(200).entity(\r
- new NeutronRouterRequest(extractFields(ans, fields))).build();\r
- } else\r
- return Response.status(200).entity(\r
- new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
- }\r
-\r
- /**\r
- * Creates new Routers */\r
-\r
- @POST\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouters.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 201, condition = "Created"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response createRouters(final NeutronRouterRequest input) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (input.isSingleton()) {\r
- NeutronRouter singleton = input.getSingleton();\r
-\r
- /*\r
- * verify that the router doesn't already exist (issue: is deeper inspection necessary?)\r
- * if there is external gateway information provided, verify that the specified network\r
- * exists and has been designated as "router:external"\r
- */\r
- if (routerInterface.routerExists(singleton.getID()))\r
- return Response.status(400).build();\r
- if (singleton.getExternalGatewayInfo() != null) {\r
- String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
- if (!networkInterface.networkExists(externNetworkPtr))\r
- return Response.status(400).build();\r
- NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
- if (!externNetwork.isRouterExternal())\r
- return Response.status(400).build();\r
- }\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- int status = service.canCreateRouter(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
-\r
- /*\r
- * add router to the cache\r
- */\r
- routerInterface.addRouter(singleton);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterCreated(singleton);\r
- }\r
- }\r
- } else {\r
-\r
- /*\r
- * only singleton router creates supported\r
- */\r
- return Response.status(400).build();\r
- }\r
- return Response.status(201).entity(input).build();\r
- }\r
-\r
- /**\r
- * Updates a Router */\r
-\r
- @Path("{routerUUID}")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouters.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response updateRouter(\r
- @PathParam("routerUUID") String routerUUID,\r
- NeutronRouterRequest input\r
- ) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * router has to exist and only a single delta can be supplied\r
- */\r
- if (!routerInterface.routerExists(routerUUID))\r
- return Response.status(404).build();\r
- if (!input.isSingleton())\r
- return Response.status(400).build();\r
- NeutronRouter singleton = input.getSingleton();\r
- NeutronRouter original = routerInterface.getRouter(routerUUID);\r
-\r
- /*\r
- * attribute changes blocked by Neutron\r
- */\r
- if (singleton.getID() != null || singleton.getTenantID() != null ||\r
- singleton.getStatus() != null)\r
- return Response.status(400).build();\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- int status = service.canUpdateRouter(singleton, original);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- /*\r
- * if the external gateway info is being changed, verify that the new network\r
- * exists and has been designated as an external network\r
- */\r
- if (singleton.getExternalGatewayInfo() != null) {\r
- String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
- if (!networkInterface.networkExists(externNetworkPtr))\r
- return Response.status(400).build();\r
- NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
- if (!externNetwork.isRouterExternal())\r
- return Response.status(400).build();\r
- }\r
-\r
- /*\r
- * update the router entry and return the modified object\r
- */\r
- routerInterface.updateRouter(routerUUID, singleton);\r
- NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterUpdated(updatedRouter);\r
- }\r
- }\r
- return Response.status(200).entity(\r
- new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
-\r
- }\r
-\r
- /**\r
- * Deletes a Router */\r
-\r
- @Path("{routerUUID}")\r
- @DELETE\r
- @StatusCodes({\r
- @ResponseCode(code = 204, condition = "No Content"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response deleteRouter(\r
- @PathParam("routerUUID") String routerUUID) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * verify that the router exists and is not in use before removing it\r
- */\r
- if (!routerInterface.routerExists(routerUUID))\r
- return Response.status(404).build();\r
- if (routerInterface.routerInUse(routerUUID))\r
- return Response.status(409).build();\r
- NeutronRouter singleton = routerInterface.getRouter(routerUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- int status = service.canDeleteRouter(singleton);\r
- if (status < 200 || status > 299)\r
- return Response.status(status).build();\r
- }\r
- }\r
- routerInterface.removeRouter(routerUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterDeleted(singleton);\r
- }\r
- }\r
- return Response.status(204).build();\r
- }\r
-\r
- /**\r
- * Adds an interface to a router */\r
-\r
- @Path("{routerUUID}/add_router_interface")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouterInterfaces.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response addRouterInterface(\r
- @PathParam("routerUUID") String routerUUID,\r
- NeutronRouter_Interface input\r
- ) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id\r
- * or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present\r
- */\r
- if (!routerInterface.routerExists(routerUUID))\r
- return Response.status(400).build();\r
- NeutronRouter target = routerInterface.getRouter(routerUUID);\r
- if (input.getSubnetUUID() == null ||\r
- input.getPortUUID() == null)\r
- return Response.status(400).build();\r
-\r
- // check that the port is part of the subnet\r
- NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
- if (targetSubnet == null)\r
- return Response.status(400).build();\r
- NeutronPort targetPort = portInterface.getPort(input.getPortUUID());\r
- if (targetPort == null)\r
- return Response.status(400).build();\r
- if (!targetSubnet.getPortsInSubnet().contains(targetPort))\r
- return Response.status(400).build();\r
-\r
- if (targetPort.getFixedIPs().size() != 1)\r
- return Response.status(400).build();\r
- if (targetPort.getDeviceID() != null ||\r
- targetPort.getDeviceOwner() != null)\r
- return Response.status(409).build();\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canAttachInterface(target, input);\r
- }\r
- }\r
-\r
- //mark the port device id and device owner fields\r
- targetPort.setDeviceOwner("network:router_interface");\r
- targetPort.setDeviceID(routerUUID);\r
-\r
- target.addInterface(input.getPortUUID(), input);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterInterfaceAttached(target, input);\r
- }\r
- }\r
-\r
- return Response.status(200).entity(input).build();\r
- }\r
-\r
- /**\r
- * Removes an interface to a router */\r
-\r
- @Path("{routerUUID}/remove_router_interface")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackRouterInterfaces.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response removeRouterInterface(\r
- @PathParam("routerUUID") String routerUUID,\r
- NeutronRouter_Interface input\r
- ) {\r
- INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- // verify the router exists\r
- if (!routerInterface.routerExists(routerUUID))\r
- return Response.status(400).build();\r
- NeutronRouter target = routerInterface.getRouter(routerUUID);\r
-\r
- /*\r
- * remove by subnet id. Collect information about the impacted router for the response and\r
- * remove the port corresponding to the gateway IP address of the subnet\r
- */\r
- if (input.getPortUUID() == null &&\r
- input.getSubnetUUID() != null) {\r
- NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());\r
- if (port == null)\r
- return Response.status(404).build();\r
- input.setPortUUID(port.getID());\r
- input.setID(target.getID());\r
- input.setTenantID(target.getTenantID());\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canDetachInterface(target, input);\r
- }\r
- }\r
-\r
- // reset the port ownership\r
- port.setDeviceID(null);\r
- port.setDeviceOwner(null);\r
-\r
- target.removeInterface(input.getPortUUID());\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterInterfaceDetached(target, input);\r
- }\r
- }\r
- return Response.status(200).entity(input).build();\r
- }\r
-\r
- /*\r
- * remove by port id. collect information about the impacted router for the response\r
- * remove the interface and reset the port ownership\r
- */\r
- if (input.getPortUUID() != null &&\r
- input.getSubnetUUID() == null) {\r
- NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());\r
- input.setSubnetUUID(targetInterface.getSubnetUUID());\r
- input.setID(target.getID());\r
- input.setTenantID(target.getTenantID());\r
- NeutronPort port = portInterface.getPort(input.getPortUUID());\r
- port.setDeviceID(null);\r
- port.setDeviceOwner(null);\r
- target.removeInterface(input.getPortUUID());\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterInterfaceDetached(target, input);\r
- }\r
- return Response.status(200).entity(input).build();\r
- }\r
-\r
- /*\r
- * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid\r
- * IP address for the subnet, and then remove the interface, collecting information about the\r
- * impacted router for the response and reset port ownership\r
- */\r
- if (input.getPortUUID() != null &&\r
- input.getSubnetUUID() != null) {\r
- NeutronPort port = portInterface.getPort(input.getPortUUID());\r
- NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
- if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))\r
- return Response.status(409).build();\r
- input.setID(target.getID());\r
- input.setTenantID(target.getTenantID());\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canDetachInterface(target, input);\r
- }\r
- }\r
- port.setDeviceID(null);\r
- port.setDeviceOwner(null);\r
- target.removeInterface(input.getPortUUID());\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.neutronRouterInterfaceDetached(target, input);\r
- }\r
- return Response.status(200).entity(input).build();\r
- }\r
-\r
- // have to specify either a port ID or a subnet ID\r
- return Response.status(400).build();\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+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.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/routers")
+public class NeutronRoutersNorthbound {
+
+ private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Routers */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listRouters(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronRouter> allRouters = routerInterface.getAllRouters();
+ List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+ Iterator<NeutronRouter> i = allRouters.iterator();
+ while (i.hasNext()) {
+ NeutronRouter oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronRouterRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Router */
+
+ @Path("{routerUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showRouter(
+ @PathParam("routerUUID") String routerUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronRouter ans = routerInterface.getRouter(routerUUID);
+ return Response.status(200).entity(
+ new NeutronRouterRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+ }
+
+ /**
+ * Creates new Routers */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createRouters(final NeutronRouterRequest input) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronRouter singleton = input.getSingleton();
+
+ /*
+ * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
+ * if there is external gateway information provided, verify that the specified network
+ * exists and has been designated as "router:external"
+ */
+ if (routerInterface.routerExists(singleton.getID()))
+ return Response.status(400).build();
+ if (singleton.getExternalGatewayInfo() != null) {
+ String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+ if (!networkInterface.networkExists(externNetworkPtr))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canCreateRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ /*
+ * add router to the cache
+ */
+ routerInterface.addRouter(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterCreated(singleton);
+ }
+ }
+ } else {
+
+ /*
+ * only singleton router creates supported
+ */
+ return Response.status(400).build();
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Router */
+
+ @Path("{routerUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateRouter(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouterRequest input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * router has to exist and only a single delta can be supplied
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronRouter singleton = input.getSingleton();
+ NeutronRouter original = routerInterface.getRouter(routerUUID);
+
+ /*
+ * attribute changes blocked by Neutron
+ */
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canUpdateRouter(singleton, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if the external gateway info is being changed, verify that the new network
+ * exists and has been designated as an external network
+ */
+ if (singleton.getExternalGatewayInfo() != null) {
+ String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+ if (!networkInterface.networkExists(externNetworkPtr))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ }
+
+ /*
+ * update the router entry and return the modified object
+ */
+ routerInterface.updateRouter(routerUUID, singleton);
+ NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterUpdated(updatedRouter);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+
+ }
+
+ /**
+ * Deletes a Router */
+
+ @Path("{routerUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteRouter(
+ @PathParam("routerUUID") String routerUUID) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify that the router exists and is not in use before removing it
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (routerInterface.routerInUse(routerUUID))
+ return Response.status(409).build();
+ NeutronRouter singleton = routerInterface.getRouter(routerUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDeleteRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ routerInterface.removeRouter(routerUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+
+ /**
+ * Adds an interface to a router */
+
+ @Path("{routerUUID}/add_router_interface")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouterInterfaces.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response addRouterInterface(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouter_Interface input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
+ * or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(400).build();
+ NeutronRouter target = routerInterface.getRouter(routerUUID);
+ if (input.getSubnetUUID() == null ||
+ input.getPortUUID() == null)
+ return Response.status(400).build();
+
+ // check that the port is part of the subnet
+ NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (targetSubnet == null)
+ return Response.status(400).build();
+ NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
+ if (targetPort == null)
+ return Response.status(400).build();
+ if (!targetSubnet.getPortsInSubnet().contains(targetPort))
+ return Response.status(400).build();
+
+ if (targetPort.getFixedIPs().size() != 1)
+ return Response.status(400).build();
+ if (targetPort.getDeviceID() != null ||
+ targetPort.getDeviceOwner() != null)
+ return Response.status(409).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canAttachInterface(target, input);
+ }
+ }
+
+ //mark the port device id and device owner fields
+ targetPort.setDeviceOwner("network:router_interface");
+ targetPort.setDeviceID(routerUUID);
+
+ target.addInterface(input.getPortUUID(), input);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceAttached(target, input);
+ }
+ }
+
+ return Response.status(200).entity(input).build();
+ }
+
+ /**
+ * Removes an interface to a router */
+
+ @Path("{routerUUID}/remove_router_interface")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouterInterfaces.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response removeRouterInterface(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouter_Interface input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // verify the router exists
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(400).build();
+ NeutronRouter target = routerInterface.getRouter(routerUUID);
+
+ /*
+ * remove by subnet id. Collect information about the impacted router for the response and
+ * remove the port corresponding to the gateway IP address of the subnet
+ */
+ if (input.getPortUUID() == null &&
+ input.getSubnetUUID() != null) {
+ NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
+ if (port == null)
+ return Response.status(404).build();
+ input.setPortUUID(port.getID());
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canDetachInterface(target, input);
+ }
+ }
+
+ // reset the port ownership
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+
+ target.removeInterface(input.getPortUUID());
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ /*
+ * remove by port id. collect information about the impacted router for the response
+ * remove the interface and reset the port ownership
+ */
+ if (input.getPortUUID() != null &&
+ input.getSubnetUUID() == null) {
+ NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
+ input.setSubnetUUID(targetInterface.getSubnetUUID());
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+ NeutronPort port = portInterface.getPort(input.getPortUUID());
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+ target.removeInterface(input.getPortUUID());
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ /*
+ * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid
+ * IP address for the subnet, and then remove the interface, collecting information about the
+ * impacted router for the response and reset port ownership
+ */
+ if (input.getPortUUID() != null &&
+ input.getSubnetUUID() != null) {
+ NeutronPort port = portInterface.getPort(input.getPortUUID());
+ NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
+ return Response.status(409).build();
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canDetachInterface(target, input);
+ }
+ }
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+ target.removeInterface(input.getPortUUID());
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ // have to specify either a port ID or a subnet ID
+ return Response.status(400).build();
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronSubnetRequest {\r
- // See OpenStack Network API v2.0 Reference for description of\r
- // annotated attributes\r
-\r
- @XmlElement(name="subnet")\r
- NeutronSubnet singletonSubnet;\r
-\r
- @XmlElement(name="subnets")\r
- List<NeutronSubnet> bulkRequest;\r
-\r
- NeutronSubnetRequest() {\r
- }\r
-\r
- NeutronSubnetRequest(List<NeutronSubnet> bulk) {\r
- bulkRequest = bulk;\r
- singletonSubnet = null;\r
- }\r
-\r
- NeutronSubnetRequest(NeutronSubnet subnet) {\r
- singletonSubnet = subnet;\r
- }\r
-\r
- public NeutronSubnet getSingleton() {\r
- return singletonSubnet;\r
- }\r
-\r
- public List<NeutronSubnet> getBulk() {\r
- return bulkRequest;\r
- }\r
-\r
- public boolean isSingleton() {\r
- return (singletonSubnet != null);\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnetRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="subnet")
+ NeutronSubnet singletonSubnet;
+
+ @XmlElement(name="subnets")
+ List<NeutronSubnet> bulkRequest;
+
+ NeutronSubnetRequest() {
+ }
+
+ NeutronSubnetRequest(List<NeutronSubnet> bulk) {
+ bulkRequest = bulk;
+ singletonSubnet = null;
+ }
+
+ NeutronSubnetRequest(NeutronSubnet subnet) {
+ singletonSubnet = subnet;
+ }
+
+ public NeutronSubnet getSingleton() {
+ return singletonSubnet;
+ }
+
+ public List<NeutronSubnet> getBulk() {
+ return bulkRequest;
+ }
+
+ public boolean isSingleton() {
+ return (singletonSubnet != null);
+ }
+}
-/*\r
- * Copyright IBM Corporation, 2013. 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
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing open DOVE internals related to Subnets\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/subnets")\r
-public class NeutronSubnetsNorthbound {\r
-\r
- private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {\r
- return o.extractFields(fields);\r
- }\r
-\r
-\r
- /**\r
- * Returns a list of all Subnets */\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackSubnets.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response listSubnets(\r
- // return fields\r
- @QueryParam("fields") List<String> fields,\r
- // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
- @QueryParam("id") String queryID,\r
- @QueryParam("network_id") String queryNetworkID,\r
- @QueryParam("name") String queryName,\r
- @QueryParam("ip_version") String queryIPVersion,\r
- @QueryParam("cidr") String queryCIDR,\r
- @QueryParam("gateway_ip") String queryGatewayIP,\r
- @QueryParam("enable_dhcp") String queryEnableDHCP,\r
- @QueryParam("tenant_id") String queryTenantID,\r
- // pagination\r
- @QueryParam("limit") String limit,\r
- @QueryParam("marker") String marker,\r
- @QueryParam("page_reverse") String pageReverse\r
- // sorting not supported\r
- ) {\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();\r
- List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
- Iterator<NeutronSubnet> i = allNetworks.iterator();\r
- while (i.hasNext()) {\r
- NeutronSubnet oSS = i.next();\r
- if ((queryID == null || queryID.equals(oSS.getID())) &&\r
- (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
- (queryName == null || queryName.equals(oSS.getName())) &&\r
- (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&\r
- (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&\r
- (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&\r
- (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&\r
- (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
- if (fields.size() > 0) {\r
- ans.add(extractFields(oSS,fields));\r
- } else {\r
- ans.add(oSS);\r
- }\r
- }\r
- }\r
- //TODO: apply pagination to results\r
- return Response.status(200).entity(\r
- new NeutronSubnetRequest(ans)).build();\r
- }\r
-\r
- /**\r
- * Returns a specific Subnet */\r
-\r
- @Path("{subnetUUID}")\r
- @GET\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackSubnets.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response showSubnet(\r
- @PathParam("subnetUUID") String subnetUUID,\r
- // return fields\r
- @QueryParam("fields") List<String> fields) {\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (!subnetInterface.subnetExists(subnetUUID)) {\r
- return Response.status(404).build();\r
- }\r
- if (fields.size() > 0) {\r
- NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);\r
- return Response.status(200).entity(\r
- new NeutronSubnetRequest(extractFields(ans, fields))).build();\r
- } else {\r
- return Response.status(200).entity(\r
- new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
- }\r
- }\r
-\r
- /**\r
- * Creates new Subnets */\r
-\r
- @POST\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackSubnets.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 201, condition = "Created"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response createSubnets(final NeutronSubnetRequest input) {\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- if (input.isSingleton()) {\r
- NeutronSubnet singleton = input.getSingleton();\r
-\r
- /*\r
- * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
- * the specified network exists, the subnet has a valid network address,\r
- * and that the gateway IP doesn't overlap with the allocation pools\r
- * *then* add the subnet to the cache\r
- */\r
- if (subnetInterface.subnetExists(singleton.getID())) {\r
- return Response.status(400).build();\r
- }\r
- if (!networkInterface.networkExists(singleton.getNetworkUUID())) {\r
- return Response.status(404).build();\r
- }\r
- if (!singleton.isValidCIDR()) {\r
- return Response.status(400).build();\r
- }\r
- if (!singleton.initDefaults()) {\r
- throw new InternalServerErrorException("subnet object could not be initialized properly");\r
- }\r
- if (singleton.gatewayIP_Pool_overlap()) {\r
- return Response.status(409).build();\r
- }\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- int status = service.canCreateSubnet(singleton);\r
- if (status < 200 || status > 299) {\r
- return Response.status(status).build();\r
- }\r
- }\r
- }\r
- subnetInterface.addSubnet(singleton);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- service.neutronSubnetCreated(singleton);\r
- }\r
- }\r
- } else {\r
- List<NeutronSubnet> bulk = input.getBulk();\r
- Iterator<NeutronSubnet> i = bulk.iterator();\r
- HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
- while (i.hasNext()) {\r
- NeutronSubnet test = i.next();\r
-\r
- /*\r
- * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
- * the specified network exists, the subnet has a valid network address,\r
- * and that the gateway IP doesn't overlap with the allocation pools,\r
- * and that the bulk request doesn't already contain a subnet with this id\r
- */\r
-\r
- if (!test.initDefaults()) {\r
- throw new InternalServerErrorException("subnet object could not be initialized properly");\r
- }\r
- if (subnetInterface.subnetExists(test.getID())) {\r
- return Response.status(400).build();\r
- }\r
- if (testMap.containsKey(test.getID())) {\r
- return Response.status(400).build();\r
- }\r
- testMap.put(test.getID(), test);\r
- if (!networkInterface.networkExists(test.getNetworkUUID())) {\r
- return Response.status(404).build();\r
- }\r
- if (!test.isValidCIDR()) {\r
- return Response.status(400).build();\r
- }\r
- if (test.gatewayIP_Pool_overlap()) {\r
- return Response.status(409).build();\r
- }\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- int status = service.canCreateSubnet(test);\r
- if (status < 200 || status > 299) {\r
- return Response.status(status).build();\r
- }\r
- }\r
- }\r
- }\r
-\r
- /*\r
- * now, each element of the bulk request can be added to the cache\r
- */\r
- i = bulk.iterator();\r
- while (i.hasNext()) {\r
- NeutronSubnet test = i.next();\r
- subnetInterface.addSubnet(test);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- service.neutronSubnetCreated(test);\r
- }\r
- }\r
- }\r
- }\r
- return Response.status(201).entity(input).build();\r
- }\r
-\r
- /**\r
- * Updates a Subnet */\r
-\r
- @Path("{subnetUUID}")\r
- @PUT\r
- @Produces({ MediaType.APPLICATION_JSON })\r
- @Consumes({ MediaType.APPLICATION_JSON })\r
- //@TypeHint(OpenStackSubnets.class)\r
- @StatusCodes({\r
- @ResponseCode(code = 200, condition = "Operation successful"),\r
- @ResponseCode(code = 400, condition = "Bad Request"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 403, condition = "Forbidden"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response updateSubnet(\r
- @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input\r
- ) {\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * verify the subnet exists and there is only one delta provided\r
- */\r
- if (!subnetInterface.subnetExists(subnetUUID)) {\r
- return Response.status(404).build();\r
- }\r
- if (!input.isSingleton()) {\r
- return Response.status(400).build();\r
- }\r
- NeutronSubnet delta = input.getSingleton();\r
- NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);\r
-\r
- /*\r
- * updates restricted by Neutron\r
- */\r
- if (delta.getID() != null || delta.getTenantID() != null ||\r
- delta.getIpVersion() != null || delta.getCidr() != null ||\r
- delta.getAllocationPools() != null) {\r
- return Response.status(400).build();\r
- }\r
-\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- int status = service.canUpdateSubnet(delta, original);\r
- if (status < 200 || status > 299) {\r
- return Response.status(status).build();\r
- }\r
- }\r
- }\r
-\r
- /*\r
- * update the object and return it\r
- */\r
- subnetInterface.updateSubnet(subnetUUID, delta);\r
- NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- service.neutronSubnetUpdated(updatedSubnet);\r
- }\r
- }\r
- return Response.status(200).entity(\r
- new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
- }\r
-\r
- /**\r
- * Deletes a Subnet */\r
-\r
- @Path("{subnetUUID}")\r
- @DELETE\r
- @StatusCodes({\r
- @ResponseCode(code = 204, condition = "No Content"),\r
- @ResponseCode(code = 401, condition = "Unauthorized"),\r
- @ResponseCode(code = 404, condition = "Not Found"),\r
- @ResponseCode(code = 409, condition = "Conflict"),\r
- @ResponseCode(code = 501, condition = "Not Implemented") })\r
- public Response deleteSubnet(\r
- @PathParam("subnetUUID") String subnetUUID) {\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
-\r
- /*\r
- * verify the subnet exists and it isn't currently in use\r
- */\r
- if (!subnetInterface.subnetExists(subnetUUID)) {\r
- return Response.status(404).build();\r
- }\r
- if (subnetInterface.subnetInUse(subnetUUID)) {\r
- return Response.status(409).build();\r
- }\r
- NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);\r
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- int status = service.canDeleteSubnet(singleton);\r
- if (status < 200 || status > 299) {\r
- return Response.status(status).build();\r
- }\r
- }\r
- }\r
-\r
- /*\r
- * remove it and return 204 status\r
- */\r
- subnetInterface.removeSubnet(subnetUUID);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
- service.neutronSubnetDeleted(singleton);\r
- }\r
- }\r
- return Response.status(204).build();\r
- }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013. 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.networkconfig.neutron.northbound;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Subnets
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/subnets")
+public class NeutronSubnetsNorthbound {
+
+ private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+
+ /**
+ * Returns a list of all Subnets */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listSubnets(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("ip_version") String queryIPVersion,
+ @QueryParam("cidr") String queryCIDR,
+ @QueryParam("gateway_ip") String queryGatewayIP,
+ @QueryParam("enable_dhcp") String queryEnableDHCP,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();
+ List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+ Iterator<NeutronSubnet> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&
+ (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&
+ (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&
+ (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(oSS,fields));
+ } else {
+ ans.add(oSS);
+ }
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Subnet */
+
+ @Path("{subnetUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showSubnet(
+ @PathParam("subnetUUID") String subnetUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (fields.size() > 0) {
+ NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Subnets */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createSubnets(final NeutronSubnetRequest input) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronSubnet singleton = input.getSingleton();
+
+ /*
+ * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+ * the specified network exists, the subnet has a valid network address,
+ * and that the gateway IP doesn't overlap with the allocation pools
+ * *then* add the subnet to the cache
+ */
+ if (subnetInterface.subnetExists(singleton.getID())) {
+ return Response.status(400).build();
+ }
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {
+ return Response.status(404).build();
+ }
+ if (!singleton.isValidCIDR()) {
+ return Response.status(400).build();
+ }
+ if (!singleton.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (singleton.gatewayIP_Pool_overlap()) {
+ return Response.status(409).build();
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ subnetInterface.addSubnet(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronSubnet> bulk = input.getBulk();
+ Iterator<NeutronSubnet> i = bulk.iterator();
+ HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronSubnet test = i.next();
+
+ /*
+ * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+ * the specified network exists, the subnet has a valid network address,
+ * and that the gateway IP doesn't overlap with the allocation pools,
+ * and that the bulk request doesn't already contain a subnet with this id
+ */
+
+ if (!test.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (subnetInterface.subnetExists(test.getID())) {
+ return Response.status(400).build();
+ }
+ if (testMap.containsKey(test.getID())) {
+ return Response.status(400).build();
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {
+ return Response.status(404).build();
+ }
+ if (!test.isValidCIDR()) {
+ return Response.status(400).build();
+ }
+ if (test.gatewayIP_Pool_overlap()) {
+ return Response.status(409).build();
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ }
+
+ /*
+ * now, each element of the bulk request can be added to the cache
+ */
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet test = i.next();
+ subnetInterface.addSubnet(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Subnet */
+
+ @Path("{subnetUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateSubnet(
+ @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input
+ ) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the subnet exists and there is only one delta provided
+ */
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (!input.isSingleton()) {
+ return Response.status(400).build();
+ }
+ NeutronSubnet delta = input.getSingleton();
+ NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getID() != null || delta.getTenantID() != null ||
+ delta.getIpVersion() != null || delta.getCidr() != null ||
+ delta.getAllocationPools() != null) {
+ return Response.status(400).build();
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canUpdateSubnet(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ subnetInterface.updateSubnet(subnetUUID, delta);
+ NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetUpdated(updatedSubnet);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+ }
+
+ /**
+ * Deletes a Subnet */
+
+ @Path("{subnetUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteSubnet(
+ @PathParam("subnetUUID") String subnetUUID) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the subnet exists and it isn't currently in use
+ */
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (subnetInterface.subnetInUse(subnetUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canDeleteSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ subnetInterface.removeSubnet(subnetUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
throw new AsynchronousCloseException();
}
- inBuffer.flip();
- msgs = factory.parseMessages(inBuffer);
- if (inBuffer.hasRemaining()) {
- inBuffer.compact();
- } else {
+ try {
+ inBuffer.flip();
+ msgs = factory.parseMessages(inBuffer);
+ if (inBuffer.hasRemaining()) {
+ inBuffer.compact();
+ } else {
+ inBuffer.clear();
+ }
+ } catch (Exception e) {
inBuffer.clear();
+ logger.debug("Caught exception: ", e);
}
return msgs;
}
peerNetData.position(), peerNetData.limit());
}
- peerAppData.flip();
- msgs = factory.parseMessages(peerAppData);
- if (peerAppData.hasRemaining()) {
- peerAppData.compact();
- } else {
+ try {
+ peerAppData.flip();
+ msgs = factory.parseMessages(peerAppData);
+ if (peerAppData.hasRemaining()) {
+ peerAppData.compact();
+ } else {
+ peerAppData.clear();
+ }
+ } catch (Exception e) {
peerAppData.clear();
+ logger.debug("Caught exception: ", e);
}
this.socket.register(this.selector, SelectionKey.OP_READ, this);
}
if (msgs == null) {
- logger.info("{} is down", this);
- reportSwitchStateChange(false);
return;
}
for (OFMessage msg : msgs) {
OFType type = msg.getType();
switch (type) {
case HELLO:
- // send feature request
- OFMessage featureRequest = factory.getMessage(OFType.FEATURES_REQUEST);
- asyncFastSend(featureRequest);
- this.state = SwitchState.WAIT_FEATURES_REPLY;
- startSwitchTimer();
+ sendFeaturesRequest();
break;
case ECHO_REQUEST:
OFEchoReply echoReply = (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
// respond immediately
asyncSendNow(echoReply, msg.getXid());
+
+ // send features request if not sent yet
+ sendFeaturesRequest();
break;
case ECHO_REPLY:
this.probeSent = false;
return this.sid;
}
+ private void sendFeaturesRequest() {
+ if (!isOperational() && (this.state != SwitchState.WAIT_FEATURES_REPLY)) {
+ // send feature request
+ OFMessage featureRequest = factory.getMessage(OFType.FEATURES_REQUEST);
+ asyncFastSend(featureRequest);
+ this.state = SwitchState.WAIT_FEATURES_REPLY;
+ startSwitchTimer();
+ }
+ }
+
private void processFeaturesReply(OFFeaturesReply reply) {
if (this.state == SwitchState.WAIT_FEATURES_REPLY) {
this.sid = reply.getDatapathId();
private boolean isDefaultContainer = true;
private static final int REPLACE_RETRY = 1;
+ /* Information about the default subnet. If there have been no configured subnets, i.e.,
+ * subnets.size() == 0 or subnetsConfigList.size() == 0, then this subnet will be the
+ * only subnet returned. As soon as a user-configured subnet is created this one will
+ * vanish.
+ */
+ protected static SubnetConfig DEFAULT_SUBNETCONFIG;
+ protected static Subnet DEFAULT_SUBNET;
+ protected static String DEFAULT_SUBNET_NAME = "default (cannot be modifed)";
+ static{
+ DEFAULT_SUBNETCONFIG = new SubnetConfig(DEFAULT_SUBNET_NAME, "0.0.0.0/0", new ArrayList<String>());
+ DEFAULT_SUBNET = new Subnet(DEFAULT_SUBNETCONFIG);
+ }
+
public void notifySubnetChange(Subnet sub, boolean add) {
synchronized (switchManagerAware) {
for (Object subAware : switchManagerAware) {
@Override
public List<SubnetConfig> getSubnetsConfigList() {
- return new ArrayList<SubnetConfig>(subnetsConfigList.values());
+ // if there are no subnets, return the default subnet
+ if(subnetsConfigList.size() == 0){
+ return Collections.singletonList(DEFAULT_SUBNETCONFIG);
+ }else{
+ return new ArrayList<SubnetConfig>(subnetsConfigList.values());
+ }
}
@Override
public SubnetConfig getSubnetConfig(String subnet) {
- return subnetsConfigList.get(subnet);
+ // if there are no subnets, return the default subnet
+ if(subnetsConfigList.size() == 0 && subnet == DEFAULT_SUBNET_NAME){
+ return DEFAULT_SUBNETCONFIG;
+ }else{
+ return subnetsConfigList.get(subnet);
+ }
}
private List<SpanConfig> getSpanConfigList(Node node) {
@Override
public Subnet getSubnetByNetworkAddress(InetAddress networkAddress) {
+ // if there are no subnets, return the default subnet
+ if (subnets.size() == 0) {
+ return DEFAULT_SUBNET;
+ }
+
Subnet sub;
Set<InetAddress> indices = subnets.keySet();
for (InetAddress i : indices) {