Package org.apache.uima.ducc.transport.dispatcher

Source Code of org.apache.uima.ducc.transport.dispatcher.DuccEventDispatcher

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF 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 org.apache.uima.ducc.transport.dispatcher;

import java.util.Map;

import org.apache.camel.CamelContext;
import org.apache.camel.ExchangePattern;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.dataformat.xstream.XStreamDataFormat;
import org.apache.camel.impl.DefaultClassResolver;
import org.apache.uima.ducc.common.exception.DuccRuntimeException;
import org.apache.uima.ducc.transport.DuccExchange;
import org.apache.uima.ducc.transport.event.DuccEvent;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class DuccEventDispatcher {
  private ProducerTemplate pt;

  private String targetEndpoint;

  CamelContext context;

  public DuccEventDispatcher(CamelContext context) {
    this.pt = context.createProducerTemplate();
  }

  public DuccEventDispatcher(CamelContext context, String targetEndpoint) {
    this.pt = context.createProducerTemplate();
    this.context = context;
    this.targetEndpoint = targetEndpoint;
  }

  private String marshallDuccEvent(DuccEvent duccEvent) throws Exception {
    XStreamDataFormat xStreamDataFormat = new XStreamDataFormat();
    XStream xStream = xStreamDataFormat.getXStream(new DefaultClassResolver());
    return xStream.toXML(duccEvent);
  }

  private DuccEvent unmarshallDuccEvent(Object targetToUnmarshall) throws Exception {
    XStream xStream = new XStream(new DomDriver());
    String claz = targetToUnmarshall.getClass().getName();
    if (targetToUnmarshall instanceof byte[]) {
      Object reply = xStream.fromXML(new String((byte[]) targetToUnmarshall));
      if (reply instanceof DuccEvent) {
        return (DuccEvent) reply;
      } else {
        claz = (reply == null) ? "NULL" : reply.getClass().getName();
      }
    }
    throw new Exception(
            "Unexpected Reply type received from Ducc Component. Expected DuccEvent, instead received:"
                    + claz);

  }

  public void dispatch(int serviceSocketPort, DuccEvent duccEvent) throws Exception {
    //  by default Mina doesnt include exchange.The transferExchange=true forces inclusion of the Exchange in
    //  a message
    //  Dispatch event via a socket (Mina Camel Component) to a service running on the
    //  same machine
//    pt.sendBody("mina:tcp://localhost:"+serviceSocketPort+"?transferExchange=true&sync=false", marshallDuccEvent(duccEvent));
    pt.sendBody("mina:tcp://localhost:"+serviceSocketPort+"?transferExchange=true&sync=false", duccEvent)}

  public void dispatch(String targetEndpoint, DuccEvent duccEvent) throws Exception {
    dispatch(targetEndpoint, duccEvent, null);
  }

  public void dispatch(DuccEvent duccEvent, String nodeList) throws Exception {
    dispatch(this.targetEndpoint, duccEvent, nodeList);
  }

  public void dispatch(String endpoint, DuccEvent duccEvent, String nodeList) throws Exception {
    try {
//      XStreamDataFormat xStreamDataFormat = new XStreamDataFormat();
//      XStream xStream = xStreamDataFormat.getXStream(new DefaultClassResolver());

//      String marshalledEvent = xStream.toXML(duccEvent);
     
      if (nodeList != null) {
        // No reply is expected
//        pt.sendBodyAndHeader(endpoint, marshalledEvent, DuccExchange.TARGET_NODES_HEADER_NAME,
        pt.sendBodyAndHeader(endpoint, duccEvent, DuccExchange.TARGET_NODES_HEADER_NAME,
                nodeList);
      } else {
//        pt.asyncRequestBody(endpoint, marshalledEvent);
        pt.asyncRequestBody(endpoint, duccEvent);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void dispatch(String serializedEvent) throws Exception {
    // this is a one-way send. Reply is not expected
    pt.sendBody(targetEndpoint, serializedEvent);
  }

  public void dispatch(DuccEvent duccEvent) throws Exception {
    pt.asyncSendBody(targetEndpoint, duccEvent);
  }

  public void dispatch(DuccEvent duccEvent, final Map<String, Object> headers) throws Exception {
    pt.sendBodyAndHeaders(targetEndpoint, duccEvent, headers);
  }
  public void dispatch(DuccEvent duccEvent, String serviceEndpoint, final Map<String, Object> headers) throws Exception {
    //  by default Mina doesnt include Exchange message envelope containing headers.The
    //  transferExchange=true forces inclusion of the Exchange in a message.
    //  Dispatch event via a socket (Mina Camel Component) to a service running on the
    //  same machine
//    pt.sendBodyAndHeaders("mina:tcp://localhost:"+serviceSocketPort+"?transferExchange=true&sync=false", duccEvent, headers);
    pt.sendBodyAndHeaders(serviceEndpoint, duccEvent, headers);
  }

  public DuccEvent dispatchAndWaitForDuccReply(DuccEvent duccEvent) throws Exception {
    int maxRetryCount = 20;
    int i = 0;
    Object reply = null;
    RuntimeExchangeException ree = null;

    // retry up to 20 times. This is an attempt to handle an error thrown
    // by Camel: Failed to resolve replyTo destination on the exchange
    // Camel waits at most 10000ms( 10secs) for AMQ to create a temp queue.
    // After 10secs Camel times out and throws an Exception.
    for (; i < maxRetryCount; i++) {
      try {
        reply = pt.sendBody(targetEndpoint, ExchangePattern.InOut, marshallDuccEvent(duccEvent));
        ree = null; // all is well - got a reply
        break; // done here

      } catch (RuntimeExchangeException e) {
        String msg = e.getMessage();
        // Only retry if AMQ failed to create a temp queue
        if (msg != null && msg.startsWith("Failed to resolve replyTo destination on the exchange")) {
          ree = e;
        } else {
          throw new DuccRuntimeException("Ducc JMS Dispatcher is unable to deliver a request.", e);
        }
      }
    }
    // when retries hit the threshold, just throw an exception
    if (i == maxRetryCount) {
      throw new DuccRuntimeException(
              "ActiveMQ failed to create temp reply queue. After 20 attempts to deliver request to the OR, Ducc JMS Dispatcher is giving up.",
              ree);
    }
    return unmarshallDuccEvent(reply);
  }

  public void stop() throws Exception {
    if (pt != null) {
      pt.stop();
    }
  }
}
TOP

Related Classes of org.apache.uima.ducc.transport.dispatcher.DuccEventDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.