ADARA Networks
Committed by Gerrit Code Review

RabbitMQ Integration - Updates changeset 11110 - Review comments incorporated

Change-Id: I0bfd7838b87d55769165b21dc735e1ba4468b611
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
76 <module>scalablegateway</module> 76 <module>scalablegateway</module>
77 <module>bmv2-demo</module> 77 <module>bmv2-demo</module>
78 <module>yms</module> 78 <module>yms</module>
79 + <module>rabbitmq</module>
79 </modules> 80 </modules>
80 81
81 82
......
1 +COMPILE_DEPS = [
2 + '//lib:CORE_DEPS',
3 + '//incubator/api:onos-incubator-api',
4 + '//lib:guava',
5 + '//lib:gson',
6 + '//lib:amqp-client',
7 +]
8 +
9 +BUNDLES = [
10 + '//apps/rabbitmq:onos-apps-rabbitmq',
11 +]
12 +
13 +osgi_jar (
14 + deps = COMPILE_DEPS,
15 +)
16 +
17 +onos_app (
18 + title = 'Rabbit MQ APP',
19 + category = 'Traffic Steering',
20 + url = 'http://onosproject.org',
21 + description = 'Rabbit MQ application.',
22 + required_apps = [ 'org.onosproject.proxyarp' ],
23 + included_bundles = BUNDLES,
24 +)
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016-present Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<app name="org.onosproject.rabbitmq" origin="ON.Lab" version="${project.version}"
18 + category="Traffic Steering" url="http://onosproject.org" title="Rabbit MQ App"
19 + featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
20 + features="${project.artifactId}">
21 + <description>${project.description}</description>
22 + <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
23 + <!-- <artifact>mvn:${project.groupId}/onos-app-routing-api/${project.version}</artifact>
24 + <artifact>mvn:${project.groupId}/onos-app-routing/${project.version}</artifact>
25 + <artifact>mvn:${project.groupId}/onos-app-proxyarp/${project.version}</artifact> -->
26 +</app>
1 +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 +<!--
3 + ~ Copyright 2016-present Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
18 + <feature name="${project.artifactId}" version="${project.version}"
19 + description="${project.description}">
20 + <feature>onos-api</feature>
21 + <bundle>mvn:${project.groupId}/onos-app-rabbitmq/${project.version}</bundle>
22 + <bundle>mvn:com.rabbitmq/amqp-client/3.6.1</bundle>
23 + <bundle>mvn:com.google.code.gson/gson/2.6.2</bundle>
24 + </feature>
25 +</features>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!-- ~ Copyright 2016-present Open Networking Laboratory ~ ~ Licensed under
3 + the Apache License, Version 2.0 (the "License"); ~ you may not use this file
4 + except in compliance with the License. ~ You may obtain a copy of the License
5 + at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by
6 + applicable law or agreed to in writing, software ~ distributed under the
7 + License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS
8 + OF ANY KIND, either express or implied. ~ See the License for the specific
9 + language governing permissions and ~ limitations under the License. -->
10 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11 +xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
12 + <parent>
13 + <groupId>org.onosproject</groupId>
14 + <artifactId>onos-apps</artifactId>
15 + <version>1.7.0-SNAPSHOT</version>
16 + </parent>
17 + <modelVersion>4.0.0</modelVersion>
18 + <artifactId>onos-app-rabbitmq</artifactId>
19 + <packaging>bundle</packaging>
20 + <description>Rabbit MQ application</description>
21 + <properties>
22 + <rabbitmq.version>3.6.1</rabbitmq.version>
23 + </properties>
24 + <dependencies>
25 + <dependency>
26 + <groupId>com.rabbitmq</groupId>
27 + <artifactId>amqp-client</artifactId>
28 + <version>${rabbitmq.version}</version>
29 + </dependency>
30 + <dependency>
31 + <groupId>org.onosproject</groupId>
32 + <artifactId>onos-app-routing</artifactId>
33 + <version>${project.version}</version>
34 + </dependency>
35 + <dependency>
36 + <groupId>org.onosproject</groupId>
37 + <artifactId>onos-app-routing-api</artifactId>
38 + <version>${project.version}</version>
39 + </dependency>
40 + <dependency>
41 + <groupId>org.onosproject</groupId>
42 + <artifactId>onlab-misc</artifactId>
43 + </dependency>
44 + <dependency>
45 + <groupId>org.onosproject</groupId>
46 + <artifactId>onos-incubator-api</artifactId>
47 + </dependency>
48 + <dependency>
49 + <groupId>com.google.guava</groupId>
50 + <artifactId>guava</artifactId>
51 + </dependency>
52 + <dependency>
53 + <groupId>org.onosproject</groupId>
54 + <artifactId>onos-app-proxyarp</artifactId>
55 + <version>${project.version}</version>
56 + </dependency>
57 + <dependency>
58 + <groupId>com.google.code.gson</groupId>
59 + <artifactId>gson</artifactId>
60 + <version>2.6.2</version>
61 + </dependency>
62 + <dependency>
63 + <groupId>org.osgi</groupId>
64 + <artifactId>org.osgi.core</artifactId>
65 + </dependency>
66 + <dependency>
67 + <groupId>org.onosproject</groupId>
68 + <artifactId>onos-api</artifactId>
69 + <classifier>tests</classifier>
70 + <scope>test</scope>
71 + </dependency>
72 + <dependency>
73 + <groupId>org.easymock</groupId>
74 + <artifactId>easymock</artifactId>
75 + <scope>test</scope>
76 + </dependency>
77 + <dependency>
78 + <groupId>org.osgi</groupId>
79 + <artifactId>org.osgi.compendium</artifactId>
80 + </dependency>
81 + <dependency>
82 + <groupId>org.onosproject</groupId>
83 + <artifactId>onlab-junit</artifactId>
84 + <scope>test</scope>
85 + </dependency>
86 + <dependency>
87 + <groupId>org.onosproject</groupId>
88 + <artifactId>onos-core-net</artifactId>
89 + <version>${project.version}</version>
90 + <scope>test</scope>
91 + </dependency>
92 + </dependencies>
93 +</project>
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.api;
17 +
18 +/**
19 + * Declares the constants used in this module.
20 + */
21 +public final class MQConstants {
22 + // No instantiation
23 + private MQConstants() {
24 + }
25 +
26 + /**
27 + * MQ correlation id.
28 + */
29 + public static final String CORRELATION_ID = "correlation_id";
30 +
31 + /**
32 + * MQ exchange name.
33 + */
34 + public static final String EXCHANGE_NAME_PROPERTY = "EXCHANGE_NAME_PROPERTY";
35 +
36 + /**
37 + * MQ routing key.
38 + */
39 + public static final String ROUTING_KEY_PROPERTY = "ROUTING_KEY_PROPERTY";
40 +
41 + /**
42 + * MQ queue name.
43 + */
44 + public static final String QUEUE_NAME_PROPERTY = "QUEUE_NAME_PROPERTY";
45 +
46 + /**
47 + * Switch id connected to onos controller published via json.
48 + */
49 + public static final String SWITCH_ID = "switch_id";
50 +
51 + /**
52 + * Switch's infrastructure device name published via json.
53 + */
54 + public static final String INFRA_DEVICE_NAME = "infra_device_name";
55 +
56 + /**
57 + * Captured event type published via json.
58 + */
59 + public static final String EVENT_TYPE = "event_type";
60 +
61 + /**
62 + * Signifies device event in json.
63 + */
64 + public static final String DEVICE_EVENT = "DEVICE_EVENT";
65 +
66 + /**
67 + * Port connect via switch.
68 + */
69 + public static final String PORT_NUMBER = "port_number";
70 +
71 + /**
72 + * Describes port status enabled or disabled.
73 + */
74 + public static final String PORT_ENABLED = "port_enabled";
75 +
76 + /**
77 + * Specifies port speed.
78 + */
79 + public static final String PORT_SPEED = "port_speed";
80 +
81 + /**
82 + * Specifies sub event types like device added, device updated etc.
83 + */
84 + public static final String SUB_EVENT_TYPE = "sub_event_type";
85 +
86 + /**
87 + * Specifies hardware version of the switch.
88 + */
89 + public static final String HW_VERSION = "hw_version";
90 +
91 + /**
92 + * Specifies switch's manufacturer.
93 + */
94 + public static final String MFR = "mfr";
95 +
96 + /**
97 + * Specifies the serial number of the connected switch.
98 + */
99 + public static final String SERIAL = "serial";
100 +
101 + /**
102 + * Specifies software version of the switch.
103 + */
104 + public static final String SW_VERSION = "sw_version";
105 +
106 + /**
107 + * Specifies chassis id of the switch.
108 + */
109 + public static final String CHASIS_ID = "chassis_id";
110 +
111 + /**
112 + * Specifies event occurence time.
113 + */
114 + public static final String OCC_TIME = "occurrence_time";
115 +
116 + /**
117 + * Specifies switch's available time.
118 + */
119 + public static final String AVAILABLE = "available_time";
120 +
121 + /**
122 + * Specifies packet_in port details.
123 + */
124 + public static final String IN_PORT = "in_port";
125 +
126 + /**
127 + * Specifies port is logical or not.
128 + */
129 + public static final String LOGICAL = "logical";
130 +
131 + /**
132 + * Specifies packet recieved time.
133 + */
134 + public static final String RECIEVED = "received";
135 +
136 + /**
137 + * Specifies message type.
138 + */
139 + public static final String MSG_TYPE = "msg_type";
140 +
141 + /**
142 + * Specifies packet type.
143 + */
144 + public static final String PKT_TYPE = "PACKET_IN";
145 +
146 + /**
147 + * Specifies sub message type under msg_type.
148 + */
149 + public static final String SUB_MSG_TYPE = "sub_msg_type";
150 +
151 + /**
152 + * Specifies Ethernet type of the packet.
153 + */
154 + public static final String ETH_TYPE = "eth_type";
155 +
156 + /**
157 + * Source MAC address of the packet.
158 + */
159 + public static final String SRC_MAC_ADDR = "src_mac_address";
160 +
161 + /**
162 + * Destination MAC address of the packet.
163 + */
164 + public static final String DEST_MAC_ADDR = "dest_mac_address";
165 +
166 + /**
167 + * Specifies VLAN ID of the packet.
168 + */
169 + public static final String VLAN_ID = "vlan_id";
170 +
171 + /**
172 + * Specifies if the packet is a Broadcast or not.
173 + */
174 + public static final String B_CAST = "is_bcast";
175 +
176 + /**
177 + * Specifies if the packet is a Multicast or not.
178 + */
179 + public static final String M_CAST = "is_mcast";
180 +
181 + /**
182 + * Specifies if the packet is padded or not.
183 + */
184 + public static final String PAD = "pad";
185 +
186 + /**
187 + * Specifies priority of the packet.
188 + */
189 + public static final String PRIORITY_CODE = "priority_code";
190 +
191 + /**
192 + * Specifies length of the payload.
193 + */
194 + public static final String DATA_LEN = "data_length";
195 +
196 + /**
197 + * Packet payload(raw) in unicode format.
198 + */
199 + public static final String PAYLOAD = "payload";
200 +
201 + /**
202 + * Network topology type TopologyEvent.Type.
203 + */
204 + public static final String TOPO_TYPE = "topology_type";
205 +
206 + /**
207 + * Represents number of strongly connected components in the topology.
208 + */
209 + public static final String CLUSTER_COUNT = "cluster_count";
210 +
211 + /**
212 + * Cost for doing topology computation.
213 + */
214 + public static final String COMPUTE_COST = "compute_cost";
215 +
216 + /**
217 + * Represents topology creation time.
218 + */
219 + public static final String CREATE_TIME = "creation_time";
220 +
221 + /**
222 + * Represents number of infrastructure devices in the topology.
223 + */
224 + public static final String DEVICE_COUNT = "device_count";
225 +
226 + /**
227 + * Represents number of links in the topology.
228 + */
229 + public static final String LINK_COUNT = "link_count";
230 +
231 + /**
232 + * Represents links destination DeviceId.
233 + */
234 + public static final String DEST = "dst";
235 +
236 + /**
237 + * Represents links source DeviceId.
238 + */
239 + public static final String SRC = "src";
240 +
241 + /**
242 + * True if the link is expected, false otherwise.
243 + */
244 + public static final String EXPECTED = "expected";
245 +
246 + /**
247 + * Represents link state ACTIVE or INACTIVE.
248 + */
249 + public static final String STATE = "state";
250 +
251 + /**
252 + * Represents link type like LINK_ADDED, LINK_UPDATE, LINK_REMOVED.
253 + */
254 + public static final String LINK_TYPE = "link_type";
255 +
256 + /**
257 + * Represents the rabbit mq server properties stored in resources directory.
258 + */
259 + public static final String MQ_PROP_NAME = "rabbitmq.properties";
260 +
261 + /**
262 + * Represents rabbit mq module name for app initialization.
263 + */
264 + public static final String ONOS_APP_NAME = "org.onosproject.rabbitmq";
265 +
266 + /**
267 + * Represents rabbit mq publisher correlation identifier.
268 + */
269 + public static final String SENDER_COR_ID = "rmq.sender.correlation.id";
270 +
271 + /**
272 + * Represents rabbit mq server protocol.
273 + */
274 + public static final String SERVER_PROTO = "rmq.server.protocol";
275 +
276 + /**
277 + * Represents rabbit mq server user name.
278 + */
279 + public static final String SERVER_UNAME = "rmq.server.username";
280 +
281 + /**
282 + * Represents rabbit mq server password.
283 + */
284 + public static final String SERVER_PWD = "rmq.server.password";
285 +
286 + /**
287 + * Represents rabbit mq server address.
288 + */
289 + public static final String SERVER_ADDR = "rmq.server.ip.address";
290 +
291 + /**
292 + * Represents rabbit mq server port.
293 + */
294 + public static final String SERVER_PORT = "rmq.server.port";
295 +
296 + /**
297 + * Represents rabbit mq server vhost.
298 + */
299 + public static final String SERVER_VHOST = "rmq.server.vhost";
300 +
301 + /**
302 + * Represents rabbit mq server exchange.
303 + */
304 + public static final String SENDER_EXCHG = "rmq.sender.exchange";
305 +
306 + /**
307 + * Represents rabbit mq server routing key binds exchange and queue.
308 + */
309 + public static final String ROUTE_KEY = "rmq.sender.routing.key";
310 +
311 + /**
312 + * Represents rabbit mq server queue for message delivery.
313 + */
314 + public static final String SENDER_QUEUE = "rmq.sender.queue";
315 +
316 + /**
317 + * Represents rabbit mq server topic.
318 + */
319 + public static final String TOPIC = "topic";
320 +
321 + /**
322 + * Represents correlation ID of the sender.
323 + */
324 + public static final String COR_ID = "onos->rmqserver";
325 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.api;
17 +
18 +import org.onosproject.event.Event;
19 +import org.onosproject.net.packet.PacketContext;
20 +
21 +/**
22 + * Service apis for publishing device and packet events.
23 + */
24 +public interface MQService {
25 +
26 + /**
27 + * Publishes device/link/topology events to MQ server.
28 + *
29 + * @param event the event type
30 + */
31 + void publish(Event<? extends Enum, ?> event);
32 +
33 + /**
34 + * Publishes packet context message to MQ server.
35 + *
36 + * @param context for processing an inbound packet
37 + */
38 + void publish(PacketContext context);
39 +
40 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.api;
17 +
18 +import java.util.Map;
19 +import java.util.concurrent.BlockingQueue;
20 +
21 +import org.onosproject.rabbitmq.impl.BrokerHost;
22 +import org.onosproject.rabbitmq.impl.MessageContext;
23 +
24 +/**
25 + * API for registering producer with server.
26 + */
27 +public interface MQTransport {
28 + /**
29 + * Registers MQ client with the server.
30 + *
31 + * @param host the broker host
32 + * @param channelConf the mq channel configurations
33 + * @param queue the message context
34 + * @return the sender handle
35 + */
36 + Manageable registerProducer(BrokerHost host, Map<String, String> channelConf,
37 + BlockingQueue<MessageContext> queue);
38 +
39 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +package org.onosproject.rabbitmq.api;
18 +
19 +/**
20 + * Interface for declaring a start, publish and stop api's for mq transactions.
21 + */
22 +public interface Manageable {
23 + /**
24 + * Establishes connection with MQ server.
25 + */
26 + void start();
27 +
28 + /**
29 + * Publishes onos events on to MQ server.
30 + */
31 + void publish();
32 +
33 + /**
34 + * Releases connection and channels.
35 + */
36 + void stop();
37 +
38 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +/**
18 + * package for api declarations.
19 + */
20 +package org.onosproject.rabbitmq.api;
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.impl;
17 +
18 +/**
19 + * Represents the URL pointing to MQ Server. Used to connect to MQ Server.
20 + */
21 +public class BrokerHost {
22 +
23 + private final String url;
24 +
25 + /**
26 + * Sets the MQ Server URL.
27 + *
28 + * @param url represents url of the MQ Server
29 + */
30 + public BrokerHost(String url) {
31 + this.url = url;
32 + }
33 +
34 + /**
35 + * Returns the MQ Server URL.
36 + *
37 + * @return url of the MQ Server
38 + */
39 + public String getUrl() {
40 + return url;
41 + }
42 +
43 + @Override
44 + public boolean equals(Object o) {
45 + if (this == o) {
46 + return true;
47 + }
48 +
49 + if (o == null || getClass() != o.getClass()) {
50 + return false;
51 + }
52 +
53 + BrokerHost that = (BrokerHost) o;
54 +
55 + return url != null ? url.equals(that.url) : that.url == null;
56 + }
57 +
58 + @Override
59 + public int hashCode() {
60 + return url != null ? url.hashCode() : 0;
61 + }
62 +
63 + @Override
64 + public String toString() {
65 + return url;
66 + }
67 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.impl;
17 +
18 +import java.io.IOException;
19 +import java.util.concurrent.BlockingQueue;
20 +import java.util.concurrent.ExecutorService;
21 +import java.util.concurrent.TimeoutException;
22 +
23 +import org.onosproject.rabbitmq.api.Manageable;
24 +import org.slf4j.Logger;
25 +import org.slf4j.LoggerFactory;
26 +
27 +import com.rabbitmq.client.AMQP;
28 +import com.rabbitmq.client.Channel;
29 +import com.rabbitmq.client.Connection;
30 +import com.rabbitmq.client.ConnectionFactory;
31 +
32 +import static org.onosproject.rabbitmq.api.MQConstants.*;
33 +
34 +/**
35 + * Connects client with server using start API, publish the messages received
36 + * from onos events and disconnect the client from server using stop API.
37 + */
38 +public class MQSender implements Manageable {
39 +
40 + private static final String E_CREATE_CHAN =
41 + "Error creating the RabbitMQ channel";
42 + private static final String E_PUBLISH_CHAN =
43 + "Error in publishing to the RabbitMQ channel";
44 + private static final Logger log = LoggerFactory.getLogger(MQSender.class);
45 + private static final int RECOVERY_INTERVAL = 15000;
46 +
47 + private final BlockingQueue<MessageContext> outQueue;
48 + private final String exchangeName;
49 + private final String routingKey;
50 + private final String queueName;
51 + private final String url;
52 +
53 + private ExecutorService executorService;
54 + private Connection conn;
55 + private Channel channel;
56 +
57 +
58 + /**
59 + * Creates a MQSender initialized with the specified parameters.
60 + *
61 + * @param outQueue represents message context
62 + * @param exchangeName represents mq exchange name
63 + * @param routingKey represents bound routing key
64 + * @param queueName represents mq queue name
65 + * @param url represents the mq server url
66 + */
67 + public MQSender(BlockingQueue<MessageContext> outQueue, String exchangeName,
68 + String routingKey, String queueName, String url) {
69 + this.outQueue = outQueue;
70 + this.exchangeName = exchangeName;
71 + this.routingKey = routingKey;
72 + this.queueName = queueName;
73 + this.url = url;
74 + }
75 +
76 + /**
77 + * Sets the executor service.
78 + *
79 + * @param executorService the executor service to use
80 + */
81 + public void setExecutorService(ExecutorService executorService) {
82 + this.executorService = executorService;
83 + }
84 +
85 + @Override
86 + public void start() {
87 + ConnectionFactory factory = new ConnectionFactory();
88 + factory.setAutomaticRecoveryEnabled(true);
89 + factory.setNetworkRecoveryInterval(RECOVERY_INTERVAL);
90 + try {
91 + factory.setUri(url);
92 + if (executorService != null) {
93 + conn = factory.newConnection(executorService);
94 + } else {
95 + conn = factory.newConnection();
96 + }
97 + channel = conn.createChannel();
98 + channel.exchangeDeclare(exchangeName, TOPIC, true);
99 + /*
100 + * Setting the following parameters to queue
101 + * durable - true
102 + * exclusive - false
103 + * autoDelete - false
104 + * arguments - null
105 + */
106 + channel.queueDeclare(this.queueName, true, false, false, null);
107 + channel.queueBind(queueName, exchangeName, routingKey);
108 + } catch (Exception e) {
109 + log.error(E_CREATE_CHAN, e);
110 + }
111 + }
112 +
113 + @Override
114 + public void publish() {
115 + try {
116 + MessageContext input = outQueue.poll();
117 + channel.basicPublish(exchangeName, routingKey,
118 + new AMQP.BasicProperties.Builder()
119 + .correlationId(COR_ID).build(),
120 + input.getBody());
121 + String message1 = new String(input.getBody(), "UTF-8");
122 + log.debug(" [x] Sent: '{}'", message1);
123 + } catch (Exception e) {
124 + log.error(E_PUBLISH_CHAN, e);
125 + }
126 + }
127 +
128 + @Override
129 + public void stop() {
130 + try {
131 + channel.close();
132 + conn.close();
133 + } catch (IOException e) {
134 + log.error("Error closing the rabbit MQ connection", e);
135 + } catch (TimeoutException e) {
136 + log.error("Timeout exception in closing the rabbit MQ connection",
137 + e);
138 + }
139 + }
140 +
141 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.impl;
17 +
18 +import java.io.UnsupportedEncodingException;
19 +import java.util.Map;
20 +import java.util.Properties;
21 +import java.util.concurrent.BlockingQueue;
22 +import java.util.concurrent.LinkedBlockingQueue;
23 +import org.apache.commons.lang.exception.ExceptionUtils;
24 +
25 +import static org.onosproject.rabbitmq.api.MQConstants.*;
26 +
27 +import org.onosproject.event.Event;
28 +import org.onosproject.net.device.DeviceEvent;
29 +import org.onosproject.net.link.LinkEvent;
30 +import org.onosproject.net.packet.PacketContext;
31 +import org.onosproject.net.topology.TopologyEvent;
32 +import org.onosproject.rabbitmq.api.MQService;
33 +import org.onosproject.rabbitmq.api.Manageable;
34 +import org.onosproject.rabbitmq.util.MQUtil;
35 +import org.osgi.service.component.ComponentContext;
36 +import org.slf4j.Logger;
37 +import org.slf4j.LoggerFactory;
38 +import com.google.gson.JsonObject;
39 +
40 +
41 +import com.google.common.collect.Maps;
42 +
43 +/**
44 + * Default implementation of {@link MQService}.
45 + */
46 +public class MQServiceImpl implements MQService {
47 + private static final Logger log = LoggerFactory.getLogger(
48 + MQServiceImpl.class);
49 +
50 + private final BlockingQueue<MessageContext> msgOutQueue =
51 + new LinkedBlockingQueue<>(10);
52 +
53 + private Manageable manageSender;
54 + private String correlationId;
55 +
56 + /**
57 + * Initializes using ComponentContext.
58 + *
59 + * @param context ComponentContext from OSGI
60 + */
61 + public MQServiceImpl(ComponentContext context) {
62 + initializeProducers(context);
63 + }
64 +
65 + /**
66 + * Initializes MQ sender and receiver with RMQ server.
67 + *
68 + * @param context ComponentContext from OSGI
69 + */
70 + private void initializeProducers(ComponentContext context) {
71 + BrokerHost rfHost;
72 + Properties prop = MQUtil.getProp(context);
73 + if (prop == null) {
74 + log.error("RabbitMQ configuration file not found...");
75 + return;
76 + }
77 + try {
78 + correlationId = prop.getProperty(SENDER_COR_ID);
79 + rfHost = new BrokerHost(MQUtil.getMqUrl(
80 + prop.getProperty(SERVER_PROTO),
81 + prop.getProperty(SERVER_UNAME),
82 + prop.getProperty(SERVER_PWD),
83 + prop.getProperty(SERVER_ADDR),
84 + prop.getProperty(SERVER_PORT),
85 + prop.getProperty(SERVER_VHOST)));
86 +
87 + manageSender = registerProducer(rfHost,
88 + MQUtil.rfProducerChannelConf(
89 + prop.getProperty(SENDER_EXCHG),
90 + prop.getProperty(ROUTE_KEY),
91 + prop.getProperty(SENDER_QUEUE)),
92 + msgOutQueue);
93 + } catch (Exception e) {
94 + throw new RuntimeException(e);
95 + }
96 + manageSender.start();
97 + }
98 +
99 + /**
100 + * Returns the handle to call an api for publishing messages to RMQ server.
101 + */
102 + private Manageable registerProducer(BrokerHost host, Map<String, String> channelConf,
103 + BlockingQueue<MessageContext> msgOutQueue) {
104 + return new MQTransportImpl().registerProducer(host, channelConf, msgOutQueue);
105 + }
106 +
107 + private byte[] bytesOf(JsonObject jo) {
108 + return jo.toString().getBytes();
109 + }
110 +
111 + /**
112 + * Publishes Device, Topology &amp; Link event message to MQ server.
113 + *
114 + * @param event Event received from the corresponding service like topology, device etc
115 + */
116 + @Override
117 + public void publish(Event<? extends Enum, ?> event) {
118 + byte[] body = null;
119 + if (null == event) {
120 + log.error("Captured event is null...");
121 + return;
122 + }
123 + if (event instanceof DeviceEvent) {
124 + body = bytesOf(MQUtil.json((DeviceEvent) event));
125 + } else if (event instanceof TopologyEvent) {
126 + body = bytesOf(MQUtil.json((TopologyEvent) event));
127 + } else if (event instanceof LinkEvent) {
128 + body = bytesOf(MQUtil.json((LinkEvent) event));
129 + } else {
130 + log.error("Invalid event: '{}'", event);
131 + }
132 + processAndPublishMessage(body);
133 + }
134 +
135 + /**
136 + * Publishes packet message to MQ server.
137 + *
138 + * @param context Context of the packet recieved including details like mac, length etc
139 + */
140 + @Override
141 + public void publish(PacketContext context) {
142 + byte[] body = bytesOf(MQUtil.json(context));
143 + processAndPublishMessage(body);
144 + }
145 +
146 + /*
147 + * Constructs message context and publish it to rabbit mq server.
148 + *
149 + * @param body Byte stream of the event's JSON data
150 + */
151 + private void processAndPublishMessage(byte[] body) {
152 + Map<String, Object> props = Maps.newHashMap();
153 + props.put(CORRELATION_ID, correlationId);
154 + MessageContext mc = new MessageContext(body, props);
155 + try {
156 + msgOutQueue.put(mc);
157 + String message = new String(body, "UTF-8");
158 + log.debug(" [x] Sent '{}'", message);
159 + } catch (InterruptedException | UnsupportedEncodingException e) {
160 + log.error(ExceptionUtils.getFullStackTrace(e));
161 + }
162 + manageSender.publish();
163 + }
164 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.impl;
17 +
18 +import java.util.Map;
19 +import java.util.concurrent.BlockingQueue;
20 +
21 +import org.onosproject.rabbitmq.api.MQTransport;
22 +import org.onosproject.rabbitmq.api.Manageable;
23 +
24 +import static org.onosproject.rabbitmq.api.MQConstants.*;
25 +
26 +/**
27 + * Provides handle to call MQSender for message delivery.
28 + */
29 +public class MQTransportImpl implements MQTransport {
30 +
31 + @Override
32 + public Manageable registerProducer(BrokerHost host,
33 + Map<String, String> channelConf,
34 + BlockingQueue<MessageContext> queue) {
35 + String exchangeName = channelConf.get(EXCHANGE_NAME_PROPERTY);
36 + String routingKey = channelConf.get(ROUTING_KEY_PROPERTY);
37 + String queueName = channelConf.get(QUEUE_NAME_PROPERTY);
38 + return new MQSender(queue, exchangeName, routingKey, queueName,
39 + host.getUrl());
40 + }
41 +
42 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.impl;
17 +
18 +import java.io.Serializable;
19 +import java.util.Map;
20 +
21 +import static com.google.common.base.Preconditions.checkNotNull;
22 +
23 +/**
24 + * Represents message context like data in byte stream and mq properties for
25 + * message delivery.
26 + */
27 +public class MessageContext implements Serializable {
28 + private static final long serialVersionUID = -4174900539976805047L;
29 + private static final String NULL_ERR =
30 + "The body and properties should be present";
31 +
32 + private final Map<String, Object> properties;
33 + private final byte[] body;
34 +
35 + /**
36 + * Initializes MessageContext class.
37 + *
38 + * @param body Byte stream of the event's JSON data
39 + * @param properties Map of the Message Queue properties
40 + */
41 + public MessageContext(byte[] body, Map<String, Object> properties) {
42 + this.body = checkNotNull(body, NULL_ERR);
43 + this.properties = checkNotNull(properties, NULL_ERR);
44 + }
45 +
46 + /**
47 + * Returns the Message Properties Map.
48 + *
49 + * @return Map of the Message Queue properties
50 + */
51 +
52 + public Map<String, Object> getProperties() {
53 + return properties;
54 + }
55 +
56 + /**
57 + * Returns the Message Properties Map.
58 + *
59 + * @return Byte stream of the event's JSON data
60 + */
61 + public byte[] getBody() {
62 + return body;
63 + }
64 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +/**
18 + * Package for mq implementation.
19 + */
20 +package org.onosproject.rabbitmq.impl;
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +package org.onosproject.rabbitmq.listener;
18 +
19 +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
20 +import static org.onlab.util.Tools.groupedThreads;
21 +
22 +import java.util.concurrent.ExecutorService;
23 +
24 +import org.apache.felix.scr.annotations.Activate;
25 +import org.apache.felix.scr.annotations.Component;
26 +import org.apache.felix.scr.annotations.Deactivate;
27 +import org.apache.felix.scr.annotations.Reference;
28 +import org.apache.felix.scr.annotations.ReferenceCardinality;
29 +import org.onosproject.net.device.DeviceEvent;
30 +import org.onosproject.net.device.DeviceListener;
31 +import org.onosproject.net.device.DeviceService;
32 +import org.onosproject.net.link.LinkEvent;
33 +import org.onosproject.net.link.LinkListener;
34 +import org.onosproject.net.link.LinkService;
35 +import org.onosproject.net.link.ProbedLinkProvider;
36 +import org.onosproject.net.packet.PacketContext;
37 +import org.onosproject.net.packet.PacketProcessor;
38 +import org.onosproject.net.packet.PacketService;
39 +import org.onosproject.net.provider.AbstractProvider;
40 +import org.onosproject.net.provider.ProviderId;
41 +import org.onosproject.net.topology.TopologyEvent;
42 +import org.onosproject.net.topology.TopologyListener;
43 +import org.onosproject.net.topology.TopologyService;
44 +import org.onosproject.rabbitmq.api.MQConstants;
45 +import org.onosproject.rabbitmq.api.MQService;
46 +import org.onosproject.rabbitmq.impl.MQServiceImpl;
47 +import org.osgi.service.component.ComponentContext;
48 +import org.slf4j.Logger;
49 +import org.slf4j.LoggerFactory;
50 +
51 +/**
52 + * Listens to events generated from Device Event/PKT_IN/Topology/Link.
53 + * Then publishes events to rabbitmq server via publish() api.
54 + */
55 +
56 +@Component(immediate = true)
57 +public class MQEventHandler extends AbstractProvider
58 + implements ProbedLinkProvider {
59 +
60 + private static final Logger log = LoggerFactory.getLogger(
61 + MQEventHandler.class);
62 + private static final String PROVIDER_NAME = MQConstants.ONOS_APP_NAME;
63 + private static final int PKT_PROC_PRIO = 1;
64 +
65 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 + protected DeviceService deviceService;
67 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 + protected PacketService packetService;
69 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 + protected LinkService linkService;
71 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 + protected TopologyService topologyService;
73 +
74 + private MQService mqService;
75 + private DeviceListener deviceListener;
76 + protected ExecutorService eventExecutor;
77 +
78 + private final InternalPacketProcessor packetProcessor =
79 + new InternalPacketProcessor();
80 + private final LinkListener linkListener = new InternalLinkListener();
81 + private final TopologyListener topologyListener =
82 + new InternalTopologyListener();
83 +
84 + /**
85 + * Initialize parent class with provider.
86 + */
87 + public MQEventHandler() {
88 + super(new ProviderId("rabbitmq", PROVIDER_NAME));
89 + }
90 +
91 + @Activate
92 + protected void activate(ComponentContext context) {
93 + mqService = new MQServiceImpl(context);
94 + eventExecutor = newSingleThreadScheduledExecutor(
95 + groupedThreads("onos/deviceevents", "events-%d", log));
96 + deviceListener = new InternalDeviceListener();
97 + deviceService.addListener(deviceListener);
98 + packetService.addProcessor(packetProcessor,
99 + PacketProcessor.advisor(PKT_PROC_PRIO));
100 + linkService.addListener(linkListener);
101 + topologyService.addListener(topologyListener);
102 + log.info("Started");
103 + }
104 +
105 + @Deactivate
106 + protected void deactivate() {
107 + deviceService.removeListener(deviceListener);
108 + packetService.removeProcessor(packetProcessor);
109 + eventExecutor.shutdownNow();
110 + eventExecutor = null;
111 + linkService.removeListener(linkListener);
112 + topologyService.removeListener(topologyListener);
113 + log.info("Stopped");
114 + }
115 +
116 + /**
117 + * Captures incoming device events.
118 + */
119 + private class InternalDeviceListener implements DeviceListener {
120 +
121 + @Override
122 + public void event(DeviceEvent event) {
123 + if (event == null) {
124 + log.error("Device event is null.");
125 + return;
126 + }
127 + mqService.publish(event);
128 + }
129 + }
130 +
131 + /**
132 + * Captures incoming packets from switches connected to ONOS
133 + * controller..
134 + */
135 + private class InternalPacketProcessor implements PacketProcessor {
136 + @Override
137 + public void process(PacketContext context) {
138 + if (context == null) {
139 + log.error("Packet context is null.");
140 + return;
141 + }
142 + mqService.publish(context);
143 + }
144 + }
145 +
146 + /**
147 + * Listens to link events and processes the link additions.
148 + */
149 + private class InternalLinkListener implements LinkListener {
150 + @Override
151 + public void event(LinkEvent event) {
152 + if (event == null) {
153 + log.error("Link event is null.");
154 + return;
155 + }
156 + mqService.publish(event);
157 + }
158 + }
159 +
160 + /**
161 + * Listens to topology events and processes the topology changes.
162 + */
163 + private class InternalTopologyListener implements TopologyListener {
164 +
165 + @Override
166 + public void event(TopologyEvent event) {
167 + if (event == null) {
168 + log.error("Topology event is null.");
169 + return;
170 + }
171 + mqService.publish(event);
172 + }
173 + }
174 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +/**
18 + * RabbitMQ module used for publishing device and packet events to MQ server.
19 + */
20 +package org.onosproject.rabbitmq.listener;
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +package org.onosproject.rabbitmq.util;
17 +
18 +import java.io.File;
19 +import java.io.InputStream;
20 +import java.io.UnsupportedEncodingException;
21 +import java.net.MalformedURLException;
22 +import java.net.URL;
23 +import java.net.URLEncoder;
24 +import java.util.Date;
25 +import java.util.HashMap;
26 +import java.util.Map;
27 +import java.util.Properties;
28 +import org.apache.commons.lang.exception.ExceptionUtils;
29 +
30 +import org.onlab.packet.EthType;
31 +import org.onosproject.net.Link;
32 +import org.onosproject.net.device.DeviceEvent;
33 +import org.onosproject.net.link.LinkEvent;
34 +import org.onosproject.net.packet.PacketContext;
35 +import org.onosproject.net.topology.Topology;
36 +import org.onosproject.net.topology.TopologyEvent;
37 +import org.onosproject.net.packet.InboundPacket;
38 +import org.osgi.service.component.ComponentContext;
39 +import com.google.gson.JsonObject;
40 +import org.slf4j.Logger;
41 +import org.slf4j.LoggerFactory;
42 +
43 +import static org.onosproject.rabbitmq.api.MQConstants.*;
44 +
45 +/**
46 + * MQ utility class for constructing server url, packet message, device message,
47 + * topology message and link message.
48 + */
49 +public final class MQUtil {
50 +
51 + private static final String COLON = ":";
52 + private static final String AT = "@";
53 + private static final String CDFS = "://";
54 + private static final String FS = "/";
55 + private static final String UTF8 = "UTF-8";
56 + private static final Logger log = LoggerFactory.getLogger(MQUtil.class);
57 +
58 + private MQUtil() {
59 + }
60 +
61 + /**
62 + * Returns the MQ server url.
63 + *
64 + * @param proto mq server protocol
65 + * @param userName mq server username
66 + * @param password mq server password
67 + * @param ipAddr server ip address
68 + * @param port server port
69 + * @param vhost server vhost
70 + * @return server url
71 + */
72 + public static String getMqUrl(String proto, String userName,
73 + String password, String ipAddr, String port,
74 + String vhost) {
75 + StringBuilder urlBuilder = new StringBuilder();
76 + try {
77 + urlBuilder.append(proto).append(CDFS).append(userName).append(COLON)
78 + .append(password).append(AT)
79 + .append(ipAddr).append(COLON).append(port).append(FS)
80 + .append(URLEncoder.encode(vhost, UTF8));
81 + } catch (UnsupportedEncodingException e) {
82 + log.error(ExceptionUtils.getFullStackTrace(e));
83 + }
84 + return urlBuilder.toString().replaceAll("\\s+", "");
85 + }
86 +
87 + /**
88 + * Initializes and returns publisher channel configuration.
89 + *
90 + * @param exchange the configured mq exchange name
91 + * @param routingKey the configured mq routing key
92 + * @param queueName the configured mq queue name
93 + * @return the server url
94 + */
95 + public static Map<String, String> rfProducerChannelConf(String exchange,
96 + String routingKey, String queueName) {
97 + Map<String, String> channelConf = new HashMap<>();
98 + channelConf.put(EXCHANGE_NAME_PROPERTY, exchange);
99 + channelConf.put(ROUTING_KEY_PROPERTY, routingKey);
100 + channelConf.put(QUEUE_NAME_PROPERTY, queueName);
101 + return channelConf;
102 + }
103 +
104 + /**
105 + * Returns a JSON representation of the given device event.
106 + *
107 + * @param event the device event
108 + * @return the device event json message
109 + */
110 + public static JsonObject json(DeviceEvent event) {
111 + JsonObject jo = new JsonObject();
112 + jo.addProperty(SWITCH_ID, event.subject().id().toString());
113 + jo.addProperty(INFRA_DEVICE_NAME, event.subject().type().name());
114 + jo.addProperty(EVENT_TYPE, DEVICE_EVENT);
115 + if (event.port() != null) {
116 + jo.addProperty(PORT_NUMBER, event.port().number().toLong());
117 + jo.addProperty(PORT_ENABLED, event.port().isEnabled());
118 + jo.addProperty(PORT_SPEED, event.port().portSpeed());
119 + jo.addProperty(SUB_EVENT_TYPE,
120 + event.type().name() != null ? event.type().name() : null);
121 + } else {
122 + jo.addProperty(SUB_EVENT_TYPE,
123 + event.type().name() != null ? event.type().name() : null);
124 + }
125 + jo.addProperty(HW_VERSION, event.subject().hwVersion());
126 + jo.addProperty(MFR, event.subject().manufacturer());
127 + jo.addProperty(SERIAL, event.subject().serialNumber());
128 + jo.addProperty(SW_VERSION, event.subject().swVersion());
129 + jo.addProperty(CHASIS_ID, event.subject().chassisId().id());
130 + jo.addProperty(OCC_TIME, new Date(event.time()).toString());
131 + return jo;
132 + }
133 +
134 + /**
135 + * Returns a JSON representation of the given packet context.
136 + *
137 + * @param context the packet context
138 + * @return the inbound packetjson message
139 + */
140 + public static JsonObject json(PacketContext context) {
141 + JsonObject jo = new JsonObject();
142 + InboundPacket pkt = context.inPacket();
143 + // parse connection host
144 + jo.addProperty(SWITCH_ID, pkt.receivedFrom().deviceId().toString());
145 + jo.addProperty(IN_PORT, pkt.receivedFrom().port().name());
146 + jo.addProperty(LOGICAL, pkt.receivedFrom().port().isLogical());
147 + jo.addProperty(RECIEVED, new Date(context.time()).toString());
148 + jo.addProperty(MSG_TYPE, PKT_TYPE);
149 + // parse ethernet
150 + jo.addProperty(SUB_MSG_TYPE,
151 + EthType.EtherType.lookup(pkt.parsed().getEtherType()).name());
152 + jo.addProperty(ETH_TYPE, pkt.parsed().getEtherType());
153 + jo.addProperty(SRC_MAC_ADDR, pkt.parsed().getSourceMAC().toString());
154 + jo.addProperty(DEST_MAC_ADDR, pkt.parsed().getDestinationMAC().toString());
155 + jo.addProperty(VLAN_ID, pkt.parsed().getVlanID());
156 + jo.addProperty(B_CAST, pkt.parsed().isBroadcast());
157 + jo.addProperty(M_CAST, pkt.parsed().isMulticast());
158 + jo.addProperty(PAD, pkt.parsed().isPad());
159 + jo.addProperty(PRIORITY_CODE, pkt.parsed().getPriorityCode());
160 + // parse bytebuffer
161 + jo.addProperty(DATA_LEN, pkt.unparsed().array().length);
162 + jo.addProperty(PAYLOAD, pkt.unparsed().asCharBuffer().toString());
163 + return jo;
164 + }
165 +
166 + /**
167 + * Returns a JSON representation of the given topology event.
168 + *
169 + * @param event the topology event
170 + * @return the topology event json message
171 + */
172 + public static JsonObject json(TopologyEvent event) {
173 + Topology topology = event.subject();
174 + JsonObject jo = new JsonObject();
175 + jo.addProperty(TOPO_TYPE, TopologyEvent.Type.TOPOLOGY_CHANGED.name());
176 + jo.addProperty(CLUSTER_COUNT, topology.clusterCount());
177 + jo.addProperty(COMPUTE_COST, topology.computeCost());
178 + jo.addProperty(CREATE_TIME, new Date(topology.creationTime()).toString());
179 + jo.addProperty(DEVICE_COUNT, topology.deviceCount());
180 + jo.addProperty(LINK_COUNT, topology.linkCount());
181 + jo.addProperty(AVAILABLE, new Date(topology.time()).toString());
182 + return jo;
183 + }
184 +
185 + /**
186 + * Returns a JSON representation of the given link event.
187 + *
188 + * @param event the link event
189 + * @return the link event json message
190 + */
191 + public static JsonObject json(LinkEvent event) {
192 + Link link = event.subject();
193 + JsonObject jo = new JsonObject();
194 + jo.addProperty(EVENT_TYPE, event.type().name());
195 + jo.addProperty(DEST, link.dst().deviceId().toString());
196 + jo.addProperty(SRC, link.src().deviceId().toString());
197 + jo.addProperty(EXPECTED, link.isExpected());
198 + jo.addProperty(STATE, link.state().name());
199 + jo.addProperty(LINK_TYPE, link.type().name());
200 + return jo;
201 + }
202 +
203 + /**
204 + * Handles load mq property file from resources and returns Properties.
205 + *
206 + * @param context the component context
207 + * @return the mq server properties
208 + * @throws RuntimeException if property file not found.
209 + */
210 + public static Properties getProp(ComponentContext context) {
211 + URL configUrl;
212 + try {
213 + configUrl = context.getBundleContext().getBundle()
214 + .getResource(MQ_PROP_NAME);
215 + } catch (Exception ex) {
216 + // This will be used only during junit test case since bundle
217 + // context will be available during runtime only.
218 + File file = new File(
219 + MQUtil.class.getClassLoader().getResource(MQ_PROP_NAME)
220 + .getFile());
221 + try {
222 + configUrl = file.toURL();
223 + } catch (MalformedURLException e) {
224 + log.error(ExceptionUtils.getFullStackTrace(e));
225 + throw new RuntimeException(e);
226 + }
227 + }
228 +
229 + Properties properties;
230 + try {
231 + InputStream is = configUrl.openStream();
232 + properties = new Properties();
233 + properties.load(is);
234 + } catch (Exception e) {
235 + log.error(ExceptionUtils.getFullStackTrace(e));
236 + throw new RuntimeException(e);
237 + }
238 + return properties;
239 + }
240 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
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 + */
16 +
17 +/**
18 + * Packet for mq utility.
19 + */
20 +package org.onosproject.rabbitmq.util;
1 +#Modified the below properties as per your requirements.
2 +rmq.server.protocol = amqp
3 +rmq.server.username = onosrmq
4 +rmq.server.password = onosrocks
5 +rmq.server.port = 5672
6 +rmq.server.ip.address = 127.0.0.1
7 +rmq.server.vhost = /
8 +rmq.sender.type = topic
9 +rmq.sender.correlation.id = onos->rmqserver
10 +rmq.sender.exchange = onos_exchg_wr_to_rmqs
11 +rmq.sender.routing.key = onos.rkey.rmqs
12 +rmq.sender.queue = onos_send_queue
1 +package org.onosproject.rabbitmq.listener;
2 +
3 +import static com.google.common.collect.ImmutableSet.of;
4 +import static org.easymock.EasyMock.createMock;
5 +import static org.easymock.EasyMock.expect;
6 +import static org.easymock.EasyMock.replay;
7 +import static org.junit.Assert.assertEquals;
8 +import static org.junit.Assert.assertFalse;
9 +import static org.onosproject.net.DeviceId.deviceId;
10 +import static org.onosproject.net.NetTestTools.device;
11 +import static org.onosproject.net.NetTestTools.link;
12 +import static org.onosproject.net.PortNumber.portNumber;
13 +import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
14 +import static org.onosproject.net.device.DeviceEvent.Type.*;
15 +import static org.onosproject.net.link.LinkEvent.Type.*;
16 +import static org.onosproject.net.Device.Type.*;
17 +
18 +import java.nio.ByteBuffer;
19 +import java.util.ArrayList;
20 +import java.util.HashMap;
21 +import java.util.List;
22 +import java.util.Map;
23 +import java.util.Set;
24 +
25 +import org.easymock.EasyMockRunner;
26 +import org.easymock.Mock;
27 +import org.junit.After;
28 +import org.junit.Before;
29 +import org.junit.Test;
30 +import org.junit.runner.RunWith;
31 +import org.onlab.packet.ChassisId;
32 +import org.onlab.packet.Ethernet;
33 +import org.onlab.packet.ONOSLLDP;
34 +import org.onosproject.core.ApplicationId;
35 +import org.onosproject.core.CoreService;
36 +import org.onosproject.core.DefaultApplicationId;
37 +import org.onosproject.event.AbstractEventTest;
38 +import org.onosproject.event.Event;
39 +import org.onosproject.net.ConnectPoint;
40 +import org.onosproject.net.DefaultDevice;
41 +import org.onosproject.net.DefaultLink;
42 +import org.onosproject.net.DefaultPort;
43 +import org.onosproject.net.Device;
44 +import org.onosproject.net.DeviceId;
45 +import org.onosproject.net.Link;
46 +import org.onosproject.net.link.LinkEvent;
47 +import org.onosproject.net.MastershipRole;
48 +import org.onosproject.net.Port;
49 +import org.onosproject.net.device.DeviceEvent;
50 +import org.onosproject.net.device.DeviceListener;
51 +import org.onosproject.net.device.DeviceServiceAdapter;
52 +import org.onosproject.net.flow.TrafficTreatment;
53 +import org.onosproject.net.link.LinkListener;
54 +import org.onosproject.net.link.LinkService;
55 +import org.onosproject.net.packet.DefaultInboundPacket;
56 +import org.onosproject.net.packet.InboundPacket;
57 +import org.onosproject.net.packet.OutboundPacket;
58 +import org.onosproject.net.packet.PacketContext;
59 +import org.onosproject.net.packet.PacketProcessor;
60 +import org.onosproject.net.packet.PacketServiceAdapter;
61 +import org.onosproject.net.provider.AbstractProvider;
62 +import org.onosproject.net.provider.ProviderId;
63 +import org.onosproject.net.topology.DefaultGraphDescription;
64 +import org.onosproject.net.topology.GraphDescription;
65 +import org.onosproject.net.topology.Topology;
66 +import org.onosproject.net.topology.TopologyEvent;
67 +import org.onosproject.net.topology.TopologyListener;
68 +import org.onosproject.net.topology.TopologyProvider;
69 +import org.onosproject.net.topology.TopologyProviderRegistry;
70 +import org.onosproject.net.topology.TopologyProviderService;
71 +import org.onosproject.net.topology.TopologyService;
72 +import org.onosproject.rabbitmq.api.MQService;
73 +import org.onosproject.rabbitmq.api.Manageable;
74 +import org.osgi.service.component.ComponentContext;
75 +
76 +import com.google.common.collect.ArrayListMultimap;
77 +import com.google.common.collect.ImmutableList;
78 +import com.google.common.collect.Lists;
79 +import com.google.common.util.concurrent.MoreExecutors;
80 +/**
81 + * Junit tests for packet in, device, topology and link events.
82 + */
83 +@RunWith(EasyMockRunner.class)
84 +public class MQEventHandlerTest extends AbstractEventTest {
85 +
86 + private final MQEventHandler mqEventHandler = new MQEventHandler();
87 + private static final DeviceId DID1 = deviceId("of:0000000000000001");
88 + private static final DeviceId DID2 = deviceId("of:0000000000000002");
89 + private static final DeviceId DID3 = deviceId("of:0000000000000003");
90 +
91 + private ApplicationId appId = new DefaultApplicationId(100,
92 + "org.onosproject.rabbitmq");
93 + private final TestPacketService packetService = new TestPacketService();
94 + private final TestDeviceService deviceService = new TestDeviceService();
95 + private PacketProcessor testProcessor;
96 + private DeviceListener deviceListener;
97 + private static Port pd1;
98 + private static Port pd2;
99 + private static Port pd3;
100 + private static Port pd4;
101 + private CoreService coreService;
102 + @Mock
103 + ComponentContext context;
104 + @Mock
105 + private Manageable manageSender;
106 +
107 + private static final ProviderId PID = new ProviderId("of", "foo");
108 + private TestLinkListener testLinkListener = new TestLinkListener();
109 + @Mock
110 + private LinkService linkService;
111 + @Mock
112 + Topology topology;
113 + @Mock
114 + protected TopologyService service;
115 + protected TopologyProviderRegistry registry;
116 + @Mock
117 + protected TopologyProviderService providerService;
118 + protected TestProvider provider;
119 + protected TestTopologyListener listener = new TestTopologyListener();
120 + @Mock
121 + MQService mqService;
122 +
123 + @Before
124 + public void setUp() {
125 + coreService = createMock(CoreService.class);
126 + expect(coreService.registerApplication(appId.name()))
127 + .andReturn(appId).anyTimes();
128 + replay(coreService);
129 + mqEventHandler.deviceService = deviceService;
130 + mqEventHandler.packetService = packetService;
131 + mqEventHandler.eventExecutor = MoreExecutors.newDirectExecutorService();
132 + linkService.addListener(testLinkListener);
133 + mqEventHandler.linkService = linkService;
134 + mqEventHandler.topologyService = service;
135 + mqEventHandler.activate(context);
136 + }
137 +
138 + @After
139 + public void tearDown() {
140 + mqEventHandler.deactivate();
141 + mqEventHandler.deviceService = null;
142 + mqEventHandler.packetService = null;
143 + }
144 +
145 + private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
146 + return new DeviceEvent(type, deviceService.getDevice(did));
147 +
148 + }
149 +
150 + private Port port(DeviceId did, long port, boolean enabled) {
151 + return new DefaultPort(deviceService.getDevice(did),
152 + portNumber(port), enabled);
153 + }
154 +
155 + private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did,
156 + Port port) {
157 + return new DeviceEvent(type, deviceService.getDevice(did), port);
158 + }
159 +
160 + @Test
161 + public void switchAdd() {
162 + DeviceEvent de = deviceEvent(DEVICE_ADDED, DID1);
163 + deviceListener.event(de);
164 +
165 + }
166 +
167 + @Test
168 + public void switchRemove() {
169 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
170 + deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
171 + }
172 +
173 + @Test
174 + public void switchUpdate() {
175 + deviceListener.event(deviceEvent(DEVICE_UPDATED, DID1));
176 + deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
177 + }
178 +
179 + @Test
180 + public void switchSuspend() {
181 + deviceListener.event(deviceEvent(DEVICE_SUSPENDED, DID1));
182 + deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
183 + }
184 +
185 + @Test
186 + public void portUp() {
187 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
188 + deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 3, true)));
189 + }
190 +
191 + @Test
192 + public void portDown() {
193 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
194 + deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 1, false)));
195 + }
196 +
197 + @Test
198 + public void portRemoved() {
199 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
200 + deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 3, true)));
201 + deviceListener.event(portEvent(PORT_REMOVED, DID1,
202 + port(DID1, 3, true)));
203 + }
204 +
205 + @Test
206 + public void unknownPktCtx() {
207 + // Note: DID3 hasn't been added to TestDeviceService
208 + PacketContext pktCtx = new TestPacketContext(device1(DID3));
209 + testProcessor.process(pktCtx);
210 + assertFalse("Context should still be free", pktCtx.isHandled());
211 + }
212 +
213 + private DefaultDevice device1(DeviceId did) {
214 + return new DefaultDevice(ProviderId.NONE, did, SWITCH,
215 + "TESTMF", "TESTHW", "TESTSW", "TESTSN",
216 + new ChassisId());
217 + }
218 +
219 + @Test
220 + public void knownPktCtx() {
221 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
222 + deviceListener.event(deviceEvent(DEVICE_ADDED, DID2));
223 + PacketContext pktCtx = new TestPacketContext(
224 + deviceService.getDevice(DID2));
225 + /*
226 + * EasyMock.expectLastCall(); EasyMock.replay(manageSender);
227 + */
228 + testProcessor.process(pktCtx);
229 + }
230 +
231 + private class TestDeviceService extends DeviceServiceAdapter {
232 +
233 + private final Map<DeviceId, Device> devices = new HashMap<>();
234 + private final ArrayListMultimap<DeviceId, Port> ports =
235 + ArrayListMultimap.create();
236 +
237 + public TestDeviceService() {
238 + Device d1 = new DefaultDevice(ProviderId.NONE, DID1,
239 + SWITCH, "TESTMF", "TESTHW",
240 + "TESTSW", "TESTSN", new ChassisId());
241 + Device d2 = new DefaultDevice(ProviderId.NONE, DID2, SWITCH,
242 + "TESTMF", "TESTHW", "TESTSW",
243 + "TESTSN", new ChassisId());
244 + devices.put(DID1, d1);
245 + devices.put(DID2, d2);
246 + pd1 = new DefaultPort(d1, portNumber(1), true);
247 + pd2 = new DefaultPort(d1, portNumber(2), true);
248 + pd3 = new DefaultPort(d2, portNumber(1), true);
249 + pd4 = new DefaultPort(d2, portNumber(2), true);
250 + ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
251 + ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
252 + }
253 +
254 + @Override
255 + public int getDeviceCount() {
256 + return devices.values().size();
257 + }
258 +
259 + @Override
260 + public Iterable<Device> getDevices() {
261 + return ImmutableList.copyOf(devices.values());
262 + }
263 +
264 + @Override
265 + public Device getDevice(DeviceId deviceId) {
266 + return devices.get(deviceId);
267 + }
268 +
269 + @Override
270 + public MastershipRole getRole(DeviceId deviceId) {
271 + return MastershipRole.MASTER;
272 + }
273 +
274 + @Override
275 + public boolean isAvailable(DeviceId deviceId) {
276 + return true;
277 + }
278 +
279 + @Override
280 + public void addListener(DeviceListener listener) {
281 + deviceListener = listener;
282 +
283 + }
284 +
285 + @Override
286 + public void removeListener(DeviceListener listener) {
287 +
288 + }
289 + }
290 +
291 + private class TestPacketService extends PacketServiceAdapter {
292 + @Override
293 + public void addProcessor(PacketProcessor processor, int priority) {
294 + testProcessor = processor;
295 + }
296 + }
297 +
298 + private class TestPacketContext implements PacketContext {
299 +
300 + protected Device device;
301 + protected boolean blocked = false;
302 +
303 + public TestPacketContext(Device dev) {
304 + device = dev;
305 + }
306 +
307 + @Override
308 + public long time() {
309 + return 0;
310 + }
311 +
312 + @Override
313 + public InboundPacket inPacket() {
314 + ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1)
315 + .id().toString(),
316 + device.chassisId(),
317 + (int) pd1.number().toLong());
318 +
319 + Ethernet ethPacket = new Ethernet();
320 + ethPacket.setEtherType(Ethernet.TYPE_LLDP);
321 + ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_ONLAB);
322 + ethPacket.setPayload(lldp);
323 + ethPacket.setPad(true);
324 +
325 + ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
326 +
327 + ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
328 +
329 + return new DefaultInboundPacket(cp, ethPacket,
330 + ByteBuffer.wrap(ethPacket
331 + .serialize()));
332 +
333 + }
334 +
335 + @Override
336 + public OutboundPacket outPacket() {
337 + return null;
338 + }
339 +
340 + @Override
341 + public TrafficTreatment.Builder treatmentBuilder() {
342 + return null;
343 + }
344 +
345 + @Override
346 + public void send() {
347 +
348 + }
349 +
350 + @Override
351 + public boolean block() {
352 + blocked = true;
353 + return blocked;
354 + }
355 +
356 + @Override
357 + public boolean isHandled() {
358 + return blocked;
359 + }
360 + }
361 +
362 + private void submitTopologyGraph() {
363 + Set<Device> devices = of(device("a"), device("b"), device("c"),
364 + device("d"), device("e"), device("f"));
365 + Set<Link> links = of(link("a", 1, "b", 1), link("b", 1, "a", 1),
366 + link("b", 2, "c", 1), link("c", 1, "b", 2),
367 + link("c", 2, "d", 1), link("d", 1, "c", 2),
368 + link("d", 2, "a", 2), link("a", 2, "d", 2),
369 + link("e", 1, "f", 1), link("f", 1, "e", 1));
370 + GraphDescription data = new DefaultGraphDescription(4321L,
371 + System.currentTimeMillis(),
372 + devices, links);
373 + providerService.topologyChanged(data, null);
374 + }
375 +
376 + protected void validateEvents(Enum... types) {
377 + int i = 0;
378 + for (Event event : listener.events) {
379 + assertEquals("incorrect event type", types[i], event.type());
380 + i++;
381 + }
382 + listener.events.clear();
383 + }
384 +
385 + @Test
386 + public void testCreateTopology() {
387 + submitTopologyGraph();
388 + validateEvents(TOPOLOGY_CHANGED);
389 + }
390 +
391 + private class TestProvider extends AbstractProvider
392 + implements TopologyProvider {
393 + public TestProvider() {
394 + super(PID);
395 + }
396 +
397 + @Override
398 + public void triggerRecompute() {
399 + }
400 + }
401 +
402 + private class TestTopologyListener implements TopologyListener {
403 + final List<TopologyEvent> events = new ArrayList<>();
404 +
405 + @Override
406 + public void event(TopologyEvent event) {
407 + mqService.publish(event);
408 + }
409 + }
410 +
411 + private Link createLink() {
412 + return DefaultLink.builder().providerId(new ProviderId("of", "foo"))
413 + .src(new ConnectPoint(deviceId("of:foo"), portNumber(1)))
414 + .dst(new ConnectPoint(deviceId("of:bar"), portNumber(2)))
415 + .type(Link.Type.INDIRECT).build();
416 + }
417 +
418 + @Test
419 + public void testAddLink() throws Exception {
420 + Link link = createLink();
421 + LinkEvent event = new LinkEvent(LINK_ADDED, link, 123L);
422 + validateEvent(event, LINK_ADDED, link, 123L);
423 + }
424 +
425 + @Test
426 + public void testUpdateLink() throws Exception {
427 + Link link = createLink();
428 + LinkEvent event = new LinkEvent(LINK_UPDATED, link, 123L);
429 + validateEvent(event, LINK_UPDATED, link, 123L);
430 + }
431 +
432 + @Test
433 + public void testRemoveLink() throws Exception {
434 + Link link = createLink();
435 + LinkEvent event = new LinkEvent(LINK_ADDED, link, 123L);
436 + validateEvent(event, LINK_ADDED, link, 123L);
437 + LinkEvent event1 = new LinkEvent(LINK_REMOVED, link, 123L);
438 + validateEvent(event1, LINK_REMOVED, link, 123L);
439 + }
440 +
441 + private class TestLinkListener implements LinkListener {
442 +
443 + @Override
444 + public void event(LinkEvent event) {
445 + mqService.publish(event);
446 + }
447 +
448 + }
449 +
450 +}
...@@ -33,6 +33,8 @@ osgi_feature_group( ...@@ -33,6 +33,8 @@ osgi_feature_group(
33 ':org.apache.karaf.features.core', 33 ':org.apache.karaf.features.core',
34 ':org.apache.karaf.system.core', 34 ':org.apache.karaf.system.core',
35 ':jsr305', 35 ':jsr305',
36 + ':amqp-client',
37 + ':gson',
36 ], 38 ],
37 ) 39 )
38 40
...@@ -1102,3 +1104,21 @@ remote_jar ( ...@@ -1102,3 +1104,21 @@ remote_jar (
1102 visibility = [ 'PUBLIC' ], 1104 visibility = [ 'PUBLIC' ],
1103 ) 1105 )
1104 1106
1107 +remote_jar (
1108 + name = 'amqp-client',
1109 + out = 'amqp-client-3.6.1.jar',
1110 + url = 'mvn:com.rabbitmq:amqp-client:jar:3.6.1',
1111 + sha1 = '089be4acfa8a0fa48a775a82d20632f90aecf10b',
1112 + maven_coords = 'com.rabbitmq:amqp-client:3.6.1',
1113 + visibility = [ 'PUBLIC' ],
1114 +)
1115 +
1116 +remote_jar (
1117 + name = 'gson',
1118 + out = 'gson-2.6.2.jar',
1119 + url = 'mvn:com.google.code.gson:gson:jar:2.6.2',
1120 + sha1 = 'f1bc476cc167b18e66c297df599b2377131a8947',
1121 + maven_coords = 'com.google.code.gson:gson:2.6.2',
1122 + visibility = [ 'PUBLIC' ],
1123 +)
1124 +
......