<type>xml</type>
<classifier>config</classifier>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-service-model-base-features</artifactId>
+ <classifier>features</classifier>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>alto-northbound-route-networkmap-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>alto-service-model-base-features</artifactId>
+ <artifactId>alto-service-model-networkmap-features</artifactId>
<classifier>features</classifier>
<version>${project.version}</version>
<type>xml</type>
<scope>runtime</scope>
</dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>alto-service-model-networkmap-features</artifactId>
+ <artifactId>alto-northbound-route-costmap-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-northbound-route-costmap-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-northbound-route-costmap-impl</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-service-model-costmap-features</artifactId>
<classifier>features</classifier>
<version>${project.version}</version>
<type>xml</type>
<repository>mvn:org.opendaylight.dlux/features-dlux/${dlux.version}/xml/features</repository>
<repository>mvn:org.opendaylight.alto.core/alto-service-model-networkmap-features/${project.version}/xml/features</repository>
+ <repository>mvn:org.opendaylight.alto.core/alto-service-model-costmap-features/${project.version}/xml/features</repository>
<feature name='odl-alto-northbound-api' version='${project.version}' description='OpenDaylight :: alto-northbound :: api'>
<feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
<configfile finalname="${configfile.directory}/alto-northbound-route-networkmap.xml">
mvn:org.opendaylight.alto.core/alto-northbound-route-networkmap-impl/${project.version}/xml/config
</configfile>
+
+ <feature version='${project.version}'>odl-alto-service-model-costmap</feature>
+ <bundle>mvn:org.opendaylight.alto.core/alto-northbound-route-costmap-api/${project.version}</bundle>
+ <bundle>mvn:org.opendaylight.alto.core/alto-northbound-route-costmap-impl/${project.version}</bundle>
+ <configfile finalname="${configfile.directory}/alto-northbound-route-costmap.xml">
+ mvn:org.opendaylight.alto.core/alto-northbound-route-costmap-impl/${project.version}/xml/config
+ </configfile>
+
</feature>
<feature name='odl-alto-northbound-rest' version='${project.version}' description='OpenDaylight :: alto-northbound :: REST'>
<feature version="${project.version}">odl-alto-northbound</feature>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-parent</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.opendaylight.alto.core</groupId>
+ <artifactId>alto-northbound-route-costmap-api</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-service-model-costmap-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-server</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types-2013-07-15</artifactId>
+ </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.core.northbound.route.costmap;
+
+/**
+ * Created by wukunheng00 on 12/3/15.
+ */
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.Records;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.records.Record;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.records.RecordKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class AltoNbrCostmapUtils {
+
+ public static InstanceIdentifier<Record> getRecordIID(String path) {
+ RecordKey key = new RecordKey(new Uri(path));
+ return InstanceIdentifier.builder(Records.class).child(Record.class, key).build();
+ }
+}
+
--- /dev/null
+module alto-nbr-costmap {
+ yang-version 1;
+
+ namespace "urn:opendaylight:alto:core:northbound:route:costmap";
+
+ prefix "alto-nbr-costmap";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import ietf-inet-types { prefix ietf-inet; revision-date 2013-07-15; }
+ import alto-model-costmap { prefix costmap-model; revision-date 2015-10-21; }
+
+ organization "Yale University";
+
+ contact "alto-dev@lists.opendaylight.org";
+
+ revision "2015-10-21" {
+ description "Initial revision of alto-northbound model";
+ }
+
+ container "records" {
+ list "record" {
+ key "path";
+
+ leaf "path" {
+ type ietf-inet:uri;
+ }
+
+ leaf "resource-iid" {
+ type instance-identifier;
+ }
+
+
+ }
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-parent</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.opendaylight.alto.core</groupId>
+ <artifactId>alto-northbound-route-costmap-impl</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-northbound-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-service-model-costmap-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>alto-northbound-route-costmap-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types-2013-07-15</artifactId>
+ </dependency>
+
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-json-org</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlets</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ </dependencies>
+
+ <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>*,com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets</Import-Package>
+ <Web-ContextPath>/alto</Web-ContextPath>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright © 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
+-->
+<snapshot>
+ <required-capabilities>
+ <capability>urn:opendaylight:alto:core:northbound:route:costmap:impl?module=alto-northbound-route-costmap-impl&revision=2015-10-21</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:alto:core:northbound?module=alto-northbound&revision=2015-10-21</capability>
+ </required-capabilities>
+ <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:prefix="urn:opendaylight:alto:core:northbound:route:costmap:impl">prefix:alto-northbound-route-costmap-impl</type>
+ <name>alto-northbound-route-costmap</name>
+ <broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <name>binding-osgi-broker</name>
+ </broker>
+ <alto-northbound-router>
+ <type xmlns:alto-northbound-router="urn:opendaylight:alto:core:northbound">alto-northbound-router:alto-northbound-router</type>
+ <name>alto-northbound-router</name>
+ </alto-northbound-router>
+ </module>
+ </modules>
+ </data>
+ </configuration>
+</snapshot>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+ <groupId>org.opendaylight.alto.core</groupId>
+ <artifactId>alto-northbound-impl</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <versioning>
+ <snapshot>
+ <localCopy>true</localCopy>
+ </snapshot>
+ <lastUpdated>20151105030453</lastUpdated>
+ <snapshotVersions>
+ <snapshotVersion>
+ <classifier>config</classifier>
+ <extension>xml</extension>
+ <value>0.2.0-SNAPSHOT</value>
+ <updated>20151105030453</updated>
+ </snapshotVersion>
+ </snapshotVersions>
+ </versioning>
+</metadata>
--- /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.core.northbound.route.costmap.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Optional;
+import org.opendaylight.alto.core.northbound.api.AltoNorthboundRoute;
+import org.opendaylight.alto.core.northbound.api.AltoNorthboundRouter;
+import org.opendaylight.alto.core.northbound.api.utils.rfc7285.RFC7285CostMap;
+import org.opendaylight.alto.core.northbound.api.utils.rfc7285.RFC7285CostType;
+import org.opendaylight.alto.core.northbound.api.utils.rfc7285.RFC7285VersionTag;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.Records;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.records.Record;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.rev151021.records.RecordKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.resourcepool.rev150921.context.Resource;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.resourcepool.rev150921.context.resource.ContextTag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.resourcepool.rev150921.context.resource.ContextTagKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.types.rev150921.CostMetric;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.types.rev150921.PidName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.AltoModelCostmapService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.QueryInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.QueryInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.QueryOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.ResourceTypeCostmap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.alto.request.costmap.request.CostmapRequestBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.alto.response.costmap.response.CostmapResponse;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.cost.type.data.CostTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.costmap.request.data.CostmapParamsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.costmap.response.data.CostmapResponseData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.costmap.response.data.costmap.response.data.CostmapSource;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.costmap.response.data.costmap.response.data.costmap.source.CostmapDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rev151021.costmap.response.data.costmap.response.data.costmap.source.costmap.destination.Cost;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rfc7285.rev151021.costmap.filter.data.CostmapFilterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.costmap.rfc7285.rev151021.query.input.request.costmap.request.costmap.params.filter.CostmapFilterDataBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+public class AltoNorthboundRouteCostmap implements BindingAwareProvider, AutoCloseable, AltoNorthboundRoute {
+ public static final String COSTMAP_ROUTE = "costmap";
+
+ public static final String ALTO_COSTMAP_FILTER = "application/alto-costmapfilter+json";
+ public static final String ALTO_COSTMAP = "application/alto-costmap+json";
+
+ public static final String FIELD_PIDS = "pids";
+ public static final String FIELD_COST_TYPE = "cost-type";
+ public static final String FIELD_COST_MODE = "cost-mode";
+ public static final String FIELD_COST_METRIC = "cost-metric";
+ public static final String FIELD_PID_SOURCE = "srcs";
+ public static final String FIELD_PID_DESTINSTION = "dsts";
+
+ private ObjectMapper mapper = new ObjectMapper();
+ private static final Logger LOG = LoggerFactory.getLogger(AltoNorthboundRouteCostmap.class);
+ private static DataBroker m_dataBroker = null;
+ private AltoNorthboundRouter m_router = null;
+
+ private static AltoModelCostmapService mapService = null;
+ @Override
+ public void onSessionInitiated(ProviderContext session) {
+ m_dataBroker = session.getSALService(DataBroker.class);
+ if (m_dataBroker == null) {
+ LOG.error("Failed to init: data broker is null");
+ }
+
+ mapService = session.getRpcService(AltoModelCostmapService.class);
+ LOG.info("AltoNorthboundRouteCostmap initiated");
+
+ }
+
+ public void register(AltoNorthboundRouter router) {
+ m_router = router;
+ m_router.addRoute("costmap", new AltoNorthboundRouteCostmap());
+ }
+
+ @Override
+ public void close() {
+ m_router.removeRoute("costmap");
+ }
+
+ @Path("{path}")
+ @GET
+ @Produces({ALTO_COSTMAP, ALTO_ERROR})
+ public Response getFullMap(@PathParam("path") String path) throws JsonProcessingException{
+ QueryInput input = prepareDefaultInput(path);
+ Future<RpcResult<QueryOutput>> outputFuture = mapService.query(input);
+ QueryOutput output = null;
+ try {
+ output = outputFuture.get().getResult();
+ } catch (Exception e) {
+ LOG.warn("get output failed:" , e);
+ }
+ Response response = buildOutput(input, output);
+ if(response != null)
+ return response;
+ else
+ return Response.status(404).build();
+ }
+
+ @Path("{path}")
+ @POST
+ @Consumes({ALTO_COSTMAP_FILTER})
+ @Produces({ALTO_COSTMAP, ALTO_ERROR})
+ public Response getFilteredMap(@PathParam("path") String path, String filter) throws JsonProcessingException {
+ Response error;
+
+ String cost_mode = null;
+ String cost_metric = null;
+ List<String> pid_source = null;
+ List<String> pid_destination = null;
+
+
+ try {
+ JsonNode filterNode = mapper.readTree(filter);
+
+ JsonNode _pids = filterNode.get(FIELD_PIDS);
+
+ error = CostmapRouteChecker.checkMissing(_pids, FIELD_PIDS, filter);
+ if (error != null)
+ return error;
+
+ error = CostmapRouteChecker.checkList(_pids, FIELD_PIDS, filter);
+ if (error != null)
+ return error;
+
+ //need check pid_source
+ JsonNode _pid_source = _pids.get(FIELD_PID_SOURCE);
+ error = CostmapRouteChecker.checkList(_pid_source, FIELD_PID_SOURCE, filter);
+ if (error != null){
+ return error;
+ }
+ pid_source = arrayNode2List(FIELD_PID_SOURCE, (ArrayNode)_pid_source);
+
+ //need check pid_destination
+ JsonNode _pid_destination = _pids.get(FIELD_PID_DESTINSTION);
+ error = CostmapRouteChecker.checkList(_pid_destination, FIELD_PID_DESTINSTION, filter);
+ if (error != null){
+ return error;
+ }
+ pid_destination = arrayNode2List(FIELD_PID_DESTINSTION, (ArrayNode) _pid_destination);
+
+ JsonNode _cost_type = filterNode.get(FIELD_COST_TYPE);
+ if(_cost_type == null){
+ error = null;
+ return error;
+ }else {
+ cost_mode = _cost_type.get(FIELD_COST_MODE).asText();
+ cost_metric = _cost_type.get(FIELD_COST_METRIC).asText();
+ }
+
+
+ } catch (JsonProcessingException e) {
+ throw e;
+ } catch (Exception e) {
+ return Response.status(500).build();
+ }
+
+ //TODO
+ QueryInput input = prepareInput(path, cost_mode, cost_metric, pid_source, pid_destination);
+ Future<RpcResult<QueryOutput>> outputFuture = mapService.query(input);
+ QueryOutput output = null;
+ try {
+ output = outputFuture.get().getResult();
+ } catch (Exception e) {
+ LOG.warn("get output failed:" , e);
+ }
+ Response response = buildOutput(input, output);
+ if(response != null)
+ return response;
+ else
+ return Response.status(404).build();
+ }
+
+ protected List<String> arrayNode2List(String field, ArrayNode node) {
+ HashSet<String> retval = new HashSet<String>();
+
+ for (Iterator<JsonNode> itr = node.elements(); itr.hasNext(); ) {
+ JsonNode data = itr.next();
+
+ retval.add(data.asText());
+ }
+ return new LinkedList<String>(retval);
+ }
+
+ protected QueryInput prepareDefaultInput(String rid) {
+ /*
+ * Set pids as empty so all PID should be returned.
+ *
+ * Set address-types as missing so all address types should be returned.
+ *
+ * See https://tools.ietf.org/html/rfc7285#section-11.3.1.3
+ *
+ * */
+ return prepareInput(rid, null, null, new LinkedList<String>(), new LinkedList<String>());
+ }
+
+ protected QueryInput prepareInput(String path, String cost_mode, String cost_metric, List<String> pid_source, List<String> pid_destination) {
+ //TODO
+ QueryInputBuilder queryInputBuilder = new QueryInputBuilder();
+
+ CostmapRequestBuilder costmapRequestBuilder = new CostmapRequestBuilder();
+ CostmapParamsBuilder costmapParamsBuilder = new CostmapParamsBuilder();
+
+ CostTypeBuilder costTypeBuilder = new CostTypeBuilder();
+ costTypeBuilder.setCostMetric(new CostMetric(cost_metric));
+ costTypeBuilder.setCostMode(cost_mode);
+
+ CostmapFilterBuilder costmapFilterBuilder = new CostmapFilterBuilder();
+
+ List<PidName> pidNames1 = new LinkedList<PidName>();
+ for (String pid:pid_source){
+ PidName p = new PidName(pid);
+ pidNames1.add(p);
+ }
+ costmapFilterBuilder.setPidSource(pidNames1);
+
+ List<PidName> pidNames2 = new LinkedList<PidName>();
+ for (String pid:pid_destination){
+ PidName p = new PidName(pid);
+ pidNames2.add(p);
+ }
+ costmapFilterBuilder.setPidDestination(pidNames2);
+
+ CostmapFilterDataBuilder filterdata = new CostmapFilterDataBuilder();
+ filterdata.setCostmapFilter(costmapFilterBuilder.build());
+
+ costmapParamsBuilder.setFilter(filterdata.build());
+ costmapParamsBuilder.setCostType(costTypeBuilder.build());
+
+ costmapRequestBuilder.setCostmapParams(costmapParamsBuilder.build());
+
+ ReadOnlyTransaction rtx = m_dataBroker.newReadOnlyTransaction();
+ InstanceIdentifier<ContextTag> ctagIID = getResourceByPath(path, rtx);
+ if(ctagIID == null){
+ return null;
+ }
+
+ queryInputBuilder.setRequest(costmapRequestBuilder.build());
+ queryInputBuilder.setType(ResourceTypeCostmap.class);
+ queryInputBuilder.setServiceReference(ctagIID);
+ return queryInputBuilder.build();
+ }
+
+ public InstanceIdentifier<ContextTag> getResourceByPath(String path, ReadTransaction transaction){
+ //get iid from (list Records)
+ InstanceIdentifier<Record> recordIID = InstanceIdentifier.builder(Records.class).child(Record.class, new RecordKey(new Uri(path))).build();
+
+ Future<Optional<Record>> recordFuture = transaction.read(LogicalDatastoreType.CONFIGURATION, recordIID);
+ Optional<Record> optional = null;
+ try{
+ optional = recordFuture.get();
+ }catch(Exception e){
+ LOG.error("Reading Record failed", e);
+ return null;
+ }
+ //get resourceIID from nbr-costmap.yang
+ InstanceIdentifier<?> record2resourceIID = null;
+ if(optional.isPresent())
+ record2resourceIID = optional.get().getResourceIid();
+ InstanceIdentifier<Resource> resourceIID = (InstanceIdentifier<Resource>)record2resourceIID;
+ Future<Optional<Resource>> resourceFuture = transaction.read(LogicalDatastoreType.OPERATIONAL, resourceIID);
+
+ Optional<Resource> optional1 = null;
+ try{
+ optional1 = resourceFuture.get();
+ }
+ catch(Exception e){
+ LOG.error("Read resource failed:", e);
+ return null;
+ }
+ Resource resource = null;
+ if(optional1.isPresent())
+ resource = optional1.get();
+ InstanceIdentifier<ContextTag> finalresourceIID = resourceIID.child(ContextTag.class, new ContextTagKey(resource.getDefaultTag()));
+ return finalresourceIID;
+
+ }
+
+
+
+ protected RFC7285CostMap.Meta buildMeta(InstanceIdentifier<?> iid, RFC7285CostType costtype) {
+ RFC7285CostMap.Meta meta = new RFC7285CostMap.Meta();
+ RFC7285VersionTag vtag = new RFC7285VersionTag();
+ vtag.rid = iid.firstKeyOf(Resource.class).getResourceId().getValue();
+ vtag.tag = iid.firstKeyOf(ContextTag.class).getTag().getValue();
+ meta.netmap_tags.add(vtag);
+ meta.costType = costtype;
+ return meta;
+ }
+
+ //Cost.toString is a String like Ordinal [_cost=2, augmentation=[]],and I need to extrat "_cost=2" from this String
+ protected String getCostValue(Cost cost){
+ String costValue = null;
+ String costString = cost.toString();
+ String[] a1 = costString.split(",");
+ String[] a2 = a1[0].split("=");
+ costValue = a2[1];
+ return costValue;
+ }
+
+ protected Response buildOutput(QueryInput input, QueryOutput output) throws JsonProcessingException{
+
+ CostmapResponse costmapResponse = (CostmapResponse)output.getResponse();
+ CostmapResponseData responseData = costmapResponse.getCostmapResponseData();
+
+ RFC7285CostMap rfccostmap = new RFC7285CostMap();
+ RFC7285CostType rfccosttype = new RFC7285CostType();
+
+ rfccosttype.mode = responseData.getCostType().getCostMode();
+ rfccosttype.metric = responseData.getCostType().getCostMetric().getValue();
+
+ Map<String, Map<String, Object>> costmapsource
+ = new LinkedHashMap<String, Map<String, Object>>();
+
+ for(CostmapSource source:responseData.getCostmapSource()){
+
+ Map<String, Object> dst2cost = new HashMap<String, Object>();
+
+ for(CostmapDestination destination:source.getCostmapDestination()){
+ String destinationName = destination.getPidDestination().getValue();
+ Cost pidcost = destination.getCost();
+ dst2cost.put(destinationName, getCostValue(pidcost));
+ }
+
+ costmapsource.put(source.getPidSource().getValue(), dst2cost);
+
+ }
+
+ rfccostmap.meta = buildMeta(input.getServiceReference(), rfccosttype);
+ rfccostmap.map = costmapsource;
+
+ String responseString = mapper.writeValueAsString(rfccostmap);
+
+ return Response.ok(responseString, ALTO_COSTMAP).build();
+
+ }
+}
--- /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.core.northbound.route.costmap.impl;
+
+import javax.ws.rs.core.Response;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class CostmapRouteChecker {
+
+ public static Response checkMissing(JsonNode target, String field, String origin) {
+ if (target == null) {
+ // TODO :: report missing field, something like
+ // return new AltoMissingFieldError(field, origin);
+ return null;
+ }
+ return null;
+ }
+
+ public static Response checkList(JsonNode list, String field, String origin) {
+ if (!list.isArray()) {
+ // TODO :: report invalid field type, something like
+ // return new AltoInvalidFieldType(field, "array", origin);
+ return null;
+ }
+ return null;
+ }
+
+}
--- /dev/null
+package org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.impl.rev151021;
+
+import org.opendaylight.alto.core.northbound.route.costmap.impl.AltoNorthboundRouteCostmap;
+
+public class AltoNorthboundRouteCostmapModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.impl.rev151021.AbstractAltoNorthboundRouteCostmapModule {
+ public AltoNorthboundRouteCostmapModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public AltoNorthboundRouteCostmapModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.impl.rev151021.AltoNorthboundRouteCostmapModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ AltoNorthboundRouteCostmap costmap = new AltoNorthboundRouteCostmap();
+ getBrokerDependency().registerProvider(costmap);
+ costmap.register(getAltoNorthboundRouterDependency());
+ return costmap;
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: alto-northbound-route-costmap-impl yang module local name: alto-northbound-route-costmap-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Tue Dec 08 16:37:14 CST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.impl.rev151021;
+public class AltoNorthboundRouteCostmapModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.alto.core.northbound.route.costmap.impl.rev151021.AbstractAltoNorthboundRouteCostmapModuleFactory {
+
+}
--- /dev/null
+module alto-northbound-route-costmap-impl {
+ yang-version 1;
+ namespace "urn:opendaylight:alto:core:northbound:route:costmap:impl";
+ prefix "alto-northbound-router-costmap-impl";
+
+ import alto-northbound { prefix alto-northbound; revision-date 2015-10-21; }
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+
+ description
+ "Service definition for northbound project";
+
+ revision "2015-10-21" {
+ description
+ "Initial revision";
+ }
+
+ identity alto-northbound-route-costmap-impl {
+ base config:module-type;
+ config:java-name-prefix AltoNorthboundRouteCostmap;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case alto-northbound-route-costmap {
+ when "/config:modules/config:module/config:type = 'alto-northbound-route-costmap-impl'";
+ container broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-broker-osgi-registry;
+ }
+ }
+ }
+
+ container alto-northbound-router {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity alto-northbound:alto-northbound-router;
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright © 2015 Copyright (c) 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 INTERNAL
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.opendaylight.alto.core</groupId>
+ <artifactId>routes-costmap-aggregator</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <name>alto-northbound-route-costmap-aggregator</name>
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.1.1</maven>
+ </prerequisites>
+
+ <profiles>
+ <profile>
+ <id>minimal</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>alto-dev</id>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>alto-test</id>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+ </profile>
+ </profiles>
+ <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
</modules>
</profile>
+ <profile>
+ <id>alto-dev</id>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+ </profile>
+
<profile>
<id>alto-test</id>
<modules>
</activation>
<modules>
<module>networkmap</module>
+ <module>costmap</module>
</modules>
</profile>
<modules>
<module>example</module>
<module>networkmap</module>
+ <module>costmap</module>
</modules>
</profile>
--- /dev/null
+#!/bin/bash
+
+COSTMAP_PATH=$1
+RESOURCE_ID=$2
+if [ $3 ]; then
+ CONTEXT_ID=$3
+else
+ CONTEXT_ID="00000000-0000-0000-0000-000000000000"
+fi
+
+DATA=$(cat ./template/nbr-record-costmap \
+ | sed 's/\$1/'$COSTMAP_PATH'/g' \
+ | sed 's/\$2/'$CONTEXT_ID'/g' \
+ | sed 's/\$3/'$RESOURCE_ID'/g')
+
+# echo $DATA | python -m json.tool
+
+curl -X PUT -u admin:admin -H "Content-Type: application/json" \
+ -d "$DATA" \
+ http://localhost:8181/restconf/config/alto-nbr-costmap:records/record/$COSTMAP_PATH
--- /dev/null
+#!/bin/bash
+
+COSTMAP_PATH=$1
+
+DATA=$(cat ./template/costmap-filter)
+
+
+
+curl -X POST -u admin:admin -H "Content-Type: application/alto-costmapfilter+json" \
+ -d "$DATA" \
+ http://localhost:8080/alto/costmap/$COSTMAP_PATH | python -m json.tool
--- /dev/null
+{
+ "cost-type": {
+ "cost-metric": "routingcost",
+ "cost-mode": "numerical"
+ },
+ "pids": {
+ "dsts": [
+ "PID1",
+ "PID2",
+ "PID3"
+ ],
+ "srcs": [
+ "PID1"
+ ]
+ }
+}
+
--- /dev/null
+{
+ "record": {
+ "path": "$1",
+ "resource-iid": "/alto-resourcepool:context[alto-resourcepool:context-id='$2']/alto-resourcepool:resource[alto-resourcepool:resource-id='$3']"
+ }
+}
+{
+