--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.alto</groupId>
+ <artifactId>alto-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>alto-config</artifactId>
+ <packaging>jar</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/03-alto.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:alto="urn:opendaylight:params:xml:ns:yang:controller:config:alto-provider:impl">
+ alto:alto-provider-impl
+ </type>
+ <name>alto-provider-impl</name>
+
+ <rpc-registry>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+
+ <data-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <name>binding-data-broker</name>
+ </data-broker>
+ </module>
+ </modules>
+ </data>
+
+ </configuration>
+
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:alto-provider:impl?module=alto-provider-impl&revision=2014-11-19</capability>
+ </required-capabilities>
+
+</snapshot>
+
--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.alto</groupId>
+ <artifactId>alto-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+
+ <properties>
+ <configfile>default.networkmap</configfile>
+ </properties>
+
+ <artifactId>alto-manager</artifactId>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <version>2.2.11</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient-osgi</artifactId>
+ <version>${httpclient.version}</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore-osgi</artifactId>
+ <version>${httpclient.version}</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.apache.felix.service.command,
+ org.apache.felix.gogo.commands,
+ org.apache.karaf.shell.console,
+ org.apache.http.*,
+ *
+ </Import-Package>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <target>1.7</target>
+ <source>1.7</source>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${configfile}</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.opendaylight.alto.manager;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.ParseException;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+
+@Command(scope = "alto", name = "load", description = "Alto Manager")
+public class AltoManager extends OsgiCommandSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(AltoManager.class);
+ private JsonFactory jsonF = new JsonFactory();
+ private HttpClient httpClient;
+
+ public AltoManager () {
+ httpClient = initiateHttpClient();
+ log.info(this.getClass().getName() + " Initiated");
+ }
+
+ private HttpClient initiateHttpClient() {
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(AuthScope.ANY,
+ new UsernamePasswordCredentials("admin:admin"));
+ return HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
+ }
+
+ @Argument(index = 0, name = "map type", description = "Map Type", required = true, multiValued = false)
+ String type = null;
+
+ @Argument(index = 1, name = "map path", description = "Map Path", required = true, multiValued = false)
+ String path = null;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ if (AltoManagerConstants.SERVICE_TYPE.NETWORK.toString().toLowerCase().equals(type)) {
+ putNetworkMap();
+ } else if (AltoManagerConstants.SERVICE_TYPE.RESOURCE.toString().toLowerCase().equals(type)) {
+ putResources();
+ }
+ return null;
+ }
+
+ private void putResources() throws IOException {
+ log.info("Loading Resources From " + path);
+ String data = readFromFile(path);
+ httpPut(AltoManagerConstants.HOST, data);
+ }
+
+ private void putNetworkMap() throws IOException {
+ log.info("Loading Network Map From " + this.path);
+ String data = readFromFile(path);
+ String resourceId = resourceIdFromNetworkMap(data);
+ if (resourceId == null) {
+ log.info("Cannot parse resourceId, abort loading");
+ return;
+ }
+ String url = AltoManagerConstants.NETWORK_MAP_HOST + resourceId;
+ log.info("Url: " + url);
+ httpPut(url, data);
+ }
+
+ private void httpPut(String url, String data) throws IOException {
+ HttpPut httpput = new HttpPut(url);
+ httpput.setHeader(HTTP.CONTENT_TYPE, AltoManagerConstants.JSON_CONTENT_TYPE);
+ httpput.setEntity(new StringEntity(data));
+ HttpResponse response = httpClient.execute(httpput);
+ handleResponse(response);
+ }
+
+ private String readFromFile(String path) throws IOException {
+ return new String(Files.readAllBytes(Paths.get(path)),
+ StandardCharsets.UTF_8);
+ }
+
+ private void handleResponse(HttpResponse response) throws ParseException, IOException {
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ String body = EntityUtils.toString(entity);
+ if (response.getStatusLine().getStatusCode()== 200) {
+ log.info("Loading Succesfully.");
+ } else {
+ log.error("Failed to load file \n" + body);
+ }
+ }
+ }
+
+ private String resourceIdFromNetworkMap(String jsonString) throws JsonParseException, IOException {
+ JsonParser jParser = jsonF.createParser(jsonString);
+ while (jParser.nextToken() != JsonToken.END_OBJECT) {
+ String fieldname = jParser.getCurrentName();
+ if (AltoManagerConstants.RESOURCE_ID_LABEL.equals(fieldname)) {
+ jParser.nextToken();
+ String resourceId = jParser.getText();
+ return resourceId;
+ }
+ }
+ return null;
+ }
+
+ private void postResources(String path) throws IOException {
+ log.info("Loading Resources From " + path);
+ String content = readFromFile(path);
+
+ HttpPost httppost = new HttpPost(AltoManagerConstants.HOST);
+ httppost.setHeader(HTTP.CONTENT_TYPE, AltoManagerConstants.JSON_CONTENT_TYPE);
+ httppost.setEntity(new StringEntity(content));
+ HttpResponse response = httpClient.execute(httppost);
+ handleResponse(response);
+ }
+}
--- /dev/null
+package org.opendaylight.alto.manager;
+
+public class AltoManagerConstants {
+ public static final String HOST = "http://127.0.0.1:8181/restconf/config/";
+ public static final String MODULE = "alto-service";
+ public static final String JSON_CONTENT_TYPE = "application/yang.data+json";
+
+ public static final String RESOURCES_LABEL = MODULE + ":resources";
+ public static final String NETWORK_MAPS_LABEL = MODULE + ":network-maps";
+ public static final String NETWORK_MAP_LABEL = MODULE + ":network-map";
+
+ public static final String RESOURCE_ID_LABEL = MODULE + ":resource-id";
+
+ public static final String RESOURCES_HOST = HOST + RESOURCES_LABEL + "/";
+ public static final String NETWORK_MAPS_HOST = RESOURCES_HOST + NETWORK_MAPS_LABEL + "/";
+ public static final String NETWORK_MAP_HOST = NETWORK_MAPS_HOST + NETWORK_MAP_LABEL + "/";
+
+ public static final String DEFAULT_RESOURCES_PATH = "configuration/default.networkmap";
+
+ public static enum SERVICE_TYPE{
+ RESOURCE, NETWORK, COST
+ }
+}
--- /dev/null
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
+ <command name="alto/load">
+ <action class="org.opendaylight.alto.manager.AltoManager"/>
+ </command>
+ </command-bundle>
+</blueprint>
--- /dev/null
+{"alto-service:resources":{"alto-service:network-maps":{"alto-service:network-map":[{"alto-service:resource-id":"my-default-network-map","alto-service:tag":"da65eca2eb7a10ce8b059740b0b2e3f8eb1d4785","alto-service:map":[{"alto-service:pid":"PID1","alto-service:endpoint-address-group":[{"alto-service:address-type":"ipv4","alto-service:endpoint-prefix":["192.0.2.0/24","198.51.100.0/25"]}]},{"alto-service:pid":"PID2","alto-service:endpoint-address-group":[{"alto-service:address-type":"ipv4","alto-service:endpoint-prefix":["198.51.100.128/25"]}]},{"alto-service:pid":"PID3","alto-service:endpoint-address-group":[{"alto-service:address-type":"ipv4","alto-service:endpoint-prefix":["0.0.0.0/0"]},{"alto-service:address-type":"ipv6","alto-service:endpoint-prefix":["::/0"]}]}]}]}}}
--- /dev/null
+package org.opendaylight.alto;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
public class EndpointAddressTypeBuilder {
public static EndpointAddressType getDefaultInstance(java.lang.String defaultValue) {
- throw new java.lang.UnsupportedOperationException("Not yet implemented");
+ if ("ipv4".equals(defaultValue)) {
+ return new EndpointAddressType(EndpointAddressType.Enumeration.Ipv4);
+ } else if ("ipv6".equals(defaultValue)) {
+ return new EndpointAddressType(EndpointAddressType.Enumeration.Ipv6);
+ }
+
+ throw new java.lang.UnsupportedOperationException("Wrong EndpointAddressType");
}
}
<artifactId>alto-model</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>alto-commons</artifactId>
- <version>${project.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
- <Export-Package>org.opendaylight.controller.config.yang.alto_provider,</Export-Package>
+ <Export-Package>org.opendaylight.alto.provider.*;</Export-Package>
<Import-Package>*</Import-Package>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
</instructions>
</configuration>
</plugin>
</execution>
</executions>
</plugin>
-
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/${configfile}</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<scm>
-package org.opendaylight.controller.alto.provider;
+package org.opendaylight.alto.provider;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-import org.opendaylight.alto.commons.types.mapper.JSONMapper;
import org.opendaylight.controller.config.yang.config.alto_provider.impl.AltoProviderRuntimeMXBean;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.AltoServiceService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredNetworkMapServiceInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.FilteredNetworkMapServiceOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.Resources;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.ResourcesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.NetworkMaps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.NetworkMapsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMap;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
public class AltoProvider implements AltoServiceService, DataChangeListener,
AltoProviderRuntimeMXBean, AutoCloseable {
- private static final Logger LOG = LoggerFactory.getLogger(AltoProvider.class);
+ private static final Logger log = LoggerFactory.getLogger(AltoProvider.class);
public static final InstanceIdentifier<Resources> ALTO_IID = InstanceIdentifier
.builder(Resources.class).build();
- private static final Path configFilePath = Paths.get("configuration/default.networkmap");
- private JSONMapper jsonMapper = new JSONMapper();
-
private DataBroker dataProvider;
private final ExecutorService executor;
public AltoProvider() {
- this.executor = Executors.newFixedThreadPool(1);
+ this.executor = Executors.newFixedThreadPool(1);
}
public void setDataProvider(final DataBroker salDataProvider) {
this.dataProvider = salDataProvider;
- this.dataProvider.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, ALTO_IID, this, DataChangeScope.SUBTREE);
- setResourcesStatusUp(null);
- }
-
- private Resources buildResources() {
- try {
- return new ResourcesBuilder()
- .setNetworkMaps(loadNetworkMaps())
- .build();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- private NetworkMaps loadNetworkMaps() throws Exception {
- return new NetworkMapsBuilder()
- .setNetworkMap(loadNetworkMapList())
- .build();
+ log.info(this.getClass().getName() + " data provider initiated");
}
- private List<NetworkMap> loadNetworkMapList() {
- List<NetworkMap> networkMapList = new ArrayList<NetworkMap>();
- try {
- String content = new String(Files.readAllBytes(configFilePath), StandardCharsets.UTF_8);
- networkMapList.add(jsonMapper.asNetworkMap(content).asYangNetworkMap());
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return networkMapList;
- }
-
@Override
public void onDataChanged(
final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
DataObject dataObject = change.getUpdatedSubtree();
if (dataObject instanceof Resources) {
Resources altoResources = (Resources) dataObject;
- LOG.info("onDataChanged - new ALTO config: {}", altoResources);
+ log.info("onDataChanged - new ALTO config: {}", altoResources);
}
}
- private void setResourcesStatusUp(final Function<Boolean, Void> resultCallback) {
- WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
- tx.put(LogicalDatastoreType.OPERATIONAL, ALTO_IID, buildResources());
-
- Futures.addCallback(tx.submit(), new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- notifyCallback(true);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("Failed to initiate resources", t);
- notifyCallback(false);
- }
-
- void notifyCallback(final boolean result) {
- if (resultCallback != null) {
- resultCallback.apply(result);
- }
- }
- });
- }
-
@Override
public Future<RpcResult<EndpointCostServiceOutput>> endpointCostService(
EndpointCostServiceInput input) {
executor.shutdown();
if (dataProvider != null) {
WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
- tx.delete(LogicalDatastoreType.OPERATIONAL, ALTO_IID);
+ tx.delete(LogicalDatastoreType.CONFIGURATION, ALTO_IID);
Futures.addCallback(tx.submit(), new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
- LOG.debug("Delete ALTO commit result: " + result);
+ log.debug("Delete ALTO commit result: " + result);
}
@Override
public void onFailure(final Throwable t) {
- LOG.error("Delete of ALTO failed", t);
+ log.error("Delete of ALTO failed", t);
}
});
}
+++ /dev/null
-package org.opendaylight.controller.alto.provider;
-
-import java.io.IOException;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.ClosedWatchServiceException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.PathMatcher;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchEvent;
-import java.nio.file.WatchKey;
-import java.nio.file.WatchService;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.opendaylight.alto.commons.types.mapper.JSONMapper;
-import org.opendaylight.alto.commons.types.rfc7285.AltoNetworkMap;
-import org.opendaylight.alto.commons.types.rfc7285.VersionTag;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FileSystemNetworkMapGenerator implements Runnable, AutoCloseable {
-
- private static final Logger logger = LoggerFactory.getLogger(FileSystemNetworkMapGenerator.class);
-
- private ReentrantLock lock = new ReentrantLock();
- private Path source = null;
- private WatchService watcher = null;
- private HashMap<Path, WatchKey> keys = new HashMap<Path, WatchKey>();
- private HashMap<WatchKey, Path> paths = new HashMap<WatchKey, Path>();
- private MapFileLoader loader = null;
- private AtomicBoolean cancelled = new AtomicBoolean(false);
- private HashMap<Path, VersionTag> path_to_id = new HashMap<Path, VersionTag>();
- private HashMap<VersionTag, AltoNetworkMap> id_to_map = new HashMap<VersionTag, AltoNetworkMap>();
- private JSONMapper jsonMapper = new JSONMapper();
-
- public FileSystemNetworkMapGenerator(URI uri) throws Exception {
- source = Paths.get(uri);
-
- FileSystem fs = source.getFileSystem();
- watcher = fs.newWatchService();
- if (watcher == null) {
- throw new IOException("Unable to create watcher on given uri: " + uri);
- }
-
- onCreateDir(source);
- loader = new MapFileLoader(fs);
- Files.walkFileTree(source, loader);
- }
-
- class MapFileLoader extends SimpleFileVisitor<Path> {
- private PathMatcher matcher = null;
-
- MapFileLoader(FileSystem fs) {
- matcher = fs.getPathMatcher("glob:**/*.{networkmap}");
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- lock.lock();
- onCreateDir(dir);
- lock.unlock();
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- logger.info("visiting file: " + file.toString());
- if (file.toFile().isFile()) {
- if (matcher.matches(file)) {
- lock.lock();
- onCreate(file);
- lock.unlock();
- }
- }
- return FileVisitResult.CONTINUE;
- }
- }
-
- public void run() {
- while (!cancelled.get()) {
- WatchKey key;
- try {
- key = watcher.take();
- } catch (ClosedWatchServiceException e) {
- System.out.println(e);
- break;
- } catch (Exception e) {
- System.out.println(e);
- continue;
- }
-
- for (WatchEvent<?> event: key.pollEvents()) {
- WatchEvent.Kind<?> kind = event.kind();
-
- if (kind == StandardWatchEventKinds.OVERFLOW)
- continue;
-
- WatchEvent<Path> ev = (WatchEvent<Path>)event;
- lock.lock();
- Path dir = paths.get(key);
- Path file = dir.resolve(ev.context());
-
- if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
- if (file.toFile().isFile())
- onCreate(file);
- else if (file.toFile().isDirectory())
- onCreateDir(file);
- } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
- if (file.toFile().isFile())
- onDelete(file);
- else if (file.toFile().isDirectory())
- onDeleteDir(file);
- } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
- if (file.toFile().isFile())
- onModify(file);
- else if (file.toFile().isDirectory())
- onModifyDir(file);
- }
- lock.unlock();
- }
-
- boolean valid = key.reset();
- if (!valid) {
- Path dir = paths.get(key);
- keys.remove(dir);
- paths.remove(key);
-
- if (keys.isEmpty())
- break;
- }
- }
- cleanup();
- }
-
- private void cleanup() {
- lock.lock();
- for (WatchKey key: keys.values()) {
- try {
- if (key != null) {
- key.cancel();
- }
- } catch (Exception e) {
- }
- }
- keys.clear();
- paths.clear();
- try {
- if (watcher != null) {
- watcher.close();
- watcher = null;
- }
- } catch (Exception e) {
- }
-
- path_to_id.clear();
- id_to_map.clear();
- lock.unlock();
- }
-
- public void close() {
- cancelled.set(true);
- cleanup();
- }
-
- private void onCreate(Path file) {
- try {
- String content = new String(Files.readAllBytes(file), StandardCharsets.US_ASCII);
- AltoNetworkMap map = jsonMapper.asNetworkMap(content);
- VersionTag vtag = map.meta.vtag;
- logger.info("vtag: <" + vtag.rid + ", " + vtag.tag + ">");
- if (id_to_map.get(map.meta.vtag) != null) {
- logger.warn("Version tag already registered: ("
- + vtag.rid + ", " + vtag.tag + ")");
- return;
- }
- path_to_id.put(file, map.meta.vtag);
- id_to_map.put(map.meta.vtag, map);
- logger.info("create successfully: " + file.toString());
- logger.info("current maps: " + id_to_map.size());
- } catch (Exception e) {
- logger.warn("Error while creating " + file.toString());
- logger.warn(e.toString());
- }
- }
-
- private void onCreateDir(Path dir) {
- try {
- WatchKey key = dir.register(watcher,
- StandardWatchEventKinds.ENTRY_CREATE,
- StandardWatchEventKinds.ENTRY_DELETE,
- StandardWatchEventKinds.ENTRY_MODIFY);
- keys.put(dir, key);
- paths.put(key, dir);
- logger.info("create dir successfully: " + dir.toString());
- } catch (Exception e) {
- logger.warn(e.toString());
- }
- }
-
- private void onDelete(Path file) {
- //TODO
- try {
- VersionTag vtag = path_to_id.get(file);
- if (vtag == null)
- return;
-
- id_to_map.remove(vtag);
- logger.info("delete: " + file.toString());
- } catch (Exception e) {
- logger.warn("Error while deleting " + file.toString());
- logger.warn(e.toString());
- }
- }
-
- private void onDeleteDir(Path dir) {
- // TODO
- try {
- WatchKey key = keys.get(dir);
- if (key != null) {
- key.cancel();
-
- keys.remove(dir);
- paths.remove(key);
- }
- logger.warn("delete dir successfully: " + dir.toString());
- } catch (Exception e) {
- logger.warn(e.toString());
- }
- }
-
- private void onModify(Path file) {
- try {
- String content = new String(Files.readAllBytes(file), StandardCharsets.US_ASCII);
- AltoNetworkMap map = jsonMapper.asNetworkMap(content);
- VersionTag vtag = map.meta.vtag;
- VersionTag old = path_to_id.get(file);
-
- if (old != null) {
- if (vtag.rid != old.rid) {
- throw new Exception("defining another map in one file is not allowed");
- }
- id_to_map.remove(old);
- }
- path_to_id.put(file, vtag);
- id_to_map.put(vtag, map);
- logger.info("modify successfully: " + file.toString());
- } catch (Exception e) {
- logger.warn("Error while modifying " + file.toString());
- logger.warn(e.toString());
- }
- }
-
- private void onModifyDir(Path dir) {
- onDeleteDir(dir);
- onModifyDir(dir);
- }
-
- public List<NetworkMap> getYangNetworkMaps() {
- List<AltoNetworkMap> networkMapList = new ArrayList<AltoNetworkMap>(id_to_map.values());
- List<NetworkMap> list = new ArrayList<NetworkMap>();
- for (AltoNetworkMap map : networkMapList) {
- list.add(map.asYangNetworkMap());
- }
- return list;
- }
-}
package org.opendaylight.controller.config.yang.config.alto_provider.impl;
-import org.opendaylight.controller.alto.provider.AltoProvider;
+import org.opendaylight.alto.provider.AltoProvider;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.AltoServiceService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AltoProviderModule extends AbstractAltoProviderModule {
+ private static final Logger log = LoggerFactory.getLogger(AltoProviderModule.class);
+
public AltoProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
super(identifier, dependencyResolver);
}
final BindingAwareBroker.RpcRegistration<AltoServiceService> rpcRegistration = getRpcRegistryDependency()
.addRpcImplementation(AltoServiceService.class, altoProvider);
+
+ final ListenerRegistration<DataChangeListener> altoDataChangeListenerRegistration =
+ dataBrokerService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, AltoProvider.ALTO_IID, altoProvider, DataChangeScope.SUBTREE);
final AltoProviderRuntimeRegistration runtimeReg = getRootRuntimeBeanRegistratorWrapper().register(altoProvider);
final class AutoCloseableAlto implements AutoCloseable {
@Override
public void close() throws Exception {
rpcRegistration.close();
+ altoDataChangeListenerRegistration.close();
runtimeReg.close();
altoProvider.close();
}
+++ /dev/null
-{"meta":{"vtag":{"resource-id":"my-default-network-map","tag":"da65eca2eb7a10ce8b059740b0b2e3f8eb1d4785"}},"network-map":{"PID1":{"ipv4": ["192.0.2.0/24","198.51.100.0/25"]},"PID2":{"ipv4": ["198.51.100.128/25"]},"PID3":{"ipv4": ["0.0.0.0/0"],"ipv6": ["::/0"]}}}
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-config</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>alto-northbound</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-manager</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient-osgi</artifactId>
+ <version>${httpclient.version}</version>
+ <type>bundle</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore-osgi</artifactId>
+ <version>${httpclient.version}</version>
+ <type>bundle</type>
+ </dependency>
</dependencies>
<build>
<repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
<repository>mvn:org.opendaylight.controller/features-restconf/${mdsal.version}/xml/features</repository>
- <feature name='odl-alto-all' version='${project.version}' description='OpenDaylight :: alto :: all '>
+ <feature name='odl-alto-all' version='${project.version}' description='OpenDaylight :: alto :: All '>
<feature version='${project.version}'>odl-alto-provider</feature>
+ <feature version='${project.version}'>odl-alto-manager</feature>
<feature version='${project.version}'>odl-alto-northbound</feature>
</feature>
- <feature name='odl-alto-model' version='${project.version}' description='OpenDaylight :: alto :: model '>
+ <feature name='odl-alto-model' version='${project.version}' description='OpenDaylight :: alto :: Model '>
<feature version='${yangtools.version}'>odl-yangtools-models</feature>
+ <feature version='${yangtools.version}'>odl-yangtools-binding</feature>
<bundle>mvn:org.opendaylight.alto/alto-model/${project.version}</bundle>
</feature>
- <feature name='odl-alto-commons' version='${project.version}' description='OpenDaylight :: alto :: commons'>
+ <feature name='odl-alto-provider' version='${project.version}' description='OpenDaylight :: alto :: Provider'>
<feature version='${project.version}'>odl-alto-model</feature>
- <feature version='${jackson.version}'>odl-base-jackson</feature>
- <bundle>mvn:org.opendaylight.alto/alto-commons/${project.version}</bundle>
- </feature>
-
- <feature name='odl-alto-provider' version='${project.version}' description='OpenDaylight :: alto :: provider'>
- <feature version='${project.version}'>odl-alto-commons</feature>
- <feature version='${mdsal.version}'>odl-mdsal-common</feature>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature version='${config.version}'>odl-config-api</feature>
- <configfile finalname="configuration/default.networkmap">mvn:org.opendaylight.alto/alto-provider/${project.version}/xml/config</configfile>
+ <configfile finalname="etc/opendaylight/karaf/03-alto.xml">mvn:org.opendaylight.alto/alto-config/${project.version}/xml/config</configfile>
<bundle>mvn:org.opendaylight.alto/alto-provider/${project.version}</bundle>
</feature>
- <feature name='odl-alto-services' version='${project.version}' description='OpenDaylight :: alto :: services'>
+ <feature name='odl-alto-manager' version='${project.version}' description='OpenDaylight :: alto :: Provider'>
+ <feature version='${jackson.version}'>odl-base-jackson</feature>
+ <configfile finalname="configuration/default.networkmap">mvn:org.opendaylight.alto/alto-manager/${project.version}/xml/config</configfile>
+ <bundle>mvn:org.apache.httpcomponents/httpclient-osgi/${httpclient.version}</bundle>
+ <bundle>mvn:org.apache.httpcomponents/httpcore-osgi/${httpclient.version}</bundle>
+ <bundle>mvn:org.opendaylight.alto/alto-manager/${project.version}</bundle>
+ </feature>
+
+ <feature name='odl-alto-services' version='${project.version}' description='OpenDaylight :: alto :: Services'>
<feature version='${project.version}'>odl-alto-commons</feature>
<feature version='${mdsal.version}'>odl-mdsal-common</feature>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+ <feature version='${jackson.version}'>odl-base-jackson</feature>
+ <bundle>mvn:org.opendaylight.alto/alto-commons/${project.version}</bundle>
<bundle>mvn:org.opendaylight.alto/alto-services/${project.version}</bundle>
</feature>
- <feature name='odl-alto-northbound' version='${project.version}' description='Opendaylight :: alto :: northbound'>
+ <feature name='odl-alto-northbound' version='${project.version}' description='Opendaylight :: alto :: Northbound'>
<feature version='${project.version}'>odl-alto-services</feature>
<feature version='${jersey.version}'>odl-base-jersey</feature>
<feature version='${war.version}'>war</feature>
<bundle>mvn:org.opendaylight.alto/alto-northbound/${project.version}</bundle>
</feature>
- <!-- TODO need to create such a configuration file
- <configfile finalname="alto-provider-default-config.xml">mvn:org.opendaylight.alto/alto-provider/${project.version}/xml/config</configfile>
- -->
-
<!-- TODO not implemented yet
- <feature name='odl-alto-provider' version='${project.version}' description='OpenDaylight :: alto :: provider '>
- <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature version='${project.version}'>odl-alto-model</feature>
- <bundle>mvn:org.opendaylight.alto/alto-provider/${project.version}</bundle>
- </feature>
<feature name='odl-alto-provider-rest' version='${project.version}' description='OpenDaylight :: alto :: provider :: REST '>
<feature version="${project.version}">odl-alto-provider</feature>
<feature version="${mdsal.version}">odl-restconf</feature>
<packaging>pom</packaging>
<properties>
+ <httpclient.version>4.4.1</httpclient.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<checkstyle.skip>true</checkstyle.skip>
<ovsdb.southbound.version>1.1.0-SNAPSHOT</ovsdb.southbound.version>
<!-- Supporting Libraries -->
- <slf4j.version>1.7.5</slf4j.version>
+ <slf4j.version>1.7.2</slf4j.version>
<feature.openflowplugin.version>0.1.0-SNAPSHOT</feature.openflowplugin.version>
<branding.version>1.1.0-SNAPSHOT</branding.version>
<modules>
<module>alto-model</module>
+ <module>alto-config</module>
<module>alto-provider</module>
<module>alto-artifacts</module>
<module>features</module>
<module>alto-commons</module>
+ <module>alto-manager</module>
<module>alto-services</module>
<!--
<module>alto-karaf</module>