Repository: incubator-batchee Updated Branches: refs/heads/master 276d70903 -> 468a01f34
BATCHEE-80 adding jsonp reader/writer Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/468a01f3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/468a01f3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/468a01f3 Branch: refs/heads/master Commit: 468a01f34b556102fd53ad87b32b742702a9ae92 Parents: 276d709 Author: Romain Manni-Bucau <[email protected]> Authored: Wed Dec 2 14:08:51 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Wed Dec 2 14:08:51 2015 +0100 ---------------------------------------------------------------------- extensions/extension-doc-helper/pom.xml | 5 + extensions/jsonp/pom.xml | 54 ++++++ .../apache/batchee/jsonp/JsonPartialReader.java | 170 +++++++++++++++++++ .../org/apache/batchee/jsonp/JsonpReader.java | 90 ++++++++++ .../org/apache/batchee/jsonp/JsonpWriter.java | 156 +++++++++++++++++ .../src/main/resources/META-INF/batchee.xml | 21 +++ .../apache/batchee/jsonp/JsonpReaderTest.java | 81 +++++++++ .../apache/batchee/jsonp/JsonpWriterTest.java | 68 ++++++++ .../java/org/apache/batchee/jsonp/util/IOs.java | 62 +++++++ .../META-INF/batch-jobs/jsonp-reader.xml | 32 ++++ .../META-INF/batch-jobs/jsonp-writer.xml | 32 ++++ extensions/pom.xml | 1 + 12 files changed, 772 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/extension-doc-helper/pom.xml ---------------------------------------------------------------------- diff --git a/extensions/extension-doc-helper/pom.xml b/extensions/extension-doc-helper/pom.xml index 50cc1b8..a7df850 100644 --- a/extensions/extension-doc-helper/pom.xml +++ b/extensions/extension-doc-helper/pom.xml @@ -87,6 +87,11 @@ <artifactId>batchee-shiro</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.batchee</groupId> + <artifactId>batchee-jsonp</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/pom.xml ---------------------------------------------------------------------- diff --git a/extensions/jsonp/pom.xml b/extensions/jsonp/pom.xml new file mode 100644 index 0000000..4c166f4 --- /dev/null +++ b/extensions/jsonp/pom.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>batchee-extensions</artifactId> + <groupId>org.apache.batchee</groupId> + <version>0.3-incubating-SNAPSHOT</version> + </parent> + + <artifactId>batchee-jsonp</artifactId> + <name>BatchEE :: Extensions :: Jackson</name> + + <dependencies> + <dependency> + <groupId>org.apache.geronimo.specs</groupId> + <artifactId>geronimo-json_1.0_spec</artifactId> + <version>1.0-alpha-1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.batchee</groupId> + <artifactId>batchee-extras</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.johnzon</groupId> + <artifactId>johnzon-core</artifactId> + <version>0.9.2-incubating</version> + <scope>test</scope> + </dependency> + </dependencies> + + <properties> + <jackson.version>2.2.3</jackson.version> + </properties> +</project> http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonPartialReader.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonPartialReader.java b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonPartialReader.java new file mode 100644 index 0000000..d5e9fa6 --- /dev/null +++ b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonPartialReader.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp; + +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import javax.json.JsonStructure; +import javax.json.spi.JsonProvider; +import javax.json.stream.JsonParser; +import javax.json.stream.JsonParsingException; + +public class JsonPartialReader { + private final JsonParser parser; + private final JsonProvider provider; + private boolean closed = false; + + public JsonPartialReader(final JsonProvider provider, final JsonParser parser) { + this.parser = parser; + this.provider = provider == null ? JsonProvider.provider() : provider; + } + + public JsonStructure read(final JsonParser.Event event) { + switch (event) { + case START_OBJECT: + final JsonObjectBuilder objectBuilder = provider.createObjectBuilder(); + parseObject(objectBuilder); + return objectBuilder.build(); + case START_ARRAY: + final JsonArrayBuilder arrayBuilder = provider.createArrayBuilder(); + parseArray(arrayBuilder); + return arrayBuilder.build(); + default: + throw new JsonParsingException("Unknown structure: " + parser.next(), parser.getLocation()); + } + + } + + public void close() { + if (!closed) { + closed = true; + parser.close(); + } + } + + private void parseObject(final JsonObjectBuilder builder) { + String key = null; + while (parser.hasNext()) { + final JsonParser.Event next = parser.next(); + switch (next) { + case KEY_NAME: + key = parser.getString(); + break; + + case VALUE_STRING: + builder.add(key, parser.getString()); + break; + + case START_OBJECT: + final JsonObjectBuilder subObject = provider.createObjectBuilder(); + parseObject(subObject); + builder.add(key, subObject); + break; + + case START_ARRAY: + final JsonArrayBuilder subArray = provider.createArrayBuilder(); + parseArray(subArray); + builder.add(key, subArray); + break; + + case VALUE_NUMBER: + if (parser.isIntegralNumber()) { + builder.add(key, parser.getLong()); + } else { + builder.add(key, parser.getBigDecimal()); + } + break; + + case VALUE_NULL: + builder.addNull(key); + break; + + case VALUE_TRUE: + builder.add(key, true); + break; + + case VALUE_FALSE: + builder.add(key, false); + break; + + case END_OBJECT: + return; + + case END_ARRAY: + throw new JsonParsingException("']', shouldn't occur", parser.getLocation()); + + default: + throw new JsonParsingException(next.name() + ", shouldn't occur", parser.getLocation()); + } + } + } + + private void parseArray(final JsonArrayBuilder builder) { + while (parser.hasNext()) { + final JsonParser.Event next = parser.next(); + switch (next) { + case VALUE_STRING: + builder.add(parser.getString()); + break; + + case VALUE_NUMBER: + if (parser.isIntegralNumber()) { + builder.add(parser.getLong()); + } else { + builder.add(parser.getBigDecimal()); + } + break; + + case START_OBJECT: + JsonObjectBuilder subObject = provider.createObjectBuilder(); + parseObject(subObject); + builder.add(subObject); + break; + + case START_ARRAY: + JsonArrayBuilder subArray = provider.createArrayBuilder(); + parseArray(subArray); + builder.add(subArray); + break; + + case END_ARRAY: + return; + + case VALUE_NULL: + builder.addNull(); + break; + + case VALUE_TRUE: + builder.add(true); + break; + + case VALUE_FALSE: + builder.add(false); + break; + + case KEY_NAME: + throw new JsonParsingException("array doesn't have keys", parser.getLocation()); + + case END_OBJECT: + throw new JsonParsingException("'}', shouldn't occur", parser.getLocation()); + + default: + throw new JsonParsingException(next.name() + ", shouldn't occur", parser.getLocation()); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpReader.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpReader.java b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpReader.java new file mode 100644 index 0000000..57402fc --- /dev/null +++ b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpReader.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp; + +import org.apache.batchee.doc.api.Documentation; +import org.apache.batchee.extras.transaction.CountedReader; + +import javax.batch.api.BatchProperty; +import javax.inject.Inject; +import javax.json.spi.JsonProvider; +import javax.json.stream.JsonParser; +import java.io.FileInputStream; +import java.io.Serializable; + +@Documentation("Reads a JSON file using JSON-P providing JsonStructure as item.") +public class JsonpReader extends CountedReader { + @Inject + @BatchProperty + @Documentation("Incoming file") + private String file; + + @Inject + @BatchProperty + @Documentation("Should root be skipped (default: true)") + private String skipRoot; + + @Inject + @BatchProperty + @Documentation("JSON-P provider if not using the default") + private String provider; + + private JsonParser parser; + private JsonPartialReader reader; + private JsonParser.Event end = null; + + @Override + public void open(final Serializable checkpoint) throws Exception { + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + final JsonProvider provider = this.provider == null ? JsonProvider.provider() : JsonProvider.class.cast(loader.loadClass(this.provider)); + parser = provider.createParser(new FileInputStream(file)); + reader = new JsonPartialReader(provider, parser); + + if (skipRoot == null || "true".equalsIgnoreCase(skipRoot)) { + final JsonParser.Event event = parser.next(); + if (event == JsonParser.Event.START_ARRAY) { + end = JsonParser.Event.END_ARRAY; + } else { + end = JsonParser.Event.END_OBJECT; + } + } + super.open(checkpoint); + } + + @Override + protected Object doRead() throws Exception { + JsonParser.Event event; + do { + event = parser.next(); + } while ( + (event != JsonParser.Event.START_OBJECT && event != end) || + (end == null && (event == JsonParser.Event.END_ARRAY || + event == JsonParser.Event.END_OBJECT))); + if (!parser.hasNext()) { + return null; + } + + return reader.read(event); + } + + @Override + public void close() throws Exception { + if (reader != null) { + reader.close(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpWriter.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpWriter.java b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpWriter.java new file mode 100644 index 0000000..a4af1a6 --- /dev/null +++ b/extensions/jsonp/src/main/java/org/apache/batchee/jsonp/JsonpWriter.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp; + +import org.apache.batchee.doc.api.Documentation; +import org.apache.batchee.extras.transaction.TransactionalWriter; + +import javax.batch.api.BatchProperty; +import javax.batch.api.chunk.ItemWriter; +import javax.batch.operations.BatchRuntimeException; +import javax.inject.Inject; +import javax.json.JsonStructure; +import javax.json.spi.JsonProvider; +import javax.json.stream.JsonGenerator; +import java.io.File; +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Documentation("Write a JSON file using JSON-P and taking JsonStructure as items.") +public class JsonpWriter implements ItemWriter { + @Inject + @BatchProperty + @Documentation("output file") + private String file; + + @Inject + @BatchProperty + @Documentation("output encoding") + private String encoding; + + @Inject + @BatchProperty + @Documentation("comma separated key value pairs for the generator factory (converted to a Map<?, ?>)") + private String configuration; + + @Inject + @BatchProperty + @Documentation("is the array wrapped in an object or not") + private String skipRoot; + + @Inject + @BatchProperty + @Documentation("how to generate field names for each item, default uses item1, item2, ...") + private String fieldNameGeneratorClass; + + @Inject + @BatchProperty + @Documentation("JSON-P provider if not using the default") + private String provider; + + private JsonGenerator generator; + private TransactionalWriter writer; + private FieldNameGenerator fieldNameGenerator = null; + + @Override + public void open(final Serializable checkpoint) throws Exception { + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + final JsonProvider provider = this.provider == null ? JsonProvider.provider() : JsonProvider.class.cast(loader.loadClass(this.provider)); + + final File outputFile = new File(file); + if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) { + throw new BatchRuntimeException("Can't create " + outputFile.getAbsolutePath()); + } + + writer = new TransactionalWriter(outputFile, encoding, checkpoint); + generator = provider.createGeneratorFactory(buildConfig()).createGenerator(writer); + if (fieldNameGeneratorClass != null) { + if ("default".equals(fieldNameGeneratorClass)) { + fieldNameGenerator = new FieldNameGenerator() { + private int count = 0; + + @Override + public String nextName() { + return "item" + ++count; + } + }; + } else { + fieldNameGenerator = FieldNameGenerator.class.cast(Thread.currentThread().getContextClassLoader().loadClass(fieldNameGeneratorClass).newInstance()); + } + } + + if (useGlobalWrapper()) { + if (fieldNameGenerator != null) { + generator.writeStartObject(); + } else { + generator.writeStartArray(); + } + } + } + + private Map<String, ?> buildConfig() { + final Map<String, Object> map = new HashMap<String, Object>(); + if (configuration != null) { + for (final String entry : configuration.trim().split(" *, *")) { + final String[] parts = entry.split(" *= *"); + if (parts.length != 2) { + throw new IllegalArgumentException(entry + " not matching a=b pattern"); + } + map.put(parts[0], parts[1]); + } + } + return map; + } + + @Override + public void close() throws Exception { + if (generator != null) { + if (useGlobalWrapper()) { + generator.writeEnd(); + } + generator.close(); + } + } + + @Override + public void writeItems(final List<Object> items) throws Exception { + final List<JsonStructure> structures = List.class.cast(items); + for (final JsonStructure structure : structures) { + if (fieldNameGenerator != null) { + generator.write(fieldNameGenerator.nextName(), structure); + } else { + generator.write(structure); + } + } + writer.flush(); + } + + @Override + public Serializable checkpointInfo() throws Exception { + return writer.position(); + } + + private boolean useGlobalWrapper() { + return skipRoot == null || !"true".equalsIgnoreCase(skipRoot); + } + + public interface FieldNameGenerator { + String nextName(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/main/resources/META-INF/batchee.xml ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/main/resources/META-INF/batchee.xml b/extensions/jsonp/src/main/resources/META-INF/batchee.xml new file mode 100644 index 0000000..9208df6 --- /dev/null +++ b/extensions/jsonp/src/main/resources/META-INF/batchee.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<batch-artifacts xmlns="http://xmlns.jcp.org/xml/ns/javaee"> + <ref id="jsonpReader" class="org.apache.batchee.jsonp.JsonpReader" /> + <ref id="jsonpWriter" class="org.apache.batchee.jsonp.JsonpWriter" /> +</batch-artifacts> http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpReaderTest.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpReaderTest.java b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpReaderTest.java new file mode 100644 index 0000000..afe69ef --- /dev/null +++ b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpReaderTest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp; + +import org.apache.batchee.jsonp.util.IOs; +import org.apache.batchee.util.Batches; +import org.testng.annotations.Test; + +import javax.batch.api.chunk.ItemWriter; +import javax.batch.operations.JobOperator; +import javax.batch.runtime.BatchRuntime; +import javax.json.JsonObject; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import static org.testng.Assert.assertEquals; + +public class JsonpReaderTest { + @Test + public void read() { + IOs.write("target/work/jsonp-input.json", "[" + + " {" + + " \"v1\":\"record 1 # field 1\"," + + " \"v2\":\"record 1 # field 2\"" + + " }," + + " {" + + " \"v1\":\"record 2 # field 1\"," + + " \"v2\":\"record 2 # field 2\"" + + " }" + + "]"); + + final JobOperator operator = BatchRuntime.getJobOperator(); + Batches.waitForEnd(operator, operator.start("jsonp-reader", new Properties())); + assertEquals(Writer.ITEMS.size(), 2); + for (int i = 1; i < Writer.ITEMS.size() + 1; i++) { + final JsonObject record = Writer.ITEMS.get(i - 1); + assertEquals("record " + i + " # field 1", record.getString("v1")); + assertEquals("record " + i + " # field 2", record.getString("v2")); + } + } + + public static class Writer implements ItemWriter { + public static List<JsonObject> ITEMS = new ArrayList<JsonObject>(2); + + @Override + public void open(final Serializable checkpoint) throws Exception { + // no-op + } + + @Override + public void close() throws Exception { + // no-op + } + + @Override + public void writeItems(final List<Object> items) throws Exception { + ITEMS.addAll(List.class.cast(items)); + } + + @Override + public Serializable checkpointInfo() throws Exception { + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpWriterTest.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpWriterTest.java b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpWriterTest.java new file mode 100644 index 0000000..b039fc9 --- /dev/null +++ b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/JsonpWriterTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp; + +import org.apache.batchee.jsonp.util.IOs; +import org.apache.batchee.util.Batches; +import org.testng.annotations.Test; + +import javax.batch.api.chunk.ItemReader; +import javax.batch.operations.JobOperator; +import javax.batch.runtime.BatchRuntime; +import javax.json.Json; +import java.io.Serializable; +import java.util.Properties; + +import static org.testng.Assert.assertEquals; + +public class JsonpWriterTest { + @Test + public void write() { + final JobOperator operator = BatchRuntime.getJobOperator(); + Batches.waitForEnd(operator, operator.start("jsonp-writer", new Properties())); + final String output = IOs.slurp("target/work/jsonp-output.json"); + assertEquals(output.replace("\n", "").replace("\r", "").replace(" ", "").replace("\t", ""), + "[{\"v1\":\"v11\",\"v2\":\"v21\"},{\"v1\":\"v12\",\"v2\":\"v22\"}]"); + } + + public static class Reader implements ItemReader { + private int count = 0; + + @Override + public void open(final Serializable checkpoint) throws Exception { + // no-op + } + + @Override + public void close() throws Exception { + // no-op + } + + @Override + public Object readItem() throws Exception { + if (count++ < 2) { + return Json.createObjectBuilder().add("v1", "v1" + count).add("v2", "v2" + count).build(); + } + return null; + } + + @Override + public Serializable checkpointInfo() throws Exception { + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/util/IOs.java ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/util/IOs.java b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/util/IOs.java new file mode 100644 index 0000000..0b807e2 --- /dev/null +++ b/extensions/jsonp/src/test/java/org/apache/batchee/jsonp/util/IOs.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.jsonp.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class IOs { + public static void write(final String path, final String content) { + final File file = new File(path); + if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { + throw new RuntimeException("Can't create " + path); + } + + try { + final FileWriter writer = new FileWriter(file); + writer.write(content); + writer.close(); + } catch (final IOException e) { + // no-op + } + } + + public static String slurp(final String path) { + final StringBuilder builder = new StringBuilder(); + try { + final BufferedReader reader = new BufferedReader(new FileReader(path)); + String line; + do { + line = reader.readLine(); + if (line != null) { + builder.append(line); + } + } while (line != null); + reader.close(); + } catch (final Exception e) { + // no-op + } + return builder.toString(); + } + + private IOs() { + // no-op + } +} http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-reader.xml ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-reader.xml b/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-reader.xml new file mode 100644 index 0000000..f7df4f5 --- /dev/null +++ b/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-reader.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + See the NOTICE file distributed with this work for additional information + regarding copyright ownership. Licensed under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<job id="jsonp-reader" version="1.0" + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"> + <step id="step1"> + <chunk> + <reader ref="jsonpReader"> + <properties> + <property name="file" value="target/work/jsonp-input.json"/> + </properties> + </reader> + <writer ref="org.apache.batchee.jsonp.JsonpReaderTest$Writer" /> + </chunk> + </step> +</job> http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-writer.xml ---------------------------------------------------------------------- diff --git a/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-writer.xml b/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-writer.xml new file mode 100644 index 0000000..072493f --- /dev/null +++ b/extensions/jsonp/src/test/resources/META-INF/batch-jobs/jsonp-writer.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + See the NOTICE file distributed with this work for additional information + regarding copyright ownership. Licensed under the Apache License, + Version 2.0 (the "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<job id="jsonp-writer" version="1.0" + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://xmlns.jcp.org/xml/ns/javaee + http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"> + <step id="step1"> + <chunk> + <reader ref="org.apache.batchee.jsonp.JsonpWriterTest$Reader" /> + <writer ref="jsonpWriter"> + <properties> + <property name="file" value="target/work/jsonp-output.json"/> + </properties> + </writer> + </chunk> + </step> +</job> http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/468a01f3/extensions/pom.xml ---------------------------------------------------------------------- diff --git a/extensions/pom.xml b/extensions/pom.xml index fbb38a6..c990745 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -40,6 +40,7 @@ <module>hazelcast</module> <module>modelmapper</module> <module>commons-csv</module> + <module>jsonp</module> <module>extension-doc-helper</module> </modules>
