All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgroups.tests.ParseMessagesFields Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
package org.jgroups.tests;

import org.jgroups.Message;
import org.jgroups.stack.GossipData;
import org.jgroups.util.MessageBatch;

import java.io.*;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * While investigating network errors, we would like to look for timestamp and JGroups data.
 * But when needed, we need to add more fields like source and destination ports.
 *
 * Example: tshark -q -i lo0 -Tfields -e frame.time_epoch -e udp.srcport -e udp.dstport -e data udp and port 9090
 *
 * Run: ParseMessages -instance org.jgroups.tests.ParseMessagesFields -Dfields="frame.time_epoch,udp.srcport,udp.dstport"
 */
public class ParseMessagesFields extends ParseMessages {

   private static final DateTimeFormatter TIME_EPOCH_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss,SSS");
   private static final ZoneId ZONE_ID=ZoneId.systemDefault();

   private static String[] fields;
   static {
      String fieldsArgument = System.getProperty("fields");
      if (fieldsArgument != null) {
         fields =  fieldsArgument.split(",");
      }
   }

   @Override
   protected InputStream createInputStream(InputStream in) {
      return new BinaryToAsciiWithFieldsInputStream(in);
   }

   @Override
   public void parse(InputStream in, BiConsumer msg_consumer,
                     BiConsumer batch_consumer, Consumer gossip_consumer,
                     boolean tcp, boolean gossip) {
      parseWithFields(in, msg_consumer, batch_consumer, tcp, gossip);
   }



   public static class BinaryToAsciiWithFieldsInputStream extends ParseMessages.BinaryToAsciiInputStream {

      public BinaryToAsciiWithFieldsInputStream(InputStream in) {
         super(in);
      }

      public String readIntegerAsStr() throws IOException {
         String str = "";
         while (true) {
            input[0] = (byte)in.read();
            if (input[0] == '\t') {
               break;
            }
            input[1] = (byte)in.read();
            // tshark \t separator
            if (input[1] == '\t') {
               str += new String(new byte[]{input[0]});
               break;
            } else {
               str += new String(input);
            }
         }
         return str;
      }

      public String readEpochTime() throws IOException {
         String timestamp="";
         while (timestamp.length() != 20) {
            input[0] = (byte)in.read();
            if (input[0] == '\n' || input[0] == '\r') {
               continue;
            }
            input[1] = (byte)in.read();
            // end of file
            if (input[0] == -1 || input[1] == -1) {
               throw new EOFException();
            }
            timestamp+=new String(input);
         }
         // tshark \t separator
         readPlainByte();

         String[] time = timestamp.split("\\.");
         long epochMilli = Long.valueOf(time[0]) * 1000;
         long nanos = Long.valueOf(time[1]);
         ZonedDateTime zonedDateTime = Instant.ofEpochMilli(epochMilli).plusNanos(nanos).atZone(ZONE_ID);
         String epochTime = TIME_EPOCH_DATE_TIME_FORMATTER.format(zonedDateTime);
         return epochTime;
      }

      public byte readPlainByte() throws IOException {
         return (byte)in.read();
      }
   }

   public void parseWithFields(InputStream input, BiConsumer msg_consumer,
                                         BiConsumer batch_consumer, boolean tcp, boolean gossip) {
      try {
         for(;;) {
            // parse fields
            String[] fieldValues = new String[fields.length];
            BinaryToAsciiWithFieldsInputStream cast = ((BinaryToAsciiWithFieldsInputStream) input);
            for (int i = 0; i < fields.length; i++) {
               String field = fields[i];
               if ("frame.time_epoch".equals(field)) {
                  fieldValues[i] = cast.readEpochTime();
               } else if (field.contains(".srcport")) {
                  fieldValues[i] = cast.readIntegerAsStr();
               } else if (field.contains(".dstport")) {
                  fieldValues[i] = cast.readIntegerAsStr();
               } else {
                  throw new RuntimeException(String.format("%s not implemented", field));
               }
            }

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // after the \t separator, the data field could be empty
            for(;;) {
               byte b = cast.readPlainByte();
               if (b == '\n' || b == '\r' || b == -1) {
                  break;
               }
               outputStream.write(b);
            }
            if (outputStream.size() != 0) {
               for (String fieldValue : fieldValues) {
                  System.out.print(fieldValue + " ");
               }
               super.parse(new BinaryToAsciiInputStream(new ByteArrayInputStream(outputStream.toByteArray())),
                           msg_consumer, batch_consumer, null, tcp, false);
            }
         }
      } catch(EOFException ignored) {
         //ignored.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy