Shravan Ambati
Committed by Gerrit Code Review

CodeReview - Initial Commit for Kafka Integration Application

1. Partial REST API implementation
2. Partial Event Manager backend implementation

Change-Id: Ieaf703f7a3f6e296aea8ffcf155c7a1b603236ca
Showing 20 changed files with 1109 additions and 0 deletions
1 +<?sxml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016 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 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18 + <modelVersion>4.0.0</modelVersion>
19 +
20 + <parent>
21 + <groupId>org.onosproject</groupId>
22 + <artifactId>onos-apps</artifactId>
23 + <version>1.6.0-SNAPSHOT</version>
24 + <relativePath>../pom.xml</relativePath>
25 + </parent>
26 +
27 + <artifactId>onos-app-kafka</artifactId>
28 + <packaging>bundle</packaging>
29 +
30 + <description>
31 + ONOS Kafka Integration Application.
32 + This will export ONOS events to an external Kafka Server
33 + </description>
34 + <url>http://onosproject.org</url>
35 +
36 + <properties>
37 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
38 + <onos.version>1.6.0-SNAPSHOT</onos.version>
39 + <onos.app.name>org.onosproject.kafkaintegration</onos.app.name>
40 + <onos.app.title>Kafka Integration Application</onos.app.title>
41 + <onos.app.origin>Calix, Inc.</onos.app.origin>
42 + <web.context>/onos/kafka</web.context>
43 + <api.version>1.0.0</api.version>
44 + <api.package>org.onosproject.kafkaintegration.rest</api.package>
45 + <api.title>Kafka Integration Application REST API</api.title>
46 + <api.description>
47 + APIs for subscribing to Events generated by onos
48 + </api.description>
49 + <onos.app.category>Utility</onos.app.category>
50 + <onos.app.url>https://wiki.onosproject.org/display/ONOS/Kafka+Integration</onos.app.url>
51 + <onos.app.readme>Export onos events to a Northbound Kafka server</onos.app.readme>
52 + </properties>
53 +
54 + <dependencies>
55 + <dependency>
56 + <groupId>org.onosproject</groupId>
57 + <artifactId>onos-api</artifactId>
58 + <version>${onos.version}</version>
59 + </dependency>
60 +
61 + <dependency>
62 + <groupId>org.onosproject</groupId>
63 + <artifactId>onlab-osgi</artifactId>
64 + <version>${onos.version}</version>
65 + </dependency>
66 +
67 + <dependency>
68 + <groupId>org.onosproject</groupId>
69 + <artifactId>onos-rest</artifactId>
70 + <version>${onos.version}</version>
71 + </dependency>
72 +
73 + <dependency>
74 + <groupId>junit</groupId>
75 + <artifactId>junit</artifactId>
76 + <version>4.12</version>
77 + <scope>test</scope>
78 + </dependency>
79 +
80 + <dependency>
81 + <groupId>org.onosproject</groupId>
82 + <artifactId>onos-api</artifactId>
83 + <version>${onos.version}</version>
84 + <scope>test</scope>
85 + <classifier>tests</classifier>
86 + </dependency>
87 +
88 + <dependency>
89 + <groupId>javax.ws.rs</groupId>
90 + <artifactId>javax.ws.rs-api</artifactId>
91 + <version>2.0.1</version>
92 + </dependency>
93 +
94 + <dependency>
95 + <groupId>com.google.protobuf</groupId>
96 + <artifactId>protobuf-java</artifactId>
97 + <version>2.5.0</version>
98 + </dependency>
99 +
100 + <dependency>
101 + <groupId>org.codehaus.jackson</groupId>
102 + <artifactId>jackson-core-asl</artifactId>
103 + <version>1.9.13</version>
104 + </dependency>
105 +
106 + <dependency>
107 + <groupId>org.codehaus.jackson</groupId>
108 + <artifactId>jackson-mapper-asl</artifactId>
109 + <version>1.9.13</version>
110 + </dependency>
111 +
112 + <dependency>
113 + <groupId>org.glassfish.jersey.containers</groupId>
114 + <artifactId>jersey-container-servlet</artifactId>
115 + <version>2.22.2</version>
116 + </dependency>
117 +
118 + <dependency>
119 + <groupId>com.fasterxml.jackson.core</groupId>
120 + <artifactId>jackson-annotations</artifactId>
121 + <version>2.6.4</version>
122 + </dependency>
123 +
124 + <dependency>
125 + <groupId>org.onosproject</groupId>
126 + <artifactId>onos-core-serializers</artifactId>
127 + <version>${onos.version}</version>
128 + </dependency>
129 +
130 + <dependency>
131 + <groupId>org.apache.felix</groupId>
132 + <artifactId>org.apache.felix.scr.annotations</artifactId>
133 + <version>1.9.12</version>
134 + <scope>provided</scope>
135 + </dependency>
136 + </dependencies>
137 +
138 + <build>
139 + <plugins>
140 + <plugin>
141 + <groupId>org.apache.felix</groupId>
142 + <artifactId>maven-bundle-plugin</artifactId>
143 + <version>3.0.1</version>
144 + <extensions>true</extensions>
145 + <configuration>
146 + <instructions>
147 + <Bundle-SymbolicName>
148 + ${project.groupId}.${project.artifactId}
149 + </Bundle-SymbolicName>
150 + <_wab>src/main/webapp/</_wab>
151 + <Include-Resource>
152 + WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
153 + {maven-resources}
154 + </Include-Resource>
155 + <Import-Package>
156 + org.slf4j,
157 + org.osgi.framework,
158 + javax.ws.rs,
159 + javax.ws.rs.core,
160 + org.glassfish.jersey.servlet,
161 + com.fasterxml.jackson.databind,
162 + com.fasterxml.jackson.databind.node,
163 + com.fasterxml.jackson.core,
164 + org.onlab.packet.*,
165 + org.onosproject.*,
166 + com.google.common.*
167 + </Import-Package>
168 + <Web-ContextPath>${web.context}</Web-ContextPath>
169 + </instructions>
170 + </configuration>
171 + </plugin>
172 + <plugin>
173 + <groupId>org.apache.maven.plugins</groupId>
174 + <artifactId>maven-compiler-plugin</artifactId>
175 + <version>2.5.1</version>
176 + <configuration>
177 + <source>1.8</source>
178 + <target>1.8</target>
179 + </configuration>
180 + </plugin>
181 + <plugin>
182 + <groupId>org.apache.felix</groupId>
183 + <artifactId>maven-scr-plugin</artifactId>
184 + <version>1.21.0</version>
185 + <executions>
186 + <execution>
187 + <id>generate-scr-srcdescriptor</id>
188 + <goals>
189 + <goal>scr</goal>
190 + </goals>
191 + </execution>
192 + </executions>
193 + <configuration>
194 + <supportedProjectTypes>
195 + <supportedProjectType>bundle</supportedProjectType>
196 + <supportedProjectType>war</supportedProjectType>
197 + </supportedProjectTypes>
198 + </configuration>
199 + </plugin>
200 + <plugin>
201 + <groupId>org.onosproject</groupId>
202 + <artifactId>onos-maven-plugin</artifactId>
203 + <version>1.9</version>
204 + <executions>
205 + <execution>
206 + <id>cfg</id>
207 + <phase>generate-resources</phase>
208 + <goals>
209 + <goal>cfg</goal>
210 + </goals>
211 + </execution>
212 + <execution>
213 + <id>swagger</id>
214 + <phase>generate-sources</phase>
215 + <goals>
216 + <goal>swagger</goal>
217 + </goals>
218 + </execution>
219 + <execution>
220 + <id>app</id>
221 + <phase>package</phase>
222 + <goals>
223 + <goal>app</goal>
224 + </goals>
225 + </execution>
226 + </executions>
227 + </plugin>
228 + </plugins>
229 + </build>
230 +
231 +</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.kafkaintegration;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import java.util.Map;
21 +import java.util.UUID;
22 +
23 +import org.apache.felix.scr.annotations.Activate;
24 +import org.apache.felix.scr.annotations.Component;
25 +import org.apache.felix.scr.annotations.Deactivate;
26 +import org.apache.felix.scr.annotations.Reference;
27 +import org.apache.felix.scr.annotations.ReferenceCardinality;
28 +import org.apache.felix.scr.annotations.Service;
29 +import org.onosproject.core.ApplicationId;
30 +import org.onosproject.core.CoreService;
31 +import org.onosproject.kafkaintegration.api.EventExporterService;
32 +import org.onosproject.kafkaintegration.api.dto.EventSubscriber;
33 +import org.onosproject.kafkaintegration.api.dto.EventSubscriberGroupId;
34 +import org.onosproject.kafkaintegration.errors.InvalidApplicationException;
35 +import org.onosproject.kafkaintegration.errors.InvalidGroupIdException;
36 +import org.onosproject.kafkaintegration.errors.UnsupportedEventException;
37 +import org.onosproject.net.device.DeviceService;
38 +import org.onosproject.net.link.LinkService;
39 +import org.onosproject.store.serializers.KryoNamespaces;
40 +import org.onosproject.store.service.Serializer;
41 +import org.onosproject.store.service.StorageService;
42 +import org.slf4j.Logger;
43 +import org.slf4j.LoggerFactory;
44 +
45 +/**
46 + * Implementation of Event Exporter Service.
47 + *
48 + */
49 +@Component(immediate = true)
50 +@Service
51 +public class EventExporterManager implements EventExporterService {
52 +
53 + private final Logger log = LoggerFactory.getLogger(getClass());
54 +
55 + // Stores the currently registered applications for event export service.
56 + // Map of Appname to groupId
57 + private Map<ApplicationId, EventSubscriberGroupId> registeredApps;
58 +
59 + private static final String REGISTERED_APPS = "registered-applications";
60 +
61 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 + protected DeviceService deviceService;
63 +
64 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 + protected LinkService linkService;
66 +
67 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 + protected CoreService coreService;
69 +
70 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 + protected StorageService storageService;
72 +
73 + private static final String NOT_YET_SUPPORTED = "Not yet supported.";
74 +
75 + private ApplicationId appId;
76 +
77 + @Activate
78 + protected void activate() {
79 + appId = coreService
80 + .registerApplication("org.onosproject.kafkaintegration");
81 +
82 + registeredApps = storageService
83 + .<ApplicationId, EventSubscriberGroupId>consistentMapBuilder()
84 + .withName(REGISTERED_APPS)
85 + .withSerializer(Serializer.using(KryoNamespaces.API,
86 + EventSubscriberGroupId.class,
87 + UUID.class))
88 + .build().asJavaMap();
89 +
90 + log.info("Started");
91 + }
92 +
93 + @Deactivate
94 + protected void deactivate() {
95 + log.info("Stopped");
96 + }
97 +
98 + @Override
99 + public EventSubscriberGroupId registerListener(String appName) {
100 +
101 + // TODO: Remove it once ONOS provides a mechanism for external apps
102 + // to register with the core service. See Jira - 4409
103 + ApplicationId externalAppId = coreService.registerApplication(appName);
104 +
105 + return registeredApps.computeIfAbsent(externalAppId,
106 + (key) -> new EventSubscriberGroupId(UUID
107 + .randomUUID()));
108 +
109 + }
110 +
111 + @Override
112 + public void unregisterListener(String appName) {
113 + ApplicationId externalAppId =
114 + checkNotNull(coreService.getAppId(appName));
115 + registeredApps.remove(externalAppId);
116 + }
117 +
118 + @Override
119 + public void subscribe(EventSubscriber subscriber)
120 + throws UnsupportedEventException, InvalidGroupIdException,
121 + InvalidApplicationException {
122 +
123 + throw new UnsupportedOperationException(NOT_YET_SUPPORTED);
124 + }
125 +
126 + @Override
127 + public void unsubscribe(EventSubscriber subscriber)
128 + throws InvalidGroupIdException, InvalidApplicationException {
129 +
130 + throw new UnsupportedOperationException(NOT_YET_SUPPORTED);
131 + }
132 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.api;
16 +
17 +import org.onosproject.kafkaintegration.api.dto.EventSubscriber;
18 +import org.onosproject.kafkaintegration.api.dto.EventSubscriberGroupId;
19 +import org.onosproject.kafkaintegration.errors.InvalidApplicationException;
20 +import org.onosproject.kafkaintegration.errors.InvalidGroupIdException;
21 +import org.onosproject.kafkaintegration.errors.UnsupportedEventException;
22 +
23 +/**
24 + * APIs for subscribing to Onos Event Messages.
25 + */
26 +public interface EventExporterService {
27 +
28 + /**
29 + * Registers the external application to receive events generated in ONOS.
30 + *
31 + * @param appName Application Name
32 + * @return unique consumer group identifier
33 + */
34 + EventSubscriberGroupId registerListener(String appName);
35 +
36 + /**
37 + * Removes the Registered Listener.
38 + *
39 + * @param appName Application Name
40 + */
41 + void unregisterListener(String appName);
42 +
43 + /**
44 + * Allows registered listener to subscribe for a specific event type.
45 + *
46 + * @param subscriber Subscription data containing the event type
47 + * @throws UnsupportedEventException
48 + * @throws InvalidGroupIdException
49 + * @throws InvalidApplicationException
50 + */
51 + void subscribe(EventSubscriber subscriber)
52 + throws UnsupportedEventException, InvalidGroupIdException,
53 + InvalidApplicationException;
54 +
55 + /**
56 + * Allows the registered listener to unsubscribe for a specific event.
57 + *
58 + * @param subscriber Subscription data containing the event type
59 + * @throws InvalidGroupIdException
60 + * @throws InvalidApplicationException
61 + */
62 + void unsubscribe(EventSubscriber subscriber)
63 + throws InvalidGroupIdException, InvalidApplicationException;
64 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.api.dto;
16 +
17 +import static com.google.common.base.MoreObjects.toStringHelper;
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import java.util.Objects;
21 +
22 +import org.onosproject.kafkaintegration.api.dto.OnosEvent.Type;
23 +
24 +/**
25 + * Representation of a subscription to an event type.
26 + *
27 + */
28 +public final class EventSubscriber {
29 + private final String appName;
30 + private final EventSubscriberGroupId subscriberGroupId;
31 + private final Type eventType;
32 +
33 + /**
34 + * Creates a new Event Subscriber.
35 + *
36 + * @param name Application Name
37 + * @param groupId Subscriber group id of the application
38 + * @param eventType ONOS event type
39 + */
40 + public EventSubscriber(String name, EventSubscriberGroupId groupId,
41 + Type eventType) {
42 + this.appName = checkNotNull(name);
43 + this.subscriberGroupId = checkNotNull(groupId);
44 + this.eventType = checkNotNull(eventType);
45 + }
46 +
47 + /**
48 + * Returns the Application Name.
49 + *
50 + * @return application name
51 + */
52 + public String appName() {
53 + return appName;
54 + }
55 +
56 + /**
57 + * Returns the Subscriber Group Id.
58 + *
59 + * @return Subscriber Group Id
60 + */
61 + public EventSubscriberGroupId subscriberGroupId() {
62 + return subscriberGroupId;
63 + }
64 +
65 + /**
66 + * Returns the Event type.
67 + *
68 + * @return ONOS Event Type
69 + */
70 + public Type eventType() {
71 + return eventType;
72 + }
73 +
74 + @Override
75 + public int hashCode() {
76 + return Objects.hash(appName, subscriberGroupId, eventType);
77 + }
78 +
79 + @Override
80 + public boolean equals(Object o) {
81 + if (o instanceof EventSubscriber) {
82 + EventSubscriber sub = (EventSubscriber) o;
83 + if (sub.appName.equals(appName)
84 + && sub.subscriberGroupId.equals(subscriberGroupId)
85 + && sub.eventType.equals(eventType)) {
86 + return true;
87 + }
88 + }
89 +
90 + return false;
91 + }
92 +
93 + @Override
94 + public String toString() {
95 + return toStringHelper(this).add("appName", appName)
96 + .addValue(subscriberGroupId.toString())
97 + .add("eventType", eventType).toString();
98 + }
99 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.api.dto;
16 +
17 +import static com.google.common.base.MoreObjects.toStringHelper;
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import java.util.Objects;
21 +import java.util.UUID;
22 +
23 +/**
24 + * Wrapper Object for storing the consumer group id. Group ids are used by
25 + * external applications when consuming events from Kafka server.
26 + *
27 + */
28 +public final class EventSubscriberGroupId {
29 + private final UUID id;
30 +
31 + /**
32 + * Creates a new Subscriber Group Id.
33 + *
34 + * @param uuid representing the group id.
35 + */
36 + public EventSubscriberGroupId(UUID uuid) {
37 + id = checkNotNull(uuid);
38 + }
39 +
40 + /**
41 + * Returns the Group Id of the subscriber.
42 + *
43 + * @return uuid representing the group id.
44 + */
45 + public UUID getId() {
46 + return id;
47 + }
48 +
49 + @Override
50 + public boolean equals(Object o) {
51 + if (o instanceof EventSubscriberGroupId) {
52 + EventSubscriberGroupId sub = (EventSubscriberGroupId) o;
53 + if (sub.id.equals(id)) {
54 + return true;
55 + }
56 + }
57 +
58 + return false;
59 + }
60 +
61 + @Override
62 + public int hashCode() {
63 + return Objects.hash(id);
64 + }
65 +
66 + @Override
67 + public String toString() {
68 + return toStringHelper(this).add("subscriberGroupId", id).toString();
69 + }
70 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.api.dto;
16 +
17 +import org.onosproject.event.AbstractEvent;
18 +
19 +import com.google.protobuf.GeneratedMessage;
20 +
21 +/**
22 + * Represents the converted Onos Event data into GPB format.
23 + *
24 + */
25 +public class OnosEvent extends AbstractEvent<OnosEvent.Type, GeneratedMessage> {
26 +
27 + /**
28 + * Creates a new Onos Event.
29 + *
30 + * @param type The Type of Onos Event
31 + * @param subject Protobuf message corresponding to the Onos Event
32 + */
33 + public OnosEvent(Type type, GeneratedMessage subject) {
34 + super(type, subject);
35 + }
36 +
37 + /**
38 + * List of Event Types supported.
39 + */
40 + public enum Type {
41 + DEVICE, LINK;
42 + }
43 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory Licensed under the Apache
3 + * License, Version 2.0 (the "License"); you may not use this file except in
4 + * compliance with the License. You may obtain a copy of the License at
5 + *
6 + * http://www.apache.org/licenses/LICENSE-2.0
7 + *
8 + * Unless required by applicable law or agreed to in writing, software
9 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 + * License for the specific language governing permissions and limitations under
12 + * the License.
13 + */
14 +
15 +/**
16 + * Immutable Data Transfer Objects.
17 + */
18 +package org.onosproject.kafkaintegration.api.dto;
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory Licensed under the Apache
3 + * License, Version 2.0 (the "License"); you may not use this file except in
4 + * compliance with the License. You may obtain a copy of the License at
5 + *
6 + * http://www.apache.org/licenses/LICENSE-2.0
7 + *
8 + * Unless required by applicable law or agreed to in writing, software
9 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 + * License for the specific language governing permissions and limitations under
12 + * the License.
13 + */
14 +
15 +/**
16 + * API definitions for the Application.
17 + */
18 +package org.onosproject.kafkaintegration.api;
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.errors;
16 +
17 +/**
18 + * Represents that an unregistered application trying to subscribe to ONOS
19 + * events.
20 + *
21 + */
22 +public class InvalidApplicationException extends RuntimeException {
23 +
24 + private static final long serialVersionUID = 1L;
25 +
26 + public InvalidApplicationException(String message) {
27 + super(message);
28 + }
29 +
30 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.errors;
16 +
17 +/**
18 + * The groupId given by the external application is already in use by another
19 + * application or groupId does not exist.
20 + *
21 + */
22 +public class InvalidGroupIdException extends RuntimeException {
23 +
24 + private static final long serialVersionUID = 1L;
25 +
26 + public InvalidGroupIdException(String message) {
27 + super(message);
28 + }
29 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.errors;
16 +
17 +/**
18 + * Event Type requested for subscription is not supported/available for export.
19 + *
20 + */
21 +public class UnsupportedEventException extends RuntimeException {
22 +
23 + private static final long serialVersionUID = 1L;
24 +
25 + public UnsupportedEventException(String message) {
26 + super(message);
27 + }
28 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory Licensed under the Apache
3 + * License, Version 2.0 (the "License"); you may not use this file except in
4 + * compliance with the License. You may obtain a copy of the License at
5 + *
6 + * http://www.apache.org/licenses/LICENSE-2.0
7 + *
8 + * Unless required by applicable law or agreed to in writing, software
9 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 + * License for the specific language governing permissions and limitations under
12 + * the License.
13 + */
14 +
15 +/**
16 + * Application specific Exception classes.
17 + */
18 +package org.onosproject.kafkaintegration.errors;
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory Licensed under the Apache
3 + * License, Version 2.0 (the "License"); you may not use this file except in
4 + * compliance with the License. You may obtain a copy of the License at
5 + *
6 + * http://www.apache.org/licenses/LICENSE-2.0
7 + *
8 + * Unless required by applicable law or agreed to in writing, software
9 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 + * License for the specific language governing permissions and limitations under
12 + * the License.
13 + */
14 +
15 +/**
16 + * API implementation classes.
17 + */
18 +package org.onosproject.kafkaintegration;
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.rest;
16 +
17 +import static com.google.common.base.Preconditions.checkNotNull;
18 +import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
19 +
20 +import java.io.IOException;
21 +import java.io.InputStream;
22 +
23 +import javax.ws.rs.Consumes;
24 +import javax.ws.rs.DELETE;
25 +import javax.ws.rs.POST;
26 +import javax.ws.rs.Path;
27 +import javax.ws.rs.Produces;
28 +import javax.ws.rs.core.MediaType;
29 +import javax.ws.rs.core.Response;
30 +
31 +import org.onosproject.codec.JsonCodec;
32 +import org.onosproject.kafkaintegration.api.EventExporterService;
33 +import org.onosproject.kafkaintegration.api.dto.EventSubscriber;
34 +import org.onosproject.kafkaintegration.api.dto.EventSubscriberGroupId;
35 +import org.onosproject.rest.AbstractWebResource;
36 +import org.slf4j.Logger;
37 +import org.slf4j.LoggerFactory;
38 +
39 +import com.fasterxml.jackson.databind.ObjectMapper;
40 +import com.fasterxml.jackson.databind.node.ObjectNode;
41 +
42 +/**
43 + * Rest Interfaces for subscribing/unsubscribing to event notifications.
44 + */
45 +@Path("kafkaService")
46 +public class EventExporterWebResource extends AbstractWebResource {
47 +
48 + private final Logger log = LoggerFactory.getLogger(getClass());
49 + public static final String JSON_NOT_NULL = "Registration Data cannot be empty";
50 + public static final String REGISTRATION_SUCCESSFUL = "Registered Listener successfully";
51 + public static final String DEREGISTRATION_SUCCESSFUL = "De-Registered Listener successfully";
52 + public static final String EVENT_SUBSCRIPTION_SUCCESSFUL = "Event Registration successfull";
53 + public static final String EVENT_SUBSCRIPTION_REMOVED = "Event De-Registration successfull";
54 +
55 + /**
56 + * Registers a listener for Onos Events.
57 + *
58 + * @param appName The application trying to register
59 + * @return 200 OK with UUID string which should be used as Kafka Consumer
60 + * Group Id
61 + * @onos.rsModel KafkaRegistration
62 + */
63 + @POST
64 + @Produces(MediaType.APPLICATION_JSON)
65 + @Consumes(MediaType.APPLICATION_JSON)
66 + @Path("register")
67 + public Response registerKafkaListener(String appName) {
68 +
69 + EventExporterService service = get(EventExporterService.class);
70 +
71 + EventSubscriberGroupId groupId = service.registerListener(appName);
72 +
73 + log.info("Registered app {}", appName);
74 +
75 + // TODO: Should also return Kafka server information.
76 + // Will glue this in when we have the config and Kafka modules ready
77 + return ok(groupId.getId().toString()).build();
78 + }
79 +
80 + /**
81 + * Unregisters a listener for Onos Events.
82 + *
83 + * @param appName The application trying to unregister
84 + * @return 200 OK
85 + * @onos.rsModel KafkaRegistration
86 + */
87 + @DELETE
88 + @Produces(MediaType.APPLICATION_JSON)
89 + @Consumes(MediaType.APPLICATION_JSON)
90 + @Path("unregister")
91 + public Response removeKafkaListener(String appName) {
92 + EventExporterService service = get(EventExporterService.class);
93 +
94 + service.unregisterListener(appName);
95 +
96 + return ok(DEREGISTRATION_SUCCESSFUL).build();
97 + }
98 +
99 + /**
100 + * Creates subscription to a specific Onos event.
101 + *
102 + * @param input Subscription Data in Json format
103 + * @return 200 OK if successful or 400 BAD REQUEST
104 + * @onos.rsModel KafkaSubscription
105 + */
106 + @POST
107 + @Produces(MediaType.APPLICATION_JSON)
108 + @Path("subscribe")
109 + public Response subscribe(InputStream input) {
110 +
111 + EventExporterService service = get(EventExporterService.class);
112 +
113 + try {
114 + EventSubscriber sub = parseSubscriptionData(input);
115 + service.subscribe(sub);
116 + } catch (Exception e) {
117 + log.error(e.getMessage());
118 + return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
119 + }
120 +
121 + return ok(EVENT_SUBSCRIPTION_SUCCESSFUL).build();
122 + }
123 +
124 + /**
125 + * Parses Json Subscription Data from the external application.
126 + *
127 + * @param node node within the parsed json tree.
128 + * @return parsed DTO object
129 + * @throws IOException
130 + */
131 + private EventSubscriber parseSubscriptionData(InputStream input)
132 + throws IOException {
133 +
134 + ObjectMapper mapper = new ObjectMapper();
135 + ObjectNode node = (ObjectNode) mapper.readTree(input);
136 +
137 + checkNotNull(node, JSON_NOT_NULL);
138 +
139 + JsonCodec<EventSubscriber> codec = codec(EventSubscriber.class);
140 + return codec.decode(node, this);
141 + }
142 +
143 + /**
144 + * Deletes subscription from a specific Onos event.
145 + *
146 + * @param input data in json format
147 + * @return 200 OK if successful or 400 BAD REQUEST
148 + * @onos.rsModel KafkaSubscription
149 + */
150 + @DELETE
151 + @Produces(MediaType.APPLICATION_JSON)
152 + @Path("unsubscribe")
153 + public Response unsubscribe(InputStream input) {
154 +
155 + EventExporterService service = get(EventExporterService.class);
156 +
157 + try {
158 + EventSubscriber sub = parseSubscriptionData(input);
159 + service.subscribe(sub);
160 + } catch (Exception e) {
161 + log.error(e.getMessage());
162 + return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
163 + }
164 +
165 + return ok(EVENT_SUBSCRIPTION_REMOVED).build();
166 + }
167 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory
3 + * Licensed under the Apache License, Version 2.0 (the "License");
4 + * you may not use this file except in compliance with the License.
5 + * You may obtain a copy of the License at
6 +
7 + * http://www.apache.org/licenses/LICENSE-2.0
8 +
9 + * Unless required by applicable law or agreed to in writing, software
10 + * distributed under the License is distributed on an "AS IS" BASIS,
11 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 + * See the License for the specific language governing permissions and
13 + * limitations under the License.
14 + */
15 +package org.onosproject.kafkaintegration.rest;
16 +
17 +import static com.google.common.base.Preconditions.checkNotNull;
18 +
19 +import java.util.UUID;
20 +
21 +import org.onosproject.codec.CodecContext;
22 +import org.onosproject.codec.JsonCodec;
23 +import org.onosproject.kafkaintegration.api.dto.EventSubscriber;
24 +import org.onosproject.kafkaintegration.api.dto.EventSubscriberGroupId;
25 +import org.onosproject.kafkaintegration.api.dto.OnosEvent.Type;
26 +
27 +import com.fasterxml.jackson.databind.node.ObjectNode;
28 +
29 +/**
30 + * Codec for encoding/decoding a Subscriber object to/from JSON.
31 + *
32 + */
33 +public final class SubscriberCodec extends JsonCodec<EventSubscriber> {
34 +
35 + // JSON field names
36 + private static final String NAME = "appName";
37 + private static final String GROUP_ID = "groupId";
38 + private static final String EVENT_TYPE = "eventType";
39 +
40 + @Override
41 + public ObjectNode encode(EventSubscriber data, CodecContext context) {
42 + checkNotNull(data, "Subscriber cannot be null");
43 + return context.mapper().createObjectNode().put(NAME, data.appName())
44 + .put(GROUP_ID, data.subscriberGroupId().getId().toString())
45 + .put(EVENT_TYPE, data.eventType().toString());
46 + }
47 +
48 + @Override
49 + public EventSubscriber decode(ObjectNode json, CodecContext context) {
50 + String name = json.path(NAME).asText();
51 + String groupId = json.path(GROUP_ID).asText();
52 + EventSubscriberGroupId subscriberGroupId = new EventSubscriberGroupId(UUID
53 + .fromString(groupId));
54 + String eventType = json.path(EVENT_TYPE).asText();
55 +
56 + return new EventSubscriber(name, subscriberGroupId,
57 + Type.valueOf(eventType));
58 + }
59 +}
1 +/**
2 + * Copyright 2016-present Open Networking Laboratory Licensed under the Apache
3 + * License, Version 2.0 (the "License"); you may not use this file except in
4 + * compliance with the License. You may obtain a copy of the License at
5 + *
6 + * http://www.apache.org/licenses/LICENSE-2.0
7 + *
8 + * Unless required by applicable law or agreed to in writing, software
9 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 + * License for the specific language governing permissions and limitations under
12 + * the License.
13 + */
14 +
15 +/**
16 + * REST API Definitions.
17 + */
18 +package org.onosproject.kafkaintegration.rest;
1 +{
2 + "type": "string",
3 + "title": "KafkaRegistration",
4 + "example": "forwardingApp"
5 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "type": "object",
3 + "title": "KafkaSubscription",
4 + "required": [
5 + "appName",
6 + "groupId",
7 + "eventType"
8 + ],
9 + "properties": {
10 + "appName": {
11 + "type": "string",
12 + "example": "forwardingApp"
13 + },
14 + "groupId": {
15 + "type": "string",
16 + "example": "18285435-2c62-4684-96dd-fb03b7cd0c83"
17 + },
18 + "eventType": {
19 + "type": "string",
20 + "example": "DEVICE"
21 + }
22 + }
23 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016 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 +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
18 + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 + id="ONOS" version="2.5">
21 + <display-name>Event Exporter REST API</display-name>
22 +
23 + <servlet>
24 + <servlet-name>JAX-RS Service</servlet-name>
25 + <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
26 + <init-param>
27 + <param-name>jersey.config.server.provider.classnames</param-name>
28 + <param-value>org.onosproject.kafkaintegration.rest.EventExporterWebResource</param-value>
29 + </init-param>
30 + <load-on-startup>10</load-on-startup>
31 + </servlet>
32 +
33 + <servlet-mapping>
34 + <servlet-name>JAX-RS Service</servlet-name>
35 + <url-pattern>/*</url-pattern>
36 + </servlet-mapping>
37 +
38 +</web-app>
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
46 <module>test</module> 46 <module>test</module>
47 <module>segmentrouting</module> 47 <module>segmentrouting</module>
48 <module>xos-integration</module> 48 <module>xos-integration</module>
49 + <module>kafka-integration</module>
49 <module>pcep-api</module> 50 <module>pcep-api</module>
50 <module>iptopology-api</module> 51 <module>iptopology-api</module>
51 <module>pce</module> 52 <module>pce</module>
......