@SuppressWarnings({"UnusedDeclaration"}) @PUT @Path("{pId}/{tId}/terminator") public Response terminate( @PathParam("pId") @DefaultValue("") String pId, @PathParam("tId") @DefaultValue("") String tId, String content) { TxStatus status = TxSupport.toTxStatus(content); // String status = TxSupport.getStatus(content); Work work = faults.get(pId); if (work == null) return Response.status(HttpURLConnection.HTTP_NOT_FOUND).build(); String fault = work.fault; if (status.isPrepare()) { if ("READONLY".equals(fault)) { // faults.remove(pId); work.status = TxStatus.TransactionReadOnly.name(); } else if ("PREPARE_FAIL".equals(fault)) { // faults.remove(pId); return Response.status(HttpURLConnection.HTTP_CONFLICT).build(); // throw new WebApplicationException(HttpURLConnection.HTTP_CONFLICT); } else { if ("PDELAY".equals(fault)) { try { Thread.sleep(2000); } catch (InterruptedException e) { } } work.status = TxStatus.TransactionPrepared.name(); } } else if (status.isCommit() || status.isCommitOnePhase()) { if ("H_HAZARD".equals(fault)) work.status = TxStatus.TransactionHeuristicHazard.name(); else if ("H_ROLLBACK".equals(fault)) work.status = TxStatus.TransactionHeuristicRollback.name(); else if ("H_MIXED".equals(fault)) work.status = TxStatus.TransactionHeuristicMixed.name(); else { if ("CDELAY".equals(fault)) { try { Thread.sleep(3000); } catch (InterruptedException e) { // ok } } work.status = status.isCommitOnePhase() ? TxStatus.TransactionCommittedOnePhase.name() : TxStatus.TransactionCommitted.name(); work.end(true); } } else if (status.isAbort()) { if ("H_HAZARD".equals(fault)) work.status = TxStatus.TransactionHeuristicHazard.name(); else if ("H_COMMIT".equals(fault)) work.status = TxStatus.TransactionHeuristicCommit.name(); else if ("H_MIXED".equals(fault)) work.status = TxStatus.TransactionHeuristicMixed.name(); else { if ("ADELAY".equals(fault)) { try { Thread.sleep(2000); } catch (InterruptedException e) { // ok } } work.status = TxStatus.TransactionRolledBack.name(); work.end(false); // faults.remove(pId); } } else { return Response.status(HttpURLConnection.HTTP_BAD_REQUEST).build(); // throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); } // return TxSupport.toStatusContent(work.status); return Response.ok(TxSupport.toStatusContent(work.status)).build(); }
@POST @Produces(TxMediaType.PLAIN_MEDIA_TYPE) public String enlist( @Context UriInfo info, @QueryParam("pId") @DefaultValue("") String pId, @QueryParam("fault") @DefaultValue("") String fault, @QueryParam("twoPhaseAware") @DefaultValue("true") String twoPhaseAware, @QueryParam("isVolatile") @DefaultValue("false") String isVolatile, String enlistUrl) throws IOException { Work work = faults.get(pId); TxSupport txn = new TxSupport(); String txId = enlistUrl.substring(enlistUrl.lastIndexOf('/') + 1); boolean isTwoPhaseAware = "true".equals(twoPhaseAware); boolean isVolatileParticipant = "true".equals(isVolatile); String vRegistration = null; // URI for registering with the volatile phase String vParticipantLink = null; // URI for handling pre and post 2PC phases String path = TxSupport.extractUri(info); if (work == null) { int id = ++pid; work = makeWork( txn, path, String.valueOf(id), txId, enlistUrl, isTwoPhaseAware, isVolatileParticipant, null, fault); } else { Work newWork = makeWork( txn, path, work.id, txId, enlistUrl, isTwoPhaseAware, isVolatileParticipant, null, fault); newWork.oldState = work.oldState; newWork.newState = work.newState; work = newWork; } if (enlistUrl.indexOf(',') != -1) { String[] urls = enlistUrl.split(","); if (urls.length < 2) throw new WebApplicationException(HttpURLConnection.HTTP_BAD_REQUEST); enlistUrl = urls[0]; vRegistration = urls[1]; String vParticipant = new StringBuilder(path) .append('/') .append(work.id) .append('/') .append(txId) .append('/') .append("vp") .toString(); vParticipantLink = txn.addLink2(new StringBuilder(), TxLinkNames.VOLATILE_PARTICIPANT, vParticipant, true) .toString(); } try { // enlist TestResource in the transaction as a participant work.recoveryUrl = txn.enlistParticipant(enlistUrl, work.pLinks); if (vParticipantLink != null) txn.enlistVolatileParticipant(vRegistration, vParticipantLink); } catch (HttpResponseException e) { throw new WebApplicationException(e.getActualResponse()); } work.status = TxStatus.TransactionActive.name(); work.start(); faults.put(work.id, work); return work.id; }