diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilder.java new file mode 100644 index 000000000..b94061014 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilder.java @@ -0,0 +1,95 @@ +/* + * Copyright 2017 the original author or authors. + * + * 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. + */ + +package org.springframework.batch.item.data.builder; + +import org.springframework.batch.item.data.GemfireItemWriter; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.gemfire.GemfireTemplate; +import org.springframework.util.Assert; + +/** + * A builder implementation for the {@link GemfireItemWriter} + * + * @author Glenn Renfro + * @since 4.0 + * @see GemfireItemWriterBuilder + */ +public class GemfireItemWriterBuilder { + + private GemfireTemplate template; + + private Converter itemKeyMapper; + + private boolean delete; + + /** + * Establishes the GemfireTemplate the writer should use. + * @param template the {@link GemfireTemplate} to set. + * @return The current instance of the builder. + * @see GemfireItemWriter#setTemplate(GemfireTemplate) + */ + public GemfireItemWriterBuilder template(GemfireTemplate template) { + this.template = template; + + return this; + } + + /** + * Set the {@link Converter} to use to derive the key from the item. + * + * @param itemKeyMapper the Converter to use. + * @return The current instance of the builder. + * @see GemfireItemWriter#setItemKeyMapper(Converter) + */ + public GemfireItemWriterBuilder itemKeyMapper(Converter itemKeyMapper) { + this.itemKeyMapper = itemKeyMapper; + + return this; + } + + /** + * Indicates if the items being passed to the writer are to be saved or removed from + * the data store. If set to false (default), the items will be saved. If set to true, + * the items will be removed. + * + * @param delete removal indicator. + * @return The current instance of the builder. + * @see GemfireItemWriter#setDelete(boolean) + */ + public GemfireItemWriterBuilder delete(boolean delete) { + this.delete = delete; + + return this; + } + + + /** + * Validates and builds a {@link GemfireItemWriter}. + * + * @return a {@link GemfireItemWriter} + */ + public GemfireItemWriter build() { + Assert.notNull(this.template, "template is required."); + Assert.notNull(this.itemKeyMapper, "itemKeyMapper is required."); + + GemfireItemWriter writer = new GemfireItemWriter<>(); + writer.setTemplate(this.template); + writer.setItemKeyMapper(this.itemKeyMapper); + writer.setDelete(this.delete); + return writer; + } +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/GemfireItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/GemfireItemWriterTests.java index dfc1999ec..b0c6777f8 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/GemfireItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/GemfireItemWriterTests.java @@ -37,8 +37,6 @@ public class GemfireItemWriterTests { @Mock private GemfireTemplate template; - //private PlatformTransactionManager transactionManager = new ResourcelessTransactionManager(); - @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilderTests.java new file mode 100644 index 000000000..13259ee01 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/GemfireItemWriterBuilderTests.java @@ -0,0 +1,125 @@ +/* + * Copyright 2017 the original author or authors. + * + * 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. + */ + +package org.springframework.batch.item.data.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.springframework.batch.item.SpELItemKeyMapper; +import org.springframework.batch.item.data.GemfireItemWriter; +import org.springframework.data.gemfire.GemfireTemplate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +/** + * @author Glenn Renfro + */ +public class GemfireItemWriterBuilderTests { + @Mock + private GemfireTemplate template; + + private SpELItemKeyMapper itemKeyMapper; + + private List items; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + this.items = new ArrayList() { + { + add(new GemfireItemWriterBuilderTests.Foo(new GemfireItemWriterBuilderTests.Bar("val1"))); + add(new GemfireItemWriterBuilderTests.Foo(new GemfireItemWriterBuilderTests.Bar("val2"))); + } + }; + this.itemKeyMapper = new SpELItemKeyMapper<>("bar.val"); + } + + @Test + public void testBasicWrite() throws Exception { + GemfireItemWriter writer = new GemfireItemWriterBuilder() + .template(this.template).itemKeyMapper(this.itemKeyMapper).build(); + + writer.write(this.items); + + verify(this.template).put("val1", items.get(0)); + verify(this.template).put("val2", items.get(1)); + verify(this.template, never()).remove("val1"); + verify(this.template, never()).remove("val2"); + } + + @Test + public void testBasicDelete() throws Exception { + GemfireItemWriter writer = new GemfireItemWriterBuilder() + .template(this.template).delete(true).itemKeyMapper(this.itemKeyMapper).build(); + + writer.write(this.items); + + verify(this.template).remove("val1"); + verify(this.template).remove("val2"); + verify(this.template, never()).put("val1", items.get(0)); + verify(this.template, never()).put("val2", items.get(1)); + } + + @Test + public void testNullTemplate() { + try { + new GemfireItemWriterBuilder().itemKeyMapper(this.itemKeyMapper) + .build(); + fail("IllegalArgumentException should have been thrown"); + } + catch (IllegalArgumentException iae) { + assertEquals("IllegalArgumentException message did not match the expected result.", "template is required.", + iae.getMessage()); + } + } + + @Test + public void testNullItemKeyMapper() { + try { + new GemfireItemWriterBuilder().template(this.template).build(); + fail("IllegalArgumentException should have been thrown"); + } + catch (IllegalArgumentException iae) { + assertEquals("IllegalArgumentException message did not match the expected result.", + "itemKeyMapper is required.", iae.getMessage()); + } + } + + static class Foo { + public GemfireItemWriterBuilderTests.Bar bar; + + public Foo(GemfireItemWriterBuilderTests.Bar bar) { + this.bar = bar; + } + } + + static class Bar { + public String val; + + public Bar(String b1) { + this.val = b1; + } + } +}