Java tutorial
package com.webbfontaine.valuewebb.action.fcvr; import com.webbfontaine.ellipse.lightso.Message; import com.webbfontaine.valuewebb.action.tt.TTDataLoader; import com.webbfontaine.valuewebb.action.tt.TtGenHome; import com.webbfontaine.valuewebb.authentication.AuthenticatorBean; import com.webbfontaine.valuewebb.model.TtGen; import com.webbfontaine.valuewebb.model.util.Utils; import org.apache.commons.lang3.StringUtils; import org.jboss.seam.Component; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.AutoCreate; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.async.Asynchronous; import org.jboss.seam.annotations.async.Expiration; import org.jboss.seam.annotations.async.IntervalCron; import org.jboss.seam.async.QuartzTriggerHandle; import org.jboss.seam.log.Log; import org.jboss.seam.log.Logging; import org.jboss.seam.transaction.Transaction; import javax.persistence.EntityManager; import javax.transaction.SystemException; import javax.transaction.UserTransaction; import java.io.IOException; import java.rmi.NotBoundException; import java.util.Date; import java.util.List; import static com.webbfontaine.valuewebb.model.constants.Constants.*; /** * Copyrights 2002-2013 Webb Fontaine * This software is the proprietary information of Webb Fontaine. * Its use is subject to License terms. * Developer: nigiyan * Date: 12/04/2013 */ @Name("FCVRSendScheduler") @AutoCreate @Scope(ScopeType.APPLICATION) public class FCVRSendScheduler { private static final Log LOGGER = Logging.getLog(FCVRSendScheduler.class); private static final Object LOCK = new Object(); @Asynchronous public QuartzTriggerHandle scheduleTask(@Expiration Date when, @IntervalCron String interval) { LOGGER.info("Started"); long startTime = System.currentTimeMillis(); synchronized (LOCK) { // allow only one async thread to do this EntityManager entityManager = (EntityManager) Component.getInstance("entityManager", ScopeType.STATELESS, true); List<Long> ttIDs = Utils.setDirectRead(entityManager.createNamedQuery(findSentTTIdsCI)).getResultList(); LOGGER.debug("Found Sent TTs: {0}}", ttIDs); if (ttIDs.isEmpty()) { return null; } if (!AuthenticatorBean.getDaemonIdentity().tryLogin()) { LOGGER.error("Can not login with 'daemon' identity to update TTs"); return null; } try { for (Long ttId : ttIDs) { try { TtGen ttGen = entityManager.find(TtGen.class, ttId); LOGGER.debug("TT to sent to FCVR: {0}, status {1}", ttId, ttGen.getStatus()); if (!ttGen.getStatus().equals(TT_SENT)) { // already processed by other thread continue; } new TTDataLoader(ttGen).processAll(); Message message = FCVRSender.getInstance().sendFCVR(ttGen); if (FCVRHelper.transactionError(message)) { LOGGER.error("SOGate respond with error for TT {0} with FCVR Number {1}. Error: {2}", ttId, ttGen.getFcvrNum(), message.getProperties()); FCVRHelper.logExceptions(ttId, message); } else { if (FCVRHelper.transactionFailed(message)) { FCVRHelper.logExceptions(ttId, message); String remoteExceptionMessage = FCVRHelper.extractErrors(message); FCVRHelper.appendErrorsToTT(ttGen, remoteExceptionMessage); if (isFCVRAlreadyExists(remoteExceptionMessage)) { LOGGER.warn( "FCVR already exists for TT with ID {0}, check logs for previous unexpected errors. TT status will be changed to Sent Ok.", ttId); updateTT(ttGen, RESPONSE_OK); // ignore existance and change the status. } else { if (isAccessProblem(remoteExceptionMessage)) { LOGGER.warn( "Cannot complete transaction for FCVR document, got {0} for TT ID: {1}, document processing skipped.", remoteExceptionMessage, ttId); } else { LOGGER.info( "Cannot complete transaction for FCVR document, TT ID: {0}, document status will be changed accordingly.", ttId); updateTT(ttGen, ERROR_RESPONSE); } } } else { if (FCVRHelper.transactionSucceeded(message)) { LOGGER.info("FCVR transaction on TT {0} completed successfully", ttId); updateTT(ttGen, RESPONSE_OK); } else { LOGGER.error("Unknown FCVR response for TT: {0}, message: {1}", ttId, message.getProperties()); throw new FCVRProcessingException( "Unknown FCVR reponse, remote document change is "); } } } } catch (FCVRProcessingException e) { Throwable cause = e.getCause(); if (isConnectionProblem(cause) || isLoginProblem(cause)) { LOGGER.warn("{0}: Can not connect to TWM-FCVR. {1}", cause.getClass().getName(), cause.getMessage()); break; // do not continue with next TT if connection problem } else { LOGGER.error("", e); } } } } finally { AuthenticatorBean.getDaemonIdentity().logout(); } LOGGER.debug("Processing took {0} ms", System.currentTimeMillis() - startTime); return null; } } protected void updateTT(TtGen ttGen, String operation) { LOGGER.debug("Going to execute {0} operation on TT with id {1}.", operation, ttGen.getId()); UserTransaction utx = null; try { utx = Transaction.instance(); utx.begin(); TtGenHome ttGenHome = createTTHomeInstance(ttGen); if (ttGenHome.performDirectTaskWithoutDocumentCheck(operation).equals(UPDATED)) { utx.commit(); } else { LOGGER.error("Failed to execute {0} operation for TT with id {1}. Will continue with next TTs", operation, ttGen.getId()); utx.rollback(); } } catch (Exception e) { LOGGER.error("Exception on updating TT with id: {0} for operation: {1} fails", e, ttGen.getId(), operation); if (utx != null) { try { utx.rollback(); } catch (SystemException sex) { LOGGER.error("", sex); } } } } private static TtGenHome createTTHomeInstance(TtGen ttGen) { return TtGenHome.createInstance(ttGen); } private static boolean isConnectionProblem(Throwable t) { return t != null && t instanceof IOException || t instanceof NotBoundException; } private static boolean isLoginProblem(Throwable t) { return t != null && "Exception at login".equals(t.getMessage()); } private static boolean isFCVRAlreadyExists(String error) { return "FCVR Number already exists".equals(StringUtils.trim(error)); } private static boolean isAccessProblem(String error) { return StringUtils.trim(error).toLowerCase().contains("access denied to binder"); } }