2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bmp.impl.app;
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.protocol.bmp.impl.app.KeyConstructorUtil.constructKeys;
13 import com.google.common.base.Preconditions;
14 import com.google.common.net.InetAddresses;
15 import com.google.common.util.concurrent.FluentFuture;
16 import io.netty.channel.Channel;
17 import io.netty.channel.ChannelFuture;
18 import io.netty.channel.ChannelFutureListener;
19 import java.net.InetAddress;
20 import java.net.InetSocketAddress;
21 import java.util.List;
22 import java.util.concurrent.ExecutionException;
23 import org.opendaylight.mdsal.common.api.CommitInfo;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
27 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
28 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
29 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
30 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
31 import org.opendaylight.protocol.bmp.impl.config.BmpDeployerDependencies;
32 import org.opendaylight.protocol.bmp.impl.spi.BmpMonitoringStation;
33 import org.opendaylight.protocol.concepts.KeyMapping;
34 import org.opendaylight.protocol.util.Ipv4Util;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.config.rev200120.odl.bmp.monitors.bmp.monitor.config.MonitoredRouter;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.BmpMonitor;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.MonitorId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.bmp.monitor.Monitor;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev200120.routers.Router;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
41 import org.opendaylight.yangtools.yang.common.QName;
42 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
43 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 public final class BmpMonitoringStationImpl implements BmpMonitoringStation, ClusterSingletonService {
49 private static final Logger LOG = LoggerFactory.getLogger(BmpMonitoringStationImpl.class);
51 private static final QName MONITOR_ID_QNAME = QName.create(Monitor.QNAME, "monitor-id").intern();
52 private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER =
53 ServiceGroupIdentifier.create("bmp-monitors-service-group");
55 private final DOMDataBroker domDataBroker;
56 private final InetSocketAddress address;
57 private final MonitorId monitorId;
58 private final List<MonitoredRouter> monitoredRouters;
59 private final BmpDispatcher dispatcher;
60 private final RouterSessionManager sessionManager;
61 private final YangInstanceIdentifier yangMonitorId;
62 private Channel channel;
63 private ClusterSingletonServiceRegistration singletonServiceRegistration;
65 public BmpMonitoringStationImpl(final BmpDeployerDependencies bmpDeployerDependencies,
66 final BmpDispatcher dispatcher, final MonitorId monitorId, final InetSocketAddress address,
67 final List<MonitoredRouter> mrs) {
68 this.domDataBroker = requireNonNull(bmpDeployerDependencies.getDomDataBroker());
69 this.dispatcher = requireNonNull(dispatcher);
70 this.monitorId = monitorId;
71 this.monitoredRouters = mrs;
72 this.address = requireNonNull(address);
74 this.yangMonitorId = YangInstanceIdentifier.builder()
75 .node(BmpMonitor.QNAME).node(Monitor.QNAME)
76 .nodeWithKey(Monitor.QNAME, MONITOR_ID_QNAME, monitorId.getValue()).build();
78 this.sessionManager = new RouterSessionManager(this.yangMonitorId, this.domDataBroker,
79 bmpDeployerDependencies.getExtensions(), bmpDeployerDependencies.getTree());
81 LOG.info("BMP Monitor Singleton Service {} registered, Monitor Id {}",
82 getIdentifier().getName(), this.monitorId.getValue());
83 this.singletonServiceRegistration = bmpDeployerDependencies.getClusterSingletonProvider()
84 .registerClusterSingletonService(this);
88 public synchronized void instantiateServiceInstance() {
89 LOG.info("BMP Monitor Singleton Service {} instantiated, Monitor Id {}",
90 getIdentifier().getName(), this.monitorId.getValue());
92 final ChannelFuture channelFuture = this.dispatcher.createServer(this.address, this.sessionManager,
93 constructKeys(this.monitoredRouters));
95 this.channel = channelFuture.sync().channel();
97 LOG.info("BMP Monitoring station {} started", this.monitorId.getValue());
99 connectMonitoredRouters(this.dispatcher);
100 LOG.info("Connecting to monitored routers completed.");
101 } catch (final InterruptedException e) {
102 LOG.error("Failed to instantiate BMP Monitor Singleton {}", this.monitorId.getValue(), e);
108 public synchronized FluentFuture<? extends CommitInfo> closeServiceInstance() {
109 LOG.info("BMP Monitor Singleton Service {} instance closed, Monitor Id {}",
110 getIdentifier().getName(), this.monitorId.getValue());
111 if (this.channel != null) {
112 this.channel.close().addListener((ChannelFutureListener) future -> {
113 Preconditions.checkArgument(future.isSuccess(),
114 "Channel failed to close: %s", future.cause());
115 BmpMonitoringStationImpl.this.sessionManager.close();
119 final DOMDataTreeWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
120 wTx.delete(LogicalDatastoreType.OPERATIONAL, this.yangMonitorId);
121 LOG.info("BMP monitoring station {} closed.", this.monitorId.getValue());
126 public ServiceGroupIdentifier getIdentifier() {
127 return SERVICE_GROUP_IDENTIFIER;
130 private void connectMonitoredRouters(final BmpDispatcher pdispatcher) {
131 if (this.monitoredRouters != null) {
132 for (final MonitoredRouter mr : this.monitoredRouters) {
134 requireNonNull(mr.getAddress());
135 requireNonNull(mr.getPort());
136 final String s = mr.getAddress().getIpv4AddressNoZone().getValue();
137 final InetAddress addr = InetAddresses.forString(s);
138 final KeyMapping ret;
139 final Rfc2385Key rfc2385KeyPassword = mr.getPassword();
140 ret = KeyMapping.getKeyMapping(addr, rfc2385KeyPassword.getValue());
141 pdispatcher.createClient(Ipv4Util.toInetSocketAddress(mr.getAddress(), mr.getPort()),
142 this.sessionManager, ret);
148 private synchronized void createEmptyMonitor() {
149 final DOMDataTreeWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
150 wTx.put(LogicalDatastoreType.OPERATIONAL,
151 YangInstanceIdentifier.builder().node(BmpMonitor.QNAME).node(Monitor.QNAME)
152 .nodeWithKey(Monitor.QNAME, MONITOR_ID_QNAME, this.monitorId.getValue()).build(),
153 ImmutableNodes.mapEntryBuilder(Monitor.QNAME, MONITOR_ID_QNAME, this.monitorId.getValue())
154 .addChild(ImmutableNodes.leafNode(MONITOR_ID_QNAME, this.monitorId.getValue()))
155 .addChild(ImmutableNodes.mapNodeBuilder(Router.QNAME).build())
159 } catch (final ExecutionException | InterruptedException e) {
160 LOG.error("Failed to initiate BMP Monitor {}.", this.monitorId.getValue(), e);
165 public synchronized void close() throws Exception {
166 if (this.singletonServiceRegistration != null) {
167 this.singletonServiceRegistration.close();
168 this.singletonServiceRegistration = null;