83d7a4b17eb9449d01e574d26b4879dc5a1cebe8
[bgpcep.git] / bgp / bmp-impl / src / main / java / org / opendaylight / protocol / bmp / impl / app / BmpMonitoringStationImpl.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.protocol.bmp.impl.app;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.net.InetAddresses;
14 import io.netty.channel.Channel;
15 import io.netty.channel.ChannelFuture;
16 import io.netty.channel.ChannelFutureListener;
17 import java.net.InetAddress;
18 import java.net.InetSocketAddress;
19 import java.util.List;
20 import org.opendaylight.controller.config.yang.bmp.impl.MonitoredRouter;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
23 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
25 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
26 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
27 import org.opendaylight.protocol.bmp.impl.spi.BmpMonitoringStation;
28 import org.opendaylight.protocol.concepts.KeyMapping;
29 import org.opendaylight.protocol.util.Ipv4Util;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.BmpMonitor;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.MonitorId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.bmp.monitor.Monitor;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.routers.Router;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
35 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTree;
36 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
37 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
38 import org.opendaylight.yangtools.yang.common.QName;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
41 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
42 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
43 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
44 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public final class BmpMonitoringStationImpl implements BmpMonitoringStation {
49
50     private static final Logger LOG = LoggerFactory.getLogger(BmpMonitoringStationImpl.class);
51
52     private static final QName MONITOR_ID_QNAME = QName.create(Monitor.QNAME, "monitor-id").intern();
53
54     private final DOMDataBroker domDataBroker;
55     private final YangInstanceIdentifier yangMonitorId;
56     private final RouterSessionManager sessionManager;
57     private final Channel channel;
58     private final MonitorId monitorId;
59     private final List<MonitoredRouter> monitoredRouters;
60
61     private BmpMonitoringStationImpl(final DOMDataBroker domDataBroker, final YangInstanceIdentifier yangMonitorId,
62             final Channel channel, final RouterSessionManager sessionManager, final MonitorId monitorId,
63             final BmpDispatcher dispatcher, final List<MonitoredRouter> mrs) {
64         this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
65         this.yangMonitorId = Preconditions.checkNotNull(yangMonitorId);
66         this.channel = Preconditions.checkNotNull(channel);
67         this.sessionManager = Preconditions.checkNotNull(sessionManager);
68         this.monitorId = monitorId;
69         this.monitoredRouters = mrs;
70
71         createEmptyMonitor();
72         LOG.info("BMP Monitoring station {} started", this.monitorId.getValue());
73
74         connectMonitoredRouters(dispatcher);
75         LOG.info("Connecting to monitored routers completed.");
76     }
77
78     private void connectMonitoredRouters(final BmpDispatcher dispatcher) {
79         if (this.monitoredRouters != null) {
80             for (final MonitoredRouter mr : this.monitoredRouters) {
81                 if (mr.getActive()) {
82                     Preconditions.checkNotNull(mr.getAddress());
83                     Preconditions.checkNotNull(mr.getPort());
84                     final String s = mr.getAddress().getIpv4Address().getValue();
85                     final InetAddress addr = InetAddresses.forString(s);
86                     KeyMapping ret = null;
87                     final Rfc2385Key rfc2385KeyPassword = mr.getPassword();
88                     ret = KeyMapping.getKeyMapping(addr, rfc2385KeyPassword.getValue());
89                     dispatcher.createClient(
90                         Ipv4Util.toInetSocketAddress(mr.getAddress(), mr.getPort()),
91                         this.sessionManager, Optional.<KeyMapping>fromNullable(ret));
92                 }
93             }
94         }
95     }
96
97     public static BmpMonitoringStation createBmpMonitorInstance(final RIBExtensionConsumerContext ribExtensions, final BmpDispatcher dispatcher,
98             final DOMDataBroker domDataBroker, final MonitorId monitorId, final InetSocketAddress address,
99             final Optional<KeyMapping> keys, final BindingCodecTreeFactory codecFactory, final SchemaContext schemaContext,
100             final List<MonitoredRouter> mrs ) throws InterruptedException {
101         Preconditions.checkNotNull(ribExtensions);
102         Preconditions.checkNotNull(dispatcher);
103         Preconditions.checkNotNull(domDataBroker);
104         Preconditions.checkNotNull(monitorId);
105         Preconditions.checkNotNull(address);
106
107         final YangInstanceIdentifier yangMonitorId = YangInstanceIdentifier.builder()
108                 .node(BmpMonitor.QNAME)
109                 .node(Monitor.QNAME)
110                 .nodeWithKey(Monitor.QNAME, MONITOR_ID_QNAME, monitorId.getValue())
111                 .build();
112
113         final BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(ribExtensions.getClassLoadingStrategy(),
114                 schemaContext);
115         final BindingCodecTree tree  = codecFactory.create(runtimeContext);
116         final RouterSessionManager sessionManager = new RouterSessionManager(yangMonitorId, domDataBroker, ribExtensions, tree);
117         final ChannelFuture channelFuture = dispatcher.createServer(address, sessionManager, keys);
118
119         return new BmpMonitoringStationImpl(domDataBroker, yangMonitorId, channelFuture.sync().channel(), sessionManager, monitorId, dispatcher, mrs);
120     }
121
122     private static void ensureParentExists(final DOMDataWriteTransaction wTx, final YangInstanceIdentifier path) {
123         final ContainerNode parentNode = Builders.containerBuilder().withNodeIdentifier(
124                 new NodeIdentifier(BmpMonitor.QNAME)).addChild(ImmutableNodes.mapNodeBuilder(Monitor.QNAME).build()).build();
125         wTx.merge(LogicalDatastoreType.OPERATIONAL, path, parentNode);
126     }
127
128     private void createEmptyMonitor() {
129         final DOMDataWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
130         ensureParentExists(wTx, YangInstanceIdentifier.of(BmpMonitor.QNAME));
131         wTx.put(LogicalDatastoreType.OPERATIONAL,
132                 YangInstanceIdentifier.builder().node(BmpMonitor.QNAME).node(Monitor.QNAME)
133                     .nodeWithKey(Monitor.QNAME, MONITOR_ID_QNAME, this.monitorId.getValue()).build(),
134                 ImmutableNodes.mapEntryBuilder(Monitor.QNAME, MONITOR_ID_QNAME, this.monitorId.getValue())
135                     .addChild(ImmutableNodes.leafNode(MONITOR_ID_QNAME, this.monitorId.getValue()))
136                     .addChild(ImmutableNodes.mapNodeBuilder(Router.QNAME).build())
137                     .build());
138         try {
139             wTx.submit().checkedGet();
140         } catch (final TransactionCommitFailedException e) {
141             LOG.error("Failed to initiate BMP Monitor {}.", this.monitorId.getValue(), e);
142         }
143     }
144
145     @Override
146     public void close() throws Exception {
147         this.channel.close().addListener(new ChannelFutureListener() {
148             @Override
149             public void operationComplete(final ChannelFuture channelFuture) throws Exception {
150                 BmpMonitoringStationImpl.this.sessionManager.close();
151             }
152         }).await();
153
154         final DOMDataWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
155         wTx.delete(LogicalDatastoreType.OPERATIONAL, this.yangMonitorId);
156         wTx.submit().checkedGet();
157         LOG.info("BMP monitoring station {} closed.", this.monitorId.getValue());
158     }
159
160 }