org.opendaylight.alto.core.northbound.route.endpointproperty.impl.AltoNorthboundRouteEndpointproperty.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.alto.core.northbound.route.endpointproperty.impl.AltoNorthboundRouteEndpointproperty.java

Source

/*
 * 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.endpointproperty.impl;

import org.opendaylight.controller.md.sal.binding.api.DataBroker;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import org.opendaylight.alto.core.northbound.api.exception.AltoErrorInvalidFieldValue;
import org.opendaylight.alto.core.northbound.api.utils.rfc7285.RFC7285EndpointPropertyMap;
import org.opendaylight.alto.core.northbound.api.utils.rfc7285.RFC7285VersionTag;

import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.alto.core.northbound.api.AltoNorthboundRoute;
import org.opendaylight.alto.core.northbound.api.AltoNorthboundRouter;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.alto.northbound.route.endpointproperty.rev151021.records.Record;
import org.opendaylight.yang.gen.v1.urn.alto.northbound.route.endpointproperty.rev151021.records.RecordKey;
import org.opendaylight.yang.gen.v1.urn.alto.resourcepool.rev150921.context.Resource;
import org.opendaylight.yang.gen.v1.urn.alto.resourcepool.rev150921.context.resource.ContextTag;
import org.opendaylight.yang.gen.v1.urn.alto.resourcepool.rev150921.context.resource.ContextTagKey;
import org.opendaylight.yang.gen.v1.urn.alto.types.rev150921.SpecificEndpointProperty;
import org.opendaylight.yang.gen.v1.urn.alto.types.rev150921.GlobalEndpointProperty;
import org.opendaylight.yang.gen.v1.urn.alto.northbound.route.endpointproperty.rev151021.Records;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.AltoModelEndpointpropertyService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.QueryInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.QueryInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.QueryOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.ResourceTypeEndpointproperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.alto.request.endpointproperty.request.EndpointpropertyRequestBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.alto.response.endpointproperty.response.EndpointpropertyResponse;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rev151021.endpointproperty.request.data.EndpointpropertyParamsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.Ipv4AddressData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.Ipv6AddressData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointproperty.filter.data.EndpointpropertyFilterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointproperty.filter.data.endpointproperty.filter.EndpointFilter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointproperty.filter.data.endpointproperty.filter.EndpointFilterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointproperty.filter.data.endpointproperty.filter.PropertyFilter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointproperty.filter.data.endpointproperty.filter.PropertyFilterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointpropertymap.response.data.EndpointPropertyMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointpropertymap.response.data.endpoint.property.map.EndpointProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointpropertymap.response.data.endpoint.property.map.endpoint.property.Properties;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointpropertymap.response.data.endpoint.property.map.endpoint.property.Source;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.endpointpropertymap.response.data.endpoint.property.map.endpoint.property.properties.PropertyValue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.input.request.endpointproperty.request.endpointproperty.params.filter.EndpointpropertyFilterDataBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.input.request.endpointproperty.request.endpointproperty.params.filter.endpointproperty.filter.data.endpointproperty.filter.endpoint.filter.address.Ipv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.input.request.endpointproperty.request.endpointproperty.params.filter.endpointproperty.filter.data.endpointproperty.filter.endpoint.filter.address.Ipv6Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.input.request.endpointproperty.request.endpointproperty.params.filter.endpointproperty.filter.data.endpointproperty.filter.property.filter.property.InputGlobalPropertyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.input.request.endpointproperty.request.endpointproperty.params.filter.endpointproperty.filter.data.endpointproperty.filter.property.filter.property.InputResourceSpecificPropertyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.output.response.endpointproperty.response.endpointproperty.data.EndpointPropertymapData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.output.response.endpointproperty.response.endpointproperty.data.endpoint.propertymap.data.endpoint.property.map.endpoint.property.properties.property.container.property.OutputGlobalProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.output.response.endpointproperty.response.endpointproperty.data.endpoint.propertymap.data.endpoint.property.map.endpoint.property.properties.property.container.property.OutputResourceSpecificProperty;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.query.output.response.endpointproperty.response.endpointproperty.data.endpoint.propertymap.data.endpoint.property.map.endpoint.property.properties.property.value.PidName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.typed.address.data.Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.model.endpointproperty.rfc7285.rev151021.typed.property.data.Property;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.Future;
import javax.ws.rs.Consumes;
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;

public class AltoNorthboundRouteEndpointproperty implements AltoNorthboundRoute {
    public static final String ALTO_ENDPOINTPROPERTY_FILTER = "application/alto-endpointpropparams+json";
    public static final String ALTO_ENDPOINTPROPERTY = "application/alto-endpointprop+json";
    public static final String FIELD_PROPERTIES = "properties";
    public static final String FIELD_ENDPOINTS = "endpoints";
    public static final String IPv4_PREFIX = "ipv4:";
    public static final String IPv6_PREFIX = "ipv6:";
    public static final String PRIV_PREFIX = "priv:";

    private ObjectMapper mapper = new ObjectMapper();
    private static final Logger LOG = LoggerFactory.getLogger(AltoNorthboundRouteEndpointproperty.class);

    private DataBroker dataBroker = null;

    private AltoNorthboundRouter m_router = null;

    private static AltoModelEndpointpropertyService mapService = null;

    public void setDataBroker(DataBroker dataBroker) {
        this.dataBroker = dataBroker;
    }

    public void setMapService(final AltoModelEndpointpropertyService mapService) {
        this.mapService = mapService;
    }

    public void init() {

        if (dataBroker == null) {
            LOG.error("Failed to init: data broker is null");
        }

        LOG.info("AltoNorthboundRouteEndpointProperty initiated");
    }

    public void register(AltoNorthboundRouter router) {
        m_router = router;
        m_router.addRoute("endpointproperty", new AltoNorthboundRouteEndpointproperty());
    }

    public void close() {
        m_router.removeRoute("endpointproperty");
    }

    @Path("{path}")
    @POST
    @Consumes({ ALTO_ENDPOINTPROPERTY_FILTER })
    @Produces({ ALTO_ENDPOINTPROPERTY, ALTO_ERROR })
    public Response getEndpointProperty(@PathParam("path") String path, String content) {
        JsonNode filterNode = EndpointpropertyRouteChecker.checkJsonSyntax(content);
        JsonNode _properties = filterNode.get(FIELD_PROPERTIES);
        EndpointpropertyRouteChecker.checkMissing(_properties, FIELD_PROPERTIES);
        EndpointpropertyRouteChecker.checkList(_properties, FIELD_PROPERTIES);

        JsonNode _endpoints = filterNode.get(FIELD_ENDPOINTS);
        EndpointpropertyRouteChecker.checkMissing(_endpoints, FIELD_ENDPOINTS);
        EndpointpropertyRouteChecker.checkList(_endpoints, FIELD_ENDPOINTS);

        QueryInput input = prepareInput(path, _properties.elements(), _endpoints.elements());
        LOG.info(input.toString());

        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 = null;
        try {
            response = buildOutput(input, output);
        } catch (Exception E) {

        }
        if (response != null)
            return response;
        else
            return Response.status(404).build();
    }

    private Property constructProperty(String property) {
        try {
            if (property.contains(".")) {
                return new InputResourceSpecificPropertyBuilder()
                        .setResourceSpecificProperty(new SpecificEndpointProperty(property)).build();
            } else if (property.equals(PRIV_PREFIX)) {
                throw new AltoErrorInvalidFieldValue(FIELD_PROPERTIES, property);
            } else {
                return new InputGlobalPropertyBuilder().setGlobalProperty(new GlobalEndpointProperty(property))
                        .build();
            }
        } catch (IllegalArgumentException E) {
            throw new AltoErrorInvalidFieldValue(FIELD_PROPERTIES, property);
        }
    }

    private Address constructAddress(String address) {
        try {
            if (address.contains(IPv4_PREFIX)) {
                return new Ipv4Builder().setIpv4(new Ipv4Address(address.replace(IPv4_PREFIX, ""))).build();
            } else if (address.contains(IPv6_PREFIX)) {
                return new Ipv6Builder().setIpv6(new Ipv6Address(address.replace(IPv6_PREFIX, ""))).build();
            } else {
                throw new AltoErrorInvalidFieldValue(FIELD_ENDPOINTS, address);
            }
        } catch (IllegalArgumentException E) {
            throw new AltoErrorInvalidFieldValue(FIELD_PROPERTIES, address);
        }
    }

    protected List<PropertyFilter> constructListPropertyFilter(Iterator<JsonNode> properties) {
        List<PropertyFilter> listPropertyFilter = new LinkedList<>();
        while (properties.hasNext()) {
            listPropertyFilter.add(
                    new PropertyFilterBuilder().setProperty(constructProperty(properties.next().asText())).build());
        }
        return listPropertyFilter;
    }

    protected List<EndpointFilter> constructListEndpointFilter(Iterator<JsonNode> endpoints) {
        List<EndpointFilter> listEndpointFilter = new LinkedList<>();
        while (endpoints.hasNext()) {
            listEndpointFilter.add(
                    new EndpointFilterBuilder().setAddress(constructAddress(endpoints.next().asText())).build());
        }
        return listEndpointFilter;
    }

    protected QueryInput buildQueryInput(InstanceIdentifier<ContextTag> ctagIID,
            List<PropertyFilter> listPropertyFilter, List<EndpointFilter> listEndpointFilter) {
        return new QueryInputBuilder()
                .setType(ResourceTypeEndpointproperty.class).setServiceReference(
                        ctagIID)
                .setRequest(
                        new EndpointpropertyRequestBuilder()
                                .setEndpointpropertyParams(
                                        new EndpointpropertyParamsBuilder()
                                                .setFilter(
                                                        new EndpointpropertyFilterDataBuilder()
                                                                .setEndpointpropertyFilter(
                                                                        new EndpointpropertyFilterBuilder()
                                                                                .setEndpointFilter(
                                                                                        listEndpointFilter)
                                                                                .setPropertyFilter(
                                                                                        listPropertyFilter)
                                                                                .build())
                                                                .build())
                                                .build())
                                .build())
                .build();
    }

    protected QueryInput prepareInput(String path, Iterator<JsonNode> properties, Iterator<JsonNode> endpoints) {
        ReadOnlyTransaction rtx = dataBroker.newReadOnlyTransaction();
        InstanceIdentifier<ContextTag> ctagIID = getResourceByPath(path, rtx);
        if (ctagIID == null) {
            return null;
        }
        List<PropertyFilter> listPropertyFilter = constructListPropertyFilter(properties);
        List<EndpointFilter> listEndpointFilter = constructListEndpointFilter(endpoints);
        return buildQueryInput(ctagIID, listPropertyFilter, listEndpointFilter);
    }

    public InstanceIdentifier<ContextTag> getResourceByPath(String path, ReadOnlyTransaction 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> recordOptional = null;
        try {
            recordOptional = recordFuture.get();
        } catch (Exception e) {
            LOG.error("Reading Record failed", e);
            return null;
        }
        //get resourceIID from nbr-endpointproperty.yang
        InstanceIdentifier<?> record2resourceIID = null;
        if (recordOptional.isPresent()) {
            record2resourceIID = recordOptional.get().getResourceIid();
        }
        InstanceIdentifier<Resource> resourceIID = (InstanceIdentifier<Resource>) record2resourceIID;
        Future<Optional<Resource>> resourceFuture = transaction.read(LogicalDatastoreType.OPERATIONAL, resourceIID);
        Optional<Resource> resourceOptional = null;
        try {
            resourceOptional = resourceFuture.get();
        } catch (Exception e) {
            LOG.error("Read resource failed:", e);
            return null;
        }
        Resource resource = null;
        if (resourceOptional.isPresent())
            resource = resourceOptional.get();
        InstanceIdentifier<ContextTag> finalresourceIID = resourceIID.child(ContextTag.class,
                new ContextTagKey(resource.getDefaultTag()));
        return finalresourceIID;
    }

    protected String getAddressValue(Address address) {
        String addressValue = null;
        if (address instanceof Ipv4AddressData) {
            Ipv4AddressData ipv4 = (Ipv4AddressData) address;
            addressValue = IPv4_PREFIX + ipv4.getIpv4().getValue();
        } else if (address instanceof Ipv6AddressData) {
            Ipv6AddressData ipv6 = (Ipv6AddressData) address;
            addressValue = IPv6_PREFIX + ipv6.getIpv6().getValue();
        }
        return addressValue;
    }

    protected Response buildOutput(QueryInput input, QueryOutput output) throws JsonProcessingException {
        EndpointpropertyResponse epResponse = (EndpointpropertyResponse) output.getResponse();
        EndpointPropertymapData epMapData = (EndpointPropertymapData) epResponse.getEndpointpropertyData();
        EndpointPropertyMap epMap = epMapData.getEndpointPropertyMap();
        List<EndpointProperty> linkEndpointProperty = epMap.getEndpointProperty();
        Map<String, Map<String, String>> endpointpropertyMap = new HashMap<>();
        for (EndpointProperty ep : linkEndpointProperty) {
            Map<String, String> propertyMap = new HashMap<>();
            Source source = ep.getSource();
            String endpointSourceAddress = getAddressValue(source.getAddress());
            List<Properties> properties = ep.getProperties();
            for (Properties property : properties) {
                PropertyValue propertyValue = property.getPropertyValue();
                if (property.getPropertyContainer().getProperty() instanceof OutputResourceSpecificProperty)
                    propertyMap.put(
                            ((OutputResourceSpecificProperty) property.getPropertyContainer().getProperty())
                                    .getResourceSpecificProperty().getValue(),
                            ((PidName) propertyValue).getValue().getValue());
                else {
                    propertyMap.put(
                            ((OutputGlobalProperty) property.getPropertyContainer().getProperty())
                                    .getGlobalProperty().getValue(),
                            ((PidName) propertyValue).getValue().getValue());
                }
            }

            endpointpropertyMap.put(endpointSourceAddress, propertyMap);
        }

        RFC7285EndpointPropertyMap rfcEPM = new RFC7285EndpointPropertyMap();
        rfcEPM.map = endpointpropertyMap;
        rfcEPM.meta = buildMeta(input.getServiceReference());
        String responseString = mapper.writeValueAsString(rfcEPM);

        return Response.ok(responseString, ALTO_ENDPOINTPROPERTY).build();
    }

    protected RFC7285EndpointPropertyMap.Meta buildMeta(InstanceIdentifier<?> iid) {
        RFC7285EndpointPropertyMap.Meta meta = new RFC7285EndpointPropertyMap.Meta();
        RFC7285VersionTag vtag = new RFC7285VersionTag();
        vtag.rid = iid.firstKeyOf(Resource.class).getResourceId().getValue();
        vtag.tag = iid.firstKeyOf(ContextTag.class).getTag().getValue();
        meta.netmap_tags = new LinkedList<>();
        meta.netmap_tags.add(vtag);
        return meta;
    }
}