use of org.jboss.narayana.blacktie.jatmibroker.core.tx.TransactionException 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.blacktie.jatmibroker.core.tx.TransactionException in project narayana by jbosstm.
the class BufferImpl method serialize.
/**
* Serialize the buffer.
*
* @return The byte array for sending.
* @throws ConnectionException In case the data cannot be formatted correctly
*/
public byte[] serialize() throws ConnectionException {
currentPos = 0;
byte[] toReturn = null;
if (requiresSerialization) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
for (int i = 0; i < types.length; i++) {
try {
if (types[i] == int.class) {
Integer toWrite = (Integer) structure.get(keys[i]);
if (toWrite != null) {
writeInt(dos, toWrite);
} else {
writeInt(dos, 0);
}
} else if (types[i] == short.class) {
Short toWrite = (Short) structure.get(keys[i]);
if (toWrite != null) {
writeShort(dos, toWrite);
} else {
writeShort(dos, (short) 0);
}
} else if (types[i] == long.class) {
Long toWrite = (Long) structure.get(keys[i]);
if (toWrite != null) {
writeLong(dos, toWrite);
} else {
writeLong(dos, 0);
}
} else if (types[i] == byte.class) {
Byte toWrite = (Byte) structure.get(keys[i]);
if (toWrite != null) {
writeByte(dos, toWrite);
} else {
// writeByte(dos, '\0');
writeByte(dos, (byte) 0);
}
} else if (types[i] == float.class) {
Float toWrite = (Float) structure.get(keys[i]);
if (toWrite != null) {
writeFloat(dos, toWrite);
} else {
writeFloat(dos, 0);
}
} else if (types[i] == double.class) {
Double toWrite = (Double) structure.get(keys[i]);
if (toWrite != null) {
writeDouble(dos, toWrite);
} else {
writeDouble(dos, 0);
}
} else if (types[i] == int[].class) {
int[] toWrite = (int[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < lengths[i]; j++) {
writeInt(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
writeInt(dos, 0);
}
} else if (types[i] == short[].class) {
short[] toWrite = (short[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < lengths[i]; j++) {
writeShort(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
writeShort(dos, (short) 0);
}
} else if (types[i] == long[].class) {
long[] toWrite = (long[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < lengths[i]; j++) {
writeLong(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
writeLong(dos, 0);
}
} else if (types[i] == byte[].class) {
byte[] toWrite = (byte[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < max; j++) {
writeByte(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
// writeByte(dos, '\0');
writeByte(dos, (byte) 0);
}
} else if (types[i] == float[].class) {
float[] toWrite = (float[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < lengths[i]; j++) {
writeFloat(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
writeFloat(dos, 0);
}
} else if (types[i] == double[].class) {
double[] toWrite = (double[]) structure.get(keys[i]);
int max = 0;
if (toWrite != null) {
max = Math.min(lengths[i], toWrite.length);
for (int j = 0; j < lengths[i]; j++) {
writeDouble(dos, toWrite[j]);
}
}
for (int j = max; j < lengths[i]; j++) {
writeDouble(dos, 0);
}
} else if (types[i] == byte[][].class) {
byte[][] toWrite = (byte[][]) structure.get(keys[i]);
if (toWrite != null) {
for (int k = 0; k < counts[i]; k++) {
for (int j = 0; j < lengths[i]; j++) {
writeByte(dos, toWrite[k][j]);
}
}
} else {
for (int j = 0; j < counts[i] * lengths[i]; j++) {
writeByte(dos, (byte) 0);
}
}
} else {
if (TransactionImpl.current() != null) {
try {
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(ConnectionImpl.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
throw new ConnectionException(ConnectionImpl.TPEOTYPE, "Could not serialize: " + types[i]);
}
} catch (IOException e) {
throw new ConnectionException(ConnectionImpl.TPEOTYPE, "Could not parse the value as: " + keys[i] + " was not a " + types[i] + " and even if it was an array of that type its length was not: " + lengths[i]);
}
}
toReturn = baos.toByteArray();
} else {
toReturn = getRawData();
}
if (toReturn == null) {
toReturn = new byte[1];
}
return toReturn;
}
use of org.jboss.narayana.blacktie.jatmibroker.core.tx.TransactionException in project narayana by jbosstm.
the class SocketReceiverImpl method receive.
public Message receive(long flags) throws ConnectionException {
if (closed) {
throw new ConnectionException(Connection.TPEPROTO, "Receiver already closed");
}
Message message = null;
if ((flags & Connection.TPNOBLOCK) != Connection.TPNOBLOCK) {
if (server != null) {
message = server.receiveMessage(cd, determineTimeout(flags));
} else if (socket != null) {
synchronized (this) {
if ((flags & Connection.TPNOBLOCK) != Connection.TPNOBLOCK) {
if (data.isEmpty()) {
try {
wait(determineTimeout(flags));
} catch (InterruptedException e) {
}
}
}
if (!data.isEmpty()) {
message = data.remove(0);
}
}
}
} else {
log.debug("Not waiting for the response, hope its there!");
}
if (message == null && (flags & Connection.TPNOBLOCK) == Connection.TPNOBLOCK) {
throw new ConnectionException(Connection.TPEBLOCK, "Did not receive a message");
} else if (message == null) {
if (JtsTransactionImple.hasTransaction()) {
try {
log.debug("Marking rollbackOnly");
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(Connection.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
throw new ConnectionException(Connection.TPETIME, "Did not receive a message");
} else {
log.debug("Message was available");
if (message.rval == EventListener.DISCON_CODE) {
if (TransactionImpl.current() != null) {
try {
log.debug("Marking rollbackOnly as disconnection");
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(Connection.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
} else if (message.rcode == Connection.TPESVCERR) {
if (TransactionImpl.current() != null) {
try {
log.debug("Marking rollbackOnly as svc err");
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(Connection.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
} else if (message.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 (responseMonitor != null) {
responseMonitor.responseReceived(cd, true);
}
return message;
}
use of org.jboss.narayana.blacktie.jatmibroker.core.tx.TransactionException in project narayana by jbosstm.
the class SessionImpl method tpdiscon.
/**
* Close the conversation with the remote service. This will close the
* session.
*/
public void tpdiscon() throws ConnectionException {
log.debug("tpdiscon: " + cd);
if (closed) {
throw new ConnectionException(ConnectionImpl.TPEPROTO, "Session already closed");
}
if (sender == null) {
throw new ConnectionException(ConnectionImpl.TPEPROTO, "Session had no endpoint to respond to for tpdiscon");
}
if (TransactionImpl.current() != null) {
try {
TransactionImpl.current().rollback_only();
} catch (TransactionException e) {
throw new ConnectionException(ConnectionImpl.TPESYSTEM, "Could not mark transaction for rollback only");
}
}
try {
sender.send("", EventListener.DISCON_CODE, 0, null, 0, cd, 0, 0, null, null);
} catch (org.omg.CORBA.OBJECT_NOT_EXIST one) {
log.warn("The disconnect called failed to notify the remote end");
log.debug("The disconnect called failed to notify the remote end", one);
}
close();
}
Aggregations