package com.constellio.model.services.records;
import static com.constellio.model.entities.schemas.MetadataValueType.NUMBER;
import static com.constellio.sdk.tests.TestUtils.asList;
import static junit.framework.TestCase.fail;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Before;
import org.junit.Test;
import com.constellio.data.dao.dto.records.OptimisticLockingResolution;
import com.constellio.data.utils.ThreadList;
import com.constellio.model.entities.calculators.CalculatorParameters;
import com.constellio.model.entities.calculators.MetadataValueCalculator;
import com.constellio.model.entities.calculators.dependencies.Dependency;
import com.constellio.model.entities.calculators.dependencies.LocalDependency;
import com.constellio.model.entities.calculators.dependencies.ReferenceDependency;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataValueType;
import com.constellio.model.services.records.RecordServicesException.UnresolvableOptimisticLockingConflict;
import com.constellio.model.services.schemas.builders.MetadataBuilder;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.TestRecord;
import com.constellio.sdk.tests.annotations.SlowTest;
import com.constellio.sdk.tests.schemas.TestsSchemasSetup;
@SlowTest
public class RecordServicesOptimisticLockingHandlingAcceptanceTest extends ConstellioTest {
RecordServices recordServices;
OptimisticLockingTestSchemasSetup schemas = new OptimisticLockingTestSchemasSetup();
OptimisticLockingTestSchemasSetup.ZeSchemaMetadatas zeSchema = schemas.new ZeSchemaMetadatas();
OptimisticLockingTestSchemasSetup.AnotherSchemaMetadatas anotherSchema = schemas.new AnotherSchemaMetadatas();
String zeSchemaRecord1Id;
String zeSchemaRecord2Id;
String zeSchemaRecord3Id;
String anotherSchemaRecordId;
@Before
public void setUp()
throws Exception {
recordServices = getModelLayerFactory().newRecordServices();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run1()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run2()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run3()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run4()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run5()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run6()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run7()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run8()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run9()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge_run10()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionThenMerge();
}
private void givenOptimisticLockingWhenExecutingSecondTransactionThenMerge()
throws Exception {
givenSchemasAndInitialRecords();
Transaction transactionModifyingFirstNumberAndAnotherSchema = modifyFirstNumberAndAnotherSchema();
Transaction transactionModifyingSecondNumber = modifySecondNumber();
recordServices.execute(transactionModifyingFirstNumberAndAnotherSchema);
transactionModifyingSecondNumber.setOptimisticLockingResolution(OptimisticLockingResolution.TRY_MERGE);
recordServices.execute(transactionModifyingSecondNumber);
assertThat(getRecord1().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord2().get(zeSchema.calculatedNumber())).isEqualTo(222.0);
assertThat(getRecord3().get(zeSchema.calculatedNumber())).isEqualTo(212.0);
}
@Test
public void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder_run1()
throws Exception {
givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder();
}
@Test
public void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder_run2()
throws Exception {
givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder();
}
@Test
public void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder_run3()
throws Exception {
givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder();
}
@Test
public void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder_run4()
throws Exception {
givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder();
}
@Test
public void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder_run5()
throws Exception {
givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder();
}
private void givenOptimisticLockingHandledWithKeepOlderWhenExecutingSecondTransactionThenKeepOlder()
throws Exception {
givenSchemasAndInitialRecords();
Transaction transactionModifyingFirstNumberAndAnotherSchema = modifyFirstNumberAndAnotherSchema();
Transaction transactionModifyingSecondNumber = modifySecondNumber();
recordServices.execute(transactionModifyingFirstNumberAndAnotherSchema);
transactionModifyingSecondNumber.setOptimisticLockingResolution(OptimisticLockingResolution.KEEP_OLDER);
recordServices.execute(transactionModifyingSecondNumber);
assertThat(getRecord1().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord2().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord3().get(zeSchema.calculatedNumber())).isEqualTo(211.0);
}
@Test
public void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException_run1()
throws Exception {
givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException();
}
@Test
public void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException_run2()
throws Exception {
givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException();
}
@Test
public void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException_run3()
throws Exception {
givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException();
}
@Test
public void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException_run4()
throws Exception {
givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException();
}
@Test
public void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException_run5()
throws Exception {
givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException();
}
private void givenOptimisticLockingHandledWithExceptionWhenExecutingSecondTransactionThenThrowException()
throws Exception {
givenSchemasAndInitialRecords();
Transaction transactionModifyingFirstNumberAndAnotherSchema = modifyFirstNumberAndAnotherSchema();
Transaction transactionModifyingSecondNumber = modifySecondNumber();
recordServices.execute(transactionModifyingFirstNumberAndAnotherSchema);
transactionModifyingSecondNumber.setOptimisticLockingResolution(OptimisticLockingResolution.EXCEPTION);
try {
recordServices.execute(transactionModifyingSecondNumber);
fail("exception expected");
} catch (RecordServicesException.OptimisticLocking e) {
// OK
}
assertThat(getRecord1().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord2().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord3().get(zeSchema.calculatedNumber())).isEqualTo(211.0);
}
@Test
public void givenRecordWithCopiedValuesWhenMergingThenCopiedMetadatasMerged()
throws Exception {
getDataLayerFactory().getDataLayerLogger().monitor("zeRecord");
final int numberOfThreads = 10;
final int numberOfIncrements = 20;
defineSchemasManager().using(schemas.withCopiedMetadatas(numberOfThreads));
final AtomicInteger exceptionsCounter = new AtomicInteger();
final AtomicInteger cannotMergeCounter = new AtomicInteger();
final AtomicInteger corruptionCounter = new AtomicInteger();
final String zeRecordId = "zeRecord";
Transaction transaction = new Transaction();
Record zeRecord = new TestRecord(zeSchema, zeRecordId);
for (int i = 0; i < numberOfThreads; i++) {
zeRecord.set(zeSchema.reference(i), "anotherRecord" + i);
transaction.add(new TestRecord(anotherSchema, "anotherRecord" + i).set(anotherSchema.number(), 0));
}
transaction.add(zeRecord);
recordServices.execute(transaction);
ThreadList<Thread> threads = new ThreadList<>();
for (int i = 0; i < numberOfThreads; i++) {
final int index = i;
threads.add(new Thread() {
@Override
public void run() {
for (int j = 1; j < numberOfIncrements; j++) {
while (true) {
if (index == numberOfThreads - 1) {
// System.out.println("Progression : " + j + " / " + numberOfIncrements);
}
try {
double currentCopiedNumber = recordServices.getDocumentById(zeRecordId)
.get(zeSchema.number(index));
double expectedNumber = j - 1;
if (currentCopiedNumber != expectedNumber) {
System.out.println(" **** Field #" + index + " : Expected '" + expectedNumber + "' but was '"
+ currentCopiedNumber + "'");
corruptionCounter.incrementAndGet();
}
Record anotherRecord = recordServices.getDocumentById("anotherRecord" + index);
Transaction transaction = new Transaction("threadTransaction_" + index + "_" + j);
transaction.add(anotherRecord.set(anotherSchema.number(), j));
recordServices.execute(transaction);
break;
} catch (UnresolvableOptimisticLockingConflict e) {
cannotMergeCounter.incrementAndGet();
} catch (Throwable e) {
exceptionsCounter.incrementAndGet();
}
}
}
}
});
}
threads.startAll();
threads.joinAll();
assertThat(corruptionCounter.get()).isZero();
assertThat(cannotMergeCounter.get()).isZero();
assertThat(exceptionsCounter.get()).isZero();
}
@Test
public void givenRecordWithCalculatedValuesWhenMergingThenCalculatedMetadatasMerged()
throws Exception {
getDataLayerFactory().getDataLayerLogger().monitor("zeRecord");
final int numberOfThreads = 5;
final int numberOfIncrements = 20;
defineSchemasManager().using(schemas.withFiveCalculatedMetadatas());
final AtomicInteger exceptionsCounter = new AtomicInteger();
final AtomicInteger cannotMergeCounter = new AtomicInteger();
final AtomicInteger corruptionCounter = new AtomicInteger();
final String zeRecordId = "zeRecord";
Transaction transaction = new Transaction();
Record zeRecord = new TestRecord(zeSchema, zeRecordId);
for (int i = 0; i < numberOfThreads; i++) {
zeRecord.set(zeSchema.reference(i), "anotherRecord" + i);
transaction.add(new TestRecord(anotherSchema, "anotherRecord" + i).set(anotherSchema.number(), 0));
}
transaction.add(zeRecord);
recordServices.execute(transaction);
ThreadList<Thread> threads = new ThreadList<>();
for (int i = 0; i < numberOfThreads; i++) {
final int index = i;
threads.add(new Thread() {
@Override
public void run() {
for (int j = 1; j < numberOfIncrements; j++) {
while (true) {
if (index == numberOfThreads - 1) {
// System.out.println("Progression : " + j + " / " + numberOfIncrements);
}
try {
double currentCopiedNumber = recordServices.getDocumentById(zeRecordId)
.get(zeSchema.number(index));
double expectedNumber = j - 1;
if (currentCopiedNumber != expectedNumber) {
System.out.println(" **** Field #" + index + " : Expected '" + expectedNumber + "' but was '"
+ currentCopiedNumber + "'");
corruptionCounter.incrementAndGet();
}
Record anotherRecord = recordServices.getDocumentById("anotherRecord" + index);
Transaction transaction = new Transaction("threadTransaction_" + index + "_" + j);
transaction.add(anotherRecord.set(anotherSchema.number(), j));
recordServices.execute(transaction);
break;
} catch (UnresolvableOptimisticLockingConflict e) {
cannotMergeCounter.incrementAndGet();
} catch (Throwable e) {
exceptionsCounter.incrementAndGet();
}
}
}
}
});
}
threads.startAll();
threads.joinAll();
assertThat(corruptionCounter.get()).isZero();
assertThat(cannotMergeCounter.get()).isZero();
assertThat(exceptionsCounter.get()).isZero();
}
@Test
public void givenRecordWithManualValuesWhenMergingThenMetadatasCorrectlyMerged()
throws Exception {
getDataLayerFactory().getDataLayerLogger().monitor("zeRecord");
final int numberOfThreads = 10;
final int numberOfIncrements = 20;
defineSchemasManager().using(schemas.withManualNumberMetadatasInZeSchemas(numberOfThreads));
final AtomicInteger exceptionsCounter = new AtomicInteger();
final AtomicInteger cannotMergeCounter = new AtomicInteger();
final AtomicInteger corruptionCounter = new AtomicInteger();
final String zeRecordId = "zeRecord";
Transaction transaction = new Transaction();
Record zeRecord = new TestRecord(zeSchema, zeRecordId);
for (int i = 0; i < numberOfThreads; i++) {
zeRecord.set(zeSchema.number(i), 0);
}
transaction.add(zeRecord);
recordServices.execute(transaction);
ThreadList<Thread> threads = new ThreadList<>();
for (int i = 0; i < numberOfThreads; i++) {
final int index = i;
threads.add(new Thread() {
@Override
public void run() {
for (int j = 1; j < numberOfIncrements; j++) {
while (true) {
if (index == numberOfThreads - 1) {
// System.out.println("Progression : " + j + " / " + numberOfIncrements);
}
try {
double currentCopiedNumber = recordServices.getDocumentById(zeRecordId)
.get(zeSchema.number(index));
double expectedNumber = j - 1;
if (currentCopiedNumber != expectedNumber) {
System.out.println(" **** Field #" + index + " : Expected '" + expectedNumber + "' but was '"
+ currentCopiedNumber + "' **** ");
corruptionCounter.incrementAndGet();
}
Record zeRecord = recordServices.getDocumentById(zeRecordId);
Transaction transaction = new Transaction();
transaction.add(zeRecord.set(zeSchema.number(index), j));
recordServices.execute(transaction);
break;
} catch (UnresolvableOptimisticLockingConflict e) {
cannotMergeCounter.incrementAndGet();
} catch (Throwable e) {
exceptionsCounter.incrementAndGet();
}
}
}
}
});
}
threads.startAll();
threads.joinAll();
assertThat(corruptionCounter.get()).isZero();
assertThat(cannotMergeCounter.get()).isZero();
assertThat(exceptionsCounter.get()).isZero();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail_run1()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail_run2()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail_run3()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail_run4()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail();
}
@Test
public void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail_run5()
throws Exception {
givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail();
}
// -----------------------------------------------------------------
private void givenOptimisticLockingWhenExecutingSecondTransactionWithConflictThenFail()
throws Exception {
givenSchemasAndInitialRecords();
Transaction transactionModifyingFirstNumberAndAnotherSchema = modifyFirstNumberAndAnotherSchema();
Transaction modifyFirstNumberWithOtherValues = modifyFirstNumberWithOtherValues();
recordServices.execute(transactionModifyingFirstNumberAndAnotherSchema);
modifyFirstNumberWithOtherValues.setOptimisticLockingResolution(OptimisticLockingResolution.TRY_MERGE);
try {
recordServices.execute(modifyFirstNumberWithOtherValues);
fail("exception expected");
} catch (RecordServicesException.UnresolvableOptimisticLockingConflict e) {
// OK
}
assertThat(getRecord1().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord2().get(zeSchema.calculatedNumber())).isEqualTo(221.0);
assertThat(getRecord3().get(zeSchema.calculatedNumber())).isEqualTo(211.0);
}
private Transaction modifySecondNumber() {
Transaction transaction = new Transaction();
transaction.addUpdate(getRecord2().set(zeSchema.number2(), 2.0));
transaction.addUpdate(getRecord3().set(zeSchema.number2(), 2.0));
transaction.addUpdate(getAnotherSchemaRecord().set(anotherSchema.number(), 200.0));
return transaction;
}
private Transaction modifyFirstNumberAndAnotherSchema() {
Transaction transaction = new Transaction();
transaction.addUpdate(getRecord1().set(zeSchema.number1(), 20.0));
transaction.addUpdate(getRecord2().set(zeSchema.number1(), 20.0));
transaction.addUpdate(getAnotherSchemaRecord().set(anotherSchema.number(), 200.0));
return transaction;
}
private Transaction modifyFirstNumberWithOtherValues() {
Transaction transaction = new Transaction();
transaction.addUpdate(getRecord1().set(zeSchema.number1(), 30.0));
transaction.addUpdate(getRecord2().set(zeSchema.number1(), 30.0));
return transaction;
}
private Record getRecord1() {
return recordServices.getDocumentById(zeSchemaRecord1Id);
}
private Record getRecord2() {
return recordServices.getDocumentById(zeSchemaRecord2Id);
}
private Record getRecord3() {
return recordServices.getDocumentById(zeSchemaRecord3Id);
}
private Record getAnotherSchemaRecord() {
return recordServices.getDocumentById(anotherSchemaRecordId);
}
private void givenSchemasAndInitialRecords()
throws RecordServicesException {
defineSchemasManager().using(schemas.withCalculatorUsingOtherNumbers());
Record anotherSchemaRecord = new TestRecord(anotherSchema);
recordServices.add(anotherSchemaRecord.set(anotherSchema.number(), 100.0));
anotherSchemaRecordId = anotherSchemaRecord.getId();
Transaction transaction = new Transaction();
Record zeSchemaRecord1 = recordServices.newRecordWithSchema(zeSchema.instance());
transaction.addUpdate(zeSchemaRecord1.set(zeSchema.number1(), 10.0).set(zeSchema.number2(), 1.0)
.set(zeSchema.refToAnotherSchema(), anotherSchemaRecordId));
Record zeSchemaRecord2 = recordServices.newRecordWithSchema(zeSchema.instance());
transaction.addUpdate(zeSchemaRecord2.set(zeSchema.number1(), 10.0).set(zeSchema.number2(), 1.0)
.set(zeSchema.refToAnotherSchema(), anotherSchemaRecordId));
Record zeSchemaRecord3 = recordServices.newRecordWithSchema(zeSchema.instance());
transaction.addUpdate(zeSchemaRecord3.set(zeSchema.number1(), 10.0).set(zeSchema.number2(), 1.0)
.set(zeSchema.refToAnotherSchema(), anotherSchemaRecordId));
recordServices.execute(transaction);
zeSchemaRecord1Id = zeSchemaRecord1.getId();
zeSchemaRecord2Id = zeSchemaRecord2.getId();
zeSchemaRecord3Id = zeSchemaRecord3.getId();
}
private static class OptimisticLockingTestSchemasSetup extends TestsSchemasSetup {
private OptimisticLockingTestSchemasSetup withCalculatorUsingOtherNumbers() {
anOtherDefaultSchemaBuilder.create("number").setType(NUMBER);
zeDefaultSchemaBuilder.create("number1").setType(NUMBER);
zeDefaultSchemaBuilder.create("number2").setType(NUMBER);
zeDefaultSchemaBuilder.create("refToAnotherSchema").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("calculatedNumber").setType(NUMBER).defineDataEntry()
.asCalculated(SumOfOtherMetadatas.class);
return this;
}
private OptimisticLockingTestSchemasSetup withCopiedMetadatas(int quantity) {
MetadataBuilder anotherSchemaNumber = anOtherDefaultSchemaBuilder.create("number").setType(NUMBER);
for (int i = 0; i < quantity; i++) {
MetadataBuilder reference = zeDefaultSchemaBuilder.create("reference" + i)
.defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("number" + i).setType(NUMBER)
.defineDataEntry().asCopied(reference, anotherSchemaNumber);
}
return this;
}
private OptimisticLockingTestSchemasSetup withFiveCalculatedMetadatas() {
anOtherDefaultSchemaBuilder.create("number").setType(NUMBER);
zeDefaultSchemaBuilder.create("reference0").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("reference1").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("reference2").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("reference3").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("reference4").defineReferencesTo(anOtherSchemaTypeBuilder);
zeDefaultSchemaBuilder.create("number0").setType(NUMBER)
.defineDataEntry().asCalculated(RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator1.class);
zeDefaultSchemaBuilder.create("number1").setType(NUMBER)
.defineDataEntry().asCalculated(RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator2.class);
zeDefaultSchemaBuilder.create("number2").setType(NUMBER)
.defineDataEntry().asCalculated(RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator3.class);
zeDefaultSchemaBuilder.create("number3").setType(NUMBER)
.defineDataEntry().asCalculated(RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator4.class);
zeDefaultSchemaBuilder.create("number4").setType(NUMBER)
.defineDataEntry().asCalculated(RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator5.class);
return this;
}
private OptimisticLockingTestSchemasSetup withManualNumberMetadatasInZeSchemas(int quantity) {
for (int i = 0; i < quantity; i++) {
zeDefaultSchemaBuilder.create("number" + i).setType(NUMBER);
}
return this;
}
private class ZeSchemaMetadatas extends TestsSchemasSetup.ZeSchemaMetadatas {
private Metadata reference(int n) {
return getMetadata(code() + "_reference" + n);
}
private Metadata number(int n) {
return getMetadata(code() + "_number" + n);
}
private Metadata number1() {
return getMetadata(code() + "_number1");
}
private Metadata number2() {
return getMetadata(code() + "_number2");
}
private Metadata refToAnotherSchema() {
return getMetadata(code() + "_refToAnotherSchema");
}
private Metadata calculatedNumber() {
return getMetadata(code() + "_calculatedNumber");
}
}
private class AnotherSchemaMetadatas extends TestsSchemasSetup.AnotherSchemaMetadatas {
private Metadata number() {
return getMetadata(code() + "_number");
}
}
}
public static class SumOfOtherMetadatas implements MetadataValueCalculator<Double> {
LocalDependency<Double> number1Param = LocalDependency.toANumber("number1");
LocalDependency<Double> number2Param = LocalDependency.toANumber("number2");
ReferenceDependency<Double> number3Param = ReferenceDependency.toANumber("refToAnotherSchema", "number");
@Override
public Double calculate(CalculatorParameters parameters) {
Double number1 = parameters.get(number1Param);
Double number2 = parameters.get(number2Param);
Double number3 = parameters.get(number3Param);
return number1 + number2 + number3;
}
@Override
public Double getDefaultValue() {
return 0.0;
}
@Override
public MetadataValueType getReturnType() {
return NUMBER;
}
@Override
public boolean isMultiValue() {
return false;
}
@Override
public List<? extends Dependency> getDependencies() {
return Arrays.asList(number1Param, number2Param, number3Param);
}
}
public static class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator1
extends RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator implements MetadataValueCalculator<Double> {
@Override
protected String getReferenceCode() {
return "reference0";
}
}
public static class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator2
extends RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator implements MetadataValueCalculator<Double> {
@Override
protected String getReferenceCode() {
return "reference1";
}
}
public static class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator3
extends RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator implements MetadataValueCalculator<Double> {
@Override
protected String getReferenceCode() {
return "reference2";
}
}
public static class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator4
extends RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator implements MetadataValueCalculator<Double> {
@Override
protected String getReferenceCode() {
return "reference3";
}
}
public static class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator5
extends RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator implements MetadataValueCalculator<Double> {
@Override
protected String getReferenceCode() {
return "reference4";
}
}
public static abstract class RecordServicesOptimisticLockingHandlingAcceptanceTest_Calculator
implements MetadataValueCalculator<Double> {
ReferenceDependency<Double> referenceDependency = ReferenceDependency.toANumber(getReferenceCode(), "number");
@Override
public Double calculate(CalculatorParameters parameters) {
return parameters.get(referenceDependency);
}
@Override
public Double getDefaultValue() {
return null;
}
@Override
public MetadataValueType getReturnType() {
return MetadataValueType.NUMBER;
}
@Override
public boolean isMultiValue() {
return false;
}
@Override
public List<? extends Dependency> getDependencies() {
return asList(referenceDependency);
}
protected abstract String getReferenceCode();
}
}