Search in sources :

Example 6 with XAContext

use of com.swiftmq.swiftlet.xa.XAContext in project swiftmq-ce by iitsoftware.

the class XARecoveryStage method init.

protected void init() {
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/init...");
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.SMQRFactory.START_STAGE_REQ, new RequestHandler() {

        public void visited(Request request) {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + "...");
            RecoveryRequest rc = new RecoveryRequest();
            rc.setBranchQualifier(recoveryBranchQ);
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", sending request=" + rc);
            routingConnection.getOutboundQueue().enqueue(rc);
            routingConnection.setXaSelected(true);
        }
    });
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.RECOVERY_REPREQ, new RequestHandler() {

        public void visited(Request request) {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + "...");
            RecoveryReplyRequest reply = (RecoveryReplyRequest) request;
            if (reply.isOk()) {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", do recovery");
                // do recovery
                List localXids = getPreparedXids(new Filter(recoveryBranchQ));
                List remoteXids = reply.getXidList();
                doRecover(localXids, remoteXids);
                localRecovered = true;
                if (remoteRecovered) {
                    if (ctx.traceSpace.enabled)
                        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", launching delivery stage");
                    getStageQueue().setStage(new XADeliveryStage(ctx, routingConnection));
                }
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", start remote delivery");
                // start delivery
                routingConnection.getOutboundQueue().enqueue(new StartDeliveryRequest());
            } else {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", disconnect");
                ctx.logSwiftlet.logError(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/exception: " + reply.getException());
                ctx.networkSwiftlet.getConnectionManager().removeConnection(routingConnection.getConnection());
            }
        }
    });
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.RECOVERY_REQ, new RequestHandler() {

        public void visited(Request request) {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request);
            // It then sends a request by itself to ensure the XARecoveryStage is active at the connector side.
            if (listener)
                getStageQueue().enqueue(new StartStageRequest());
            RecoveryRequest pr = (RecoveryRequest) request;
            RecoveryReplyRequest reply = new RecoveryReplyRequest();
            reply.setOk(true);
            // fill xid list
            reply.setXidList(getPreparedXids(new Filter(pr.getBranchQualifier())));
            routingConnection.getOutboundQueue().enqueue(reply);
            remoteRecovered = true;
        }
    });
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.COMMIT_REQ, new RequestHandler() {

        public void visited(Request request) {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request);
            CommitRequest cr = (CommitRequest) request;
            XAContext xac = ctx.xaResourceManagerSwiftlet.getXAContext(cr.getXid());
            try {
                xac.commit(false);
            } catch (XAContextException e) {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/visited, request=" + request + ", exception=" + e);
                ctx.logSwiftlet.logError(ctx.routingSwiftlet.getName(), toString() + "/visited, request=" + request + ", exception=" + e);
            }
            ctx.xaResourceManagerSwiftlet.removeXAContext(cr.getXid());
        }
    });
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.STARTDELIVERY_REQ, new RequestHandler() {

        public void visited(Request request) {
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), XARecoveryStage.this.toString() + "/visited, request=" + request + ", launching delivery stage");
            if (localRecovered && remoteRecovered)
                getStageQueue().setStage(new XADeliveryStage(ctx, routingConnection));
        }
    });
    if (!listener)
        getStageQueue().enqueue(new StartStageRequest());
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/init done");
}
Also used : CommitRequest(com.swiftmq.impl.routing.single.smqpr.v400.CommitRequest) RequestHandler(com.swiftmq.impl.routing.single.smqpr.RequestHandler) RecoveryRequest(com.swiftmq.impl.routing.single.smqpr.v400.RecoveryRequest) XAContext(com.swiftmq.swiftlet.xa.XAContext) XidFilter(com.swiftmq.swiftlet.xa.XidFilter) StartStageRequest(com.swiftmq.impl.routing.single.smqpr.StartStageRequest) CommitRequest(com.swiftmq.impl.routing.single.smqpr.v400.CommitRequest) RecoveryRequest(com.swiftmq.impl.routing.single.smqpr.v400.RecoveryRequest) StartStageRequest(com.swiftmq.impl.routing.single.smqpr.StartStageRequest) Request(com.swiftmq.tools.requestreply.Request) StartDeliveryRequest(com.swiftmq.impl.routing.single.smqpr.v400.StartDeliveryRequest) RecoveryReplyRequest(com.swiftmq.impl.routing.single.smqpr.v400.RecoveryReplyRequest) StartDeliveryRequest(com.swiftmq.impl.routing.single.smqpr.v400.StartDeliveryRequest) ArrayList(java.util.ArrayList) List(java.util.List) RecoveryReplyRequest(com.swiftmq.impl.routing.single.smqpr.v400.RecoveryReplyRequest) XAContextException(com.swiftmq.swiftlet.xa.XAContextException)

Example 7 with XAContext

use of com.swiftmq.swiftlet.xa.XAContext in project swiftmq-ce by iitsoftware.

the class XAResourceManagerSwiftletImpl method startup.

protected void startup(Configuration configuration) throws SwiftletException {
    ctx = new SwiftletContext(this, configuration);
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(getName(), "startup...");
    try {
        ctx.heuristicHandler.loadHeuristics();
    } catch (Exception e) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(getName(), "exception during loadHeuristics: " + e.toString());
        ctx.logSwiftlet.logError(getName(), "exception during loadHeuristics: " + e.toString());
    }
    try {
        buildPreparedTransactions();
    } catch (Exception e) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(getName(), "exception during buildPreparedTransactions: " + e.toString());
        ctx.logSwiftlet.logError(getName(), "exception during buildPreparedTransactions: " + e.toString());
    }
    if (contexts.size() > 0) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(getName(), contexts.size() + " prepared transactions found");
        ctx.logSwiftlet.logWarning(getName(), contexts.size() + " prepared transactions found!");
        System.out.println("+++ WARNING! " + contexts.size() + " prepared transactions found!");
        System.out.println("+++          HA/Routing XA transactions are automatically recovered.");
        System.out.println("+++          You may also use Explorer/CLI for heuristic commit or rollback.");
    }
    Property prop = configuration.getProperty("scan-interval");
    scanInterval = ((Long) prop.getValue()).longValue();
    ctx.timerSwiftlet.addTimerListener(scanInterval, this);
    prop.setPropertyChangeListener(new PropertyChangeListener() {

        public void propertyChanged(Property property, Object oldValue, Object newValue) throws PropertyChangeException {
            ctx.timerSwiftlet.removeTimerListener(XAResourceManagerSwiftletImpl.this);
            scanInterval = ((Long) newValue).longValue();
            ctx.timerSwiftlet.addTimerListener(scanInterval, XAResourceManagerSwiftletImpl.this);
        }
    });
    prop = configuration.getProperty("default-transaction-timeout");
    defaultTxTimeout = ((Long) prop.getValue()).longValue();
    long timeout = getTransactionTimeout();
    if (timeout > 0)
        ctx.timerSwiftlet.addTimerListener(timeout, txTimer);
    prop.setPropertyChangeListener(new PropertyChangeListener() {

        public void propertyChanged(Property property, Object oldValue, Object newValue) throws PropertyChangeException {
            long timeout = getTransactionTimeout();
            if (timeout > 0)
                ctx.timerSwiftlet.removeTimerListener(txTimer);
            defaultTxTimeout = ((Long) newValue).longValue();
            timeout = getTransactionTimeout();
            if (timeout > 0)
                ctx.timerSwiftlet.addTimerListener(timeout, txTimer);
        }
    });
    CommandRegistry commandRegistry = ctx.preparedUsageList.getCommandRegistry();
    CommandExecutor commitExecutor = new CommandExecutor() {

        public String[] execute(String[] context, Entity entity, String[] cmd) {
            if (cmd.length != 2)
                return new String[] { TreeCommands.ERROR, "Invalid command, please try 'commit <id>'" };
            Entity e = ctx.preparedUsageList.getEntity(cmd[1]);
            if (e == null)
                return new String[] { TreeCommands.ERROR, "Unknown Entity: " + cmd[1] };
            XAContext xac = (XAContext) contexts.get(e.getDynamicObject());
            XidImpl xid = xac.getXid();
            try {
                xac.commit(false);
                if (!xid.isRouting())
                    ctx.heuristicHandler.addHeuristic(xid, true);
            } catch (Exception e1) {
                return new String[] { TreeCommands.ERROR, "Exception during commit: " + e1 };
            }
            removeXAContext(xid);
            return null;
        }
    };
    Command commitCommand = new Command("commit", "commit <id>", "Commit", true, commitExecutor, true, true);
    commandRegistry.addCommand(commitCommand);
    CommandExecutor rollbackExecutor = new CommandExecutor() {

        public String[] execute(String[] context, Entity entity, String[] cmd) {
            if (cmd.length != 2)
                return new String[] { TreeCommands.ERROR, "Invalid command, please try 'rollback <id>'" };
            Entity e = ctx.preparedUsageList.getEntity(cmd[1]);
            if (e == null)
                return new String[] { TreeCommands.ERROR, "Unknown Entity: " + cmd[1] };
            XAContext xac = (XAContext) contexts.get(e.getDynamicObject());
            XidImpl xid = xac.getXid();
            try {
                xac.rollback();
                if (!xid.isRouting())
                    ctx.heuristicHandler.addHeuristic(xid, false);
            } catch (Exception e1) {
                return new String[] { TreeCommands.ERROR, "Exception during rollback: " + e1 };
            }
            removeXAContext(xid);
            return null;
        }
    };
    Command rollbackCommand = new Command("rollback", "rollback <id>", "Rollback", true, rollbackExecutor, true, true);
    commandRegistry.addCommand(rollbackCommand);
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(getName(), "startup...done");
}
Also used : XAContext(com.swiftmq.swiftlet.xa.XAContext) XidImpl(com.swiftmq.jms.XidImpl) SwiftletException(com.swiftmq.swiftlet.SwiftletException) XAContextException(com.swiftmq.swiftlet.xa.XAContextException)

Example 8 with XAContext

use of com.swiftmq.swiftlet.xa.XAContext in project swiftmq-ce by iitsoftware.

the class XAResourceManagerSwiftletImpl method shutdown.

protected void shutdown() throws SwiftletException {
    // true when shutdown while standby
    if (ctx == null)
        return;
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(getName(), "shutdown...");
    ctx.heuristicHandler.close();
    ctx.timerSwiftlet.removeTimerListener(this);
    if (defaultTxTimeout > 0)
        ctx.timerSwiftlet.removeTimerListener(txTimer);
    for (Iterator iter = contexts.entrySet().iterator(); iter.hasNext(); ) {
        XAContext xac = (XAContext) ((Map.Entry) iter.next()).getValue();
        xac.close();
    }
    contexts.clear();
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(getName(), "shutdown...done");
    ctx = null;
}
Also used : XAContext(com.swiftmq.swiftlet.xa.XAContext)

Example 9 with XAContext

use of com.swiftmq.swiftlet.xa.XAContext in project swiftmq-ce by iitsoftware.

the class XADeliveryStage method close.

public void close() {
    if (ctx.traceSpace.enabled)
        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close ...");
    super.close();
    closed = true;
    if (notificationList.size() > 0) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, final notify ...");
        for (Iterator iter = notificationList.entrySet().iterator(); iter.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iter.next();
            DeliveryRequest dr = (DeliveryRequest) entry.getValue();
            if (ctx.traceSpace.enabled)
                ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, final notify: " + dr);
            dr.callback.delivered(dr);
        }
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, final notify done");
        notificationList.clear();
    }
    if (outboundTransactions.size() > 0) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, passing prepared outbound tx to XAResourceManager ...");
        for (Iterator iter = outboundTransactions.entrySet().iterator(); iter.hasNext(); ) {
            try {
                Map.Entry entry = (Map.Entry) iter.next();
                XidImpl xid = (XidImpl) entry.getKey();
                XAContext xac = ctx.xaResourceManagerSwiftlet.createXAContext(xid);
                int id = xac.register(toString());
                QueuePullTransaction t = (QueuePullTransaction) entry.getValue();
                xac.addTransaction(id, t.getQueueName(), t);
                xac.unregister(id, false);
                xac.setPrepared(true);
            } catch (XAContextException e) {
                ctx.logSwiftlet.logError(ctx.routingSwiftlet.getName(), toString() + "/close, passing prepared outbound tx to XAResourceManager, exception: " + e);
            }
        }
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, passing prepared outbound tx to XAResourceManager done");
        outboundTransactions.clear();
    }
    if (inboundTransactions.size() > 0) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, passing prepared inbound tx to XAResourceManager ...");
        for (Iterator iter = inboundTransactions.entrySet().iterator(); iter.hasNext(); ) {
            ((Tx) ((Map.Entry) iter.next()).getValue()).handOver();
        }
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/close, passing prepared inbound tx to XAResourceManager done");
    }
    for (Iterator iter = producers.entrySet().iterator(); iter.hasNext(); ) {
        QueueSender sender = (QueueSender) ((Map.Entry) iter.next()).getValue();
        try {
            sender.close();
        } catch (Exception e) {
        }
    }
    producers.clear();
    for (Iterator iter = consumers.entrySet().iterator(); iter.hasNext(); ) {
        QueueReceiver receiver = (QueueReceiver) ((Map.Entry) iter.next()).getValue();
        try {
            receiver.close();
        } catch (Exception e) {
        }
    }
    consumers.clear();
    if (throttleQueue != null)
        throttleQueue.close();
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.SMQRFactory.START_STAGE_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.SMQRFactory.SEND_ROUTE_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.SMQRFactory.DELIVERY_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.ROUTE_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.ADJUST_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.TRANSACTION_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.COMMIT_REQ, null);
    visitor.setRequestHandler(com.swiftmq.impl.routing.single.smqpr.v400.SMQRFactory.COMMIT_REPREQ, null);
}
Also used : XAContext(com.swiftmq.swiftlet.xa.XAContext) XidImpl(com.swiftmq.jms.XidImpl) QueuePullTransaction(com.swiftmq.swiftlet.queue.QueuePullTransaction) JMSException(javax.jms.JMSException) XAContextException(com.swiftmq.swiftlet.xa.XAContextException) QueueSender(com.swiftmq.swiftlet.queue.QueueSender) QueueReceiver(com.swiftmq.swiftlet.queue.QueueReceiver) XAContextException(com.swiftmq.swiftlet.xa.XAContextException)

Example 10 with XAContext

use of com.swiftmq.swiftlet.xa.XAContext in project swiftmq-ce by iitsoftware.

the class XARecoveryStage method doRecover.

private void doRecover(List localXids, List remoteXids) {
    // Nothing to recover
    if (localXids == null && remoteXids == null) {
        if (ctx.traceSpace.enabled)
            ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover, nothing to do");
        return;
    }
    List remoteRecoveryList = new ArrayList();
    // Check local vs remote
    if (localXids != null) {
        for (int i = 0; i < localXids.size(); i++) {
            XidImpl lXid = (XidImpl) localXids.get(i);
            if (containsXid(remoteXids, lXid)) {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover [" + lXid + "], local prepared, remote prepared, commit 1:local, 2:remote");
                // local prepared, remote prepared, commit 1:local, 2:remote
                XAContext xac = ctx.xaResourceManagerSwiftlet.getXAContext(lXid);
                try {
                    xac.commit(false);
                } catch (XAContextException e) {
                    if (ctx.traceSpace.enabled)
                        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover, exception=" + e);
                    ctx.logSwiftlet.logError(ctx.routingSwiftlet.getName(), toString() + "/doRecover, commit, exception=" + e);
                }
                ctx.xaResourceManagerSwiftlet.removeXAContext(lXid);
                remoteRecoveryList.add(new CommitRequest(lXid));
            } else {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover [" + lXid + "], local prepared, remote unknown, rollback local");
                // local prepared, remote unknown, rollback local
                XAContext xac = ctx.xaResourceManagerSwiftlet.getXAContext(lXid);
                try {
                    xac.rollback();
                } catch (XAContextException e) {
                    if (ctx.traceSpace.enabled)
                        ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover, exception=" + e);
                    ctx.logSwiftlet.logError(ctx.routingSwiftlet.getName(), toString() + "/doRecover, rollback, exception=" + e);
                }
                ctx.xaResourceManagerSwiftlet.removeXAContext(lXid);
            }
        }
    }
    // Check remote Xids not known locally
    if (remoteXids != null) {
        for (int i = 0; i < remoteXids.size(); i++) {
            XidImpl rXid = (XidImpl) remoteXids.get(i);
            if (!containsXid(localXids, rXid)) {
                if (ctx.traceSpace.enabled)
                    ctx.traceSpace.trace(ctx.routingSwiftlet.getName(), toString() + "/doRecover [" + rXid + "], remote prepared, locally already committed, commit remote");
                // remote prepared, locally already committed, commit remote
                remoteRecoveryList.add(new CommitRequest(rXid));
            }
        }
    }
    if (remoteRecoveryList.size() > 0) {
        Collections.sort(remoteRecoveryList, new Comparator() {

            public int compare(Object o1, Object o2) {
                int i1 = ((CommitRequest) o1).getXid().getFormatId();
                int i2 = ((CommitRequest) o2).getXid().getFormatId();
                return i1 == i2 ? 0 : i1 < i2 ? -1 : 1;
            }
        });
        for (int i = 0; i < remoteRecoveryList.size(); i++) {
            CommitRequest r = (CommitRequest) remoteRecoveryList.get(i);
            routingConnection.getOutboundQueue().enqueue(r);
        }
    }
}
Also used : CommitRequest(com.swiftmq.impl.routing.single.smqpr.v400.CommitRequest) XAContext(com.swiftmq.swiftlet.xa.XAContext) XidImpl(com.swiftmq.jms.XidImpl) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) XAContextException(com.swiftmq.swiftlet.xa.XAContextException) Comparator(java.util.Comparator)

Aggregations

XAContext (com.swiftmq.swiftlet.xa.XAContext)10 XAContextException (com.swiftmq.swiftlet.xa.XAContextException)8 XidImpl (com.swiftmq.jms.XidImpl)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 RequestHandler (com.swiftmq.impl.routing.single.smqpr.RequestHandler)2 StartStageRequest (com.swiftmq.impl.routing.single.smqpr.StartStageRequest)2 CommitRequest (com.swiftmq.impl.routing.single.smqpr.v400.CommitRequest)2 CommitRequest (com.swiftmq.impl.routing.single.smqpr.v942.CommitRequest)2 QueuePullTransaction (com.swiftmq.swiftlet.queue.QueuePullTransaction)2 QueueReceiver (com.swiftmq.swiftlet.queue.QueueReceiver)2 QueueSender (com.swiftmq.swiftlet.queue.QueueSender)2 XidFilter (com.swiftmq.swiftlet.xa.XidFilter)2 Request (com.swiftmq.tools.requestreply.Request)2 Comparator (java.util.Comparator)2 JMSException (javax.jms.JMSException)2 RecoveryReplyRequest (com.swiftmq.impl.routing.single.smqpr.v400.RecoveryReplyRequest)1 RecoveryRequest (com.swiftmq.impl.routing.single.smqpr.v400.RecoveryRequest)1 StartDeliveryRequest (com.swiftmq.impl.routing.single.smqpr.v400.StartDeliveryRequest)1 RecoveryReplyRequest (com.swiftmq.impl.routing.single.smqpr.v942.RecoveryReplyRequest)1