-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds an ndjson input codec. This reads JSON objects for ND-JSON and m…
…ore lenient formats that do not have the newline. (#4533) Signed-off-by: David Venable <dlv@amazon.com>
- Loading branch information
Showing
4 changed files
with
413 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
...ocessor/src/main/java/org/opensearch/dataprepper/plugins/codec/json/NdjsonInputCodec.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.dataprepper.plugins.codec.json; | ||
|
||
import com.fasterxml.jackson.core.JsonFactory; | ||
import com.fasterxml.jackson.core.JsonParser; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import com.fasterxml.jackson.databind.MappingIterator; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.opensearch.dataprepper.model.annotations.DataPrepperPlugin; | ||
import org.opensearch.dataprepper.model.annotations.DataPrepperPluginConstructor; | ||
import org.opensearch.dataprepper.model.codec.InputCodec; | ||
import org.opensearch.dataprepper.model.event.Event; | ||
import org.opensearch.dataprepper.model.event.EventFactory; | ||
import org.opensearch.dataprepper.model.event.LogEventBuilder; | ||
import org.opensearch.dataprepper.model.log.Log; | ||
import org.opensearch.dataprepper.model.record.Record; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.function.Consumer; | ||
|
||
/** | ||
* A Data Prepper {@link InputCodec} which reads ND-JSON and other similar | ||
* formats which have JSON objects together. | ||
*/ | ||
@DataPrepperPlugin(name = "ndjson", pluginType = InputCodec.class, pluginConfigurationType = NdjsonInputConfig.class) | ||
public class NdjsonInputCodec implements InputCodec { | ||
private static final TypeReference<Map<String, Object>> MAP_TYPE_REFERENCE = new TypeReference<>() {}; | ||
private final ObjectMapper objectMapper = new ObjectMapper(); | ||
private final NdjsonInputConfig ndjsonInputConfig; | ||
private final EventFactory eventFactory; | ||
private final JsonFactory jsonFactory; | ||
|
||
@DataPrepperPluginConstructor | ||
public NdjsonInputCodec(final NdjsonInputConfig ndjsonInputConfig, final EventFactory eventFactory) { | ||
this.ndjsonInputConfig = ndjsonInputConfig; | ||
this.eventFactory = eventFactory; | ||
jsonFactory = new JsonFactory(); | ||
} | ||
|
||
@Override | ||
public void parse(final InputStream inputStream, final Consumer<Record<Event>> eventConsumer) throws IOException { | ||
Objects.requireNonNull(inputStream, "Parameter inputStream must not be null."); | ||
Objects.requireNonNull(eventConsumer, "Parameter eventConsumer must not be null."); | ||
|
||
final JsonParser parser = jsonFactory.createParser(inputStream); | ||
|
||
final MappingIterator<Map<String, Object>> mapMappingIterator = objectMapper.readValues(parser, MAP_TYPE_REFERENCE); | ||
while (mapMappingIterator.hasNext()) { | ||
final Map<String, Object> json = mapMappingIterator.next(); | ||
|
||
if(!ndjsonInputConfig.isIncludeEmptyObjects() && json.isEmpty()) | ||
continue; | ||
|
||
final Record<Event> record = createRecord(json); | ||
eventConsumer.accept(record); | ||
} | ||
} | ||
|
||
private Record<Event> createRecord(final Map<String, Object> json) { | ||
final Log event = eventFactory.eventBuilder(LogEventBuilder.class) | ||
.withData(json) | ||
.build(); | ||
|
||
return new Record<>(event); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...cessor/src/main/java/org/opensearch/dataprepper/plugins/codec/json/NdjsonInputConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.dataprepper.plugins.codec.json; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
/** | ||
* Configuration for the {@link NdjsonInputCodec} input codec. | ||
*/ | ||
public class NdjsonInputConfig { | ||
/** | ||
* By default, we will not create events for empty objects. However, we will | ||
* permit users to include them if they desire. | ||
*/ | ||
@JsonProperty("include_empty_objects") | ||
private boolean includeEmptyObjects = false; | ||
|
||
public boolean isIncludeEmptyObjects() { | ||
return includeEmptyObjects; | ||
} | ||
} |
Oops, something went wrong.