Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
added skeleton and unit tests for transaction api
  • Loading branch information
fasseg committed May 8, 2013
1 parent 5c4bfe2 commit e0b8d34
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 0 deletions.
@@ -0,0 +1,75 @@
package org.fcrepo.api;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.fcrepo.AbstractResource;
import org.fcrepo.Transaction;
import org.fcrepo.Transaction.State;
import org.springframework.stereotype.Component;

import com.sun.jersey.spi.resource.Singleton;

@Component
@Path("/rest/fcr:tx")
public class FedoraTransactions extends AbstractResource {

/* TODO: since transactions have to be available on all nodes, they have to be either persisted or written to a */
/* distributed map or sth, not just this plain hashmap that follows */
private static Map<String, Transaction> transactions = new ConcurrentHashMap<String, Transaction>();

@POST
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
public Transaction createTransaction() throws RepositoryException {
Session sess = getAuthenticatedSession();
Transaction tx = new Transaction(sess);
transactions.put(tx.getId(), tx);
return tx;
}

@GET
@Path("/{txid}")
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
public Transaction getTransaction(@PathParam("txid") final String txid) throws RepositoryException {
Transaction tx = transactions.get(txid);
if (tx == null) {
throw new RepositoryException("Transaction with id " + txid + " is not available");
}
return tx;
}

@POST
@Path("/{txid}/fcr:commmit")
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
public Transaction commit(@PathParam("txid") final String txid) throws RepositoryException {
Transaction tx = transactions.remove(txid);
if (tx == null) {
throw new RepositoryException("Transaction with id " + txid + " is not available");
}
tx.getSession().save();
tx.setState(State.COMMITED);
return tx;
}

@POST
@Path("/{txid}/fcr:rollback")
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
public Transaction rollback(@PathParam("txid") final String txid) throws RepositoryException {
Transaction tx = transactions.remove(txid);
if (tx == null) {
throw new RepositoryException("Transaction with id " + txid + " is not available");
}
tx.setState(State.ROLLED_BACK);
return tx;
}

}
@@ -0,0 +1,82 @@
package org.fcrepo.api;

import static org.junit.Assert.*;

import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.fcrepo.Transaction;
import org.fcrepo.Transaction.State;
import org.fcrepo.test.util.TestHelpers;
import org.junit.Before;
import org.junit.Test;

public class FedoraTransactionsTest {

FedoraTransactions resource;

Session mockSession;

@Before
public void setup() throws Exception {
resource = new FedoraTransactions();
mockSession = TestHelpers.mockSession(resource);
}

@Test
public void testCreateTx() throws Exception {
Transaction tx = resource.createTransaction();

assertNotNull(tx);
assertNotNull(tx.getCreated());
assertNotNull(tx.getId());
assertTrue(tx.getState() == State.NEW);
}

@Test
public void testGetTx() throws Exception {
Transaction tx = resource.createTransaction();
tx = resource.getTransaction(tx.getId());

assertNotNull(tx);
assertNotNull(tx.getCreated());
assertNotNull(tx.getId());
assertTrue(tx.getState() == State.NEW);
}

@Test
public void testCommitTx() throws Exception {
Transaction tx = resource.createTransaction();
tx = resource.commit(tx.getId());

assertNotNull(tx);
assertNotNull(tx.getCreated());
assertNotNull(tx.getId());
assertTrue(tx.getState() == State.COMMITED);
try{
assertNull(resource.getTransaction(tx.getId()));
fail("Transaction is available after commit");
}catch(RepositoryException e){
// just checking that the exception occurs
}

}

@Test
public void testRollbackTx() throws Exception {
Transaction tx = resource.createTransaction();
tx = resource.rollback(tx.getId());

assertNotNull(tx);
assertNotNull(tx.getCreated());
assertNotNull(tx.getId());
assertTrue(tx.getState() == State.ROLLED_BACK);
try{
assertNull(resource.getTransaction(tx.getId()));
fail("Transaction is available after rollback");
}catch(RepositoryException e){
// just checking that the exception occurs
}
}

}
56 changes: 56 additions & 0 deletions fcrepo-kernel/src/main/java/org/fcrepo/Transaction.java
@@ -0,0 +1,56 @@
package org.fcrepo;

import java.util.Date;
import java.util.UUID;

import javax.jcr.Session;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement(name = "transaction")
public class Transaction {

public enum State {
DIRTY, NEW, COMMITED, ROLLED_BACK;
}

@XmlTransient
private final Session session;

@XmlAttribute(name = "id")
private final String id;

@XmlAttribute(name = "created-date")
private final Date created;

private State state = State.NEW;

public Transaction(Session session) {
super();
this.session = session;
this.created = new Date();
this.id = UUID.randomUUID().toString();
}

public Session getSession() {
return session;
}

public Date getCreated() {
return created;
}

public String getId() {
return id;
}

public void setState(State state) {
this.state = state;
}

public State getState() {
return state;
}

}

0 comments on commit e0b8d34

Please sign in to comment.