Migrate topology-manager to CompositeListener
[openflowplugin.git] / applications / topology-manager / src / main / java / org / opendaylight / openflowplugin / applications / topology / manager / FlowCapableTopologyExporter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.applications.topology.manager;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import java.util.Optional;
14 import java.util.Set;
15 import java.util.concurrent.ExecutionException;
16 import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener;
17 import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener.Component;
18 import org.opendaylight.mdsal.binding.api.NotificationService.Listener;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.openflowplugin.common.txchain.TransactionChainManager;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 class FlowCapableTopologyExporter {
30     private static final Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyExporter.class);
31
32     private final InstanceIdentifier<Topology> iiToTopology;
33     private final OperationProcessor processor;
34
35     FlowCapableTopologyExporter(final OperationProcessor processor, final InstanceIdentifier<Topology> topology) {
36         this.processor = requireNonNull(processor);
37         iiToTopology = requireNonNull(topology);
38     }
39
40     CompositeListener toListener() {
41         return new CompositeListener(Set.of(
42             new Component(LinkDiscovered.class, (Listener<LinkDiscovered>) this::onLinkDiscovered),
43             new Component(LinkRemoved.class, (Listener<LinkRemoved>) this::onLinkRemoved)));
44     }
45
46     @VisibleForTesting
47     void onLinkDiscovered(final LinkDiscovered notification) {
48         processor.enqueueOperation(new OnLinkDiscovered(notification));
49     }
50
51     @VisibleForTesting
52     void onLinkRemoved(final LinkRemoved notification) {
53         processor.enqueueOperation(new OnLinkRemoved(notification));
54     }
55
56     private abstract static class AbstractLinkOperation implements TopologyOperation {
57         private final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link;
58
59         AbstractLinkOperation(
60                 final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link link) {
61             this.link = requireNonNull(link);
62         }
63
64         @Override
65         public final void applyOperation(final TransactionChainManager manager) {
66             applyOperation(manager, FlowCapableNodeMapping.toTopologyLink(link));
67         }
68
69         abstract void applyOperation(TransactionChainManager manager, Link link);
70     }
71
72     private final class OnLinkDiscovered extends AbstractLinkOperation {
73         OnLinkDiscovered(final LinkDiscovered notification) {
74             super(notification);
75         }
76
77         @Override
78         public void applyOperation(final TransactionChainManager manager, final Link link) {
79             manager.mergeToTransaction(LogicalDatastoreType.OPERATIONAL,
80                 TopologyManagerUtil.linkPath(link, iiToTopology), link, true);
81         }
82
83         @Override
84         public String toString() {
85             return "onLinkDiscovered";
86         }
87     }
88
89     private final class OnLinkRemoved extends AbstractLinkOperation {
90         OnLinkRemoved(final LinkRemoved notification) {
91             super(notification);
92         }
93
94         @Override
95         public void applyOperation(final TransactionChainManager manager, final Link link) {
96             final var linkPath = TopologyManagerUtil.linkPath(link, iiToTopology);
97
98             Optional<Link> linkOptional = Optional.empty();
99             try {
100                 // read that checks if link exists (if we do not do this we might get an exception on delete)
101                 linkOptional = manager.readFromTransaction(LogicalDatastoreType.OPERATIONAL, linkPath).get();
102             } catch (InterruptedException | ExecutionException e) {
103                 LOG.warn("Error occurred when trying to read Link: {}", e.getMessage());
104                 LOG.debug("Error occurred when trying to read Link.. ", e);
105             }
106             if (linkOptional.isPresent()) {
107                 manager.addDeleteOperationToTxChain(LogicalDatastoreType.OPERATIONAL, linkPath);
108             }
109         }
110
111         @Override
112         public String toString() {
113             return "onLinkRemoved";
114         }
115     }
116 }