Ejemplo n.º 1
0
  /**
   * Gets license version 2 data for sign.
   *
   * @param lic GridGain license version 2.
   * @return Data for sign.
   */
  public static byte[] getDataV2ForSign(GridLicenseV2 lic) {
    assert lic != null;

    try {
      return new SB()
          .a(lic.getVersion())
          .a(lic.getId())
          .a(lic.getIssueDate() != null ? U.format(lic.getIssueDate(), DATE_PTRN) : "")
          .a(lic.getIssueOrganization())
          .a(lic.getUserOrganization())
          .a(lic.getUserWww())
          .a(lic.getUserEmail())
          .a(lic.getUserName())
          .a(lic.getLicenseNote())
          .a(lic.getVersionRegexp())
          .a(lic.getType())
          .a(lic.getExpireDate() != null ? U.format(lic.getExpireDate(), DATE_PTRN) : "")
          .a(lic.getMeteringKey1())
          .a(lic.getMeteringKey2())
          .a(lic.getMaxCpus())
          .a(lic.getMaxComputers())
          .a(lic.getMaxNodes())
          .a(lic.getMaxUpTime())
          .toString()
          .getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new GridRuntimeException(e);
    }
  }
Ejemplo n.º 2
0
  /**
   * Decodes value from a given byte array to the object according to the flags given.
   *
   * @param flags Flags.
   * @param bytes Byte array to decode.
   * @return Decoded value.
   * @throws GridException If deserialization failed.
   */
  private Object decodeObj(short flags, byte[] bytes) throws GridException {
    assert bytes != null;

    if ((flags & SERIALIZED_FLAG) != 0)
      return jdkMarshaller.unmarshal(new ByteArrayInputStream(bytes), null);

    int masked = flags & 0xff00;

    switch (masked) {
      case BOOLEAN_FLAG:
        return bytes[0] == '1';
      case INT_FLAG:
        return U.bytesToInt(bytes, 0);
      case LONG_FLAG:
        return U.bytesToLong(bytes, 0);
      case DATE_FLAG:
        return new Date(U.bytesToLong(bytes, 0));
      case BYTE_FLAG:
        return bytes[0];
      case FLOAT_FLAG:
        return Float.intBitsToFloat(U.bytesToInt(bytes, 0));
      case DOUBLE_FLAG:
        return Double.longBitsToDouble(U.bytesToLong(bytes, 0));
      case BYTE_ARR_FLAG:
        return bytes;
      default:
        return new String(bytes);
    }
  }
  /**
   * Processes unlock request.
   *
   * @param nodeId Sender node ID.
   * @param req Unlock request.
   */
  @SuppressWarnings({"unchecked"})
  private void processUnlockRequest(UUID nodeId, GridDistributedUnlockRequest req) {
    assert nodeId != null;

    try {
      ClassLoader ldr = ctx.deploy().globalLoader();
      List<byte[]> keys = req.keyBytes();

      for (byte[] keyBytes : keys) {
        K key = (K) U.unmarshal(ctx.marshaller(), new ByteArrayInputStream(keyBytes), ldr);

        while (true) {
          boolean created = false;

          GridDistributedCacheEntry<K, V> entry = peekexx(key);

          if (entry == null) {
            entry = entryexx(key);

            created = true;
          }

          try {
            entry.doneRemote(
                req.version(), req.version(), req.committedVersions(), req.rolledbackVersions());

            // Note that we don't reorder completed versions here,
            // as there is no point to reorder relative to the version
            // we are about to remove.
            if (entry.removeLock(req.version())) {
              if (log.isDebugEnabled())
                log.debug("Removed lock [lockId=" + req.version() + ", key=" + key + ']');

              if (created && entry.markObsolete(req.version())) removeIfObsolete(entry.key());
            } else if (log.isDebugEnabled())
              log.debug(
                  "Received unlock request for unknown candidate "
                      + "(added to cancelled locks set): "
                      + req);

            break;
          } catch (GridCacheEntryRemovedException ignored) {
            if (log.isDebugEnabled())
              log.debug(
                  "Received remove lock request for removed entry (will retry) [entry="
                      + entry
                      + ", req="
                      + req
                      + ']');
          }
        }
      }
    } catch (GridException e) {
      U.error(log, "Failed to unmarshal unlock key (unlock will not be performed): " + req, e);
    }
  }
Ejemplo n.º 4
0
  /**
   * Encodes given object to a byte array and returns flags that describe the type of serialized
   * object.
   *
   * @param obj Object to serialize.
   * @param out Output stream to which object should be written.
   * @return Serialization flags.
   * @throws GridException If JDK serialization failed.
   */
  private int encodeObj(Object obj, ByteArrayOutputStream out) throws GridException {
    int flags = 0;

    byte[] data = null;

    if (obj instanceof String) {
      data = ((String) obj).getBytes();
    } else if (obj instanceof Boolean) {
      data = new byte[] {(byte) ((Boolean) obj ? '1' : '0')};

      flags |= BOOLEAN_FLAG;
    } else if (obj instanceof Integer) {
      data = U.intToBytes((Integer) obj);

      flags |= INT_FLAG;
    } else if (obj instanceof Long) {
      data = U.longToBytes((Long) obj);

      flags |= LONG_FLAG;
    } else if (obj instanceof Date) {
      data = U.longToBytes(((Date) obj).getTime());

      flags |= DATE_FLAG;
    } else if (obj instanceof Byte) {
      data = new byte[] {(Byte) obj};

      flags |= BYTE_FLAG;
    } else if (obj instanceof Float) {
      data = U.intToBytes(Float.floatToIntBits((Float) obj));

      flags |= FLOAT_FLAG;
    } else if (obj instanceof Double) {
      data = U.longToBytes(Double.doubleToLongBits((Double) obj));

      flags |= DOUBLE_FLAG;
    } else if (obj instanceof byte[]) {
      data = (byte[]) obj;

      flags |= BYTE_ARR_FLAG;
    } else {
      jdkMarshaller.marshal(obj, out);

      flags |= SERIALIZED_FLAG;
    }

    if (data != null) out.write(data, 0, data.length);

    return flags;
  }
  /** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    threadId = in.readLong();
    commit = in.readBoolean();
    invalidate = in.readBoolean();
    reply = in.readBoolean();

    futId = U.readGridUuid(in);
    commitVer = CU.readVersion(in);
    baseVer = CU.readVersion(in);

    writeEntries = U.readList(in);
  }
  /** {@inheritDoc} */
  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);

    out.writeLong(threadId);
    out.writeBoolean(commit);
    out.writeBoolean(invalidate);
    out.writeBoolean(reply);

    U.writeGridUuid(out, futId);
    CU.writeVersion(out, commitVer);
    CU.writeVersion(out, baseVer);

    U.writeCollection(out, writeEntries);
  }
Ejemplo n.º 7
0
  /** {@inheritDoc} */
  @SuppressWarnings({"CatchGenericClass"})
  @Override
  public final void run() {
    try {
      body();
    } catch (InterruptedException e) {
      if (log.isDebugEnabled()) {
        log.debug("Caught interrupted exception: " + e);
      }
    }
    // Catch everything to make sure that it gets logged properly and
    // not to kill any threads from the underlying thread pool.
    catch (Throwable e) {
      U.error(log, "Runtime error caught during grid runnable execution: " + this, e);
    } finally {
      cleanup();

      if (log.isDebugEnabled()) {
        if (isInterrupted()) {
          log.debug(
              "Grid runnable finished due to interruption without cancellation: " + getName());
        } else {
          log.debug("Grid runnable finished normally: " + getName());
        }
      }
    }
  }
  /** Initializes future. */
  @SuppressWarnings({"unchecked"})
  void finish() {
    if (mappings != null) {
      finish(mappings.values());

      markInitialized();

      if (!isSync()) {
        boolean complete = true;

        for (GridFuture<?> f : pending())
          // Mini-future in non-sync mode gets done when message gets sent.
          if (isMini(f) && !f.isDone()) complete = false;

        if (complete) onComplete();
      }
    } else {
      assert !commit;

      try {
        tx.rollback();
      } catch (GridException e) {
        U.error(log, "Failed to rollback empty transaction: " + tx, e);
      }

      markInitialized();
    }
  }
Ejemplo n.º 9
0
  /** {@inheritDoc} */
  @SuppressWarnings({"unchecked"})
  @Override
  public void listenAsync(@Nullable final GridInClosure<? super GridFuture<R>> lsnr) {
    if (lsnr != null) {
      checkValid();

      boolean done;

      synchronized (mux) {
        done = this.done;

        if (!done) lsnrs.add(lsnr);
      }

      if (done) {
        try {
          if (syncNotify) notifyListener(lsnr);
          else
            ctx.closure()
                .runLocalSafe(
                    new GPR() {
                      @Override
                      public void run() {
                        notifyListener(lsnr);
                      }
                    },
                    true);
        } catch (IllegalStateException ignore) {
          U.warn(
              null,
              "Future notification will not proceed because grid is stopped: " + ctx.gridName());
        }
      }
    }
  }
  /**
   * @param nodeId Sender node ID.
   * @param msg Response to prepare request.
   */
  private void processPrepareResponse(UUID nodeId, GridDistributedTxPrepareResponse<K, V> msg) {
    assert nodeId != null;
    assert msg != null;

    GridReplicatedTxLocal<K, V> tx = ctx.tm().tx(msg.version());

    if (tx == null) {
      if (log.isDebugEnabled())
        log.debug(
            "Received prepare response for non-existing transaction [senderNodeId="
                + nodeId
                + ", res="
                + msg
                + ']');

      return;
    }

    GridReplicatedTxPrepareFuture<K, V> future = (GridReplicatedTxPrepareFuture<K, V>) tx.future();

    if (future != null) future.onResult(nodeId, msg);
    else
      U.error(
          log,
          "Received prepare response for transaction with no future [res="
              + msg
              + ", tx="
              + tx
              + ']');
  }
  /**
   * Records deploy event.
   *
   * @param cls Deployed class.
   * @param clsLdr Class loader.
   * @param recordEvt Flag indicating whether to record events.
   */
  @SuppressWarnings({"unchecked"})
  private void recordDeployFailed(Class<?> cls, ClassLoader clsLdr, boolean recordEvt) {
    assert cls != null;
    assert clsLdr != null;

    boolean isTask = isTask(cls);

    String msg =
        "Failed to deploy "
            + (isTask ? "task" : "class")
            + " [cls="
            + cls
            + ", clsLdr="
            + clsLdr
            + ']';

    if (recordEvt
        && ctx.event().isRecordable(isTask ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED)) {
      String taskName = isTask ? U.getTaskName((Class<? extends GridTask<?, ?>>) cls) : null;

      GridDeploymentEvent evt = new GridDeploymentEvent();

      evt.message(msg);
      evt.nodeId(ctx.localNodeId());
      evt.type(isTask(cls) ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED);
      evt.alias(taskName);

      ctx.event().record(evt);
    }

    if (log.isInfoEnabled()) {
      log.info(msg);
    }
  }
  /**
   * Load classes from given file. File could be either directory or JAR file.
   *
   * @param clsLdr Class loader to load files.
   * @param file Either directory or JAR file which contains classes or references to them.
   * @return Set of found and loaded classes or empty set if file does not exist.
   * @throws GridSpiException Thrown if given JAR file references to none existed class or
   *     IOException occurred during processing.
   */
  static Set<Class<? extends GridTask<?, ?>>> getClasses(ClassLoader clsLdr, File file)
      throws GridSpiException {
    Set<Class<? extends GridTask<?, ?>>> rsrcs = new HashSet<Class<? extends GridTask<?, ?>>>();

    if (file.exists() == false) {
      return rsrcs;
    }

    GridUriDeploymentFileResourceLoader fileRsrcLdr =
        new GridUriDeploymentFileResourceLoader(clsLdr, file);

    if (file.isDirectory()) {
      findResourcesInDirectory(fileRsrcLdr, file, rsrcs);
    } else {
      try {
        for (JarEntry entry : U.asIterable(new JarFile(file.getAbsolutePath()).entries())) {
          Class<? extends GridTask<?, ?>> rsrc = fileRsrcLdr.createResource(entry.getName(), false);

          if (rsrc != null) {
            rsrcs.add(rsrc);
          }
        }
      } catch (IOException e) {
        throw new GridSpiException(
            "Failed to discover classes in file: " + file.getAbsolutePath(), e);
      }
    }

    return rsrcs;
  }
Ejemplo n.º 13
0
  /** {@inheritDoc} */
  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);

    assert futId != null;
    assert miniId != null;
    assert ver != null;

    U.writeGridUuid(out, futId);
    U.writeGridUuid(out, miniId);
    U.writeCollection(out, entries);
    U.writeIntCollection(out, invalidParts);

    CU.writeVersion(out, ver);

    out.writeObject(err);
  }
 /**
  * @param bytes Bytes to unmarshal.
  * @param ldr Class loader.
  * @param <T> Type to unmarshal.
  * @return Unmarshalled value.
  * @throws GridException If unmarshal failed.
  */
 @SuppressWarnings({"unchecked", "TypeMayBeWeakened"})
 private <T> T unmarshal(GridSwapByteArray bytes, ClassLoader ldr) throws GridException {
   return (T)
       U.unmarshal(
           cctx.marshaller(),
           new ByteArrayInputStream(bytes.getArray(), bytes.getOffset(), bytes.getLength()),
           ldr);
 }
Ejemplo n.º 15
0
 /**
  * Delegates to {@link #call()} method.
  *
  * <p>{@inheritDoc}
  *
  * @return {@inheritDoc}
  * @throws GridException {@inheritDoc}
  */
 @Override
 public final Object execute() throws GridException {
   try {
     return call();
   } catch (Throwable e) {
     throw U.cast(e);
   }
 }
  /** {@inheritDoc} */
  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    super.writeExternal(out);

    out.writeLong(topVer);
    out.writeBoolean(implicitTx);
    out.writeBoolean(implicitSingleTx);
    out.writeBoolean(syncCommit);
    out.writeBoolean(syncRollback);
    out.writeObject(filterBytes);

    U.writeArray(out, dhtVers);

    assert miniId != null;

    U.writeGridUuid(out, miniId);
  }
  /** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    topVer = in.readLong();
    implicitTx = in.readBoolean();
    implicitSingleTx = in.readBoolean();
    syncCommit = in.readBoolean();
    syncRollback = in.readBoolean();
    filterBytes = (byte[][]) in.readObject();

    dhtVers = U.readArray(in, CU.versionArrayFactory());

    miniId = U.readGridUuid(in);

    assert miniId != null;
  }
  /**
   * @param nodeId Sender node ID.
   * @param msg Finish transaction response.
   */
  private void processFinishResponse(UUID nodeId, GridDistributedTxFinishResponse<K, V> msg) {
    GridReplicatedTxCommitFuture<K, V> fut =
        (GridReplicatedTxCommitFuture<K, V>)
            ctx.mvcc().<GridCacheTx>future(msg.xid().id(), msg.futureId());

    if (fut != null) fut.onResult(nodeId);
    else U.warn(log, "Received finish response for unknown transaction: " + msg);
  }
  /**
   * Reconstructs object on demarshalling.
   *
   * @return Reconstructed object.
   * @throws ObjectStreamException Thrown in case of demarshalling error.
   */
  private Object readResolve() throws ObjectStreamException {
    GridTuple2<GridCacheContext, String> t = stash.get();

    try {
      return t.get1().dataStructures().sequence(t.get2(), 0L, false, false);
    } catch (GridException e) {
      throw U.withCause(new InvalidObjectException(e.getMessage()), e);
    }
  }
  /**
   * Removes locks regardless of whether they are owned or not for given version and keys.
   *
   * @param ver Lock version.
   * @param keys Keys.
   */
  @SuppressWarnings({"unchecked"})
  public void removeLocks(GridCacheVersion ver, Collection<? extends K> keys) {
    if (keys.isEmpty()) return;

    Collection<GridRichNode> nodes = ctx.remoteNodes(keys);

    try {
      // Send request to remove from remote nodes.
      GridDistributedUnlockRequest<K, V> req = new GridDistributedUnlockRequest<K, V>(keys.size());

      req.version(ver);

      for (K key : keys) {
        while (true) {
          GridDistributedCacheEntry<K, V> entry = peekexx(key);

          try {
            if (entry != null) {
              GridCacheMvccCandidate<K> cand = entry.candidate(ver);

              if (cand != null) {
                // Remove candidate from local node first.
                if (entry.removeLock(cand.version())) {
                  // If there is only local node in this lock's topology,
                  // then there is no reason to distribute the request.
                  if (nodes.isEmpty()) continue;

                  req.addKey(entry.key(), entry.getOrMarshalKeyBytes(), ctx);
                }
              }
            }

            break;
          } catch (GridCacheEntryRemovedException ignored) {
            if (log.isDebugEnabled())
              log.debug(
                  "Attempted to remove lock from removed entry (will retry) [rmvVer="
                      + ver
                      + ", entry="
                      + entry
                      + ']');
          }
        }
      }

      if (nodes.isEmpty()) return;

      req.completedVersions(ctx.tm().committedVersions(ver), ctx.tm().rolledbackVersions(ver));

      if (!req.keyBytes().isEmpty())
        // We don't wait for reply to this message.
        ctx.io().safeSend(nodes, req, null);
    } catch (GridException ex) {
      U.error(log, "Failed to unlock the lock for keys: " + keys, ex);
    }
  }
  /** {@inheritDoc} */
  @Override
  public void start() throws GridException {
    ctxLdr = U.detectClassLoader(getClass());

    spi.setListener(new LocalDeploymentListener());

    if (log.isDebugEnabled()) {
      log.debug(startInfo());
    }
  }
  /**
   * Reconstructs object on demarshalling.
   *
   * @return Reconstructed object.
   * @throws ObjectStreamException Thrown in case of demarshalling error.
   */
  @SuppressWarnings({"ConstantConditions"})
  private Object readResolve() throws ObjectStreamException {
    GridTuple2<GridCacheContext, String> t = stash.get();

    try {
      return t.get1().dataStructures().countDownLatch(t.get2(), 0, false, false);
    } catch (GridException e) {
      throw U.withCause(new InvalidObjectException(e.getMessage()), e);
    }
  }
Ejemplo n.º 23
0
  /**
   * Delegates to {@link #apply()} method.
   *
   * <p>{@inheritDoc}
   *
   * @return {@inheritDoc}
   * @throws GridException {@inheritDoc}
   */
  @Override
  public final Object execute() throws GridException {
    try {
      apply();
    } catch (Throwable e) {
      throw U.cast(e);
    }

    return null;
  }
Ejemplo n.º 24
0
  /** {@inheritDoc} */
  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    super.readExternal(in);

    futId = U.readGridUuid(in);
    miniId = U.readGridUuid(in);
    entries = U.readCollection(in);
    invalidParts = U.readIntSet(in);

    ver = CU.readVersion(in);

    err = (Throwable) in.readObject();

    if (invalidParts == null) invalidParts = Collections.emptyList();

    assert futId != null;
    assert miniId != null;
    assert ver != null;
  }
Ejemplo n.º 25
0
  /**
   * Create signature for license version 2.
   *
   * @param key Private key.
   * @param lic License version 2.
   * @return Signature.
   * @throws GeneralSecurityException If any exception occurs while signature creation.
   */
  public static String createSignatureV2(PrivateKey key, GridLicenseV2 lic)
      throws GeneralSecurityException {
    assert key != null;
    assert lic != null;

    byte[] data = getDataV2ForSign(lic);
    byte[] sign = createSignature(SIGN_ALG, PRV, key, data);

    return U.byteArray2HexString(sign);
  }
Ejemplo n.º 26
0
  /**
   * Verifies license version 2 signature.
   *
   * @param key Public key.
   * @param lic License version 2.
   * @return {@code true} if signature was verified, {@code false} - otherwise.
   * @throws GeneralSecurityException If any exception occurs while verifying.
   */
  public static boolean verifySignatureV2(PublicKey key, GridLicenseV2 lic)
      throws GeneralSecurityException {
    assert key != null;
    assert lic != null;

    byte[] data = getDataV2ForSign(lic);
    byte[] sign = U.hexString2ByteArray(lic.getSignature());

    return verifySignature(SIGN_ALG, PRV, key, data, sign);
  }
  /**
   * Adds new participant to deployment.
   *
   * @param dep Shared deployment.
   * @param meta Request metadata.
   * @return {@code True} if participant was added.
   */
  private boolean addParticipant(SharedDeployment dep, GridDeploymentMetadata meta) {
    assert dep != null;
    assert meta != null;

    assert Thread.holdsLock(mux);

    if (!checkModeMatch(dep, meta)) return false;

    if (meta.participants() != null) {
      for (Map.Entry<UUID, GridTuple2<GridUuid, Long>> e : meta.participants().entrySet()) {
        dep.addParticipant(e.getKey(), e.getValue().get1(), e.getValue().get2());

        if (log.isDebugEnabled())
          log.debug(
              "Added new participant [nodeId="
                  + e.getKey()
                  + ", clsLdrId="
                  + e.getValue().get1()
                  + ", seqNum="
                  + e.getValue().get2()
                  + ']');
      }
    }

    if (dep.deployMode() == CONTINUOUS || meta.participants() == null) {
      if (!dep.addParticipant(meta.senderNodeId(), meta.classLoaderId(), meta.sequenceNumber())) {
        U.warn(
            log,
            "Failed to create shared mode deployment "
                + "(requested class loader was already undeployed, did sender node leave grid?) "
                + "[clsLdrId="
                + meta.classLoaderId()
                + ", senderNodeId="
                + meta.senderNodeId()
                + ']');

        return false;
      }

      if (log.isDebugEnabled())
        log.debug(
            "Added new participant [nodeId="
                + meta.senderNodeId()
                + ", clsLdrId="
                + meta.classLoaderId()
                + ", seqNum="
                + meta.sequenceNumber()
                + ']');
    }

    return true;
  }
  /**
   * Converts given input stream expecting XML inside to {@link GridUriDeploymentSpringDocument}.
   *
   * <p>This is a workaround for the {@link InputStreamResource} which does not work properly.
   *
   * @param in Input stream with XML.
   * @param log Logger
   * @return Grid wrapper for the input stream.
   * @throws GridSpiException Thrown if incoming input stream could not be read or parsed by {@code
   *     Spring} {@link XmlBeanFactory}.
   * @see XmlBeanFactory
   */
  static GridUriDeploymentSpringDocument parseTasksDocument(InputStream in, GridLogger log)
      throws GridSpiException {
    assert in != null;

    // Note: use ByteArrayResource instead of InputStreamResource because InputStreamResource
    // doesn't work.
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try {
      U.copy(in, out);

      XmlBeanFactory factory = new XmlBeanFactory(new ByteArrayResource(out.toByteArray()));

      return new GridUriDeploymentSpringDocument(factory);
    } catch (BeansException e) {
      throw new GridSpiException("Failed to parse spring XML file.", e);
    } catch (IOException e) {
      throw new GridSpiException("Failed to parse spring XML file.", e);
    } finally {
      U.close(out, log);
    }
  }
Ejemplo n.º 29
0
  /**
   * Notifies single listener.
   *
   * @param lsnr Listener.
   */
  private void notifyListener(GridInClosure<? super GridFuture<R>> lsnr) {
    assert lsnr != null;

    try {
      lsnr.apply(this);
    } catch (IllegalStateException ignore) {
      U.warn(
          null,
          "Failed to notify listener (grid is stopped) [grid="
              + ctx.gridName()
              + ", lsnr="
              + lsnr
              + ']');
    } catch (RuntimeException e) {
      U.error(log, "Failed to notify listener: " + lsnr, e);

      throw e;
    } catch (Error e) {
      U.error(log, "Failed to notify listener: " + lsnr, e);

      throw e;
    }
  }
Ejemplo n.º 30
0
 /** {@inheritDoc} */
 @Override
 public String toString() {
   return S.toString(
       GridDiscoveryEvent.class,
       this,
       "nodeId8",
       U.id8(nodeId()),
       "msg",
       message(),
       "type",
       name(),
       "tstamp",
       timestamp());
 }