[ONOS-1925]
1.fix javadocs bugs.
2.add pcep tunnel provider;
3.change pcep to pcep app;
4.fix some bugs according to review suggestions.

Change-Id: I4b90d9bf871dee3be70615d66db3d74f2fd85389
diff --git a/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
new file mode 100644
index 0000000..9ef9412
--- /dev/null
+++ b/providers/pcep/topology/src/main/java/org/onosproject/provider/pcep/topology/impl/PcepTopologyProvider.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.pcep.topology.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.ChassisId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Link.Type;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.link.DefaultLinkDescription;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.api.PcepController;
+import org.onosproject.pcep.api.PcepDpid;
+import org.onosproject.pcep.api.PcepLink;
+import org.onosproject.pcep.api.PcepLinkListener;
+import org.onosproject.pcep.api.PcepOperator.OperationType;
+import org.onosproject.pcep.api.PcepSwitch;
+import org.onosproject.pcep.api.PcepSwitchListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.pcep.api.PcepDpid.uri;
+
+/**
+ * Provider which uses an PCEP controller to detect network infrastructure
+ * topology.
+ */
+@Component(immediate = true)
+public class PcepTopologyProvider extends AbstractProvider
+        implements LinkProvider, DeviceProvider {
+
+    public PcepTopologyProvider() {
+        super(new ProviderId("pcep", "org.onosproject.provider.pcep"));
+    }
+
+    private static final Logger log = LoggerFactory
+            .getLogger(PcepTopologyProvider.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry linkProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry deviceProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PcepController controller;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipAdminService mastershipAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    private DeviceProviderService deviceProviderService;
+    private LinkProviderService linkProviderService;
+    // List<Long> srcportList = new ArrayList<Long>();
+    HashSet<Long> portSet = new HashSet<>();
+    private InternalLinkProvider listener = new InternalLinkProvider();
+
+    @Activate
+    public void activate() {
+        linkProviderService = linkProviderRegistry.register(this);
+        deviceProviderService = deviceProviderRegistry.register(this);
+        controller.addListener(listener);
+        controller.addLinkListener(listener);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        linkProviderRegistry.unregister(this);
+        linkProviderService = null;
+        controller.removeListener(listener);
+        controller.removeLinkListener(listener);
+    }
+
+    private List<PortDescription> buildPortDescriptions(List<Long> ports,
+                                                        String portType) {
+        final List<PortDescription> portDescs = new ArrayList<>();
+        for (long port : ports) {
+            portDescs.add(buildPortDescription(port, portType));
+        }
+        return portDescs;
+    }
+
+    private PortDescription buildPortDescription(long port, String portType) {
+        final PortNumber portNo = PortNumber.portNumber(port);
+        final boolean enabled = true;
+        DefaultAnnotations extendedAttributes = DefaultAnnotations.builder()
+                .set("portType", portType).build();
+        return new DefaultPortDescription(portNo, enabled, extendedAttributes);
+    }
+
+    /**
+     * Build link annotations from pcep link description.the annotations consist
+     * of lots of property of Huawei device.
+     *
+     * @param linkDesc
+     * @return
+     */
+    private DefaultAnnotations buildLinkAnnotations(PcepLink linkDesc) {
+        DefaultAnnotations extendedAttributes = DefaultAnnotations
+                .builder()
+                .set("subType", String.valueOf(linkDesc.linkSubType()))
+                .set("workState", linkDesc.linkState())
+                .set("distance", String.valueOf(linkDesc.linkDistance()))
+                .set("capType", linkDesc.linkCapacityType().toLowerCase())
+                .set("avail_" + linkDesc.linkCapacityType().toLowerCase(),
+                     String.valueOf(linkDesc.linkAvailValue()))
+                .set("max_" + linkDesc.linkCapacityType().toLowerCase(),
+                     String.valueOf(linkDesc.linkMaxValue())).build();
+
+        return extendedAttributes;
+    }
+
+    /**
+     * Build a LinkDescription from a PCEPLink.
+     *
+     * @param pceLink
+     * @return LinkDescription
+     */
+    private LinkDescription buildLinkDescription(PcepLink pceLink) {
+        LinkDescription ld;
+
+        DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
+        DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
+
+        if (deviceService.getDevice(srcDeviceID) == null
+                || deviceService.getDevice(dstDeviceID) == null) {
+            log.info("the device of the link is not exited" + srcDeviceID
+                    + dstDeviceID);
+            return null;
+        }
+        // update port info
+        long srcPort = pceLink.linkSrcPort();
+        portSet.add(srcPort);
+        List<Long> srcportList = new ArrayList<Long>();
+        srcportList.addAll(portSet);
+        deviceProviderService
+                .updatePorts(srcDeviceID,
+                             buildPortDescriptions(srcportList,
+                                                   pceLink.portType()));
+
+        ConnectPoint src = new ConnectPoint(srcDeviceID,
+                                            PortNumber.portNumber(pceLink
+                                                    .linkSrcPort()));
+
+        ConnectPoint dst = new ConnectPoint(dstDeviceID,
+                                            PortNumber.portNumber(pceLink
+                                                    .linkDstPort()));
+        DefaultAnnotations extendedAttributes = buildLinkAnnotations(pceLink);
+
+        // construct the link
+        ld = new DefaultLinkDescription(src, dst, Type.OPTICAL,
+                                        extendedAttributes);
+        return ld;
+    }
+
+    private void processLinkUpdate(LinkDescription linkDescription) {
+
+        // dst changed, delete the original link,if the dst device is not in
+        // other links ,delete it.
+        if (linkService.getLink(linkDescription.src(), linkDescription.dst()) == null) {
+            // in face,one src one link
+            Set<Link> links = linkService
+                    .getIngressLinks(linkDescription.src());
+            for (Link link : links) {
+                linkProviderService.linkVanished((LinkDescription) link);
+                if (linkService.getDeviceLinks(link.dst().deviceId()).size() == 0) {
+                    deviceProviderService.deviceDisconnected(link.dst()
+                            .deviceId());
+                }
+            }
+
+        }
+        linkProviderService.linkDetected(linkDescription);
+
+    }
+
+    private class InternalLinkProvider
+            implements PcepSwitchListener, PcepLinkListener {
+
+        @Override
+        public void switchAdded(PcepDpid dpid) {
+            // TODO Auto-generated method stub
+
+            if (deviceProviderService == null) {
+                return;
+            }
+            DeviceId devicdId = deviceId(uri(dpid));
+            PcepSwitch sw = controller.getSwitch(dpid);
+            checkNotNull(sw, "device should not null.");
+            // The default device type is switch.
+            Device.Type deviceType = Device.Type.SWITCH;
+            ChassisId cId = new ChassisId(dpid.value());
+
+            // Device subType: ROADM,OTN,ROUTER.
+            DefaultAnnotations extendedAttributes = DefaultAnnotations
+                    .builder()
+                    .set("subType", String.valueOf(sw.getDeviceSubType()))
+                    .build();
+
+            DeviceDescription description = new DefaultDeviceDescription(
+                                                                         devicdId.uri(),
+                                                                         deviceType,
+                                                                         sw.manufacturerDescription(),
+                                                                         sw.hardwareDescription(),
+                                                                         sw.softwareDescription(),
+                                                                         sw.serialNumber(),
+                                                                         cId,
+                                                                         extendedAttributes);
+            NodeId localNode = clusterService.getLocalNode().id();
+            mastershipAdminService.setRole(localNode, devicdId,
+                                           MastershipRole.MASTER);
+            mastershipService.relinquishMastership(devicdId);
+            deviceProviderService.deviceConnected(devicdId, description);
+
+        }
+
+        @Override
+        public void switchRemoved(PcepDpid dpid) {
+            // TODO Auto-generated method stub
+
+            if (deviceProviderService == null || linkProviderService == null) {
+                return;
+            }
+            deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
+
+            linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
+        }
+
+        @Override
+        public void switchChanged(PcepDpid dpid) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void handlePCEPlink(PcepLink link) {
+
+            OperationType operType = link.getOperationType();
+            LinkDescription ld = buildLinkDescription(link);
+            if (ld == null) {
+                log.error("Invalid link info.");
+                return;
+            }
+            switch (operType) {
+            case ADD:
+                linkProviderService.linkDetected(ld);
+                break;
+            case UPDATE:
+                processLinkUpdate(ld);
+                break;
+
+            case DELETE:
+                linkProviderService.linkVanished(ld);
+                break;
+
+            default:
+                break;
+
+            }
+        }
+
+    }
+
+    @Override
+    public void triggerProbe(DeviceId deviceId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
+        // NodeId localNode = clusterService.getLocalNode().id();
+        // mastershipService.setRole(localNode, deviceId, newRole);
+
+    }
+
+    @Override
+    public boolean isReachable(DeviceId deviceId) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+}