package com.twasyl.slideshowfx.server.service; import com.twasyl.slideshowfx.server.SlideshowFXServer; import io.vertx.core.AbstractVerticle; import io.vertx.core.Handler; import io.vertx.core.buffer.Buffer; import io.vertx.core.eventbus.Message; import io.vertx.core.eventbus.MessageConsumer; import io.vertx.core.json.JsonObject; import java.util.HashMap; import java.util.Map; /** * This class represents the base class for creating a SlideshowFX service. * * @author Thierry Wasylczenko * @version 1.0 * @since SlideshowFX 1.0 */ public class AbstractSlideshowFXService extends AbstractVerticle implements ISlideshowFXServices { public static final String JSON_KEY_BROADCAST_MESSAGE_TYPE = "type"; public static final String JSON_KEY_SERVICE = "service"; public static final String JSON_KEY_DATA = "data"; public static final String JSON_KEY_CODE = "code"; public static final String JSON_KEY_CONTENT = "content"; public static final String JSON_KEY_ORIGIN = "origin"; public static final String JSON_KEY_MESSAGE = "message"; public static final String JSON_KEY_MESSAGE_ID = "id"; public static final String JSON_KEY_MESSAGE_STATUS = "status"; public static final String JSON_KEY_MESSAGE_ACTION = "action"; public static final String JSON_KEY_FIELDS = "fields"; public static final String JSON_KEY_FIELD_STATUS = "status"; public static final String JSON_KEY_FIELD_ACTION = "action"; private Map<String, MessageConsumer> messageConsumers = new HashMap<>(); /** * Get a {@link MessageConsumer} identified by its endpoint. * @param endpoint The endpoint to access the {@link MessageConsumer}. * @return The {@link MessageConsumer} identified by its endpoint or {@code null} if it is not found. * @throws NullPointerException if the {@code endpoint} is null. * @throws IllegalArgumentException If the {@code endpoint} is empty */ public MessageConsumer getMessageConsumer(final String endpoint) { if(endpoint == null) throw new NullPointerException("The endpoint can not be null"); if(endpoint.trim().isEmpty()) throw new NullPointerException("The endpoint can not be empty"); return this.messageConsumers.get(endpoint.trim()); } /** * Register the given {@code handler} with the given {@code endpoint} to this Vert.x EventBus instance. * @param endpoint The endpoint for accessing the consumer. * @param handler The handler to register. * @return This instance of service. * @throws NullPointerException If the endpoint or the handler is {@code null}. * @throws IllegalArgumentException If the endpoint is empty */ public AbstractSlideshowFXService register(final String endpoint, final Handler<Message<JsonObject>> handler) { if(endpoint == null) throw new NullPointerException("The endpoint can not be null"); if(endpoint.trim().isEmpty()) throw new NullPointerException("The endpoint can not be empty"); if(handler == null) throw new NullPointerException("The handler can not be null"); final MessageConsumer consumer = this.vertx.eventBus().consumer(endpoint, handler); this.messageConsumers.put(endpoint, consumer); return this; } /** * Unregister all handler of messages in the EventBus. */ public void unregisterAll() { this.messageConsumers.forEach((endpoint, consumer) -> consumer.unregister()); } /** * Build a response to be send when a service is called. The response is a JSON object with the structure expected * by the {@link com.twasyl.slideshowfx.server.SlideshowFXServer#callService(String)} method. * @param serviceEndpoint The endpoint of the service producing the response. * @param responseCode The response code of the service's call. * @param responseContent The content of the response. * @return The JSON structure that can be send by a service caller. */ protected JsonObject buildResponse(final String serviceEndpoint, final int responseCode, final Object responseContent) { final JsonObject response = new JsonObject() .put(JSON_KEY_SERVICE, serviceEndpoint) .put(JSON_KEY_CODE, responseCode) .put(JSON_KEY_CONTENT, responseContent); return response; } /** * <p>Send a given response to all WebSocket clients excluding the origin. If the given origin is {@code null} * or empty, no exclusion will be performed.</p> * * @param response The response to send. * @param excludeOrigin The origin to exclude, if needed. */ protected void sendResponseToWebSocketClients(final JsonObject response, final String excludeOrigin) { SlideshowFXServer.getSingleton().getWebSockets().forEach(socket -> { if(!socket.textHandlerID().equals(excludeOrigin)) { socket.write(Buffer.buffer(response.encode())); } }); } /** * <p>Send a given response to all WebSocket clients.</p> * * @param response The response to send. */ protected void sendResponseToWebSocketClients(final JsonObject response) { this.sendResponseToWebSocketClients(response, null); } }