maven-eclipse.xml
.DS_STORE
.metadata
+*.swp
+**/*.swp
<configuration>
<instructions>
<Import-Package>
+ com.fasterxml.jackson.annotation,
+ com.fasterxml.jackson.databind,
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924,
</Import-Package>
<Export-Package>
org.opendaylight.alto.commons.*;
+ org.opendaylight.alto.commons.types.*;
+ org.opendaylight.alto.commons.types.rfc7285.*;
</Export-Package>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
</instructions>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
</dependencies>
</project>
+++ /dev/null
-/*
- * Copyright (c) 2015 Yale University 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.alto.commons.types;
-
-public class Errors {
- /** TODO Might need to check [RFC7285] to confirm the error literals
- * */
- public static final String SYNTAX_ERROR = "syntax-error";
- public static final String MISSING_FIELD = "missing-field";
- public static final String INVALID_FIELD_TYPE = "invalid-type";
- public static final String INVALID_FIELD_VALUE = "invalid-value";
-
- /** TODO Determine error code for ALTO Errors
- * */
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Yale University 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.alto.commons.types;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType;
-
-class YangModelMediaType {
-
- /** The media types generated by alto-model
- * */
-
- public static final String ALTO_DIRECTORY
- = new MediaType(MediaType.Enumeration.AltoDirectory).toString();
- public static final String ALTO_NETWORKMAP
- = new MediaType(MediaType.Enumeration.AltoNetworkmap).toString();
- public static final String ALTO_NETWORKMAP_FILTER
- = new MediaType(MediaType.Enumeration.AltoNetworkmapfilter).toString();
- public static final String ALTO_COSTMAP
- = new MediaType(MediaType.Enumeration.AltoCostmap).toString();
- public static final String ALTO_COSTMAP_FILTER
- = new MediaType(MediaType.Enumeration.AltoCostmapfilter).toString();
- public static final String ALTO_ENDPOINT_PROP
- = new MediaType(MediaType.Enumeration.AltoEndpointprop).toString();
- public static final String ALTO_ENDPOINT_PROPPARAMS
- = new MediaType(MediaType.Enumeration.AltoEndpointpropparams).toString();
- public static final String ALTO_ENDPOINT_COST
- = new MediaType(MediaType.Enumeration.AltoEndpointcost).toString();
- public static final String ALTO_ENDPOST_COSTPARAMS
- = new MediaType(MediaType.Enumeration.AltoEndpointcostparams).toString();
- public static final String ALTO_ERROR
- = new MediaType(MediaType.Enumeration.AltoError).toString();
-}
--- /dev/null
+/*
+ * Copyright (c) 2015 Yale University 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.alto.commons.types.alto.model.rev141101;
+
+class MediaType {
+
+ /** The media types generated by alto-model
+ * */
+
+ public static final String ALTO_DIRECTORY
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoDirectory
+ ).toString();
+
+ public static final String ALTO_NETWORKMAP
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoNetworkmap
+ ).toString();
+
+ public static final String ALTO_NETWORKMAP_FILTER
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoNetworkmapfilter
+ ).toString();
+
+ public static final String ALTO_COSTMAP
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoCostmap
+ ).toString();
+
+ public static final String ALTO_COSTMAP_FILTER
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoCostmapfilter
+ ).toString();
+
+ public static final String ALTO_ENDPOINT_PROP
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoEndpointprop
+ ).toString();
+
+ public static final String ALTO_ENDPOINT_PROPPARAMS
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoEndpointpropparams
+ ).toString();
+
+ public static final String ALTO_ENDPOINT_COST
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoEndpointcost
+ ).toString();
+
+ public static final String ALTO_ENDPOST_COSTPARAMS
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoEndpointcostparams
+ ).toString();
+
+ public static final String ALTO_ERROR
+ = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType.Enumeration.AltoError
+ ).toString();
+
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Cost Map: defined in RFC7285 secion 11.2.3
+ * */
+public class CostMap {
+
+ public static class Meta extends Extensible {
+
+ @JsonProperty("dependent-vtags")
+ public List<VersionTag> netmap_tags;
+
+ @JsonProperty("cost-type")
+ public CostType costType;
+ }
+
+ /**
+ * for filtered-cost-map service, RFC7285 secion 11.3.2
+ * */
+ public static class Filter {
+
+ @JsonProperty("cost-type")
+ public CostType costType;
+
+ @JsonProperty("pids")
+ public QueryPairs pids;
+ }
+
+ @JsonProperty("meta")
+ public Meta meta;
+
+ @JsonProperty("cost-map")
+ public Map<String, Map<String, Object>> map
+ = new LinkedHashMap<String, Map<String, Object>>();
+
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Arrays;
+
+public class CostType {
+
+ @JsonProperty("cost-metric")
+ public String metric;
+
+ @JsonProperty("cost-mode")
+ public String mode;
+
+ @JsonProperty("description")
+ public String description;
+
+ @Override
+ public int hashCode() {
+ String[] members = { metric, mode };
+ return Arrays.hashCode(members);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!(obj != null ? (obj instanceof CostType) : false))
+ return false;
+
+ CostType other = (CostType)obj;
+ String[] lhs = { metric, mode };
+ String[] rhs = { other.metric, other.mode };
+ return Arrays.equals(lhs, rhs);
+ }
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+public class Endpoint {
+
+ public static class AddressGroup extends Extensible {
+
+ @JsonProperty("ipv4")
+ public List<String> ipv4 = new ArrayList<String>();
+
+ @JsonProperty("ipv6")
+ public List<String> ipv6 = new ArrayList<String>();
+
+ }
+
+ public static class PropertyRequest {
+
+ @JsonProperty("properties")
+ public List<String> properties;
+
+ @JsonProperty("endpoints")
+ public List<String> endpoints;
+ }
+
+ public static class PropertyRespond {
+
+ public static class Meta extends Extensible {
+
+ @JsonProperty("dependent-vtags")
+ public List<VersionTag> netmap_tags;
+
+ }
+
+ @JsonProperty("meta")
+ public Meta meta;
+
+ @JsonProperty("endpoint-properties")
+ public Map<String, Map<String, Object>> answer
+ = new LinkedHashMap<String, Map<String, Object>>();
+ }
+
+ public static class CostRequest {
+
+ @JsonProperty("cost-type")
+ public CostType costType;
+
+ @JsonProperty("endpoints")
+ public QueryPairs endpoints;
+ }
+
+ public static class CostRespond {
+
+ public static class Meta extends Extensible {
+
+ @JsonProperty("cost-type")
+ public CostType costType;
+
+ }
+
+ @JsonProperty("meta")
+ public Meta meta;
+
+ @JsonProperty("endpoint-cost-map")
+ public Map<String, Map<String, Object>> answer
+ = new LinkedHashMap<String, Map<String, Object>>();
+ }
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class Extensible {
+
+ @JsonIgnore
+ private Map<String, Object> extra = new LinkedHashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> any() {
+ return extra;
+ }
+
+ @JsonAnySetter
+ public void set(String name, Object value) {
+ extra.put(name, value);
+ }
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.regex.Pattern;
+
+public class FormatValidator {
+
+ /**
+ * RFC 7285 section 10.1
+ * */
+ private static final String VALID_CHARSET = "a-zA-Z_0-9\\-:@";
+ private static final Pattern VALID_ID_PATTERN
+ = Pattern.compile("^["+VALID_CHARSET+"]{1,64}$");
+ private static final String VALID_CHARSET_WITH_DOT = VALID_CHARSET + "\\.";
+ private static final Pattern VALID_ID_PATTERN_WITH_DOT
+ = Pattern.compile("^["+VALID_CHARSET_WITH_DOT+"]{1,64}$");
+
+ public static boolean validId(String id) {
+ return VALID_ID_PATTERN.matcher(id).matches();
+ }
+
+ public static boolean validIdWithDots(String id) {
+ return VALID_ID_PATTERN_WITH_DOT.matcher(id).matches();
+ }
+
+ /**
+ * RFC 7285 section 10.1
+ * */
+ public static boolean validPid(String id) {
+ return validId(id);
+ }
+
+ public static boolean validPidWithDots(String id) {
+ return validIdWithDots(id);
+ }
+
+ /**
+ * RFC 7285 section 10.2
+ * */
+ public static boolean validResourceId(String id) {
+ return validId(id);
+ }
+
+ public static boolean validResourceIdWithDots(String id) {
+ return validIdWithDots(id);
+ }
+
+ /**
+ * RFC 7285 section 10.8.1
+ * */
+ public static boolean validSpecificEndpointProperty(String prop) {
+ /* TODO maybe enhance the performance? */
+ return validId(prop) && (prop.indexOf('@') == -1);
+ }
+
+ public static boolean validSpecificEndpointPropertyWithDots(String prop) {
+ /* TODO maybe enhance the performance? */
+ return validIdWithDots(prop) && (prop.indexOf('@') == -1);
+ }
+
+ /**
+ * RFC 7285 seciton 10.8.2
+ * */
+ public static boolean validGlobalEndpointProperty(String prop) {
+ return (prop.length() <= 32) && validId(prop);
+ }
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class IRD {
+
+ public class Meta extends Extensible {
+
+ @JsonProperty("default-alto-network-map")
+ public String defaultAltoNetworkMap;
+
+ @JsonProperty("cost-types")
+ public Map<String, CostType> costTypes;
+
+ public Meta() {
+ defaultAltoNetworkMap = null;
+ costTypes = new LinkedHashMap<String, CostType>();
+ }
+
+ }
+
+ public class Entry {
+ @JsonProperty("uri")
+ public String uri;
+
+ @JsonProperty("media-type")
+ public String mediaType;
+
+ @JsonProperty("accepts")
+ public String accepts;
+
+ @JsonProperty("capabilities")
+ public Map<String, Object> capabilities;
+
+ @JsonProperty("uses")
+ public List<String> uses;
+ }
+
+ @JsonProperty("meta")
+ public Meta meta;
+
+ @JsonProperty("resources")
+ public Map<String, Entry> resources = new LinkedHashMap<String, Entry>();
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+public class JSONMapper {
+
+ private ObjectMapper mapper = new ObjectMapper()
+ .setSerializationInclusion(Include.NON_DEFAULT)
+ .disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+
+ public Endpoint.AddressGroup asAddressGroup(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.AddressGroup.class);
+ }
+
+ public Endpoint.PropertyRequest asPropertyRequest(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.PropertyRequest.class);
+ }
+
+ public Endpoint.PropertyRespond asPropertyRespond(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.PropertyRespond.class);
+ }
+
+ public Endpoint.CostRequest asCostRequest(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.CostRequest.class);
+ }
+
+ public Endpoint.CostRespond asCostRespond(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.CostRespond.class);
+ }
+
+ public CostMap asCostMap(String json) throws Exception {
+ return mapper.readValue(json, CostMap.class);
+ }
+
+ public CostType asCostType(String json) throws Exception {
+ return mapper.readValue(json, CostType.class);
+ }
+
+ public Endpoint asEndpoint(String json) throws Exception {
+ return mapper.readValue(json, Endpoint.class);
+ }
+
+ public Extensible asExtensible(String json) throws Exception {
+ return mapper.readValue(json, Extensible.class);
+ }
+
+ public IRD asIRD(String json) throws Exception {
+ return mapper.readValue(json, IRD.class);
+ }
+
+ public NetworkMap asNetworkMap(String json) throws Exception {
+ return mapper.readValue(json, NetworkMap.class);
+ }
+
+ public VersionTag asVersionTag(String json) throws Exception {
+ return mapper.readValue(json, VersionTag.class);
+ }
+
+ public String asJSON(Object obj) throws Exception {
+ return mapper.writeValueAsString(obj);
+ }
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+public class Mark {
+ public static int marker = 2;
+}
* 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.alto.commons.types;
+package org.opendaylight.alto.commons.types.rfc7285;
-public class RFC7285MediaType {
+public class MediaType {
/** The media types defined in [RFC7285]
*
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Network Map: defined in RFC 7285 section 11.2.1
+ * */
+public class NetworkMap {
+
+ public static class Meta extends Extensible {
+
+ @JsonProperty("vtag")
+ public VersionTag vtag;
+
+ }
+
+ /**
+ * used for filtered-network-map, RFC7285 secion 11.3.1
+ * */
+ public static class Filter {
+
+ @JsonProperty("pids")
+ public List<String> pids;
+
+ }
+
+ @JsonProperty("meta")
+ public Meta meta;
+
+ @JsonProperty("network-map")
+ public Map<String, Endpoint.AddressGroup> map
+ = new LinkedHashMap<String, Endpoint.AddressGroup>();
+
+}
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import java.util.List;
+import java.util.LinkedList;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class QueryPairs {
+
+ @JsonProperty("srcs")
+ List<String> src = new LinkedList<String>();
+
+ @JsonProperty("dsts")
+ List<String> dst = new LinkedList<String>();
+
+}
+
--- /dev/null
+package org.opendaylight.alto.commons.types.rfc7285;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class VersionTag {
+
+ @JsonProperty("resource-id")
+ public String rid;
+
+ @JsonProperty("tag")
+ public String tag;
+
+ public VersionTag() {
+ rid = "";
+ tag = "";
+ }
+
+ public VersionTag(String rid, String tag) {
+ this.rid = (rid != null ? rid : "");
+ this.tag = (tag != null ? tag : "");
+ }
+
+ public boolean incomplete() {
+ return (rid == null) || (tag == null) || (rid == "") || (tag == "");
+ }
+
+ private static char ILLEGAL = '$';
+
+ @Override
+ public int hashCode() {
+ return (rid + ILLEGAL + tag).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+
+ VersionTag other = (VersionTag)obj;
+ boolean _rid = (rid == null ? (other.rid == null) : rid.equals(other.rid));
+ boolean _tag = (tag == null ? (other.tag == null) : tag.equals(other.tag));
+ return (_rid && _tag);
+ }
+}
<version>${jersey.servlet.version}</version>
</dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- <version>${jersey.json.version}</version>
- </dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
<version>${corsfilter.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>alto-model</artifactId>
*/
package org.opendaylight.alto.northbound;
-import org.opendaylight.alto.commons.types.RFC7285MediaType;
+import org.opendaylight.alto.commons.types.rfc7285.MediaType;
import org.opendaylight.alto.services.api.IRDService;
//import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.NetworkMap;
private static final Logger mLogger = LoggerFactory.getLogger(AltoNorthbound.class);
@GET
- @Produces({RFC7285MediaType.ALTO_DIRECTORY, RFC7285MediaType.ALTO_ERROR})
+ @Produces({MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR})
public Response retrieveIRD() {
IRDService fas = new FakeAltoService();
try {
IRD ird = fas.getIRD();
- return Response.ok(ird, RFC7285MediaType.ALTO_DIRECTORY).build();
+ return Response.ok(ird, MediaType.ALTO_DIRECTORY).build();
} catch (Exception e) {
}
- return Response.ok("", RFC7285MediaType.ALTO_ERROR).build();
+ return Response.ok("", MediaType.ALTO_ERROR).build();
}
@Path("/networkmap/{networkmap_id}")
@GET
- @Produces({RFC7285MediaType.ALTO_NETWORKMAP, RFC7285MediaType.ALTO_ERROR})
+ @Produces({MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR})
public Response retrieveNetworkMap(@PathParam(value = "networkmap_id") String nmap_id) {
/* TODO */
- return Response.ok("", RFC7285MediaType.ALTO_ERROR).build();
+ return Response.ok("", MediaType.ALTO_ERROR).build();
}
}
<groupId>org.opendaylight.alto</groupId>
<artifactId>alto-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
- <relativePath>..</relativePath>
+ <relativePath>../..</relativePath>
</parent>
<groupId>org.opendaylight.alto</groupId>
<parent>
<groupId>org.opendaylight.alto</groupId>
- <artifactId>alto-parent</artifactId>
+ <artifactId>services.ext</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>org.opendaylight.alto</groupId>
- <artifactId>commons</artifactId>
- <packaging>jar</packaging>
+ <artifactId>services.ext.fs-map</artifactId>
+ <packaging>bundle</packaging>
<build>
<plugins>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</dependencies>
</plugin>
+ <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.alto.commons.types.rfc7285,
+ org.opendaylight.alto.services.api,
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924,
+ org.slf4j,
+ </Import-Package>
+ <Export-Package>
+ org.opendaylight.alto.services.ext.fsmap;
+ </Export-Package>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+
</plugins>
</build>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>services.api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
</dependencies>
</project>
--- /dev/null
+package org.opendaylight.alto.services.ext.fsmap;
+
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.FileVisitResult;
+import java.nio.file.PathMatcher;
+import java.nio.file.WatchService;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchEvent;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.ClosedWatchServiceException;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import java.io.IOException;
+
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.HashMap;
+
+import org.opendaylight.alto.commons.types.rfc7285.JSONMapper;
+import org.opendaylight.alto.commons.types.rfc7285.NetworkMap;
+import org.opendaylight.alto.commons.types.rfc7285.VersionTag;
+
+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, NetworkMap> id_to_map = new HashMap<VersionTag, NetworkMap>();
+ private JSONMapper mapper = 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();
+ }
+
+ public 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) {
+ }
+
+ for (VersionTag vtag: path_to_id.values()) {
+ // TODO remove network map
+ }
+ path_to_id.clear();
+ id_to_map.clear();
+ lock.unlock();
+ }
+
+ public void close() {
+ cancelled.set(true);
+ cleanup();
+ }
+
+ public void onCreate(Path file) {
+ //TODO
+ try {
+ String content = new String(Files.readAllBytes(file), StandardCharsets.US_ASCII);
+ NetworkMap map = mapper.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());
+ }
+ }
+
+ public 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());
+ }
+ }
+
+ public 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());
+ }
+ }
+
+ public 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());
+ }
+ }
+
+ public void onModify(Path file) {
+ //TODO
+ try {
+ String content = new String(Files.readAllBytes(file), StandardCharsets.US_ASCII);
+ NetworkMap map = mapper.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());
+ }
+ }
+
+ public void onModifyDir(Path dir) {
+ //TODO
+ onDeleteDir(dir);
+ onModifyDir(dir);
+ }
+}
--- /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>
+
+ <groupId>org.opendaylight.alto</groupId>
+ <artifactId>services.ext</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>fs-map</module>
+ </modules>
+
+</project>
+
+++ /dev/null
-/*
- * Copyright (c) 2015 Yale University 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.alto.commons;
-
-public class RFC7285MediaType {
-
- /** The media types defined in [RFC7285]
- *
- * The media types defined here should be identical to those
- * generated by alto-model, the main reason we need this is
- * the ones defined here are *STRING LITERALS*.
- * */
-
- public static final String ALTO_DIRECTORY
- = "application/alto-directory+json";
- public static final String ALTO_NETWORKMAP
- = "application/alto-networkmap+json";
- public static final String ALTO_NETWORKMAP_FILTER
- = "application/alto-networkmapfilter+json";
- public static final String ALTO_COSTMAP
- = "application/alto-costmap+json";
- public static final String ALTO_COSTMAP_FILTER
- = "application/alto-costmapfilter+json";
- public static final String ALTO_ENDPOINT_PROP
- = "application/alto-endpointprop+json";
- public static final String ALTO_ENDPOINT_PROPPARAMS
- = "application/alto-endpointpropparams+json";
- public static final String ALTO_ENDPOINT_COST
- = "application/alto-endpointcost+json";
- public static final String ALTO_ENDPOINT_COSTPARAMS
- = "application/alto-endpointcostparams+json";
- public static final String ALTO_ERROR
- = "application/alto-error+json";
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2015 Yale University 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.alto.commons;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev141101.MediaType;
-
-class YangModelMediaType {
-
- /** The media types generated by alto-model
- * */
-
- public static final String ALTO_DIRECTORY
- = new MediaType(MediaType.Enumeration.AltoDirectory).toString();
- public static final String ALTO_NETWORKMAP
- = new MediaType(MediaType.Enumeration.AltoNetworkmap).toString();
- public static final String ALTO_NETWORKMAP_FILTER
- = new MediaType(MediaType.Enumeration.AltoNetworkmapfilter).toString();
- public static final String ALTO_COSTMAP
- = new MediaType(MediaType.Enumeration.AltoCostmap).toString();
- public static final String ALTO_COSTMAP_FILTER
- = new MediaType(MediaType.Enumeration.AltoCostmapfilter).toString();
- public static final String ALTO_ENDPOINT_PROP
- = new MediaType(MediaType.Enumeration.AltoEndpointprop).toString();
- public static final String ALTO_ENDPOINT_PROPPARAMS
- = new MediaType(MediaType.Enumeration.AltoEndpointpropparams).toString();
- public static final String ALTO_ENDPOINT_COST
- = new MediaType(MediaType.Enumeration.AltoEndpointcost).toString();
- public static final String ALTO_ENDPOST_COSTPARAMS
- = new MediaType(MediaType.Enumeration.AltoEndpointcostparams).toString();
- public static final String ALTO_ERROR
- = new MediaType(MediaType.Enumeration.AltoError).toString();
-}
<bundle>mvn:org.opendaylight.alto/alto-model/${project.version}</bundle>
</feature>
+ <feature name='odl-alto-jackson-dependency' version='${project.version}' description='Opendaylight :: alto :: jackson_dependency'>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
+ </feature>
+
<feature name='odl-alto-utils' version='${project.version}' description='OpenDaylight :: alto :: utils'>
<feature version='${project.version}'>odl-alto-model</feature>
+ <feature version='${jackson.version}'>odl-base-jackson</feature>
<bundle>mvn:org.opendaylight.alto/commons/${project.version}</bundle>
<bundle>mvn:org.opendaylight.alto/services.api/${project.version}</bundle>
</feature>
+ <feature name='odl-alto-extension' version='${project.version}' description='Opendaylight :: alto :: extension'>
+ <feature version='${project.version}'>odl-alto-utils</feature>
+ <bundle>mvn:org.opendaylight.alto/services.ext.fs-map/${project.version}</bundle>
+ </feature>
+
<feature name='odl-alto-northbound' version='${project.version}' description='Opendaylight :: alto :: northbound'>
<feature version='${project.version}'>odl-alto-model</feature>
<feature version='${project.version}'>odl-alto-utils</feature>
<feature version='${jersey.version}'>odl-base-jersey</feature>
+ <feature version='0.5.0-SNAPSHOT'}>odl-adsal-northbound</feature>
<feature version='${controller.commons.northbound.version}'>odl-adsal-northbound</feature>
<bundle>mvn:org.opendaylight.alto/alto-northbound/${project.version}</bundle>
</feature>
<module>alto-artifacts</module>
<module>features</module>
<module>alto-commons</module>
- <module>alto-services</module>
+ <module>alto-services/api</module>
+ <module>alto-services/ext</module>
<!--
<module>alto-karaf</module>
-->