blob: b08308315e62fc0561e4585037f412d3ce241105 [file] [log] [blame]
slowrdb071b22017-07-07 11:10:25 -07001/*
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -07002 * Copyright 2017-present Open Networking Foundation
slowrdb071b22017-07-07 11:10:25 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.artemis.impl.monitors;
17
18import io.socket.client.IO;
19import io.socket.client.Socket;
Andrea Campanella80427622022-06-09 08:11:25 -070020import com.eclipsesource.json.JsonObject;
slowrdb071b22017-07-07 11:10:25 -070021import org.onlab.packet.IpPrefix;
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070022import org.onosproject.artemis.ArtemisPacketProcessor;
23import org.onosproject.artemis.Monitors;
slowrdb071b22017-07-07 11:10:25 -070024import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
26
27import java.net.URISyntaxException;
28import java.util.Objects;
29
30/**
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070031 * Implementation of RIPE Route Collector Monitors.
slowrdb071b22017-07-07 11:10:25 -070032 */
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070033public class RipeMonitors implements Monitors {
34 private final Logger log = LoggerFactory.getLogger(getClass());
slowrdb071b22017-07-07 11:10:25 -070035 private String host;
36 private Socket socket;
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070037 private IpPrefix prefix;
38 private ArtemisPacketProcessor packetProcessor;
slowrdb071b22017-07-07 11:10:25 -070039
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070040 public RipeMonitors(IpPrefix prefix, String host, ArtemisPacketProcessor packetProcessor) {
41 this.prefix = prefix;
slowrdb071b22017-07-07 11:10:25 -070042 this.host = host;
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070043 this.packetProcessor = packetProcessor;
slowrdb071b22017-07-07 11:10:25 -070044 }
45
46 /**
47 * socket.io onConnect event handler.
48 */
49 private void onConnect() {
Andrea Campanella80427622022-06-09 08:11:25 -070050 socket.emit("ping");
slowrdb071b22017-07-07 11:10:25 -070051
Andrea Campanella80427622022-06-09 08:11:25 -070052 JsonObject parameters = new JsonObject();
53 parameters.set("origin", "");
54 parameters.set("type", "");
55 parameters.set("moreSpecific", true);
56 parameters.set("lessSpecific", false);
57 parameters.set("peer", "");
58 parameters.set("host", this.host);
59 parameters.set("prefix", this.prefix.toString());
slowrdb071b22017-07-07 11:10:25 -070060
Andrea Campanella80427622022-06-09 08:11:25 -070061 socket.emit("ris_subscribe", parameters);
slowrdb071b22017-07-07 11:10:25 -070062 }
63
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -070064 @Override
65 public IpPrefix getPrefix() {
66 return prefix;
67 }
68
69 @Override
70 public void setPrefix(IpPrefix prefix) {
71 this.prefix = prefix;
72 }
73
slowrdb071b22017-07-07 11:10:25 -070074 /**
75 * socket.io onRisMessage event handler.
76 * This event is custom made that triggers when it receives an BGP update/withdraw for our prefix.
77 *
78 * @param args RIS message
79 */
80 private void onRisMessage(Object[] args) {
Andrea Campanella80427622022-06-09 08:11:25 -070081 JsonObject message = (JsonObject) args[0];
82 if (message.get("type").asString().equals("A")) {
83 // Example of BGP Update message:
84 // {
85 // "timestamp":1488044022.97,
86 // "prefix":"101.1.46.0/24",
87 // "host":"rrc21",
88 // "next_hop":"37.49.236.246",
89 // "peer":"37.49.236.246",
90 // "path":[2613,25091,9318,9524],
91 // "type":"A"
92 // }
slowrdb071b22017-07-07 11:10:25 -070093
Andrea Campanella80427622022-06-09 08:11:25 -070094 // We want to keep only prefix and path in memory.
95 message.remove("community");
96 message.remove("timestamp");
97 message.remove("next_hop");
98 message.remove("peer");
99 message.remove("type");
100 message.remove("host");
slowrdb071b22017-07-07 11:10:25 -0700101
Andrea Campanella80427622022-06-09 08:11:25 -0700102 // Append synchronized message to message list in memory.
103 packetProcessor.processMonitorPacket(message);
slowrdb071b22017-07-07 11:10:25 -0700104 }
Andrea Campanella80427622022-06-09 08:11:25 -0700105
slowrdb071b22017-07-07 11:10:25 -0700106 socket.emit("ping");
107 }
108
109 @Override
110 public void startMonitor() {
111 if (!isRunning()) {
112 log.info("Starting RIPE monitor for " + prefix + " / " + host);
113 IO.Options opts = new IO.Options();
114 opts.path = "/stream/socket.io/";
115
116 try {
117 this.socket = IO.socket("http://stream-dev.ris.ripe.net/", opts);
118 this.socket.on(Socket.EVENT_CONNECT, args -> onConnect());
119 this.socket.on(Socket.EVENT_PONG, args -> socket.emit("ping"));
120 this.socket.on("ris_message", this::onRisMessage);
121 } catch (URISyntaxException e) {
Ray Milkeyba547f92018-02-01 15:22:31 -0800122 log.error("startMonitor()", e);
slowrdb071b22017-07-07 11:10:25 -0700123 }
124
125 this.socket.connect();
126 }
127 }
128
129 @Override
130 public void stopMonitor() {
131 if (isRunning()) {
132 log.info("Stopping RIPE monitor for " + prefix + " / " + host);
133 this.socket.off();
134 this.socket.disconnect();
135 this.socket.close();
136 this.socket = null;
137 }
138 }
139
140 @Override
slowrdb071b22017-07-07 11:10:25 -0700141 public boolean isRunning() {
142 return this.socket != null;
143 }
144
145 @Override
146 public String getHost() {
147 return host;
148 }
149
150 @Override
151 public void setHost(String host) {
152 this.host = host;
153 }
154
155 @Override
156 public int hashCode() {
157 return Objects.hash(prefix, host);
158 }
159
160 @Override
161 public boolean equals(Object obj) {
162 if (this == obj) {
163 return true;
164 }
Dimitrios Mavrommatisf0c06322017-10-31 23:49:04 -0700165 if (obj instanceof RipeMonitors) {
166 final RipeMonitors that = (RipeMonitors) obj;
slowrdb071b22017-07-07 11:10:25 -0700167 return Objects.equals(this.prefix, that.prefix) &&
168 Objects.equals(this.host, that.host);
169 }
170 return false;
171 }
172
173}