package org.opennaas.extensions.bod.autobahn.commands; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getFirst; import static com.google.common.collect.Lists.newArrayList; import java.util.List; import org.opennaas.core.resources.action.ActionException; import org.opennaas.core.resources.action.ActionResponse; import org.opennaas.core.resources.command.Response; import org.opennaas.core.resources.queue.QueueConstants; public class Transaction { private static final ThreadLocal<Transaction> transaction = new ThreadLocal<Transaction>() { @Override protected Transaction initialValue() { return new Transaction(); } }; /** Commands to execute. */ private final List<IAutobahnCommand> queue = newArrayList(); /** Commands already executed. */ private final List<IAutobahnCommand> log = newArrayList(); /** True while a transaction is open. */ private boolean open = false; public static Transaction getInstance() { return transaction.get(); } public void begin() throws ActionException { checkState(!open); queue.clear(); log.clear(); open = true; } public ActionResponse commit() { checkState(open); ActionResponse actionResponse = new ActionResponse(); actionResponse.setActionID(QueueConstants.CONFIRM); for (IAutobahnCommand command : queue) { Response response = command.execute(); actionResponse.addResponse(response); log.add(command); if (response.getStatus() != Response.Status.OK) { actionResponse.setStatus(ActionResponse.STATUS.ERROR); actionResponse.setInformation(getFirst(response.getErrors(), "Commit failed")); return actionResponse; } } open = false; actionResponse.setStatus(ActionResponse.STATUS.OK); actionResponse.setInformation("Commit succeeded"); return actionResponse; } public ActionResponse rollback() { checkState(open); try { ActionResponse actionResponse = new ActionResponse(); actionResponse.setActionID(QueueConstants.RESTORE); actionResponse.setStatus(ActionResponse.STATUS.OK); actionResponse.setInformation("Rollback succeeded"); for (IAutobahnCommand command : log) { Response response = command.undo(); actionResponse.addResponse(response); if (response.getStatus() != Response.Status.OK) { actionResponse.setStatus(ActionResponse.STATUS.ERROR); actionResponse.setInformation(getFirst(response.getErrors(), "Rollback failed")); } } return actionResponse; } finally { open = false; } } public void add(IAutobahnCommand command) { checkState(open); queue.add(command); } }