All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.microcks.minion.async.producer.WebSocketProducerManager Maven / Gradle / Ivy

/*
 * Licensed to Laurent Broudoux (the "Author") under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Author licenses this
 * file to you 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 io.github.microcks.minion.async.producer;

import io.github.microcks.domain.EventMessage;
import io.github.microcks.domain.Header;
import io.github.microcks.minion.async.AsyncMockDefinition;
import io.github.microcks.minion.async.AsyncMockRepository;
import org.jboss.logging.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.Set;

@ApplicationScoped
@RootWebSocketProducerManager
@ServerEndpoint("/api/ws/{service}/{version}/")
/**
 * WebSocket implementation of producer for async event messages.
 * @author laurent
 */
public class WebSocketProducerManager {

   /** Get a JBoss logging logger. */
   private final Logger logger = Logger.getLogger(getClass());

   @Inject
   AsyncMockRepository asyncMockRepository;

   @Inject
   WebSocketSessionRegistry sessionRegistry;

   public WebSocketProducerManager() {
   }

   /**
    * Publish a message on specified channel.
    * @param channel The destination channel for message
    * @param message The message payload
    * @param headers A set of headers if any (maybe null or empty)
    */
   public void publishMessage(String channel, String message, Set
headers) { logger.infof("Publishing on channel {%s}, message: %s ", channel, message); List sessions = sessionRegistry.getSessions(channel); if (sessions != null && !sessions.isEmpty()) { logger.debugf("Sending message to %d WebSocket sessions", sessions.size()); sessions.forEach(s -> { s.getAsyncRemote().sendObject(message, result -> { if (result.getException() != null) { logger.error("Unable to send message: " + result.getException()); } }); }); } } @OnOpen public void onOpen(Session session, @PathParam("service") String service, @PathParam("version") String version) { logger.infof("New WebSocket session opening on service {%s} - {%s}. Checking if mocked...", service, version); // If service or version were encoded with '+' instead of '%20', remove them. if (service.contains("+")) { service = service.replace('+', ' '); } if (version.contains("+")) { version = version.replace('+', ' '); } Set definitions = asyncMockRepository.getMockDefinitionsByServiceAndVersion(service, version); if (definitions != null && !definitions.isEmpty()) { sessionRegistry.putSession(session); } else { try { logger.infof("No mock available on '%s', closing the session", session.getRequestURI().toString()); session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "No mock available on " + session.getRequestURI())); } catch (Exception e) { logger.infof("Caught an exception while rejecting a WebSocket opening on unmanaged '%'", session.getRequestURI().toString()); } } } @OnClose public void onClose(Session session, @PathParam("service") String service, @PathParam("version") String version) { sessionRegistry.removeSession(session); } @OnError public void onError(Session session, @PathParam("service") String service, @PathParam("version") String version, Throwable throwable) { sessionRegistry.removeSession(session); } @OnMessage public void onMessage(String message, @PathParam("service") String service, @PathParam("version") String version) { // Nothing to do here. logger.debug("Received a message on WebSocketProducerManager, nothing to do..."); } /** * Get the Websocket endpoint URI corresponding to a AsyncMockDefinition, sanitizing all parameters. * @param definition The AsyncMockDefinition * @param eventMessage The message to get topic * @return The request URI corresponding to def and message */ public String getRequestURI(AsyncMockDefinition definition, EventMessage eventMessage) { // Produce service name part of topic name. String serviceName = definition.getOwnerService().getName().replace(" ", "+"); // Produce version name part of topic name. String versionName = definition.getOwnerService().getVersion().replace(" ", "+"); // Produce operation name part of topic name. String operationName = definition.getOperation().getName(); if (operationName.startsWith("SUBSCRIBE ") || operationName.startsWith("PUBLISH ")) { operationName = operationName.substring(operationName.indexOf(" ") + 1); } // Replace the parts operationName = ProducerManager.replacePartPlaceholders(eventMessage, operationName); return "/api/ws/" + serviceName + "/" + versionName + "/" + operationName; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy