/* * codjo.net * * Common Apache License 2.0 */ package net.codjo.control.server.plugin; import net.codjo.aspect.AspectException; import net.codjo.aspect.util.PointRunner; import net.codjo.aspect.util.PointRunnerException; import net.codjo.aspect.util.TransactionException; import net.codjo.control.common.ControlContext; import net.codjo.control.common.ControlException; import net.codjo.control.common.IntegrationPlan; import net.codjo.control.common.message.ControlJobRequest; import net.codjo.control.server.api.ControlAspectContext; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.apache.log4j.Logger; import org.apache.log4j.NDC; /** * */ class QuarantineControlManager { private static final String TECHNICAL_ERROR_TYPE = "499"; private static final Logger APP = Logger.getLogger(QuarantineControlManager.class); private static final String TECHNICAL_ERROR_PREFIX = "ERREUR TECHNIQUE : "; private ControlPreference preference; QuarantineControlManager(ControlPreference preference) { this.preference = preference; } public PostControlAudit doQuarantineControls(Connection connection, ControlJobRequest jobRequest) throws QuarantineControlException, SQLException { String quarantineTable = jobRequest.getQuarantineTable(); APP.info("Controle de la quarantaine : " + quarantineTable); NDC.push("Controle " + quarantineTable); try { IntegrationPlan plan = preference.getPlan(quarantineTable); ControlAspectContext aspectContext = createContext(plan, connection, jobRequest); return proceedQuarantine(plan, aspectContext); } catch (Exception cause) { APP.error("Controle de la quarantaine " + quarantineTable + " en echec", cause); PostControlAudit audit = tagTechnicalError(connection, quarantineTable, cause); throw new QuarantineControlException(audit, cause); } finally { NDC.pop(); } } private PostControlAudit proceedQuarantine(IntegrationPlan plan, ControlAspectContext context) throws SQLException, AspectException, PointRunnerException, TransactionException, ControlException { APP.info("Initialisation..."); plan.init(context.getConnection()); try { APP.info("Transfert Quarantaine '" + context.getQuarantineTable() + "' vers Table de controle"); plan.executeShipmemt(context.getConnection()); APP.info("Tag les lignes en cours de controle"); int movedRows = tagMovedRows(context.getConnection(), context.getQuarantineTable()); APP.info("Execution des contr�les"); plan.executeBatchControls(context.getConnection(), createControlContext(context)); APP.info("Execution des controles"); executeDispatch(plan, context); APP.info("Construction de l'audit"); return createPostAudit(context, movedRows); } finally { APP.info("Nettoyage"); plan.cleanUp(context.getConnection()); } } void executeDispatch(final IntegrationPlan plan, final ControlAspectContext context) throws PointRunnerException, AspectException, TransactionException { PointRunner runner = new PointRunner() { public void run() throws PointRunnerException { try { plan.executeDispatch(context.getConnection(), createControlContext(context)); } catch (Exception e) { throw new PointRunnerException(e); } } }; preference.getDispatchPoint().run(context.toAspectContext(), runner); } private PostControlAudit createPostAudit(ControlAspectContext context, int movedRows) throws SQLException { PostControlAudit audit = new PostControlAudit(); audit.setBadLineCount(getRowCount(context, "ERROR_TYPE <> 0")); audit.setValidLineCount(movedRows - audit.getBadLineCount()); return audit; } private int getRowCount(ControlAspectContext context, String whereClause) throws SQLException { Statement stmt = context.getConnection().createStatement(); try { ResultSet rs = stmt.executeQuery("select count(1) from " + context.getQuarantineTable() + " where " + whereClause); rs.next(); return rs.getInt(1); } finally { stmt.close(); } } private int tagMovedRows(Connection connection, String quarantineTable) throws SQLException { Statement stmt = connection.createStatement(); try { return stmt.executeUpdate("update " + quarantineTable + " set ERROR_TYPE = null where ERROR_TYPE = 0"); } finally { stmt.close(); } } private PostControlAudit tagTechnicalError(Connection connection, String quarantineTable, Throwable cause) throws SQLException { PreparedStatement stmt = connection.prepareStatement("update " + quarantineTable + " set ERROR_TYPE = " + TECHNICAL_ERROR_TYPE + ", ERROR_LOG = ?" + " where ERROR_TYPE is null"); try { stmt.setString(1, getTechnicalErrorMessage(cause)); int badLine = stmt.executeUpdate(); return new PostControlAudit(0, badLine); } finally { stmt.close(); } } String getTechnicalErrorMessage(Throwable ex) { if (ex.getLocalizedMessage() == null) { return TECHNICAL_ERROR_PREFIX + ex.getClass().getName(); } return TECHNICAL_ERROR_PREFIX + ex.getLocalizedMessage().substring(0, Math.min(ex.getLocalizedMessage().length(), 254 - TECHNICAL_ERROR_PREFIX.length())); } private ControlContext createControlContext(ControlAspectContext context) { ControlContext controlContext = new ControlContext(context.getUser(), context.getJobRequestId(), context.getPathOfRequest()); controlContext.setConnection(context.getConnection()); return controlContext; } private static ControlAspectContext createContext(IntegrationPlan ctrl, Connection connection, ControlJobRequest jobRequest) { ControlAspectContext context = new ControlAspectContext(); context.setControlTableName(ctrl.getControlTableName()); context.setQuarantineTable(ctrl.getQuarantineTable()); context.setConnection(connection); context.setUser(jobRequest.getInitiatorLogin()); context.setJobRequestId(jobRequest.getId()); context.setPathOfRequest(jobRequest.getPath()); return context; } }