blob: 617f9db290a7b83e8e861878e0bb0da3791f01d4 [file] [log] [blame]
/*
* 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.test.data;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.batch.api.chunk.AbstractItemReader;
import javax.batch.api.chunk.AbstractItemWriter;
import javax.batch.operations.JobOperator;
import javax.batch.runtime.BatchRuntime;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.StepExecution;
import org.apache.batchee.container.services.data.DefaultDataRepresentationService;
import org.apache.batchee.spi.DataRepresentationService;
import org.apache.batchee.util.Batches;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import org.junit.Assert;
import org.junit.Test;
import static org.testng.Assert.assertEquals;
public class DefaultDataRepresentationServiceTest {
private DataRepresentationService dataExtSvc = new DefaultDataRepresentationService();
@Test
public void testNullConversions() {
Assert.assertNull(dataExtSvc.toInternalRepresentation(null));
Assert.assertNull(dataExtSvc.toJavaRepresentation(null));
}
@Test
public void testProperties() {
Properties props = new Properties();
props.put("Key1", "Value1");
props.put("Key2", "Value2");
props.put("Key3", "Value3");
Properties props2 = roundTrip(props, false);
Assert.assertEquals(props.size(), props2.size());
for (Object key : props.keySet()) {
Assert.assertEquals(props.get(key), props2.get(key));
}
}
@Test
public void testJavaNatives() {
assertRoundTripEquals(4712, true);
assertRoundTripEquals(Integer.valueOf(4711), true);
assertRoundTripEquals("this is a test value", true);
assertRoundTripEquals(Long.valueOf(78483L), true);
assertRoundTripEquals(12.34f, true); // be careful about different Locales!
}
@Test
public void testJavaCustomEnum() {
assertRoundTripEquals(MySampleEnum.VALUE1, true);
assertRoundTripEquals(MySampleEnum.VALUE2, true);
assertRoundTripEquals(MySampleEnum.ANOTHER_VALUE, true);
}
public enum MySampleEnum {
VALUE1,
VALUE2,
ANOTHER_VALUE
}
@Test
public void testJavaDate_Timestamp() {
Date dt = new Date();
assertRoundTripEquals(dt, true);
Timestamp tst = new Timestamp(dt.getTime());
tst.setNanos(12345);
assertRoundTripEquals(tst, true);
}
@Test
public void testJavaMathTypes() {
//X TODO BigInteger, BigDecimal
}
@Test
public void testJavaCustomObjects() {
SomeCustomJavaPojo customPojo = new SomeCustomJavaPojo();
customPojo.setI(42);
SomeCustomJavaPojo customPojo2 = roundTrip(customPojo, false);
Assert.assertNotNull(customPojo2);
Assert.assertEquals(42, customPojo2.getI());
}
@Test
public void testJava8DateTimeViaReflection() {
Object java8LocalDate = createJava8datetype("java.time.LocalDate");
Object java8LocalTime = createJava8datetype("java.time.LocalTime");
Object java8LocalDateTime = createJava8datetype("java.time.LocalDateTime");
if (java8LocalDate != null) {
assertRoundTripEquals(java8LocalDate, true);
assertRoundTripEquals(java8LocalTime, true);
assertRoundTripEquals(java8LocalDateTime, true);
}
}
private Object createJava8datetype(String className) {
try {
Class<?> clazz = Class.forName(className);
Method now = clazz.getMethod("now");
return now.invoke(null);
} catch (Exception e) {
// all fine, we are just not running on java8
}
return null;
}
@Test
public void testJodaDateTimeViaReflection() {
assertRoundTripEquals(LocalDate.now(), true);
assertRoundTripEquals(LocalDateTime.now(), true);
assertRoundTripEquals(LocalTime.now(), true);
}
@Test
public void testJavaParameterisedTypes() {
//X TODO
}
/**
* java.util.Properties e.g. in JobProperties which got stored in older versions
*/
@Test
public void testDeserializeOldProperties() {
//X TODO
}
/**
* Integer, Long, String, etc which got stored in older versions as serialized values
*/
@Test
public void testDeserializeOldJavaNatives() {
//X TODO
}
/**
* Custom Java Objects got stored in older versions as serialized values
*/
@Test
public void testDeserializeOldJavaObjects() {
//X TODO
}
private <T> void assertRoundTripEquals(T data, boolean humanReadable) {
T data2 = roundTrip(data, humanReadable);
Assert.assertEquals(data.getClass(), data2.getClass());
Assert.assertEquals(data, data2);
}
@Test
public void testBatchExecutionWithCheckpoints() {
final JobOperator op = BatchRuntime.getJobOperator();
final long id = op.start("checkpoint-storage-test", null);
Batches.waitForEnd(op, id);
final List<StepExecution> steps = op.getStepExecutions(id);
assertEquals(1, steps.size());
final StepExecution exec = steps.iterator().next();
Assert.assertEquals(BatchStatus.FAILED, exec.getBatchStatus());
// now try to restart the batch again
long restartId = op.restart(id, null);
Batches.waitForEnd(op, restartId);
}
private <T> T roundTrip(T data, boolean humanReadable) {
byte[] storedValue = dataExtSvc.toInternalRepresentation(data);
Assert.assertNotNull(storedValue);
if (humanReadable) {
Assert.assertTrue(new String(storedValue).startsWith(DefaultDataRepresentationService.BATCHEE_DATA_PREFIX));
}
T deserialisedData = dataExtSvc.toJavaRepresentation(storedValue);
Assert.assertNotNull(deserialisedData);
return deserialisedData;
}
public static class SomeCustomJavaPojo implements Serializable {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
@SuppressWarnings("unused")
public static class DummyReaderWithCheckpoint extends AbstractItemReader {
private int counter = 0;
@Override
public void open(Serializable checkpoint) throws Exception {
if (checkpoint != null) {
counter = (Integer)checkpoint;
}
}
@Override
public Object readItem() throws Exception {
return counter++ <= 3 ? counter : null;
}
@Override
public Serializable checkpointInfo() throws Exception {
return counter;
}
}
@SuppressWarnings("unused")
public static class DummyWriterWithCheckpoint extends AbstractItemWriter {
private Integer lastCount = null;
@Override
public void open(Serializable checkpoint) throws Exception {
if (checkpoint != null) {
lastCount = (Integer)checkpoint + 10;
}
}
@Override
public void writeItems(List<Object> items) throws Exception {
lastCount = (Integer) items.get(0);
if (lastCount.equals(2)) {
throw new Exception("Intentionally aborting this test batch!");
}
}
@Override
public Serializable checkpointInfo() throws Exception {
return lastCount;
}
}
}