Exemplo n.º 1
0
    public void processResult(int rc, String node, Object ctx, Stat statistics) {
      if (Code.NONODE.equals(Code.get(rc))) {
        if (configuration.shouldCreate()) {
          log.warn(format("Node '%s' did not exist, creating it...", node));
          ProductionContext context = (ProductionContext) ctx;
          OperationResult<String> result = null;
          try {
            result = createNode(context);
          } catch (Exception e) {
            log.error(format("Error trying to create node '%s'", node), e);
          }

          if (result == null || !result.isOk()) {
            log.error(format("Error creating node '%s'", node), result.getException());
          }
        }
      } else {
        logStoreComplete(node, statistics);
      }
    }
Exemplo n.º 2
0
  /**
   * async create
   *
   * <p>TODO: rename to create
   */
  @Override
  public boolean[] createChildren(List<String> paths, List<T> records, int options) {
    boolean[] success = new boolean[paths.size()];

    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
      LOG.error("Invalid async create mode. options: " + options);
      return success;
    }

    boolean[] needCreate = new boolean[paths.size()];
    Arrays.fill(needCreate, true);
    List<List<String>> pathsCreated =
        new ArrayList<List<String>>(Collections.<List<String>>nCopies(paths.size(), null));

    long startT = System.nanoTime();
    try {

      CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);

      for (int i = 0; i < cbList.length; i++) {
        CreateCallbackHandler cb = cbList[i];
        success[i] = (Code.get(cb.getRc()) == Code.OK);
      }

      return success;

    } finally {
      long endT = System.nanoTime();
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "create_async, size: "
                + paths.size()
                + ", paths: "
                + paths.get(0)
                + ",... time: "
                + (endT - startT)
                + " ns");
      }
    }
  }
Exemplo n.º 3
0
  /**
   * async update
   *
   * <p>return: updatedData on success or null on fail
   */
  List<T> update(
      List<String> paths,
      List<DataUpdater<T>> updaters,
      List<List<String>> pathsCreated,
      List<Stat> stats,
      int options) {
    if (paths == null || paths.size() == 0) {
      LOG.error("paths is null or empty");
      return Collections.emptyList();
    }

    if (updaters.size() != paths.size()
        || (pathsCreated != null && pathsCreated.size() != paths.size())) {
      throw new IllegalArgumentException(
          "paths, updaters, and pathsCreated should be of same size");
    }

    List<Stat> setStats = new ArrayList<Stat>(Collections.<Stat>nCopies(paths.size(), null));
    List<T> updateData = new ArrayList<T>(Collections.<T>nCopies(paths.size(), null));

    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
      LOG.error("Invalid update mode. options: " + options);
      return updateData;
    }

    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
    CreateCallbackHandler[] createCbList = null;
    boolean[] needUpdate = new boolean[paths.size()];
    Arrays.fill(needUpdate, true);

    long startT = System.nanoTime();

    try {
      boolean retry;
      do {
        retry = false;
        boolean[] needCreate = new boolean[paths.size()]; // init'ed with false
        boolean failOnNoNode = false;

        // asycn read all data
        List<Stat> curStats = new ArrayList<Stat>();
        List<T> curDataList = get(paths, curStats, Arrays.copyOf(needUpdate, needUpdate.length));

        // async update
        List<T> newDataList = new ArrayList<T>();
        for (int i = 0; i < paths.size(); i++) {
          if (!needUpdate[i]) {
            newDataList.add(null);
            continue;
          }
          String path = paths.get(i);
          DataUpdater<T> updater = updaters.get(i);
          T newData = updater.update(curDataList.get(i));
          newDataList.add(newData);
          Stat curStat = curStats.get(i);
          if (curStat == null) {
            // node not exists
            failOnNoNode = true;
            needCreate[i] = true;
          } else {
            cbList[i] = new SetDataCallbackHandler();
            _zkClient.asyncSetData(path, newData, curStat.getVersion(), cbList[i]);
          }
        }

        // wait for completion
        boolean failOnBadVersion = false;

        for (int i = 0; i < paths.size(); i++) {
          SetDataCallbackHandler cb = cbList[i];
          if (cb == null) continue;

          cb.waitForSuccess();

          switch (Code.get(cb.getRc())) {
            case OK:
              updateData.set(i, newDataList.get(i));
              setStats.set(i, cb.getStat());
              needUpdate[i] = false;
              break;
            case NONODE:
              failOnNoNode = true;
              needCreate[i] = true;
              break;
            case BADVERSION:
              failOnBadVersion = true;
              break;
            default:
              // if fail on error other than NoNode or BadVersion
              // will not retry
              needUpdate[i] = false;
              break;
          }
        }

        // if failOnNoNode, try create
        if (failOnNoNode) {
          createCbList = create(paths, newDataList, needCreate, pathsCreated, options);
          for (int i = 0; i < paths.size(); i++) {
            CreateCallbackHandler createCb = createCbList[i];
            if (createCb == null) {
              continue;
            }

            switch (Code.get(createCb.getRc())) {
              case OK:
                needUpdate[i] = false;
                updateData.set(i, newDataList.get(i));
                setStats.set(i, ZNode.ZERO_STAT);
                break;
              case NODEEXISTS:
                retry = true;
                break;
              default:
                // if fail on error other than NodeExists
                // will not retry
                needUpdate[i] = false;
                break;
            }
          }
        }

        // if failOnBadVersion, retry
        if (failOnBadVersion) {
          retry = true;
        }
      } while (retry);

      if (stats != null) {
        stats.clear();
        stats.addAll(setStats);
      }

      return updateData;
    } finally {
      long endT = System.nanoTime();
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "setData_async, size: "
                + paths.size()
                + ", paths: "
                + paths.get(0)
                + ",... time: "
                + (endT - startT)
                + " ns");
      }
    }
  }
Exemplo n.º 4
0
  /** async set, give up on error other than NoNode */
  boolean[] set(
      List<String> paths,
      List<T> records,
      List<List<String>> pathsCreated,
      List<Stat> stats,
      int options) {
    if (paths == null || paths.size() == 0) {
      return new boolean[0];
    }

    if ((records != null && records.size() != paths.size())
        || (pathsCreated != null && pathsCreated.size() != paths.size())) {
      throw new IllegalArgumentException("paths, records, and pathsCreated should be of same size");
    }

    boolean[] success = new boolean[paths.size()];

    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
      LOG.error("Invalid async set mode. options: " + options);
      return success;
    }

    List<Stat> setStats = new ArrayList<Stat>(Collections.<Stat>nCopies(paths.size(), null));
    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
    CreateCallbackHandler[] createCbList = null;
    boolean[] needSet = new boolean[paths.size()];
    Arrays.fill(needSet, true);

    long startT = System.nanoTime();

    try {
      boolean retry;
      do {
        retry = false;

        for (int i = 0; i < paths.size(); i++) {
          if (!needSet[i]) continue;

          String path = paths.get(i);
          T record = records.get(i);
          cbList[i] = new SetDataCallbackHandler();
          _zkClient.asyncSetData(path, record, -1, cbList[i]);
        }

        boolean failOnNoNode = false;

        for (int i = 0; i < cbList.length; i++) {
          SetDataCallbackHandler cb = cbList[i];
          cb.waitForSuccess();
          Code rc = Code.get(cb.getRc());
          switch (rc) {
            case OK:
              setStats.set(i, cb.getStat());
              needSet[i] = false;
              break;
            case NONODE:
              // if fail on NoNode, try create the node
              failOnNoNode = true;
              break;
            default:
              // if fail on error other than NoNode, give up
              needSet[i] = false;
              break;
          }
        }

        // if failOnNoNode, try create
        if (failOnNoNode) {
          boolean[] needCreate = Arrays.copyOf(needSet, needSet.length);
          createCbList = create(paths, records, needCreate, pathsCreated, options);
          for (int i = 0; i < createCbList.length; i++) {
            CreateCallbackHandler createCb = createCbList[i];
            if (createCb == null) {
              continue;
            }

            Code rc = Code.get(createCb.getRc());
            switch (rc) {
              case OK:
                setStats.set(i, ZNode.ZERO_STAT);
                needSet[i] = false;
                break;
              case NODEEXISTS:
                retry = true;
                break;
              default:
                // if creation fails on error other than NodeExists
                // no need to retry set
                needSet[i] = false;
                break;
            }
          }
        }
      } while (retry);

      // construct return results
      for (int i = 0; i < cbList.length; i++) {
        SetDataCallbackHandler cb = cbList[i];

        Code rc = Code.get(cb.getRc());
        if (rc == Code.OK) {
          success[i] = true;
        } else if (rc == Code.NONODE) {
          CreateCallbackHandler createCb = createCbList[i];
          if (Code.get(createCb.getRc()) == Code.OK) {
            success[i] = true;
          }
        }
      }

      if (stats != null) {
        stats.clear();
        stats.addAll(setStats);
      }

      return success;
    } finally {
      long endT = System.nanoTime();
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "setData_async, size: "
                + paths.size()
                + ", paths: "
                + paths.get(0)
                + ",... time: "
                + (endT - startT)
                + " ns");
      }
    }
  }
Exemplo n.º 5
0
  /** async create. give up on error other than NONODE */
  CreateCallbackHandler[] create(
      List<String> paths,
      List<T> records,
      boolean[] needCreate,
      List<List<String>> pathsCreated,
      int options) {
    if ((records != null && records.size() != paths.size())
        || needCreate.length != paths.size()
        || (pathsCreated != null && pathsCreated.size() != paths.size())) {
      throw new IllegalArgumentException(
          "paths, records, needCreate, and pathsCreated should be of same size");
    }

    CreateCallbackHandler[] cbList = new CreateCallbackHandler[paths.size()];

    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
      LOG.error("Invalid async set mode. options: " + options);
      return cbList;
    }

    boolean retry;
    do {
      retry = false;

      for (int i = 0; i < paths.size(); i++) {
        if (!needCreate[i]) continue;

        String path = paths.get(i);
        T record = records == null ? null : records.get(i);
        cbList[i] = new CreateCallbackHandler();
        _zkClient.asyncCreate(path, record, mode, cbList[i]);
      }

      List<String> parentPaths =
          new ArrayList<String>(Collections.<String>nCopies(paths.size(), null));
      boolean failOnNoNode = false;

      for (int i = 0; i < paths.size(); i++) {
        if (!needCreate[i]) continue;

        CreateCallbackHandler cb = cbList[i];
        cb.waitForSuccess();
        String path = paths.get(i);

        if (Code.get(cb.getRc()) == Code.NONODE) {
          String parentPath = new File(path).getParent();
          parentPaths.set(i, parentPath);
          failOnNoNode = true;
        } else {
          // if create succeed or fail on error other than NONODE,
          // give up
          needCreate[i] = false;

          // if succeeds, record what paths we've created
          if (Code.get(cb.getRc()) == Code.OK && pathsCreated != null) {
            if (pathsCreated.get(i) == null) {
              pathsCreated.set(i, new ArrayList<String>());
            }
            pathsCreated.get(i).add(path);
          }
        }
      }

      if (failOnNoNode) {
        boolean[] needCreateParent = Arrays.copyOf(needCreate, needCreate.length);

        CreateCallbackHandler[] parentCbList =
            create(parentPaths, null, needCreateParent, pathsCreated, AccessOption.PERSISTENT);
        for (int i = 0; i < parentCbList.length; i++) {
          CreateCallbackHandler parentCb = parentCbList[i];
          if (parentCb == null) continue;

          Code rc = Code.get(parentCb.getRc());

          // if parent is created, retry create child
          if (rc == Code.OK || rc == Code.NODEEXISTS) {
            retry = true;
            break;
          }
        }
      }
    } while (retry);

    return cbList;
  }
Exemplo n.º 6
0
  /** async get */
  List<T> get(List<String> paths, List<Stat> stats, boolean[] needRead) {
    if (paths == null || paths.size() == 0) {
      return Collections.emptyList();
    }

    // init stats
    if (stats != null) {
      stats.clear();
      stats.addAll(Collections.<Stat>nCopies(paths.size(), null));
    }

    long startT = System.nanoTime();

    try {
      // issue asyn get requests
      GetDataCallbackHandler[] cbList = new GetDataCallbackHandler[paths.size()];
      for (int i = 0; i < paths.size(); i++) {
        if (!needRead[i]) continue;

        String path = paths.get(i);
        cbList[i] = new GetDataCallbackHandler();
        _zkClient.asyncGetData(path, cbList[i]);
      }

      // wait for completion
      for (int i = 0; i < cbList.length; i++) {
        if (!needRead[i]) continue;

        GetDataCallbackHandler cb = cbList[i];
        cb.waitForSuccess();
      }

      // construct return results
      List<T> records = new ArrayList<T>(Collections.<T>nCopies(paths.size(), null));

      for (int i = 0; i < paths.size(); i++) {
        if (!needRead[i]) continue;

        GetDataCallbackHandler cb = cbList[i];
        if (Code.get(cb.getRc()) == Code.OK) {
          @SuppressWarnings("unchecked")
          T record = (T) _zkClient.deserialize(cb._data, paths.get(i));
          records.set(i, record);
          if (stats != null) {
            stats.set(i, cb._stat);
          }
        }
      }

      return records;
    } finally {
      long endT = System.nanoTime();
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "getData_async, size: "
                + paths.size()
                + ", paths: "
                + paths.get(0)
                + ",... time: "
                + (endT - startT)
                + " ns");
      }
    }
  }
Exemplo n.º 7
0
  public void processRequest(Request request) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Processing request:: " + request);
    }
    // request.addRQRec(">final");
    long traceMask = ZooTrace.CLIENT_REQUEST_TRACE_MASK;
    if (request.type == OpCode.ping) {
      traceMask = ZooTrace.SERVER_PING_TRACE_MASK;
    }
    if (LOG.isTraceEnabled()) {
      ZooTrace.logRequest(LOG, traceMask, 'E', request, "");
    }
    ProcessTxnResult rc = null;
    synchronized (zks.outstandingChanges) {
      while (!zks.outstandingChanges.isEmpty()
          && zks.outstandingChanges.get(0).zxid <= request.zxid) {
        ChangeRecord cr = zks.outstandingChanges.remove(0);
        if (cr.zxid < request.zxid) {
          LOG.warn("Zxid outstanding " + cr.zxid + " is less than current " + request.zxid);
        }
        if (zks.outstandingChangesForPath.get(cr.path) == cr) {
          zks.outstandingChangesForPath.remove(cr.path);
        }
      }
      if (request.hdr != null) {
        TxnHeader hdr = request.hdr;
        Record txn = request.txn;

        rc = zks.processTxn(hdr, txn);
      }
      // do not add non quorum packets to the queue.
      if (Request.isQuorum(request.type)) {
        zks.getZKDatabase().addCommittedProposal(request);
      }
    }

    if (request.hdr != null && request.hdr.getType() == OpCode.closeSession) {
      ServerCnxnFactory scxn = zks.getServerCnxnFactory();
      // this might be possible since
      // we might just be playing diffs from the leader
      if (scxn != null && request.cnxn == null) {
        // calling this if we have the cnxn results in the client's
        // close session response being lost - we've already closed
        // the session/socket here before we can send the closeSession
        // in the switch block below
        scxn.closeSession(request.sessionId);
        return;
      }
    }

    if (request.cnxn == null) {
      return;
    }
    ServerCnxn cnxn = request.cnxn;

    String lastOp = "NA";
    zks.decInProcess();
    Code err = Code.OK;
    Record rsp = null;
    boolean closeSession = false;
    try {
      if (request.hdr != null && request.hdr.getType() == OpCode.error) {
        throw KeeperException.create(KeeperException.Code.get(((ErrorTxn) request.txn).getErr()));
      }

      KeeperException ke = request.getException();
      if (ke != null && request.type != OpCode.multi) {
        throw ke;
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug("{}", request);
      }
      switch (request.type) {
        case OpCode.ping:
          {
            zks.serverStats().updateLatency(request.createTime);

            lastOp = "PING";
            cnxn.updateStatsForResponse(
                request.cxid, request.zxid, lastOp, request.createTime, System.currentTimeMillis());

            cnxn.sendResponse(
                new ReplyHeader(-2, zks.getZKDatabase().getDataTreeLastProcessedZxid(), 0),
                null,
                "response");
            return;
          }
        case OpCode.createSession:
          {
            zks.serverStats().updateLatency(request.createTime);

            lastOp = "SESS";
            cnxn.updateStatsForResponse(
                request.cxid, request.zxid, lastOp, request.createTime, System.currentTimeMillis());

            zks.finishSessionInit(request.cnxn, true);
            return;
          }
        case OpCode.multi:
          {
            lastOp = "MULT";
            rsp = new MultiResponse();

            for (ProcessTxnResult subTxnResult : rc.multiResult) {

              OpResult subResult;

              switch (subTxnResult.type) {
                case OpCode.check:
                  subResult = new CheckResult();
                  break;
                case OpCode.create:
                  subResult = new CreateResult(subTxnResult.path);
                  break;
                case OpCode.delete:
                  subResult = new DeleteResult();
                  break;
                case OpCode.setData:
                  subResult = new SetDataResult(subTxnResult.stat);
                  break;
                case OpCode.error:
                  subResult = new ErrorResult(subTxnResult.err);
                  break;
                default:
                  throw new IOException("Invalid type of op");
              }

              ((MultiResponse) rsp).add(subResult);
            }

            break;
          }
        case OpCode.create:
          {
            lastOp = "CREA";
            rsp = new CreateResponse(rc.path);
            err = Code.get(rc.err);
            break;
          }
        case OpCode.delete:
          {
            lastOp = "DELE";
            err = Code.get(rc.err);
            break;
          }
        case OpCode.setData:
          {
            lastOp = "SETD";
            rsp = new SetDataResponse(rc.stat);
            err = Code.get(rc.err);
            break;
          }
        case OpCode.setACL:
          {
            lastOp = "SETA";
            rsp = new SetACLResponse(rc.stat);
            err = Code.get(rc.err);
            break;
          }
        case OpCode.closeSession:
          {
            lastOp = "CLOS";
            closeSession = true;
            err = Code.get(rc.err);
            break;
          }
        case OpCode.sync:
          {
            lastOp = "SYNC";
            SyncRequest syncRequest = new SyncRequest();
            ByteBufferInputStream.byteBuffer2Record(request.request, syncRequest);
            rsp = new SyncResponse(syncRequest.getPath());
            break;
          }
        case OpCode.check:
          {
            lastOp = "CHEC";
            rsp = new SetDataResponse(rc.stat);
            err = Code.get(rc.err);
            break;
          }
        case OpCode.exists:
          {
            lastOp = "EXIS";
            // TODO we need to figure out the security requirement for this!
            ExistsRequest existsRequest = new ExistsRequest();
            ByteBufferInputStream.byteBuffer2Record(request.request, existsRequest);
            String path = existsRequest.getPath();
            if (path.indexOf('\0') != -1) {
              throw new KeeperException.BadArgumentsException();
            }
            Stat stat = zks.getZKDatabase().statNode(path, existsRequest.getWatch() ? cnxn : null);
            rsp = new ExistsResponse(stat);
            break;
          }
        case OpCode.getData:
          {
            lastOp = "GETD";
            GetDataRequest getDataRequest = new GetDataRequest();
            ByteBufferInputStream.byteBuffer2Record(request.request, getDataRequest);
            DataNode n = zks.getZKDatabase().getNode(getDataRequest.getPath());
            if (n == null) {
              throw new KeeperException.NoNodeException();
            }
            Long aclL;
            synchronized (n) {
              aclL = n.acl;
            }
            PrepRequestProcessor.checkACL(
                zks, zks.getZKDatabase().convertLong(aclL), ZooDefs.Perms.READ, request.authInfo);
            Stat stat = new Stat();
            byte b[] =
                zks.getZKDatabase()
                    .getData(
                        getDataRequest.getPath(), stat, getDataRequest.getWatch() ? cnxn : null);
            rsp = new GetDataResponse(b, stat);
            break;
          }
        case OpCode.setWatches:
          {
            lastOp = "SETW";
            SetWatches setWatches = new SetWatches();
            // XXX We really should NOT need this!!!!
            request.request.rewind();
            ByteBufferInputStream.byteBuffer2Record(request.request, setWatches);
            long relativeZxid = setWatches.getRelativeZxid();
            zks.getZKDatabase()
                .setWatches(
                    relativeZxid,
                    setWatches.getDataWatches(),
                    setWatches.getExistWatches(),
                    setWatches.getChildWatches(),
                    cnxn);
            break;
          }
        case OpCode.getACL:
          {
            lastOp = "GETA";
            GetACLRequest getACLRequest = new GetACLRequest();
            ByteBufferInputStream.byteBuffer2Record(request.request, getACLRequest);
            Stat stat = new Stat();
            List<ACL> acl = zks.getZKDatabase().getACL(getACLRequest.getPath(), stat);
            rsp = new GetACLResponse(acl, stat);
            break;
          }
        case OpCode.getChildren:
          {
            lastOp = "GETC";
            GetChildrenRequest getChildrenRequest = new GetChildrenRequest();
            ByteBufferInputStream.byteBuffer2Record(request.request, getChildrenRequest);
            DataNode n = zks.getZKDatabase().getNode(getChildrenRequest.getPath());
            if (n == null) {
              throw new KeeperException.NoNodeException();
            }
            Long aclG;
            synchronized (n) {
              aclG = n.acl;
            }
            PrepRequestProcessor.checkACL(
                zks, zks.getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ, request.authInfo);
            List<String> children =
                zks.getZKDatabase()
                    .getChildren(
                        getChildrenRequest.getPath(),
                        null,
                        getChildrenRequest.getWatch() ? cnxn : null);
            rsp = new GetChildrenResponse(children);
            break;
          }
        case OpCode.getChildren2:
          {
            lastOp = "GETC";
            GetChildren2Request getChildren2Request = new GetChildren2Request();
            ByteBufferInputStream.byteBuffer2Record(request.request, getChildren2Request);
            Stat stat = new Stat();
            DataNode n = zks.getZKDatabase().getNode(getChildren2Request.getPath());
            if (n == null) {
              throw new KeeperException.NoNodeException();
            }
            Long aclG;
            synchronized (n) {
              aclG = n.acl;
            }
            PrepRequestProcessor.checkACL(
                zks, zks.getZKDatabase().convertLong(aclG), ZooDefs.Perms.READ, request.authInfo);
            List<String> children =
                zks.getZKDatabase()
                    .getChildren(
                        getChildren2Request.getPath(),
                        stat,
                        getChildren2Request.getWatch() ? cnxn : null);
            rsp = new GetChildren2Response(children, stat);
            break;
          }
      }
    } catch (SessionMovedException e) {
      // session moved is a connection level error, we need to tear
      // down the connection otw ZOOKEEPER-710 might happen
      // ie client on slow follower starts to renew session, fails
      // before this completes, then tries the fast follower (leader)
      // and is successful, however the initial renew is then
      // successfully fwd/processed by the leader and as a result
      // the client and leader disagree on where the client is most
      // recently attached (and therefore invalid SESSION MOVED generated)
      cnxn.sendCloseSession();
      return;
    } catch (KeeperException e) {
      err = e.code();
    } catch (Exception e) {
      // log at error level as we are returning a marshalling
      // error to the user
      LOG.error("Failed to process " + request, e);
      StringBuilder sb = new StringBuilder();
      ByteBuffer bb = request.request;
      bb.rewind();
      while (bb.hasRemaining()) {
        sb.append(Integer.toHexString(bb.get() & 0xff));
      }
      LOG.error("Dumping request buffer: 0x" + sb.toString());
      err = Code.MARSHALLINGERROR;
    }

    long lastZxid = zks.getZKDatabase().getDataTreeLastProcessedZxid();
    ReplyHeader hdr = new ReplyHeader(request.cxid, lastZxid, err.intValue());

    zks.serverStats().updateLatency(request.createTime);
    cnxn.updateStatsForResponse(
        request.cxid, lastZxid, lastOp, request.createTime, System.currentTimeMillis());

    try {
      cnxn.sendResponse(hdr, rsp, "response");
      if (closeSession) {
        cnxn.sendCloseSession();
      }
    } catch (IOException e) {
      LOG.error("FIXMSG", e);
    }
  }