ImmutableLogEntry implements LogEntry { public static LogEntry fromJson(final JsonObject jsonObject) { final String correlationId = jsonObject.getValueOrThrow(JsonFields.CORRELATION_ID); final Instant timestamp = getTimestampOrThrow(jsonObject.getValueOrThrow(JsonFields.TIMESTAMP)); final LogCategory category = getLogCategoryOrThrow(jsonObject); final LogType type = getLogTypeOrThrow(jsonObject); final LogLevel level = getLogLevelOrThrow(jsonObject); final String message = jsonObject.getValueOrThrow(JsonFields.MESSAGE); final String address = jsonObject.getValue(JsonFields.ADDRESS).orElse(null); final ThingId thingId = jsonObject.getValue(JsonFields.THING_ID).map(ThingId::of).orElse(null); return getBuilder(correlationId, timestamp, category, type, level, message, address, thingId) .build(); } private  ImmutableLogEntry(final Builder builder); static LogEntryBuilder getBuilder(final String correlationId, final Instant timestamp, final LogCategory logCategory,
            final LogType logType, final LogLevel logLevel, final String message); static LogEntryBuilder getBuilder(final String correlationId, final Instant timestamp, final LogCategory logCategory,
            final LogType logType, final LogLevel logLevel, final String message,
            @Nullable final String address, @Nullable final ThingId thingId); static LogEntry fromJson(final JsonObject jsonObject); @Override String getCorrelationId(); @Override Instant getTimestamp(); @Override LogCategory getLogCategory(); @Override LogType getLogType(); @Override LogLevel getLogLevel(); @Override String getMessage(); @Override Optional<String> getAddress(); @Override Optional<ThingId> getThingId(); @Override JsonObject toJson(final JsonSchemaVersion schemaVersion, final Predicate<JsonField> predicate); @Override boolean equals(@Nullable final Object o); @Override int hashCode(); @Override String toString();  }
@Test public void fromJsonReturnsExpected() { final LogEntry actual = ImmutableLogEntry.fromJson(LOG_ENTRY_JSON); assertThat(actual).isEqualTo(LOG_ENTRY); }
@Test public void fromJsonWithIllegalDate() { final JsonObject json = LOG_ENTRY_JSON.set(LogEntry.JsonFields.TIMESTAMP, "not-a-date"); assertThatExceptionOfType(JsonParseException.class) .isThrownBy(() -> ImmutableLogEntry.fromJson(json)) .withMessage("The JSON object's field <%s> is not in ISO-8601 format as expected!", LogEntry.JsonFields.TIMESTAMP.getPointer()); }