private void transferTabletForPubSubModel(final Tablet tablet, final boolean isTableModel)
      throws UaException {
    final BaseEventTypeNode eventNode =
        getServer()
            .getEventFactory()
            .createEvent(
                new NodeId(getNamespaceIndex(), UUID.randomUUID()), Identifiers.BaseEventType);

    List<String> sourceNameList = null;
    if (isTableModel) {
      sourceNameList = new ArrayList<>(tablet.getRowSize());
      for (int i = 0; i < tablet.getRowSize(); ++i) {
        final StringBuilder idBuilder = new StringBuilder(databaseName);
        for (final Object segment : tablet.getDeviceID(i).getSegments()) {
          idBuilder
              .append(TsFileConstant.PATH_SEPARATOR)
              .append(Objects.isNull(segment) ? placeHolder : segment);
        }
        sourceNameList.add(idBuilder.toString());
      }
    }

    // Use eventNode here because other nodes doesn't support values and times simultaneously
    for (int columnIndex = 0; columnIndex < tablet.getSchemas().size(); ++columnIndex) {
      if (isTableModel && !tablet.getColumnTypes().get(columnIndex).equals(ColumnCategory.FIELD)) {
        continue;
      }
      final TSDataType dataType = tablet.getSchemas().get(columnIndex).getType();

      // Source name --> Sensor path, like root.test.d_0.s_0
      if (!isTableModel) {
        eventNode.setSourceName(
            tablet.getDeviceId()
                + TsFileConstant.PATH_SEPARATOR
                + tablet.getSchemas().get(columnIndex).getMeasurementName());
      }

      // Source node --> Sensor type, like double
      eventNode.setSourceNode(convertToOpcDataType(dataType));

      for (int rowIndex = 0; rowIndex < tablet.getRowSize(); ++rowIndex) {
        // Filter null value
        if (tablet.getBitMaps()[columnIndex].isMarked(rowIndex)) {
          continue;
        }

        if (Objects.nonNull(sourceNameList)) {
          final String deviceId = sourceNameList.get(rowIndex);
          if (Objects.isNull(deviceId)) {
            continue;
          }
          eventNode.setSourceName(
              deviceId
                  + TsFileConstant.PATH_SEPARATOR
                  + tablet.getSchemas().get(columnIndex).getMeasurementName());
        }

        // Time --> TimeStamp
        eventNode.setTime(new DateTime(timestampToUtc(tablet.getTimestamp(rowIndex))));

        // Message --> Value
        switch (dataType) {
          case BOOLEAN:
            eventNode.setMessage(
                LocalizedText.english(
                    Boolean.toString((boolean) tablet.getValue(rowIndex, columnIndex))));
            break;
          case INT32:
            eventNode.setMessage(
                LocalizedText.english(
                    Integer.toString((int) tablet.getValue(rowIndex, columnIndex))));
            break;
          case DATE:
            eventNode.setMessage(
                LocalizedText.english(
                    ((LocalDate) tablet.getValue(rowIndex, columnIndex))
                        .atStartOfDay(ZoneId.systemDefault())
                        .toString()));
            break;
          case INT64:
            eventNode.setMessage(
                LocalizedText.english(
                    Long.toString((long) tablet.getValue(rowIndex, columnIndex))));
            break;
          case TIMESTAMP:
            eventNode.setMessage(
                LocalizedText.english(
                    DateTimeUtils.convertLongToDate(
                        (long) tablet.getValue(rowIndex, columnIndex))));
            break;
          case FLOAT:
            eventNode.setMessage(
                LocalizedText.english(
                    Float.toString((float) tablet.getValue(rowIndex, columnIndex))));
            break;
          case DOUBLE:
            eventNode.setMessage(
                LocalizedText.english(
                    Double.toString((double) tablet.getValue(rowIndex, columnIndex))));
            break;
          case TEXT:
          case BLOB:
          case STRING:
            eventNode.setMessage(
                LocalizedText.english(tablet.getValue(rowIndex, columnIndex).toString()));
            break;
          case VECTOR:
          case UNKNOWN:
          default:
            throw new PipeRuntimeNonCriticalException(
                "Unsupported data type: " + tablet.getSchemas().get(columnIndex).getType());
        }

        // Send the event
        getServer().getEventBus().post(eventNode);
      }
    }
    eventNode.delete();
  }
Transfer {@link Tablet} into eventNodes and post it on the eventBus, so that they will be heard
at the subscribers. Notice that an eventNode is reused to reduce object creation costs.

@param tablet the tablet to send
@throws UaException if failed to create {@link Event}
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/connector/protocol/opcua/OpcUaNameSpace.java