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

io.vertx.resourceadapter.inflow.impl.VertxActivation Maven / Gradle / Ivy

There is a newer version: 3.9.8
Show newest version
package io.vertx.resourceadapter.inflow.impl;

import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.Message;
import io.vertx.resourceadapter.impl.VertxHolder;
import io.vertx.resourceadapter.impl.VertxPlatformConfiguration;
import io.vertx.resourceadapter.impl.VertxPlatformFactory;
import io.vertx.resourceadapter.impl.VertxResourceAdapter;
import io.vertx.resourceadapter.inflow.VertxListener;

import javax.resource.ResourceException;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * VertxActivation
 *
 */
public class VertxActivation implements VertxPlatformFactory.VertxListener, VertxHolder {

  private static final Logger log = Logger.getLogger(VertxActivation.class.getName());
 
  private final VertxResourceAdapter ra;

  private final VertxActivationSpec spec;

  private final MessageEndpointFactory endpointFactory;

  private final VertxPlatformConfiguration config;

  private Handler> messageHandler;

  private final AtomicBoolean deliveryActive = new AtomicBoolean(false);

  private Vertx vertx;

  static {
    try {
      VertxListener.class.getMethod("onMessage", new Class[] { Message.class });
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  public VertxActivation(VertxResourceAdapter ra, MessageEndpointFactory endpointFactory, VertxActivationSpec spec) 
      throws ResourceException {
    this.ra = ra;
    this.endpointFactory = endpointFactory;
    this.spec = spec;
    this.config = spec.getVertxPlatformConfig();
  }

  /**
   * Get activation spec class
   * 
   * @return Activation spec
   */
  public VertxActivationSpec getActivationSpec() {
    return spec;
  }

  /**
   * Get message endpoint factory
   * 
   * @return Message endpoint factory
   */
  public MessageEndpointFactory getMessageEndpointFactory() {
    return endpointFactory;
  }

  /**
   * Start the activation
   * 
   * @throws ResourceException
   *           Thrown if an error occurs
   */
  public void start() throws ResourceException {
    
    if (!deliveryActive.get()) {
      VertxPlatformFactory.instance().getOrCreateVertx(config, this);    
      VertxPlatformFactory.instance().addVertxHolder(this);
    }
    setup();
  }

  private void setup() {
    String address = this.spec.getAddress();
    try {
      final MessageEndpoint endPoint = endpointFactory.createEndpoint(null);
      this.messageHandler = message -> handleMessage(endPoint, message);

      if (this.vertx == null) {
        throw new ResourceException("Vertx platform did not start yet.");
      }
      vertx.eventBus().consumer(address).handler(messageHandler);
      log.log(Level.INFO,
          "Endpoint created, register Vertx handler on address: " + address);
    } catch (Exception e) {
      throw new RuntimeException("Can't create the endpoint.", e);
    }
  }

  private void handleMessage(MessageEndpoint endPoint, Message message) {
    try {
      ra.getWorkManager().scheduleWork(new HandleMessage(endPoint, message));
    } catch (WorkException e) {
      throw new RuntimeException("Can't handle message.", e);
    }
  }

  @Override
  public void whenReady(Vertx vertx) {
    if (deliveryActive.get()) {
      log.log(Level.WARNING, "Vertx has been started.");
      return;
    }
    this.vertx = vertx;
    setup();
    deliveryActive.set(true);
    VertxPlatformFactory.instance().addVertxHolder(this);
  }

  @Override
  public Vertx getVertx() {
    return this.vertx;
  }

  /**
   * Stop the activation
   */
  public void stop() {
    tearDown();
    deliveryActive.set(false);
  }

  private void tearDown() {
    
    VertxPlatformFactory.instance().removeVertxHolder(this);
    VertxPlatformFactory.instance().stopPlatformManager(this.config);
  }

  private class HandleMessage implements Work {

    private final MessageEndpoint endPoint;
    private final Message message;

    private HandleMessage(MessageEndpoint endPoint, Message message) {
      this.endPoint = endPoint;
      this.message = message;
    }

    @Override
    public void run() {
      ((VertxListener) endPoint).onMessage(message);
    }

    @Override
    public void release() {
    }
  
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy