--- /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.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.alto.commons.helper.Converter;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostRequest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.CostType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.CostTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.input.EndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMetricBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddressBuilder;
+
+public class CostRequest2EndpointCostServiceInputConverter extends
+ Converter<CostRequest, EndpointCostServiceInput> {
+
+ public CostRequest2EndpointCostServiceInputConverter() {
+ }
+
+ public CostRequest2EndpointCostServiceInputConverter(CostRequest _in) {
+ super(_in);
+ }
+
+ @Override
+ protected Object _convert() {
+ RFC7285CostType rfcCostType = in().costType;
+
+ CostType costType = new CostTypeBuilder()
+ .setCostMetric(CostMetricBuilder.getDefaultInstance(rfcCostType.metric))
+ .setCostMode(CostMode.valueOf(capitalizeFirstLetter(rfcCostType.mode)))
+ .setDescription(rfcCostType.description).build();
+
+ List<TypedEndpointAddress> srcs = toTypedEndpointAddressList(in().endpoints.src);
+ List<TypedEndpointAddress> dsts = toTypedEndpointAddressList(in().endpoints.dst);
+ Endpoints endpoints = new EndpointsBuilder().setSrcs(srcs).setDsts(dsts).build();
+
+ EndpointCostServiceInput input = new EndpointCostServiceInputBuilder()
+ .setCostType(costType)
+ .setEndpoints(endpoints)
+ .build();
+
+ return input;
+ }
+
+ private List<TypedEndpointAddress> toTypedEndpointAddressList(List<String> addresses) {
+ List<TypedEndpointAddress> result = new ArrayList<TypedEndpointAddress>();
+ for (String address : addresses) {
+ result.add(TypedEndpointAddressBuilder.getDefaultInstance(address));
+ }
+ return result;
+ }
+
+ private String capitalizeFirstLetter(String str) {
+ str = str.toLowerCase();
+ return str.substring(0, 1).toUpperCase() + str.substring(1);
+ }
+}
--- /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.converter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.opendaylight.alto.commons.helper.Converter;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostResponse;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.costdefault.rev150507.DstCosts1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.EndpointCostService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.EndpointCostMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.endpoint.cost.map.DstCosts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.endpoint.cost.service.output.endpoint.cost.service.meta.CostType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
+
+public class EndpointCostServiceOutput2CostResponseConverter extends
+ Converter<EndpointCostServiceOutput, CostResponse> {
+
+ private static final String NUMERICAL_MODE = "numerical";
+ private static final String ORDINAL_MODE = "ordinal";
+ private static final String ROUTING_COST_METRIC = "routingcost";
+ private static final String HOP_COUNT_METRIC = "hopcount";
+
+ public EndpointCostServiceOutput2CostResponseConverter() {
+ }
+
+ public EndpointCostServiceOutput2CostResponseConverter(EndpointCostServiceOutput _in) {
+ super(_in);
+ }
+
+ @Override
+ protected Object _convert() {
+ CostResponse resp = new CostResponse();
+ EndpointCostService ecService = this.in().getEndpointCostService();
+ CostType costType = ecService.getMeta().getCostType();
+
+ resp.meta = new CostResponse.Meta();
+ resp.meta.costType = new RFC7285CostType();
+ resp.meta.costType.mode = costType.getCostMode().name().toLowerCase();
+ resp.meta.costType.metric = String.valueOf(costType.getCostMetric().getValue()).toLowerCase();
+ resp.meta.costType.description = costType.getDescription();
+
+ resp.answer = new HashMap<String, Map<String, Object>>();
+ for (EndpointCostMap ecm : ecService.getEndpointCostMap()) {
+ TypedEndpointAddress src = ecm.getSrc();
+ Map<String, Object> map = new HashMap<String, Object>();
+ for (DstCosts dstCosts : ecm.getDstCosts()) {
+ String dst = String.valueOf(dstCosts.getDst().getValue());
+ String cost = dstCosts.getAugmentation(DstCosts1.class).getCostDefault();
+ map.put(dst, cost(resp.meta.costType.mode, resp.meta.costType.metric, cost));
+ }
+ resp.answer.put(String.valueOf(src.getValue()), map);
+ }
+ return resp;
+ }
+
+ private Object cost(String mode, String metric, String cost) {
+ if (ORDINAL_MODE.equals(mode.toLowerCase())) {
+ return Integer.parseInt(cost);
+ }
+
+ if (NUMERICAL_MODE.equals(mode.toLowerCase())) {
+ if (HOP_COUNT_METRIC.equals(metric.toLowerCase())) {
+ return Integer.parseInt(cost);
+ } else if (ROUTING_COST_METRIC.equals(metric.toLowerCase())) {
+ return Double.parseDouble(cost);
+ }
+ }
+ return cost;
+ }
+}
--- /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.converter;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.opendaylight.alto.commons.helper.Converter;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285EndpointPropertyMap;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285EndpointPropertyMap.Meta;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285VersionTag;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class YANGJSON2RFCEndpointPropMapConverter
+ extends Converter<JsonNode, RFC7285EndpointPropertyMap> {
+ public YANGJSON2RFCEndpointPropMapConverter() {
+ }
+
+ public YANGJSON2RFCEndpointPropMapConverter(JsonNode _in) {
+ super(_in);
+ }
+
+ @Override
+ public Object _convert() {
+ JsonNode node = this.in();
+ RFC7285EndpointPropertyMap out = new RFC7285EndpointPropertyMap();
+ out.meta = convertMeta(in().get("meta"));
+ out.map = new LinkedHashMap<String, Map<String, String>>();
+ JsonNode endpointProperties = node.get("endpointProperties");
+ assert !endpointProperties.isArray();
+ for (JsonNode endpoint : endpointProperties) {
+ String addr = extract_addr(endpoint);
+ JsonNode properties = endpoint.get("properties");
+ assert properties.isNull();
+ Map<String, String> ps = convertProperties(properties);
+ out.map.put(addr, ps);
+ }
+ return out;
+ }
+
+ private Map<String, String> convertProperties(JsonNode properties) {
+ // TODO Auto-generated method stub
+ Map<String, String> ps = new LinkedHashMap<String, String>();
+ for (JsonNode propertyType : properties) {
+ String type = propertyType.get("propertyType").get("value").asText();
+ String property = propertyType.get("property").get("value").asText();
+ ps.put(type, property);
+ }
+ return ps;
+ }
+
+ private String extract_addr(JsonNode endpoint) {
+ // TODO Auto-generated method stub
+ return endpoint.get("endpoint").get("value").asText();
+ }
+
+ private Meta convertMeta(JsonNode jsonNode) {
+ // TODO Auto-generated method stub
+ Meta meta = new Meta();
+ meta.netmap_tags = new LinkedList<RFC7285VersionTag>();
+
+ for (JsonNode vtag : jsonNode.get("dependentVtags")) {
+ String resource_id = vtag.get("resourceId").get("value").asText();
+ String tag = vtag.get("tag").get("value").asText();
+ meta.netmap_tags.add(new RFC7285VersionTag(resource_id, tag));
+ }
+ return meta;
+ }
+}
\ No newline at end of file
--- /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.converter;
+
+import java.util.LinkedList;
+
+import org.opendaylight.alto.commons.helper.Converter;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285IRD;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class YANGJSON2RFCIRDConverter extends Converter<JsonNode, RFC7285IRD> {
+
+ public YANGJSON2RFCIRDConverter() {
+ }
+
+ public YANGJSON2RFCIRDConverter(JsonNode _in) {
+ super(_in);
+ }
+
+ @Override
+ protected Object _convert() {
+ JsonNode node = this.in();
+ RFC7285IRD ird = new RFC7285IRD();
+
+ JsonNode meta = node.get("meta");
+ for (JsonNode costType : meta.get("costTypes")) {
+ String costTypeName = costType.get("costTypeName").get("value").asText();
+ String costMode = costType.get("costMode").asText().toLowerCase();
+ String costMatric = costType.get("costMetric").get("value").asText();
+ if (!costType.get("description").isNull()) {
+ ird.meta.costTypes.put(costTypeName,
+ new RFC7285CostType(costMode, costMatric, costType.get("description").asText()));
+ } else {
+ ird.meta.costTypes.put(costTypeName, new RFC7285CostType(costMode, costMatric));
+ }
+
+ }
+ ird.meta.defaultAltoNetworkMap = meta.get("defaultAltoNetworkMap").get("resourceId").get("value").asText();
+
+ JsonNode resources = node.get("resources");
+ for (JsonNode res : resources) {
+ String rid = res.get("resourceId").get("value").asText();
+
+ RFC7285IRD.Entry ent = ird.new Entry();
+ ent.uri = res.get("uri").get("value").asText();
+ ent.mediaType = res.get("mediaType").get("value").asText();
+ if (!res.get("uses").isNull()) {
+ ent.uses = new LinkedList<String>();
+ for (JsonNode use : res.get("uses")) {
+ ent.uses.add(use.get("value").asText());
+ }
+ }
+
+ if (!res.get("capabilities").isNull()) {
+ ent.capabilities = ird.new Capability();
+ if (!res.get("capabilities").get("costConstraints").isNull()) {
+ ent.capabilities.costConstraints = res.get("capabilities").get("costConstraints").asBoolean();
+
+ }
+ if (!res.get("capabilities").get("costTypeNames").isNull()) {
+ ent.capabilities.costTypeNames = new LinkedList<String>();
+ for (JsonNode name : res.get("capabilities").get("costTypeNames")) {
+ ent.capabilities.costTypeNames.add(name.get("value").asText());
+ }
+ }
+ if (!res.get("capabilities").get("propTypes").isNull()) {
+ ent.capabilities.propTypes = new LinkedList<String>();
+ for (JsonNode prop : res.get("capabilities").get("propTypes")) {
+ ent.capabilities.propTypes.add(prop.get("value").asText());
+ }
+ }
+ }
+
+ if (!res.get("accepts").isNull()) {
+ for (JsonNode act : res.get("accepts")) {
+ ent.accepts = act.get("value").asText();
+ }
+ }
+
+ ird.resources.put(rid, ent);
+ }
+ return ird;
+ }
+
+ private RFC7285CostType RFC7285CostType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
public static class CostRequest {
@JsonProperty("cost-type")
- public RFC7285CostType costType = new RFC7285CostType();
+ public RFC7285CostType costType;
@JsonProperty("endpoints")
- public RFC7285QueryPairs endpoints = new RFC7285QueryPairs();
+ public RFC7285QueryPairs endpoints;
}
public static class CostResponse {
public Meta meta = new Meta();
@JsonProperty("endpoint-cost-map")
- public Map<String, Map<String, Object>> answer
- = new LinkedHashMap<String, Map<String, Object>>();
+ public Map<String, Map<String, Object>> answer = null;
}
}
import java.util.Arrays;
import java.util.List;
-import java.io.IOException;
-
-import com.fasterxml.jackson.core.JsonParseException;
-
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class RFC7285JSONMapper {
- private ObjectMapper mapper = new ObjectMapper()
- .setSerializationInclusion(Include.NON_DEFAULT)
- .disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
+ private ObjectMapper mapper = new ObjectMapper().setSerializationInclusion(Include.NON_DEFAULT)
+ .disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
- public RFC7285Endpoint.AddressGroup asAddressGroup(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285Endpoint.AddressGroup asAddressGroup(String json) throws Exception {
return mapper.readValue(json, RFC7285Endpoint.AddressGroup.class);
}
- public RFC7285Endpoint.PropertyRequest asPropertyRequest(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return mapper.readValue(json, RFC7285Endpoint.PropertyRequest.class);
+ public RFC7285Endpoint.PropertyRequest asPropertyRequest(String json) throws Exception {
+ RFC7285Endpoint.PropertyRequest ret = mapper.readValue(json, RFC7285Endpoint.PropertyRequest.class);
+
+ if (ret.properties == null) {
+ throw new JsonMappingException("Missing field:properties");
+ }
+ if (ret.endpoints == null) {
+ throw new JsonMappingException("Missing field:endpoints");
+ }
+ return ret;
}
- public RFC7285Endpoint.PropertyResponse asPropertyResponse(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285Endpoint.PropertyResponse asPropertyResponse(String json) throws Exception {
return mapper.readValue(json, RFC7285Endpoint.PropertyResponse.class);
}
- public RFC7285Endpoint.CostRequest asCostRequest(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return mapper.readValue(json, RFC7285Endpoint.CostRequest.class);
+ public RFC7285Endpoint.CostRequest asCostRequest(String json) throws Exception {
+ RFC7285Endpoint.CostRequest ret = mapper.readValue(json, RFC7285Endpoint.CostRequest.class);
+ if (ret.costType == null) {
+ throw new JsonMappingException("Missing field:cost-type");
+ }
+ if (ret.endpoints == null) {
+ throw new JsonMappingException("Missing field:endpoints");
+ }
+ return ret;
}
- public RFC7285Endpoint.CostResponse asCostResponse(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285Endpoint.CostResponse asCostResponse(String json) throws Exception {
return mapper.readValue(json, RFC7285Endpoint.CostResponse.class);
}
- public RFC7285CostMap asCostMap(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285CostMap asCostMap(String json) throws Exception {
return mapper.readValue(json, RFC7285CostMap.class);
}
- public List<RFC7285CostMap> asCostMapList(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return Arrays.asList(mapper.readValue(json, RFC7285CostMap[].class));
+ public List<RFC7285CostMap> asCostMapList(String json) throws Exception {
+ return Arrays.asList(mapper.readValue(json, RFC7285CostMap[].class));
}
- public RFC7285CostType asCostType(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285CostType asCostType(String json) throws Exception {
return mapper.readValue(json, RFC7285CostType.class);
}
- public RFC7285Endpoint asEndpoint(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285Endpoint asEndpoint(String json) throws Exception {
return mapper.readValue(json, RFC7285Endpoint.class);
}
- public Extensible asExtensible(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public Extensible asExtensible(String json) throws Exception {
return mapper.readValue(json, Extensible.class);
}
- public RFC7285IRD asIRD(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285IRD asIRD(String json) throws Exception {
return mapper.readValue(json, RFC7285IRD.class);
}
- public RFC7285NetworkMap asNetworkMap(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285NetworkMap asNetworkMap(String json) throws Exception {
return mapper.readValue(json, RFC7285NetworkMap.class);
}
- public List<RFC7285NetworkMap> asNetworkMapList(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return Arrays.asList(mapper.readValue(json, RFC7285NetworkMap[].class));
+ public List<RFC7285NetworkMap> asNetworkMapList(String json) throws Exception {
+ return Arrays.asList(mapper.readValue(json, RFC7285NetworkMap[].class));
}
- public RFC7285NetworkMap.Filter asNetworkMapFilter(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return mapper.readValue(json, RFC7285NetworkMap.Filter.class);
+ public RFC7285NetworkMap.Filter asNetworkMapFilter(String json) throws Exception {
+ RFC7285NetworkMap.Filter ret = mapper.readValue(json, RFC7285NetworkMap.Filter.class);
+ if (ret.pids == null) {
+ throw new JsonMappingException("Missing field:pids");
+ }
+ return ret;
}
- public RFC7285CostMap.Filter asCostMapFilter(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return mapper.readValue(json, RFC7285CostMap.Filter.class);
+ public RFC7285CostMap.Filter asCostMapFilter(String json) throws Exception {
+ RFC7285CostMap.Filter ret = mapper.readValue(json, RFC7285CostMap.Filter.class);
+ if (ret.costType == null) {
+ throw new JsonMappingException("Missing field:cost-type");
+ }
+ if (ret.pids == null) {
+ throw new JsonMappingException("Missing field:pids");
+ }
+ return ret;
}
- public RFC7285VersionTag asVersionTag(String json)
- throws IOException, JsonParseException, JsonMappingException {
+ public RFC7285VersionTag asVersionTag(String json) throws Exception {
return mapper.readValue(json, RFC7285VersionTag.class);
}
- public RFC7285EndpointPropertyMap asEndpointPropMap(String json)
- throws IOException, JsonParseException, JsonMappingException {
- return mapper.readValue(json, RFC7285EndpointPropertyMap.class);
- }
+ public RFC7285EndpointPropertyMap asEndpointPropMap(String json) throws Exception {
+ return mapper.readValue(json, RFC7285EndpointPropertyMap.class);
+ }
- public String asJSON(Object obj)
- throws IOException, JsonParseException, JsonMappingException {
+ public String asJSON(Object obj) throws Exception {
return mapper.writeValueAsString(obj);
}
}
*/
package org.opendaylight.alto.commons.types.converter;
-
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.Set;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.ArrayList;
import org.junit.Test;
RFC7285Endpoint.CostRequest req = new RFC7285Endpoint.CostRequest();
req.costType = new RFC7285CostType("ordinal", "routingcost", "test");
+ req.endpoints = new RFC7285QueryPairs();
req.endpoints.src.add("ipv4:192.0.2.2");
req.endpoints.dst.add("ipv4:192.0.2.89");
req.endpoints.dst.add("ipv4:198.51.100.34");
RFC7285Endpoint.CostResponse ecsr = new RFC7285Endpoint.CostResponse();
ecsr.meta.costType = new RFC7285CostType("ordinal", "routingcost");
+ ecsr.answer = new LinkedHashMap<String, Map<String, Object>>();
ecsr.answer.put(src[0], new LinkedHashMap<String, Object>());
ecsr.answer.get(src[0]).put(dst[0], new Integer(1));
ecsr.answer.get(src[0]).put(dst[1], new Integer(2));
package org.opendaylight.alto.ext.fake;
import org.opendaylight.alto.services.api.rfc7285.AltoService;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostRequest;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostResponse;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.PropertyRequest;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.PropertyResponse;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostMap;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
return null;
}
+ @Override
+ public PropertyResponse getEndpointProperty(PropertyRequest request) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public CostResponse getEndpointCost(CostRequest request) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
PidName pid = new PidName(vis);
IpPrefix ep = new IpPrefix(new Ipv4Prefix("0.0.0.0/0"));
- this.networkMap.put("0.0.0.0/0", "pid0");
+ networkMap.put("0.0.0.0/0", "pid0");
List<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map> mapList = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map>();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node n : ns
.getNode()) {
for (NodeConnector nc : n.getNodeConnector()) {
- AddressCapableNodeConnector acnc = (AddressCapableNodeConnector) nc
+ AddressCapableNodeConnector acnc = nc
.getAugmentation(AddressCapableNodeConnector.class);
if (acnc != null) {
for (Addresses addrs : acnc.getAddresses()) {
public static final String DEFAULT_NETWORK_MAP_REGEX = "^\\{\"default-alto-network-map\":\\{\"resource-id\":\"(.*)\"\\}}$";
- public static enum COST_MODE {
+ public enum COST_MODE {
Numerical, Ordinal
}
- public static enum SERVICE_TYPE{
+ public enum SERVICE_TYPE{
NETWORK_MAP, COST_MAP, ENDPOINT_PROPERTY_MAP
}
- public static enum MAP_FORMAT_TYPE {
+ public enum MAP_FORMAT_TYPE {
YANG, RFC
}
}
package org.opendaylight.alto.northbound;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.opendaylight.alto.commons.helper.ServiceHelper;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285JSONMapper;
import org.opendaylight.alto.commons.types.rfc7285.FormatValidator;
-import org.opendaylight.alto.commons.types.rfc7285.MediaType;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285IRD;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285JSONMapper;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285VersionTag;
import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostMap;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285QueryPairs;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285IRD;
+import org.opendaylight.alto.commons.types.rfc7285.MediaType;
import org.opendaylight.alto.services.api.rfc7285.AltoService;
import org.opendaylight.alto.services.api.rfc7285.IRDService;
import org.opendaylight.alto.services.api.rfc7285.NetworkMapService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Arrays;
+import java.util.List;
+
@Path("/")
public class AltoNorthbound {
private RFC7285JSONMapper mapper = new RFC7285JSONMapper();
+ private static final List<String> definedProperties = Arrays.asList(
+ "my-alternate-network-map.pid",
+ "my-default-network-map.pid",
+ "priv:ietf-type");
+
+ private static final List<String> definedCostMetrics = Arrays.asList(
+ "routingcost",
+ "hopcount");
+
+ private static final List<String> definedCostModes = Arrays.asList(
+ "ordinal",
+ "numerical");
+
@SuppressWarnings("unchecked")
private <E> E getService(Class<E> clazz) {
E service = (E)ServiceHelper.getGlobalInstance(clazz, this);
throw new AltoBadFormatException("tag", tag);
}
+ private void checkPropertyName(List<String> properties) throws AltoBadFormatException {
+ for (String name : properties) {
+ if (!definedProperties.contains(name))
+ throw new AltoBadFormatException("E_INVALID_FIELD_VALUE", "properties", name);
+ }
+ }
+
+ private void checkEndpointAddress(List<String> endpoints) throws AltoBadFormatException {
+ for (String address : endpoints) {
+ if (!FormatValidator.validEndpointAddress(address))
+ throw new AltoBadFormatException("E_INVALID_FIELD_VALUE", "endpoints", address);
+ }
+ }
+
+ private void checkPropertyRequest(RFC7285Endpoint.PropertyRequest request) throws AltoBadFormatException {
+ checkPropertyName(request.properties);
+ checkEndpointAddress(request.endpoints);
+ }
+
+ private void checkCostMetric(String metric) throws AltoBadFormatException {
+ if (!definedCostMetrics.contains(metric))
+ throw new AltoBadFormatException("E_INVALID_FIELD_VALUE", "cost-type/cost-metric", metric);
+ }
+
+ private void checkCostMode(String mode) throws AltoBadFormatException {
+ if (!definedCostModes.contains(mode))
+ throw new AltoBadFormatException("E_INVALID_FIELD_VALUE", "cost-type/cost-mode", mode);
+ }
+
+ private void checkCostType(RFC7285CostType costType) throws AltoBadFormatException {
+ checkCostMetric(costType.metric);
+ checkCostMode(costType.mode);
+ }
+
+ private void checkConstraints(List<String> constraints) throws AltoBadFormatException {
+ for (String constraint : constraints)
+ if (!FormatValidator.validFilterConstraint(constraint))
+ throw new AltoBadFormatException("E_INVALID_FIELD_VALUE", "constraints", constraint);
+ }
+
+ private void checkCostRequest(HttpServletRequest httpRequest, RFC7285Endpoint.CostRequest request) throws AltoBadFormatException {
+ checkCostType(request.costType);
+ checkEndponints(httpRequest, request.endpoints);
+ }
+
+ private void checkCostMapFilter(RFC7285CostMap.Filter filter) throws AltoBadFormatException {
+ checkCostType(filter.costType);
+ if (filter.constraints != null)
+ checkConstraints(filter.constraints);
+ }
+
+ private void checkEndponints(HttpServletRequest httpRequest, RFC7285QueryPairs endpoints) {
+ String ipAddress = getClientIpAddress(httpRequest);
+ if (endpoints.src.size() == 0) {
+ endpoints.src.add(ipAddress);
+ }
+
+ if (endpoints.dst.size() == 0) {
+ endpoints.dst.add(ipAddress);
+ }
+ }
+
+ private String getClientIpAddress(HttpServletRequest httpRequest) {
+ String remoteAddress = httpRequest.getRemoteAddr();
+ if (FormatValidator.validAddressIpv4("ipv4:" + remoteAddress)) {
+ return "ipv4:" + remoteAddress;
+ }
+
+ if (FormatValidator.validAddressIpv6("ipv6:" + remoteAddress)) {
+ return "ipv6:" + remoteAddress;
+ }
+
+ throw new AltoBadFormatException("E_INVALID_CLIENT_IP");
+ }
+
private Response fail(Response.Status status, Object data) {
try {
String output = (data == null ? "" : mapper.asJSON(data));
return Response.ok(output, mediaType).build();
} catch (Exception e) {
logger.error("Failed to parse object to json: {}", data.toString());
+ logger.error(e.getMessage());
return fail(Status.INTERNAL_SERVER_ERROR, null);
}
}
+ @Path("/directory")
@GET
@Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
public Response retrieveIRD() throws Exception {
return success(ird, MediaType.ALTO_DIRECTORY);
}
- @Path("/ird/{id}")
- @GET
- @Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
- public Response retrieveIRD(
- @PathParam("id") String id) throws Exception {
- IRDService service = getService(IRDService.class);
- checkService(service);
- checkResourceId(id);
-
- RFC7285IRD ird = service.getIRD(id);
- if (ird == null)
- return fail(Status.NOT_FOUND, id);
- return success(ird, MediaType.ALTO_DIRECTORY);
- }
-
@Path("/networkmap")
@GET
@Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
checkResourceId(id);
RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
+ checkCostMapFilter(filter);
if (!service.validateCostMapFilter(id, filter))
return fail(Status.BAD_REQUEST, filter);
RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
+ checkCostMapFilter(filter);
if (!service.validateCostMapFilter(vtag, filter))
return fail(Status.BAD_REQUEST, filter);
return success(map, MediaType.ALTO_COSTMAP);
}
- @Path("/endpointprop/lookup/{id}")
+ @Path("/endpointprop/lookup")
@POST
@Consumes({ MediaType.ALTO_ENDPOINT_PROPPARAMS })
@Produces({ MediaType.ALTO_ENDPOINT_PROP, MediaType.ALTO_ERROR })
public Response retrieveEndpointPropMap(
- @PathParam("id") String id,
String params) throws Exception {
EndpointPropertyService service = getService(EndpointPropertyService.class);
checkService(service);
- checkResourceId(id);
RFC7285Endpoint.PropertyRequest request = mapper.asPropertyRequest(params);
- RFC7285Endpoint.PropertyResponse response = service.getEndpointProperty(id, request);
+ checkPropertyRequest(request);
+ RFC7285Endpoint.PropertyResponse response = service.getEndpointProperty(request);
if (response == null)
return fail(Status.NOT_FOUND, request);
return success(response, MediaType.ALTO_ENDPOINT_PROP);
return success(response, MediaType.ALTO_ENDPOINT_PROP);
}
- @Path("/endpointcost/lookup/{id}")
+ @Path("/endpointcost/lookup")
@POST
@Consumes({ MediaType.ALTO_ENDPOINT_COSTPARAMS })
@Produces({ MediaType.ALTO_ENDPOINT_COST, MediaType.ALTO_ERROR })
- public Response retrieveEndpointCostMap(
- @PathParam("id") String id,
+ public Response retrieveEndpointCostMap(@Context HttpServletRequest httpRequest,
String params) throws Exception {
EndpointCostService service = getService(EndpointCostService.class);
checkService(service);
- checkResourceId(id);
RFC7285Endpoint.CostRequest request = mapper.asCostRequest(params);
- RFC7285Endpoint.CostResponse response = service.getEndpointCost(id, request);
+ checkCostRequest(httpRequest, request);
+ RFC7285Endpoint.CostResponse response = service.getEndpointCost(request);
if (response == null)
return fail(Status.NOT_FOUND, request);
return success(response, MediaType.ALTO_ENDPOINT_COST);
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
+import org.opendaylight.alto.northbound.exception.AltoNorthboundExceptionHandler;
public class AltoNorthboundRSApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(AltoNorthbound.class);
+ classes.add(AltoNorthboundExceptionHandler.class);
return classes;
}
}
import javax.ws.rs.core.Response.Status;
-public class AltoBadFormatException extends AltoBasicException {
+public class AltoBadFormatException extends AltoErrorTestException {
- public static final String TEMPLATE = "Bad %s format: %s";
+ public AltoBadFormatException() {
+ super(Status.BAD_REQUEST);
+ }
+
+ public AltoBadFormatException(String code) {
+ super(Status.BAD_REQUEST, code);
+ }
- public AltoBadFormatException(String field, String value) {
- super(Status.BAD_REQUEST, String.format(TEMPLATE, field, value));
+ public AltoBadFormatException(String code, String field) {
+ super(Status.BAD_REQUEST, code, field);
}
+
+ public AltoBadFormatException(String code, String field, String value) {
+ super(Status.BAD_REQUEST, code, field, value);
+ }
+
}
--- /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.northbound.exception;
+
+import javax.ws.rs.core.Response;
+
+public class AltoErrorTestException extends AltoBasicException {
+ public static final String TEMPLATE_EMPTY = "{}";
+ public static final String TEMPLATE_CODE =
+ "{\"meta\":{\"code\":\"%s\"}}";
+ public static final String TEMPLATE_CODE_FIELD =
+ "{\"meta\":{\"code\":\"%s\",\"field\":\"%s\"}}";
+ public static final String TEMPLATE_CODE_FIELD_VALUE =
+ "{\"meta\":{\"code\":\"%s\",\"field\":\"%s\",\"value\":\"%s\"}}";
+
+ public enum ERROR_CODES {
+ E_MISSING_FIELD, E_SYNTAX, E_INVALID_FIELD_TYPE, E_INVALID_FIELD_VALUE, E_INVALID_CLIENT_IP
+ }
+
+ public AltoErrorTestException(Response.Status status) {
+ super(status, "{}");
+ }
+
+ public AltoErrorTestException(Response.Status status, String code) {
+ super(status, String.format(TEMPLATE_CODE, code));
+ }
+
+ public AltoErrorTestException(Response.Status status, String code, String field) {
+ super(status, String.format(TEMPLATE_CODE_FIELD, code, field));
+ }
+
+ public AltoErrorTestException(Response.Status status, String code, String field, String value) {
+ super(status, String.format(TEMPLATE_CODE_FIELD_VALUE, code, field, value));
+ }
+}
package org.opendaylight.alto.northbound.exception;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
-import javax.ws.rs.ext.Provider;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
import org.opendaylight.alto.commons.types.rfc7285.MediaType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class AltoNorthboundExceptionHandler implements ExceptionMapper<Exception> {
+
+ private static final Logger logger = LoggerFactory.getLogger(AltoNorthboundExceptionHandler.class);
-@Provider
-public class AltoNorthboundExceptionHandler
- implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
- if (e instanceof AltoBasicException)
- return ((AltoBasicException)e).getResponse();
- return Response.status(Status.INTERNAL_SERVER_ERROR)
- .entity(e.getMessage())
- .type(MediaType.ALTO_ERROR).build();
+ logger.info("begin exception handle: " + e.toString());
+ logger.info("exception type: " + e.getClass().toString());
+ if (e instanceof AltoBasicException) {
+ return ((AltoBasicException) e).getResponse();
+ }
+
+ if (e instanceof JsonParseException) {
+ logger.info("JsonParseException: " + e.toString());
+ AltoBasicException ept = new AltoErrorTestException(Status.BAD_REQUEST,
+ AltoErrorTestException.ERROR_CODES.E_SYNTAX.name());
+ return ept.getResponse();
+ }
+
+ if (e instanceof JsonMappingException) {
+ logger.info("JsonMappingException: " + e.toString());
+ if (e.getMessage().split(":")[0].equals("Missing field")) {
+ AltoBasicException ept = new AltoErrorTestException(Status.BAD_REQUEST,
+ AltoErrorTestException.ERROR_CODES.E_MISSING_FIELD.name(), e.getMessage().split(":")[1]);
+ return ept.getResponse();
+ } else {
+ String fieldName = ((JsonMappingException) e).getPath().get(0).getFieldName();
+ AltoBasicException ept = new AltoErrorTestException(Status.BAD_REQUEST,
+ AltoErrorTestException.ERROR_CODES.E_INVALID_FIELD_TYPE.name(), fieldName);
+ return ept.getResponse();
+ }
+ }
+
+ if (e instanceof WebApplicationException) {
+ return ((WebApplicationException) e).getResponse();
+ }
+ return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).type(MediaType.ALTO_ERROR).build();
}
}
public interface CostMapService {
- public RFC7285CostMap getCostMap(String id);
+ RFC7285CostMap getCostMap(String id);
- public RFC7285CostMap getCostMap(RFC7285VersionTag vtag);
+ RFC7285CostMap getCostMap(RFC7285VersionTag vtag);
- public RFC7285CostMap getCostMap(String id, RFC7285CostType type);
+ RFC7285CostMap getCostMap(String id, RFC7285CostType type);
- public RFC7285CostMap getCostMap(RFC7285VersionTag vtag, RFC7285CostType type);
+ RFC7285CostMap getCostMap(RFC7285VersionTag vtag, RFC7285CostType type);
- public RFC7285CostMap getCostMap(String id, RFC7285CostMap.Filter filter);
+ RFC7285CostMap getCostMap(String id, RFC7285CostMap.Filter filter);
- public RFC7285CostMap getCostMap(RFC7285VersionTag vtag, RFC7285CostMap.Filter filter);
+ RFC7285CostMap getCostMap(RFC7285VersionTag vtag, RFC7285CostMap.Filter filter);
- public Boolean supportCostType(String id, RFC7285CostType type);
+ Boolean supportCostType(String id, RFC7285CostType type);
- public Boolean supportCostType(RFC7285VersionTag vtag, RFC7285CostType type);
+ Boolean supportCostType(RFC7285VersionTag vtag, RFC7285CostType type);
- public Boolean validateCostMapFilter(String id, RFC7285CostMap.Filter filter);
+ Boolean validateCostMapFilter(String id, RFC7285CostMap.Filter filter);
- public Boolean validateCostMapFilter(RFC7285VersionTag vtag, RFC7285CostMap.Filter filter);
+ Boolean validateCostMapFilter(RFC7285VersionTag vtag, RFC7285CostMap.Filter filter);
}
public interface EndpointCostService {
- public CostResponse getEndpointCost(String id, CostRequest request);
+ CostResponse getEndpointCost(CostRequest request);
- public CostResponse getEndpointCost(RFC7285VersionTag vtag, CostRequest request);
+ CostResponse getEndpointCost(RFC7285VersionTag vtag, CostRequest request);
}
public interface EndpointPropertyService {
- public PropertyResponse getEndpointProperty(String id, PropertyRequest request);
+ PropertyResponse getEndpointProperty(PropertyRequest request);
- public PropertyResponse getEndpointProperty(RFC7285VersionTag vtag, PropertyRequest request);
+ PropertyResponse getEndpointProperty(RFC7285VersionTag vtag, PropertyRequest request);
}
public interface IRDService {
- public RFC7285IRD getDefaultIRD();
+ RFC7285IRD getDefaultIRD();
- public RFC7285IRD getIRD(String id);
+ RFC7285IRD getIRD(String id);
}
public interface NetworkMapService {
- public RFC7285NetworkMap getDefaultNetworkMap();
+ RFC7285NetworkMap getDefaultNetworkMap();
- public RFC7285NetworkMap getNetworkMap(String id);
+ RFC7285NetworkMap getNetworkMap(String id);
- public RFC7285NetworkMap getNetworkMap(RFC7285VersionTag vtag);
+ RFC7285NetworkMap getNetworkMap(RFC7285VersionTag vtag);
- public RFC7285NetworkMap getNetworkMap(String id, RFC7285NetworkMap.Filter filter);
+ RFC7285NetworkMap getNetworkMap(String id, RFC7285NetworkMap.Filter filter);
- public RFC7285NetworkMap getNetworkMap(RFC7285VersionTag vtag, RFC7285NetworkMap.Filter filter);
+ RFC7285NetworkMap getNetworkMap(RFC7285VersionTag vtag, RFC7285NetworkMap.Filter filter);
- public Boolean validateNetworkMapFilter(String id, RFC7285NetworkMap.Filter filter);
+ Boolean validateNetworkMapFilter(String id, RFC7285NetworkMap.Filter filter);
- public Boolean validateNetworkMapFilter(RFC7285VersionTag vtag, RFC7285NetworkMap.Filter filter);
+ Boolean validateNetworkMapFilter(RFC7285VersionTag vtag, RFC7285NetworkMap.Filter filter);
}
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ </dependency>
+
<!-- Testing Dependencies -->
<dependency>
<groupId>junit</groupId>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>ietf-inet-types</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ </dependency>
</dependencies>
</project>
package org.opendaylight.alto.services.provider.simple;
+import org.opendaylight.alto.commons.helper.NetworkMapIpPrefixHelper;
+import org.opendaylight.alto.commons.types.converter.CostRequest2EndpointCostServiceInputConverter;
+import org.opendaylight.alto.commons.types.converter.EndpointCostServiceOutput2CostResponseConverter;
+import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCCostMapConverter;
+import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCEndpointPropMapConverter;
+import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCIRDConverter;
+import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCNetworkMapConverter;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostMap;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.AddressGroup;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostRequest;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.CostResponse;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.PropertyRequest;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint.PropertyResponse;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285EndpointPropertyMap;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285IRD;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285JSONMapper;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
+import org.opendaylight.alto.commons.types.rfc7285.RFC7285VersionTag;
+import org.opendaylight.alto.services.api.rfc7285.AltoService;
import org.opendaylight.alto.services.api.rfc7285.NetworkMapService;
import org.opendaylight.alto.services.api.rfc7285.CostMapService;
+import org.opendaylight.alto.services.api.rfc7285.EndpointCostService;
+import org.opendaylight.alto.services.api.rfc7285.EndpointPropertyService;
+import org.opendaylight.alto.services.api.rfc7285.IRDService;
import org.opendaylight.alto.commons.helper.ServiceHelper;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285VersionTag;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostMap;
-import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
-import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCNetworkMapConverter;
-import org.opendaylight.alto.commons.types.converter.YANGJSON2RFCCostMapConverter;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.map.DstCosts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.AltoServiceService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.EndpointCostServiceOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.Resources;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.CostMaps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.EndpointPropertyMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.IRD;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.NetworkMaps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.CostMaps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.cost.maps.CostMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.cost.maps.CostMapKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMapKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.map.DstCosts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.PidName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ResourceId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ird.meta.DefaultAltoNetworkMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddressBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ird.Meta;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ird.meta.DefaultAltoNetworkMap;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.osgi.framework.ServiceRegistration;
import com.google.common.base.Optional;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.LinkedList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.module.SimpleModule;
@SuppressWarnings("rawtypes")
-public class SimpleAltoService implements NetworkMapService, CostMapService, AutoCloseable {
+public class SimpleAltoService implements AltoService, AutoCloseable {
private final Logger m_logger = LoggerFactory.getLogger(SimpleAltoService.class);
private DataBroker m_db = null;
+ private AltoServiceService m_service = null;
+
private ObjectMapper m_mapper = new ObjectMapper();
+ private RFC7285JSONMapper j_mapper = new RFC7285JSONMapper();
private List<ServiceRegistration> m_reg = new LinkedList<ServiceRegistration>();
private YANGJSON2RFCNetworkMapConverter m_nmconverter = null;
private YANGJSON2RFCCostMapConverter m_cmconverter = null;
+ private YANGJSON2RFCEndpointPropMapConverter m_epmconverter = null;
+ private YANGJSON2RFCIRDConverter m_irdconverter = null;
+ private EndpointCostServiceOutput2CostResponseConverter ecsOutputConverter = null;
+ private CostRequest2EndpointCostServiceInputConverter ecsInputConverter = null;
+ private NetworkMapIpPrefixHelper iHelper = new NetworkMapIpPrefixHelper();
+ private final String PRIV_NETWORK_MAP = "private-network-map";
+ private final String PRIV_ENDPOINT_PROPERTY_NAME = "priv:ietf-type";
protected class DstCostSerializer extends JsonSerializer<DstCosts> {
@Override
Map<Class<? extends Augmentation<?>>, Augmentation<?>> augmentations
= BindingReflections.getAugmentations(value);
String cost = null;
- for (Augmentation<?> aug: augmentations.values()) {
+ for (Augmentation<?> aug : augmentations.values()) {
try {
ObjectNode node = m_mapper.valueToTree(aug);
- for (Iterator<String> itr = node.fieldNames(); itr.hasNext(); ) {
+ for (Iterator<String> itr = node.fieldNames(); itr.hasNext();) {
String field = itr.next();
if (field.toLowerCase().indexOf("cost") >= 0) {
cost = node.get(field).asText();
}
}
- public SimpleAltoService(DataBroker db) {
+ public SimpleAltoService(DataBroker db, AltoServiceService service) {
this.m_db = db;
+ this.m_service = service;
this.m_nmconverter = new YANGJSON2RFCNetworkMapConverter();
this.m_cmconverter = new YANGJSON2RFCCostMapConverter();
+ this.m_epmconverter = new YANGJSON2RFCEndpointPropMapConverter();
+ this.m_irdconverter = new YANGJSON2RFCIRDConverter();
+ this.ecsOutputConverter = new EndpointCostServiceOutput2CostResponseConverter();
+ this.ecsInputConverter = new CostRequest2EndpointCostServiceInputConverter();
+ this.register(IRDService.class);
this.register(NetworkMapService.class);
this.register(CostMapService.class);
+ this.register(EndpointPropertyService.class);
+ this.register(EndpointCostService.class);
try {
SimpleModule module = new SimpleModule();
@Override
public void close() {
- for (ServiceRegistration reg: this.m_reg) {
+ for (ServiceRegistration reg : this.m_reg) {
reg.unregister();
}
this.m_reg.clear();
if (nm == null)
return null;
- LinkedHashMap<String, RFC7285Endpoint.AddressGroup> map
- = new LinkedHashMap<String, RFC7285Endpoint.AddressGroup>();
- for (String pid: filter.pids) {
- if (nm.map.containsKey(pid))
+ LinkedHashMap<String, RFC7285Endpoint.AddressGroup> map = new LinkedHashMap<String, RFC7285Endpoint.AddressGroup>();
+ for (String pid : filter.pids) {
+ if (nm.map.get(pid) != null)
map.put(pid, nm.map.get(pid));
}
- nm.map = map;
+ if (filter.pids.isEmpty()) {
+ map = new LinkedHashMap<String, RFC7285Endpoint.AddressGroup>(nm.map);
+ }
+ LinkedHashMap<String, RFC7285Endpoint.AddressGroup> ret = new LinkedHashMap<String, RFC7285Endpoint.AddressGroup>();
+ for (Map.Entry<String, RFC7285Endpoint.AddressGroup> entry : map.entrySet()) {
+ String pid = entry.getKey();
+ if (filter.addressTypes != null && (!filter.addressTypes.isEmpty())) {
+ AddressGroup ag = new AddressGroup();
+ if (filter.addressTypes.contains("ipv4")) {
+ ag.ipv4 = nm.map.get(pid).ipv4;
+ }
+ if (filter.addressTypes.contains("ipv6")) {
+ ag.ipv6 = nm.map.get(pid).ipv6;
+ }
+ if (!ag.ipv4.isEmpty() || !ag.ipv6.isEmpty())
+ ret.put(pid, ag);
+ } else {
+ ret.put(pid, entry.getValue());
+ }
+ }
+ nm.map = ret;
return nm;
}
@Override
public Boolean validateNetworkMapFilter(String id, RFC7285NetworkMap.Filter filter) {
- if ((filter != null) && (filter.pids != null))
- return true;
- return false;
+ return (filter != null) && (filter.pids != null);
}
@Override
return validateNetworkMapFilter(vtag.rid, filter);
}
-
@Override
public RFC7285CostMap getCostMap(String id) {
m_logger.info("Handling cost-map resource: {}", id);
@Override
public RFC7285CostMap getCostMap(String id, RFC7285CostMap.Filter filter) {
- RFC7285CostMap cm = null;
- if (filter.costType != null) {
- cm = getCostMap(id, filter.costType);
- } else {
- cm = getCostMap(id);
- }
+ RFC7285CostMap cm = getCostMap(id + "-" + filter.costType.metric + "-" + filter.costType.mode);
if (cm == null)
return null;
if (filter.pids != null) {
- if (filter.pids.src == null)
+ if (filter.pids.src.isEmpty())
filter.pids.src = new LinkedList<String>(cm.map.keySet());
- if (filter.pids.dst == null)
+ if (filter.pids.dst.isEmpty())
filter.pids.dst = new LinkedList<String>(cm.map.keySet());
Map<String, Map<String, Object>> data = new LinkedHashMap<String, Map<String, Object>>();
- for (String src: filter.pids.src) {
+ for (String src : filter.pids.src) {
if (!cm.map.containsKey(src))
continue;
- if (data.containsKey(src))
- continue;
Map<String, Object> old_data = cm.map.get(src);
if (old_data == null)
continue;
Map<String, Object> new_data = new LinkedHashMap<String, Object>();
- for (String dst: filter.pids.dst) {
+ for (String dst : filter.pids.dst) {
if (!old_data.containsKey(dst))
continue;
- if (new_data.containsKey(dst))
- continue;
- new_data.put(dst, old_data.get(dst));
+ if (filter.constraints == null || filter.constraints.isEmpty()
+ || meetConstraints(filter.constraints, old_data.get(dst)))
+ new_data.put(dst, old_data.get(dst));
}
data.put(src, new_data);
}
return cm;
}
+ private boolean meetConstraints(List<String> constraints, Object object) {
+ // We'd better simplify the constraints before using it.
+ for (String constraint : constraints)
+ if (!meetConstraint(constraint, object))
+ return false;
+ return true;
+ }
+
+ private boolean meetConstraint(String constraint, Object object) {
+ String operator = constraint.substring(0, 2);
+ double target = Double.parseDouble(object.toString());
+ double value = Double.parseDouble(constraint.substring(3));
+ switch (operator) {
+ case "gt":
+ return target > value;
+ case "lt":
+ return target < value;
+ case "ge":
+ return target >= value;
+ case "le":
+ return target <= value;
+ case "eq":
+ return target == value;
+ }
+ return false;
+ }
+
@Override
public RFC7285CostMap getCostMap(RFC7285VersionTag vtag, RFC7285CostMap.Filter filter) {
//TODO
.build();
return iid;
}
+
+ protected InstanceIdentifier<EndpointPropertyMap> getEndpointPropertyMapIID() {
+ InstanceIdentifier<EndpointPropertyMap> iid = InstanceIdentifier.builder(Resources.class)
+ .child(EndpointPropertyMap.class).build();
+ return iid;
+ }
+
+ @Override
+ public PropertyResponse getEndpointProperty(PropertyRequest request) {
+ InstanceIdentifier<EndpointPropertyMap> eiid = getEndpointPropertyMapIID();
+ m_logger.info("EndpointPropertyMap IID: {}", eiid);
+ updatePrivateNetworkMap();
+
+ try {
+ ReadOnlyTransaction tx = m_db.newReadOnlyTransaction();
+ ListenableFuture<Optional<EndpointPropertyMap>> result = tx.read(LogicalDatastoreType.CONFIGURATION, eiid);
+ if (result.get().isPresent()) {
+ EndpointPropertyMap epm = result.get().get();
+ ObjectNode node = m_mapper.valueToTree(epm);
+ m_logger.info(m_mapper.writeValueAsString(epm));
+
+ RFC7285EndpointPropertyMap endpointPropMap = m_epmconverter.convert(node);
+ RFC7285EndpointPropertyMap ret = new RFC7285EndpointPropertyMap();
+ ret.meta = endpointPropMap.meta;
+ ret.meta.netmap_tags = getDependentTags(endpointPropMap.meta, request.properties);
+ for (String addr : request.endpoints) {
+ Map<String, String> newProps = new LinkedHashMap<String, String>();
+ if (endpointPropMap.map.containsKey(addr.toLowerCase())) {
+ Map<String, String> props = endpointPropMap.map.get(addr);
+ for (String type : request.properties) {
+ if (props.containsKey(type)) {
+ newProps.put(type, props.get(type));
+ }
+ }
+ } else if (request.properties.contains(PRIV_ENDPOINT_PROPERTY_NAME)) {
+ newProps = getPrivateEndpointProperty(addr);
+ }
+ if (!newProps.isEmpty())
+ ret.map.put(addr, newProps);
+ }
+ return j_mapper.asPropertyResponse(j_mapper.asJSON(ret));
+ } else {
+ m_logger.info("Failed to read with eiid: {}", eiid);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private void updatePrivateNetworkMap() {
+ InstanceIdentifier<NetworkMap> niid = getNetworkMapIID(PRIV_NETWORK_MAP);
+ try {
+ ReadOnlyTransaction tx = m_db.newReadOnlyTransaction();
+ ListenableFuture<Optional<NetworkMap>> result
+ = tx.read(LogicalDatastoreType.CONFIGURATION, niid);
+ if (result.get().isPresent()) {
+ NetworkMap privateNetworkMap = result.get().get();
+ iHelper.update(privateNetworkMap);
+ } else {
+ m_logger.info("Failed to read with niid: {}", niid);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private List<RFC7285VersionTag> getDependentTags(RFC7285EndpointPropertyMap.Meta meta, List<String> properties) {
+ List<RFC7285VersionTag> dependentTags = new LinkedList<RFC7285VersionTag>();
+ for (RFC7285VersionTag vtag : meta.netmap_tags) {
+ if (properties.contains(vtag.rid + ".pid"))
+ dependentTags.add(vtag);
+ }
+ return dependentTags;
+ }
+
+ private Map<String, String> getPrivateEndpointProperty(String addr) {
+ Map<String, String> property = new LinkedHashMap<String, String>();
+ try {
+ TypedEndpointAddress address = TypedEndpointAddressBuilder.getDefaultInstance(addr);
+ PidName pid = iHelper.getPIDByEndpointAddress(address);
+ if (pid != null)
+ property.put(PRIV_ENDPOINT_PROPERTY_NAME, pid.getValue());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return property;
+ }
+
+ @Override
+ public RFC7285IRD getDefaultIRD() {
+ InstanceIdentifier<IRD> iid = getIRDIID();
+
+ try {
+ ReadOnlyTransaction tx = m_db.newReadOnlyTransaction();
+ ListenableFuture<Optional<IRD>> result = tx.read(LogicalDatastoreType.CONFIGURATION, iid);
+ if (result.get().isPresent()) {
+ IRD iIRD = result.get().get();
+ m_logger.info(iIRD.toString());
+ m_logger.info(m_mapper.writeValueAsString(iIRD));
+ ObjectNode node = m_mapper.valueToTree(iIRD);
+
+ RFC7285IRD ret = m_irdconverter.convert(node);
+ m_logger.info("IRD convert compelete.");
+ return ret;
+ } else {
+ m_logger.info("Failed to read with ciid: {}", iid);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public PropertyResponse getEndpointProperty(RFC7285VersionTag vtag, PropertyRequest request) {
+ return null;
+ }
+
+ @Override
+ public CostResponse getEndpointCost(CostRequest request) {
+ CostResponse response = null;
+ EndpointCostServiceInput input = this.ecsInputConverter.convert(request);
+ Future<RpcResult<EndpointCostServiceOutput>> result = this.m_service.endpointCostService(input);
+ try {
+ EndpointCostServiceOutput output = result.get().getResult();
+ response = this.ecsOutputConverter.convert(output);
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+
+ @Override
+ public CostResponse getEndpointCost(RFC7285VersionTag vtag, CostRequest request) {
+ return null;
+ }
+
+ public RFC7285IRD getIRD(String id) {
+ return this.getDefaultIRD();
+ }
+
+ protected InstanceIdentifier<IRD> getIRDIID() {
+ InstanceIdentifier<IRD> iid = InstanceIdentifier.builder(Resources.class).child(IRD.class).build();
+ return iid;
+ }
}
package org.opendaylight.yang.gen.v1.urn.opendaylight.alto.simple.impl.rev150512;
import org.opendaylight.alto.services.provider.simple.SimpleAltoService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.AltoServiceService;
public class SimpleAltoImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.alto.simple.impl.rev150512.AbstractSimpleAltoImplModule {
public SimpleAltoImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@Override
public java.lang.AutoCloseable createInstance() {
- SimpleAltoService service = new SimpleAltoService(this.getDataBrokerDependency());
+ SimpleAltoService service = new SimpleAltoService(this.getDataBrokerDependency(),
+ this.getRpcRegistryDependency().getRpcService(AltoServiceService.class));
return service;
}