-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add manual interactions to ContractNegotiation and TransferProcess
- Loading branch information
Showing
54 changed files
with
1,087 additions
and
727 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
94 changes: 94 additions & 0 deletions
94
core/common/state-machine/src/main/java/org/eclipse/edc/statemachine/ProcessorImpl.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,94 @@ | ||
/* | ||
* Copyright (c) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Apache License, Version 2.0 which is available at | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.statemachine; | ||
|
||
import java.util.Collection; | ||
import java.util.Objects; | ||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
import java.util.function.Supplier; | ||
|
||
import static java.util.function.Predicate.isEqual; | ||
|
||
/** | ||
* Describes the processing flow applied by a state machine. The entities are provided by a supplier. | ||
* A process is a function that returns a boolean that indicates if the entity has been processed or not in | ||
* the scope of the function. | ||
* The run method returns the processed state count, this is used by the state machine to decide | ||
* to apply the wait strategy or not. | ||
* <p> | ||
* An {@link Guard} can be registered, if its predicate is verified, the guard processor is executed instead of the standard one. | ||
* | ||
* @param <E> the entity that is processed | ||
*/ | ||
public class ProcessorImpl<E> implements Processor { | ||
|
||
private final Supplier<Collection<E>> entities; | ||
private Function<E, Boolean> process; | ||
private Guard<E> guard = Guard.noop(); | ||
|
||
private ProcessorImpl(Supplier<Collection<E>> entitiesSupplier) { | ||
entities = entitiesSupplier; | ||
} | ||
|
||
@Override | ||
public Long process() { | ||
return entities.get().stream() | ||
.map(entity -> { | ||
if (guard.predicate().test(entity)) { | ||
return guard.process().apply(entity); | ||
} else { | ||
return process.apply(entity); | ||
} | ||
}) | ||
.filter(isEqual(true)) | ||
.count(); | ||
} | ||
|
||
public static class Builder<E> { | ||
|
||
private final ProcessorImpl<E> processor; | ||
|
||
public Builder(Supplier<Collection<E>> entitiesSupplier) { | ||
processor = new ProcessorImpl<>(entitiesSupplier); | ||
} | ||
|
||
public static <E> Builder<E> newInstance(Supplier<Collection<E>> entitiesSupplier) { | ||
return new Builder<>(entitiesSupplier); | ||
} | ||
|
||
public Builder<E> process(Function<E, Boolean> process) { | ||
processor.process = process; | ||
return this; | ||
} | ||
|
||
public Builder<E> guard(Predicate<E> predicate, Function<E, Boolean> process) { | ||
processor.guard = new Guard<>(predicate, process); | ||
return this; | ||
} | ||
|
||
public ProcessorImpl<E> build() { | ||
Objects.requireNonNull(processor.process); | ||
|
||
return processor; | ||
} | ||
} | ||
|
||
private record Guard<E>(Predicate<E> predicate, Function<E, Boolean> process) { | ||
static <E> Guard<E> noop() { | ||
return new Guard<>(e -> false, e -> false); | ||
} | ||
} | ||
} |
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
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
91 changes: 91 additions & 0 deletions
91
core/common/state-machine/src/test/java/org/eclipse/edc/statemachine/ProcessorImplTest.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,91 @@ | ||
/* | ||
* Copyright (c) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Apache License, Version 2.0 which is available at | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - Initial implementation | ||
* | ||
*/ | ||
|
||
package org.eclipse.edc.statemachine; | ||
|
||
import org.eclipse.edc.statemachine.retry.TestEntity; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
import java.util.function.Function; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.verifyNoInteractions; | ||
import static org.mockito.Mockito.when; | ||
|
||
class ProcessorImplTest { | ||
|
||
@Test | ||
void shouldReturnTheProcessedCount() { | ||
var entity = TestEntity.Builder.newInstance().id("id").build(); | ||
var processor = ProcessorImpl.Builder.newInstance(() -> List.of(entity)) | ||
.process(e -> true) | ||
.build(); | ||
|
||
var count = processor.process(); | ||
|
||
assertThat(count).isEqualTo(1); | ||
} | ||
|
||
@Test | ||
void shouldNotCountUnprocessedEntities() { | ||
var entity = TestEntity.Builder.newInstance().id("id").build(); | ||
var processor = ProcessorImpl.Builder.newInstance(() -> List.of(entity)) | ||
.process(e -> false) | ||
.build(); | ||
|
||
var count = processor.process(); | ||
|
||
assertThat(count).isEqualTo(0); | ||
} | ||
|
||
@Test | ||
void shouldExecuteGuard_whenItsPredicateMatches() { | ||
var entity = TestEntity.Builder.newInstance().id("id").build(); | ||
Function<TestEntity, Boolean> process = mock(); | ||
Function<TestEntity, Boolean> guardProcess = mock(); | ||
when(guardProcess.apply(any())).thenReturn(true); | ||
var processor = ProcessorImpl.Builder.newInstance(() -> List.of(entity)) | ||
.guard(e -> true, guardProcess) | ||
.process(process) | ||
.build(); | ||
|
||
var count = processor.process(); | ||
|
||
assertThat(count).isEqualTo(1); | ||
verify(guardProcess).apply(entity); | ||
verifyNoInteractions(process); | ||
} | ||
|
||
@Test | ||
void shouldExecuteDefaultProcessor_whenGuardPredicateDoesNotMatch() { | ||
var entity = TestEntity.Builder.newInstance().id("id").build(); | ||
Function<TestEntity, Boolean> process = mock(); | ||
Function<TestEntity, Boolean> guardProcess = mock(); | ||
when(process.apply(any())).thenReturn(true); | ||
var processor = ProcessorImpl.Builder.newInstance(() -> List.of(entity)) | ||
.guard(e -> false, guardProcess) | ||
.process(process) | ||
.build(); | ||
|
||
var count = processor.process(); | ||
|
||
assertThat(count).isEqualTo(1); | ||
verify(process).apply(entity); | ||
verifyNoInteractions(guardProcess); | ||
} | ||
} |
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
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
Oops, something went wrong.