Replace Preconditions.CheckNotNull per RequireNonNull
[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 static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bmp.impl.app.KeyConstructorUtil.constructKeys;
13
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.net.InetAddresses;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import io.netty.channel.Channel;
19 import io.netty.channel.ChannelFuture;
20 import io.netty.channel.ChannelFutureListener;
21 import java.net.InetAddress;
22 import java.net.InetSocketAddress;
23 import java.util.List;
24 import javax.annotation.Nonnull;
25 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
26 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
27 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
30 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
31 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
32 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
33 import org.opendaylight.protocol.bmp.impl.config.BmpDeployerDependencies;
34 import org.opendaylight.protocol.bmp.impl.spi.BmpMonitoringStation;
35 import org.opendaylight.protocol.concepts.KeyMapping;
36 import org.opendaylight.protocol.util.Ipv4Util;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.config.rev170517.odl.bmp.monitors.bmp.monitor.config.MonitoredRouter;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.BmpMonitor;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.MonitorId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.bmp.monitor.Monitor;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.routers.Router;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
43 import org.opendaylight.yangtools.yang.common.QName;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
45 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 public final class BmpMonitoringStationImpl implements BmpMonitoringStation, ClusterSingletonService {
50
51     private static final Logger LOG = LoggerFactory.getLogger(BmpMonitoringStationImpl.class);
52
53     private static final QName MONITOR_ID_QNAME = QName.create(Monitor.QNAME, "monitor-id").intern();
54     private static final ServiceGroupIdentifier SERVICE_GROUP_IDENTIFIER =
55         ServiceGroupIdentifier.create("bmp-monitors-service-group");
56
57     private final DOMDataBroker domDataBroker;
58     private final InetSocketAddress address;
59     private final MonitorId monitorId;
60     private final List<MonitoredRouter> monitoredRouters;
61     private final BmpDispatcher dispatcher;
62     private final RouterSessionManager sessionManager;
63     private final YangInstanceIdentifier yangMonitorId;
64     private Channel channel;
65     private ClusterSingletonServiceRegistration singletonServiceRegistration;
66
67     public BmpMonitoringStationImpl(final BmpDeployerDependencies bmpDeployerDependencies,
68         final BmpDispatcher dispatcher, final MonitorId monitorId, final InetSocketAddress address,
69         final List<MonitoredRouter> mrs) {
70         this.domDataBroker = requireNonNull(bmpDeployerDependencies.getDomDataBroker());
71         this.dispatcher = requireNonNull(dispatcher);
72         this.monitorId = monitorId;
73         this.monitoredRouters = mrs;
74         this.address = requireNonNull(address);
75
76         this.yangMonitorId = YangInstanceIdentifier.builder()
77             .node(BmpMonitor.QNAME).node(Monitor.QNAME)
78             .nodeWithKey(Monitor.QNAME, MONITOR_ID_QNAME, monitorId.getValue()).build();
79
80         this.sessionManager = new RouterSessionManager(this.yangMonitorId, this.domDataBroker,
81             bmpDeployerDependencies.getExtensions(), bmpDeployerDependencies.getTree());
82
83         LOG.info("BMP Monitor Singleton Service {} registered, Monitor Id {}",
84             getIdentifier().getValue(), this.monitorId.getValue());
85         this.singletonServiceRegistration = bmpDeployerDependencies.getClusterSingletonProvider()
86             .registerClusterSingletonService(this);
87     }
88
89     @Override
90     public synchronized void instantiateServiceInstance() {
91         LOG.info("BMP Monitor Singleton Service {} instantiated, Monitor Id {}",
92             getIdentifier().getValue(), this.monitorId.getValue());
93
94         final ChannelFuture channelFuture = this.dispatcher.createServer(this.address, this.sessionManager,
95             constructKeys(this.monitoredRouters));
96         try {
97             this.channel = channelFuture.sync().channel();
98             createEmptyMonitor();
99             LOG.info("BMP Monitoring station {} started", this.monitorId.getValue());
100
101             connectMonitoredRouters(this.dispatcher);
102             LOG.info("Connecting to monitored routers completed.");
103         } catch (final InterruptedException e) {
104             LOG.error("Failed to instantiate BMP Monitor Singleton {}", this.monitorId.getValue(), e);
105         }
106
107     }
108
109     @Override
110     public synchronized ListenableFuture<Void> closeServiceInstance() {
111         LOG.info("BMP Monitor Singleton Service {} instance closed, Monitor Id {}",
112             getIdentifier().getValue(), this.monitorId.getValue());
113         this.channel.close().addListener((ChannelFutureListener) future -> {
114             Preconditions.checkArgument(future.isSuccess(), "Channel failed to close: %s", future.cause());
115             BmpMonitoringStationImpl.this.sessionManager.close();
116         });
117
118         final DOMDataWriteTransaction wTx = this.domDataBroker.newWriteOnlyTransaction();
119         wTx.delete(LogicalDatastoreType.OPERATIONAL, this.yangMonitorId);
120         LOG.info("BMP monitoring station {} closed.", this.monitorId.getValue());
121         return wTx.submit();
122     }
123
124     @Nonnull
125     @Override
126     public ServiceGroupIdentifier getIdentifier() {
127         return SERVICE_GROUP_IDENTIFIER;
128     }
129
130     private void connectMonitoredRouters(final BmpDispatcher dispatcher) {
131         if (this.monitoredRouters != null) {
132             for (final MonitoredRouter mr : this.monitoredRouters) {
133                 if (mr.isActive()) {
134                     requireNonNull(mr.getAddress());
135                     requireNonNull(mr.getPort());
136                     final String s = mr.getAddress().getIpv4Address().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                     dispatcher.createClient(Ipv4Util.toInetSocketAddress(mr.getAddress(), mr.getPort()),
142                         this.sessionManager, Optional.fromNullable(ret));
143                 }
144             }
145         }
146     }
147
148     private synchronized void createEmptyMonitor() {
149         final DOMDataWriteTransaction 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())
156                 .build());
157         try {
158             wTx.submit().checkedGet();
159         } catch (final TransactionCommitFailedException e) {
160             LOG.error("Failed to initiate BMP Monitor {}.", this.monitorId.getValue(), e);
161         }
162     }
163
164     @Override
165     public synchronized void close() throws Exception {
166         if (this.singletonServiceRegistration != null) {
167             this.singletonServiceRegistration.close();
168             this.singletonServiceRegistration = null;
169         }
170     }
171 }