diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff) |
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java')
-rw-r--r-- | framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java new file mode 100644 index 00000000..9b9a406c --- /dev/null +++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java @@ -0,0 +1,207 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.ui; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onlab.osgi.ServiceDirectory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Abstraction of an entity capable of processing JSON messages from the user + * interface client. + * <p> + * The message structure is: + * </p> + * <pre> + * { + * "type": "<em>event-type</em>", + * "payload": { + * <em>arbitrary JSON object structure</em> + * } + * } + * </pre> + * On {@link #init initialization} the handler will create and cache + * {@link RequestHandler} instances, each of which are bound to a particular + * <em>event-type</em>. On {@link #process arrival} of a new message, + * the <em>event-type</em> is determined, and the message dispatched to the + * corresponding <em>RequestHandler</em>'s + * {@link RequestHandler#process process} method. + */ +public abstract class UiMessageHandler { + + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Map<String, RequestHandler> handlerMap = new HashMap<>(); + private final ObjectMapper mapper = new ObjectMapper(); + + private UiConnection connection; + private ServiceDirectory directory; + + + /** + * Subclasses must create and return the collection of request handlers + * for the message types they handle. + * <p> + * Note that request handlers should be stateless. When we are + * {@link #destroy destroyed}, we will simply drop our references to them + * and allow them to be garbage collected. + * + * @return the message handler instances + */ + protected abstract Collection<RequestHandler> createRequestHandlers(); + + /** + * Returns the set of message types which this handler is capable of + * processing. + * + * @return set of message types + */ + public Set<String> messageTypes() { + return Collections.unmodifiableSet(handlerMap.keySet()); + } + + /** + * Processes a JSON message from the user interface client. + * + * @param message JSON message + */ + public void process(ObjectNode message) { + String type = JsonUtils.eventType(message); + ObjectNode payload = JsonUtils.payload(message); + // TODO: remove sid + exec(type, 0, payload); + } + + /** + * Finds the appropriate handler and executes the process method. + * + * @param eventType event type + * @param sid sequence identifier + * @param payload message payload + */ + // TODO: remove sid from signature + void exec(String eventType, long sid, ObjectNode payload) { + RequestHandler requestHandler = handlerMap.get(eventType); + if (requestHandler != null) { + requestHandler.process(sid, payload); + } else { + log.warn("no request handler for event type {}", eventType); + } + } + + /** + * Initializes the handler with the user interface connection and + * service directory context. + * + * @param connection user interface connection + * @param directory service directory + */ + public void init(UiConnection connection, ServiceDirectory directory) { + this.connection = connection; + this.directory = directory; + + Collection<RequestHandler> handlers = createRequestHandlers(); + checkNotNull(handlers, "Handlers cannot be null"); + checkArgument(!handlers.isEmpty(), "Handlers cannot be empty"); + + for (RequestHandler h : handlers) { + h.setParent(this); + handlerMap.put(h.eventType(), h); + } + } + + /** + * Destroys the message handler context. + */ + public void destroy() { + this.connection = null; + this.directory = null; + handlerMap.clear(); + } + + /** + * Returns the user interface connection with which this handler was primed. + * + * @return user interface connection + */ + public UiConnection connection() { + return connection; + } + + /** + * Returns the user interface connection with which this handler was primed. + * + * @return user interface connection + */ + public ServiceDirectory directory() { + return directory; + } + + /** + * Returns implementation of the specified service class. + * + * @param serviceClass service class + * @param <T> type of service + * @return implementation class + * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found + */ + protected <T> T get(Class<T> serviceClass) { + return directory.get(serviceClass); + } + + /** + * Returns a freshly minted object node. + * + * @return new object node + */ + protected ObjectNode objectNode() { + return mapper.createObjectNode(); + } + + /** + * Returns a freshly minted array node. + * + * @return new array node + */ + protected ArrayNode arrayNode() { + return mapper.createArrayNode(); + } + + /** + * Sends the specified data to the client. + * It is expected that the data is in the prescribed JSON format for + * events to the client. + * + * @param data data to be sent + */ + protected synchronized void sendMessage(ObjectNode data) { + UiConnection connection = connection(); + if (connection != null) { + connection.sendMessage(data); + } + } +} |