use of org.jboss.narayana.rest.bridge.inbound.InboundBridge in project narayana by jbosstm.
the class BlackTieService method processMessage.
/**
* Entry points should pass control to this method as soon as reasonably possible.
*
* @param serviceName The name of the service
* @param message The message to process
* @throws ConnectionException
* @throws ConnectionException In case communication fails
* @throws ConfigurationException
* @throws NamingException
* @throws SystemException
* @throws IllegalStateException
* @throws InvalidTransactionException
* @throws TransactionException
*/
protected void processMessage(String serviceName, Message message) throws ConnectionException, ConfigurationException, NamingException, InvalidTransactionException, IllegalStateException, SystemException, TransactionException {
log.trace("Service invoked");
if (connectionFactory == null) {
connectionFactory = ConnectionFactory.getConnectionFactory();
}
ConnectionImpl connection = (ConnectionImpl) connectionFactory.getConnection();
try {
boolean hasTx = false;
boolean hasTPNOREPLY = (message.flags & Connection.TPNOREPLY) == Connection.TPNOREPLY;
boolean responseSendable = !hasTPNOREPLY;
// To respond with
short rval = Connection.TPFAIL;
int rcode = Connection.TPESVCERR;
byte[] data = null;
int len = 0;
int flags = 0;
String type = null;
String subtype = null;
SessionImpl serviceSession = ((ConnectionImpl) connection).createServiceSession(serviceName, message.cd, message.replyTo);
InboundBridge inboundBridge = null;
try {
boolean hasTPCONV = (message.flags & Connection.TPCONV) == Connection.TPCONV;
Boolean conversational = (Boolean) connectionFactory.getProperties().get("blacktie." + serviceName + ".conversational");
log.trace(serviceName);
boolean isConversational = conversational == true;
if (hasTPCONV && isConversational) {
X_OCTET odata = new X_OCTET_Impl(null);
byte[] ack = new byte[4];
byte[] bytes = "ACK".getBytes();
System.arraycopy(bytes, 0, ack, 0, 3);
odata.setByteArray(ack);
long result = serviceSession.tpsend(odata, 0);
if (result == -1) {
log.error("Could not send ack");
serviceSession.close();
return;
} else {
log.debug("Sent ack");
serviceSession.setCreatedState(message.flags);
}
} else if (!hasTPCONV && !isConversational) {
log.debug("Session was not a TPCONV");
} else {
log.error("Session was invoked in an improper manner");
X_OCTET odata = new X_OCTET_Impl(null);
byte[] ack = new byte[4];
byte[] bytes = "ERR".getBytes();
System.arraycopy(bytes, 0, ack, 0, 3);
odata.setByteArray(bytes);
long result = serviceSession.tpsend(odata, 0);
if (result == -1) {
log.error("Could not send err");
} else {
log.error("Error reported");
}
serviceSession.close();
return;
}
log.debug("Created the session");
// THIS IS THE FIRST CALL
BufferImpl buffer = null;
if (message.type != null && !message.type.equals("")) {
buffer = (BufferImpl) connection.tpalloc(message.type, message.subtype);
buffer.deserialize(message.data);
}
TPSVCINFO tpsvcinfo = new TPSVCINFO_Impl(message.serviceName, buffer, message.flags, (hasTPCONV ? serviceSession : null), connection, message.len);
log.debug("Prepared the data for passing to the service");
hasTx = (message.control != null && message.control.length() != 0);
log.debug("hasTx=" + hasTx + " control: " + message.control);
if (hasTx) {
// service routine
if (message.control.startsWith("IOR")) {
log.debug("resume OTS transaction");
JtsTransactionImple.resume(message.control);
} else if (message.control.startsWith("http")) {
log.debug("start inbound bridge");
inboundBridge = InboundBridgeManager.getInstance().createInboundBridge(message.control);
inboundBridge.start();
} else {
log.error(message.control + " is not OTS or RTS when resume the transaction");
}
}
log.debug("Invoking the XATMI service");
Response response = null;
try {
response = tpservice(tpsvcinfo);
log.debug("Service invoked");
if (!hasTPNOREPLY && response == null) {
log.error("Error, expected response but none returned");
}
} catch (Throwable t) {
log.error("Service error detected", t);
}
if (!hasTPNOREPLY && serviceSession.getSender() != null) {
log.trace("Sending response");
if (response != null) {
rval = response.getRval();
rcode = response.getRcode();
if (rval != Connection.TPSUCCESS && rval != Connection.TPFAIL) {
rval = Connection.TPFAIL;
}
}
if (connection.hasOpenSessions()) {
rcode = Connection.TPESVCERR;
rval = Connection.TPFAIL;
}
if (rval == Connection.TPFAIL) {
if (TransactionImpl.current() != null) {
try {
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(Connection.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
}
if (response != null) {
BufferImpl toSend = (BufferImpl) response.getBuffer();
if (toSend != null) {
len = toSend.getLen();
data = toSend.serialize();
type = toSend.getType();
subtype = toSend.getSubtype();
}
flags = response.getFlags();
}
log.debug("Will return desired message");
} else if (!hasTPNOREPLY && serviceSession.getSender() == null) {
log.error("No sender avaible but message to be sent");
responseSendable = false;
} else {
log.debug("No need to send a response");
}
} finally {
if (hasTx) {
// and suspend it again
if (message.control.startsWith("IOR")) {
log.debug("suspend OTS transaction");
JtsTransactionImple.suspend();
} else if (message.control.startsWith("http")) {
log.debug("inbound bridge stop");
if (inboundBridge != null) {
inboundBridge.stop();
}
} else {
log.error(message.control + " is not OTS or RTS when suspend the transaction");
}
}
if (responseSendable) {
// Even though we can provide the cd we don't as
// atmibroker-xatmi doesn't because tpreturn doesn't
serviceSession.getSender().send("", rval, rcode, data, len, 0, flags, 0, type, subtype);
}
}
} finally {
connection.close();
}
}
use of org.jboss.narayana.rest.bridge.inbound.InboundBridge in project wildfly by wildfly.
the class InboundBridgeService method addDeserializerAndOrphanFilter.
private void addDeserializerAndOrphanFilter() {
final RecoveryManager recoveryManager = RecoveryManager.manager();
for (RecoveryModule recoveryModule : recoveryManager.getModules()) {
if (recoveryModule instanceof XARecoveryModule) {
orphanFilter = new InboundBridgeOrphanFilter();
((XARecoveryModule) recoveryModule).addXAResourceOrphanFilter(orphanFilter);
((XARecoveryModule) recoveryModule).addSerializableXAResourceDeserializer(new InboundBridge());
}
}
}
use of org.jboss.narayana.rest.bridge.inbound.InboundBridge in project narayana by jbosstm.
the class ProtocolConverter method onStompReceive.
protected void onStompReceive(StompFrame command) throws IllegalStateException, SystemException, JMSException, NamingException, IOException {
checkConnected();
Map<String, Object> headers = command.getHeaders();
String destinationName = (String) headers.remove(Stomp.Headers.Send.DESTINATION);
String xid = (String) headers.get("messagexid");
Message msg = null;
StompSession session = null;
if (xid != null) {
if (xid.startsWith("IOR")) {
log.error("OTS Transaction Not Supported");
} else if (xid.startsWith("http")) {
log.trace("RTS Transaction was propagated: " + xid);
String enlistmentUrl = xid;
final InboundBridge inboundBridge = InboundBridgeManager.getInstance().createInboundBridge(enlistmentUrl);
log.trace("Start inboundBridge");
inboundBridge.start();
session = getXASession(inboundBridge.getXid());
msg = session.receiveFromJms(destinationName, headers);
inboundBridge.stop();
log.trace("Stop inboundBridge");
} else {
log.error(xid + " is not OTS or RTS transaction");
}
} else {
log.trace("WAS NULL XID");
session = noneXaSession;
msg = session.receiveFromJms(destinationName, headers);
log.trace("Received from JMS");
}
StompFrame sf;
if (msg == null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter stream = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
stream.print("No messages available");
stream.close();
Map<String, Object> eheaders = new HashMap<String, Object>();
eheaders.put(Stomp.Headers.Error.MESSAGE, "timeout");
sf = new StompFrame(Stomp.Responses.ERROR, eheaders, baos.toByteArray());
} else {
// Don't use sendResponse since it uses Stomp.Responses.RECEIPT as the action
// which only allows zero length message bodies, Stomp.Responses.MESSAGE is correct:
sf = session.convertMessage(msg);
}
if (headers.containsKey(Stomp.Headers.RECEIPT_REQUESTED))
sf.getHeaders().put(Stomp.Headers.Response.RECEIPT_ID, headers.get(Stomp.Headers.RECEIPT_REQUESTED));
sendToStomp(sf);
}
Aggregations