@Override
 public void onDataRemoved(String key) {
   _tracer.info("Remove Routing Model: " + key);
   synchronized (_models) {
     _models.remove(key);
   }
   _tracer.info(getRoutingList());
 }
 @Override
 public void onDataChanged(String key, byte[] data) {
   _tracer.debug("Got data: " + PSConvert.bytes2HexString(data));
   RoutingModel model = bytes2Model(data);
   _tracer.info("Got RoutingModel: " + model.toString());
   synchronized (_models) {
     _models.put(model.getKey(), model);
   }
   _tracer.info(getRoutingList());
 }
 private void innerRegister(RoutingModel model) {
   boolean exists = false;
   do {
     try {
       _zk.createTempSeq(model.getKey(), model2Bytes(model));
       _tracer.info("RouteModel has been registered.\r\n" + model.toString());
       exists = false;
     } catch (KeeperException.NodeExistsException ex) {
       if (ex.code() == Code.NODEEXISTS) {
         exists = true;
         _tracer.error("Node is exist.", ex);
         try {
           Thread.sleep(2000);
         } catch (InterruptedException e) {
           e.printStackTrace();
         }
       } else {
         exists = false;
       }
     } catch (Throwable t) {
       _tracer.error("DynamicRouting.onConnected error.", t);
       exists = false;
     }
   } while (exists);
 }
  @Override
  public synchronized void onConnected(boolean newSession) {
    _isConnected = true;

    if (!newSession) {
      _tracer.info(getRoutingList());
      return;
    }

    for (RoutingModel model : _myModels) innerRegister(model);
    if (_myModels.size() == 0) {
      try {
        _zk.fireDataChanged();
      } catch (Throwable t) {
        _tracer.error("DynamicRouting.onConnected error.", t);
      }
    }
  }