@Override
    public void serialize(Record record, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonProcessingException {
      jgen.writeStartObject();
      jgen.writeStringField("id", record.getId());
      jgen.writeStringField("type", record.getType());
      jgen.writeStringField("creationDate", record.getTime().toString());

      jgen.writeObjectFieldStart("fields");
      for (Map.Entry<String, Field> entry : record.getFieldsEntrySet()) {
        // retrieve event field
        String fieldName = entry.getKey();
        Field field = entry.getValue();
        Object fieldValue = field.getRawValue();
        String fieldType = field.getType().toString();

        // dump event field as record attribute

        try {
          switch (fieldType.toLowerCase()) {
            case "string":
              jgen.writeStringField(fieldName, (String) fieldValue);
              break;
            case "integer":
              jgen.writeNumberField(fieldName, (int) fieldValue);
              break;
            case "long":
              jgen.writeNumberField(fieldName, (long) fieldValue);
              break;
            case "float":
              jgen.writeNumberField(fieldName, (float) fieldValue);
              break;
            case "double":
              jgen.writeNumberField(fieldName, (double) fieldValue);
              break;
            case "boolean":
              jgen.writeBooleanField(fieldName, (boolean) fieldValue);
              break;
            default:
              jgen.writeObjectField(fieldName, fieldValue);
              break;
          }
        } catch (Exception ex) {
          logger.debug("exception while serializing field {}", field);
        }
      }
      jgen.writeEndObject();
      jgen.writeEndObject();
    }
  @Test
  public void validateJsonSerialization() throws IOException {

    final JsonSerializer serializer = new JsonSerializer();

    Record record = new StandardRecord("cisco");
    record.setId("firewall_record1");
    record.setField("timestamp", FieldType.LONG, new Date().getTime());
    record.setField("method", FieldType.STRING, "GET");
    record.setField("ip_source", FieldType.STRING, "123.34.45.123");
    record.setField("ip_target", FieldType.STRING, "255.255.255.255");
    record.setField("url_scheme", FieldType.STRING, "http");
    record.setField("url_host", FieldType.STRING, "origin-www.20minutes.fr");
    record.setField("url_port", FieldType.STRING, "80");
    record.setField("url_path", FieldType.STRING, "/r15lgc-100KB.js");
    record.setField("request_size", FieldType.INT, 1399);
    record.setField("response_size", FieldType.INT, 452);
    record.setField("is_outside_office_hours", FieldType.BOOLEAN, false);
    record.setField("is_host_blacklisted", FieldType.BOOLEAN, false);
    // record.setField("tags", FieldType.ARRAY, new ArrayList<>(Arrays.asList("spam", "filter",
    // "mail")));

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    serializer.serialize(baos, record);
    baos.close();

    String strEvent = new String(baos.toByteArray());
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    Record deserializedRecord = serializer.deserialize(bais);

    assertTrue(deserializedRecord.equals(record));
  }
    @Override
    public Record deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
      JsonToken t = jp.getCurrentToken();

      SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
      sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
      String id = null;
      String type = null;
      Date creationDate = null;
      JsonToken currentToken = null;
      Map<String, Field> fields = new HashMap<>();

      boolean processingFields = false;
      while ((currentToken = jp.nextValue()) != null) {

        switch (currentToken) {
          case START_OBJECT:
            processingFields = true;
            break;
          case END_OBJECT:
            processingFields = true;
            break;
          case VALUE_NUMBER_INT:
            try {
              fields.put(
                  jp.getCurrentName(),
                  new Field(jp.getCurrentName(), FieldType.INT, jp.getIntValue()));
            } catch (JsonParseException ex) {
              fields.put(
                  jp.getCurrentName(),
                  new Field(jp.getCurrentName(), FieldType.LONG, jp.getLongValue()));
            }
            break;

          case VALUE_NUMBER_FLOAT:
            try {
              fields.put(
                  jp.getCurrentName(),
                  new Field(jp.getCurrentName(), FieldType.FLOAT, jp.getFloatValue()));
            } catch (JsonParseException ex) {
              fields.put(
                  jp.getCurrentName(),
                  new Field(jp.getCurrentName(), FieldType.DOUBLE, jp.getDoubleValue()));
            }
            break;
          case VALUE_FALSE:
          case VALUE_TRUE:
            fields.put(
                jp.getCurrentName(),
                new Field(jp.getCurrentName(), FieldType.BOOLEAN, jp.getBooleanValue()));
            break;
          case START_ARRAY:
            logger.info(jp.getCurrentName());
            break;

          case END_ARRAY:
            break;
          case VALUE_STRING:
            if (jp.getCurrentName() != null) {
              switch (jp.getCurrentName()) {
                case "id":
                  id = jp.getValueAsString();
                  break;
                case "type":
                  type = jp.getValueAsString();
                  break;
                case "creationDate":
                  try {
                    creationDate =
                        sdf.parse(jp.getValueAsString()); // "Thu Sep 08 12:11:08 CEST 2016\"
                  } catch (ParseException e) {
                    e.printStackTrace();
                  }
                  break;
                default:
                  fields.put(
                      jp.getCurrentName(),
                      new Field(jp.getCurrentName(), FieldType.STRING, jp.getValueAsString()));

                  break;
              }
            }

            break;
          default:
            break;
        }
      }

      Record record = new StandardRecord(type);
      record.setId(id);
      record.setType(type);
      record.setTime(creationDate);
      record.setFields(fields);

      return record;
    }