/**
*
*/
package com.trendrr.strest.server.connections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.jboss.netty.channel.ChannelFuture;
import com.trendrr.strest.server.ResponseBuilder;
import com.trendrr.strest.server.callbacks.DisconnectCallback;
import com.trendrr.strest.server.v2.models.StrestRequest;
import com.trendrr.strest.server.v2.models.StrestResponse;
import com.trendrr.strest.server.v2.models.StrestHeader.TxnStatus;
/**
* @author Dustin Norlander
* @created May 31, 2012
*
*/
public abstract class StrestConnectionChannel {
public abstract boolean isConnected();
private ConcurrentHashMap<String, StrestConnectionTxn> transactions = new ConcurrentHashMap<String, StrestConnectionTxn>();
private ConcurrentHashMap<String,Object> connectionStorage = new ConcurrentHashMap<String,Object>();
private ConcurrentLinkedQueue<DisconnectCallback> disconnectCallbacks = new ConcurrentLinkedQueue<DisconnectCallback>();
/**
* send a message.
* @param response
* @return
* @throws Exception
*/
protected abstract Object doSendMessage(StrestResponse response) throws Exception;
/**
* return the address of the connected client (or null if unavailable).
* @return
*/
public abstract String getRemoteAddress();
public Object sendMessage(ResponseBuilder responseBuilder) throws Exception{
return this.sendMessage(responseBuilder.getResponse());
}
public Object sendMessage(StrestResponse response) throws Exception {
// Write the response.
if (response.getTxnStatus() == TxnStatus.COMPLETED) {
//remove the txn
this.txnComplete(response.getTxnId());
}
return this.doSendMessage(response);
}
/**
* registers a callback for when the connection is disconnected..
* @param callback
*/
public void onDisconnect(DisconnectCallback callback) {
this.disconnectCallbacks.add(callback);
}
/**
* gets the threadsafe connection storage, never null.
* @return
*/
public Map<String, Object> getStorage() {
return connectionStorage;
}
public synchronized void cleanup() {
//first cleanup all the txns
for (String txnId : this.transactions.keySet()) {
this.transactions.get(txnId).cleanup();
}
this.transactions.clear();
//call all the disconnectCallbacks
while(!this.disconnectCallbacks.isEmpty()) {
DisconnectCallback cb = this.disconnectCallbacks.poll();
cb.disconnected(this);
}
this.disconnectCallbacks.clear();
// this.channel = null;
this.connectionStorage.clear();
}
public void incoming(StrestRequest request) {
String txnId = request.getTxnId();
if (txnId == null) {
//duh, what do we do now?
//guess this is a normal HTTP request.
return;
}
if (this.transactions.get(txnId) == null) {
this.transactions.putIfAbsent(txnId, new StrestConnectionTxn(request));
}
}
public StrestConnectionTxn getTxnConnection(String txnId) {
return this.transactions.get(txnId);
}
public void txnComplete(String id) {
if (id == null)
return;
StrestConnectionTxn txn = this.transactions.remove(id);
if (txn == null)
return;
txn.cleanup();
}
}