Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/main/java/com/iexec/commons/poco/chain/ChainDeal.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@
public class ChainDeal {

String chainDealId;
/**
* @deprecated not consistent with Smart Contracts
*/
@Deprecated(forRemoval = true)
ChainApp chainApp;

Check warning on line 35 in src/main/java/com/iexec/commons/poco/chain/ChainDeal.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIwJzu17z5OCyyfa&open=AZrKBIwJzu17z5OCyyfa&pullRequest=163
/**
* @deprecated not consistent with Smart Contracts
*/
@Deprecated(forRemoval = true)
ChainDataset chainDataset;

Check warning on line 40 in src/main/java/com/iexec/commons/poco/chain/ChainDeal.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIwJzu17z5OCyyfb&open=AZrKBIwJzu17z5OCyyfb&pullRequest=163
/**
* @deprecated not consistent with Smart Contracts
*/
@Deprecated(forRemoval = true)
ChainCategory chainCategory;

Check warning on line 45 in src/main/java/com/iexec/commons/poco/chain/ChainDeal.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIwJzu17z5OCyyfc&open=AZrKBIwJzu17z5OCyyfc&pullRequest=163
// deal_pt1
String dappPointer;
String dappOwner;
Expand Down Expand Up @@ -59,9 +71,7 @@
BigInteger schedulerRewardRatio;

public boolean containsDataset() {
return getChainDataset() != null &&
getChainDataset().getChainDatasetId() != null &&
!getChainDataset().getChainDatasetId().equals(BytesUtils.EMPTY_ADDRESS);
return dataPointer != null && !BytesUtils.EMPTY_ADDRESS.equals(dataPointer);
}

public static ChainDeal parts2ChainDeal(String chainDealId, IexecHubContract.Deal deal, ChainCategory category) {
Expand All @@ -71,7 +81,11 @@
return create(chainDealId, deal, category, null, null);
}

/**
* @deprecated app, category and dataset will no more be embedded in deal to stick to on-chain models
*/
@Deprecated(forRemoval = true)
public static ChainDeal parts2ChainDeal(String chainDealId, IexecHubContract.Deal deal, ChainApp app, ChainCategory category, ChainDataset dataset) {

Check warning on line 88 in src/main/java/com/iexec/commons/poco/chain/ChainDeal.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIwJzu17z5OCyyfd&open=AZrKBIwJzu17z5OCyyfd&pullRequest=163
if (deal == null || app == null || category == null) {
return ChainDeal.builder().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@
* @param maxRetry number of maximum retry
* @return optional ChainDeal
*/
Optional<ChainDeal> repeatGetChainDeal(String chainDealId,
long retryDelay,
int maxRetry) {
Optional<ChainDeal> repeatGetChainDeal(final String chainDealId,
final long retryDelay,
final int maxRetry) {
return new Retryer<Optional<ChainDeal>>()
.repeatCall(() -> getChainDealWithDetails(chainDealId),
.repeatCall(() -> getChainDeal(chainDealId),
Optional::isEmpty,
retryDelay, maxRetry,
String.format("getChainDeal(chainDealId) [chainDealId:%s]", chainDealId));
Expand Down Expand Up @@ -210,8 +210,10 @@
*
* @param chainDealId blockchain ID of the deal (e.g: 0x123..abc)
* @return deal object
* @deprecated on-chain app, category, dataset and deal are fetched separately (see repeatGetTaskDescriptionFromChain)
*/
@Deprecated(forRemoval = true)
public Optional<ChainDeal> getChainDealWithDetails(String chainDealId) {

Check warning on line 216 in src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIvvzu17z5OCyyfZ&open=AZrKBIvvzu17z5OCyyfZ&pullRequest=163
final byte[] chainDealIdBytes = BytesUtils.stringToBytes(chainDealId);
try {
final IexecHubContract.Deal deal = iexecHubContract.viewDeal(chainDealIdBytes).send();
Expand Down Expand Up @@ -258,9 +260,9 @@
* @param maxRetry number of maximum retry
* @return optional ChainTask
*/
Optional<ChainTask> repeatGetChainTask(String chainTaskId,
long retryDelay,
int maxRetry) {
Optional<ChainTask> repeatGetChainTask(final String chainTaskId,
final long retryDelay,
final int maxRetry) {
return new Retryer<Optional<ChainTask>>()
.repeatCall(() -> getChainTask(chainTaskId),
Optional::isEmpty,
Expand Down Expand Up @@ -458,9 +460,18 @@
return taskDescriptions.get(chainTaskId);
}

Optional<TaskDescription> repeatGetTaskDescriptionFromChain(String chainTaskId,
long retryDelay,
int maxRetry) {
/**
* Retrieves task, deal, category, app and dataset models on PoCo Smart Contracts to build a task description.
*
* @param chainTaskId ID of the task
* @param retryDelay Interval between consecutive attempts while reading on the blockchain network
* @param maxRetry Maximum number of attempts
* @return The aggregate {@code TaskDescription}.
* If the maximum number of attempts is reached without retrieving data, an empty result will be returned.
*/
Optional<TaskDescription> repeatGetTaskDescriptionFromChain(final String chainTaskId,
final long retryDelay,
final int maxRetry) {
// If retryDelay is 0, a runtime exception will be thrown from failsafe library
if (retryDelay == 0) {
log.warn("retry delay cannot be 0 [chainTaskId:{}]", chainTaskId);
Expand All @@ -478,9 +489,31 @@
return Optional.empty();
}

final TaskDescription taskDescription = TaskDescription.toTaskDescription(chainDeal, chainTask);
final ChainCategory chainCategory = new Retryer<Optional<ChainCategory>>()
.repeatCall(() -> getChainCategory(chainDeal.getCategory().longValue()),
Optional::isEmpty,
retryDelay, maxRetry,
String.format("getChainCategory() [category:%s]", chainDeal.getCategory().longValue()))
.orElse(null);

final ChainApp chainApp = new Retryer<Optional<ChainApp>>()
.repeatCall(() -> getChainApp(chainDeal.getDappPointer()),
Optional::isEmpty,
retryDelay, maxRetry,
String.format("getChainApp() [address:%s]", chainDeal.getDappPointer()))
.orElse(null);

final ChainDataset chainDataset = new Retryer<Optional<ChainDataset>>()
.repeatCall(() -> getChainDataset(chainDeal.getDataPointer()),
Optional::isEmpty,
retryDelay, maxRetry,
String.format("getChainDataset() [address:%s]", chainDeal.getDataPointer()))
.orElse(null);

final TaskDescription taskDescription = TaskDescription.toTaskDescription(
chainDeal, chainTask, chainCategory, chainApp, chainDataset);
// taskDescription cannot be null here as chainTask and ChainDeal are not
return taskDescription != null ? Optional.of(taskDescription) : Optional.empty();
return Optional.ofNullable(taskDescription);
}

/**
Expand Down
45 changes: 35 additions & 10 deletions src/main/java/com/iexec/commons/poco/task/TaskDescription.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
package com.iexec.commons.poco.task;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.iexec.commons.poco.chain.ChainDeal;
import com.iexec.commons.poco.chain.ChainTask;
import com.iexec.commons.poco.chain.DealParams;
import com.iexec.commons.poco.chain.*;
import com.iexec.commons.poco.dapp.DappType;
import com.iexec.commons.poco.tee.TeeEnclaveConfiguration;
import com.iexec.commons.poco.tee.TeeFramework;
Expand All @@ -42,6 +40,7 @@
// assets
DappType appType;
String appUri;
String appChecksum;
TeeEnclaveConfiguration appEnclaveConfiguration;
String datasetUri;
String datasetChecksum;
Expand Down Expand Up @@ -181,24 +180,50 @@
* @param chainDeal On-chain deal from PoCo smart contracts
* @param chainTask On-chain task from PoCo smart contracts
* @return the created taskDescription
* @deprecated app, category and dataset models will be removed from deal model
*/
@Deprecated(forRemoval = true)
public static TaskDescription toTaskDescription(final ChainDeal chainDeal, final ChainTask chainTask) {

Check warning on line 186 in src/main/java/com/iexec/commons/poco/task/TaskDescription.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIwhzu17z5OCyyfe&open=AZrKBIwhzu17z5OCyyfe&pullRequest=163
if (chainDeal == null || chainTask == null) {
return null;
}
String datasetUri = "";
String datasetChecksum = "";
return toTaskDescription(
chainDeal, chainTask, chainDeal.getChainCategory(), chainDeal.getChainApp(), chainDeal.getChainDataset());
}

/**
* Create a {@link TaskDescription} from the provided chain deal. This method
* if preferred to constructors or the builder method.
*
* @param chainDeal On-chain deal from PoCo smart contracts
* @param chainTask On-chain task from PoCo smart contracts
* @param chainCategory On-chain category from PoCo smart contracts
* @param chainApp On-chain application from PoCo smart contracts
* @param chainDataset On-chain dataset from PoCo smart contracts
* @return the created taskDescription
*/
public static TaskDescription toTaskDescription(final ChainDeal chainDeal,
final ChainTask chainTask,
final ChainCategory chainCategory,
final ChainApp chainApp,
final ChainDataset chainDataset) {
if (chainDeal == null || chainTask == null || chainCategory == null || chainApp == null || (chainDeal.containsDataset() && chainDataset == null)) {
return null;
}
String datasetUri = null;
String datasetChecksum = null;
if (chainDeal.containsDataset()) {
datasetUri = chainDeal.getChainDataset().getMultiaddr();
datasetChecksum = chainDeal.getChainDataset().getChecksum();
datasetUri = chainDataset.getMultiaddr();
datasetChecksum = chainDataset.getChecksum();
}
final String tag = chainDeal.getTag();
return TaskDescription.builder()
.chainTaskId(chainTask.getChainTaskId())
// assets
.appType(DappType.DOCKER)
.appUri(chainDeal.getChainApp().getMultiaddr())
.appEnclaveConfiguration(chainDeal.getChainApp().getEnclaveConfiguration())
.appUri(chainApp.getMultiaddr())
.appChecksum(chainApp.getChecksum())
.appEnclaveConfiguration(chainApp.getEnclaveConfiguration())
.datasetUri(datasetUri)
.datasetChecksum(datasetChecksum)
// deal
Expand Down Expand Up @@ -227,7 +252,7 @@
// task
.chainDealId(chainDeal.getChainDealId())
.botIndex(chainTask.getIdx())
.maxExecutionTime(chainDeal.getChainCategory().getMaxExecutionTime()) // https://github.com/iExecBlockchainComputing/PoCo/blob/v5/contracts/modules/delegates/IexecPoco2Delegate.sol#L111
.maxExecutionTime(chainCategory.getMaxExecutionTime())
.contributionDeadline(chainTask.getContributionDeadline())
.finalDeadline(chainTask.getFinalDeadline())
.build();
Expand Down
38 changes: 18 additions & 20 deletions src/main/java/com/iexec/commons/poco/utils/Retryer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,41 +35,39 @@ public class Retryer<T> {
* @param retryIfPredicate condition for retrying the supplying method call
* @param retryDelay delay in ms between two tries
* @param maxRetry number of maximum retries
* @param logContext human readable content to be display
* @param logContext human-readable content to be displayed
* @return an object that the supplying method provides
*/
public T repeatCall(CheckedSupplier<T> supplier,
Predicate<T> retryIfPredicate,
long retryDelay,
int maxRetry,
String logContext) {
String context = "\"" + logContext + "\"";
public T repeatCall(final CheckedSupplier<T> supplier,
final Predicate<T> retryIfPredicate,
final long retryDelay,
final int maxRetry,
final String logContext) {
if (retryDelay == 0) {
log.error("Cannot repeat call {} without delay " +
"[retryDelay:{}ms, maxRetry:{}]",
log.error("Cannot repeat call {} without delay [retryDelay:{}ms, maxRetry:{}]",
logContext, retryDelay, maxRetry);
return null;
}
RetryPolicy<T> retryPolicy =
final RetryPolicy<T> retryPolicy =
new RetryPolicy<T>()
.handleResultIf(retryIfPredicate) //retry if
.withDelay(Duration.ofMillis(retryDelay))
.withMaxRetries(maxRetry)
.onRetry(e -> logWarnRetry(context,
retryDelay, maxRetry, e.getAttemptCount()))
.onRetriesExceeded(e -> logErrorOnMaxRetry(context,
retryDelay, maxRetry));
.onRetry(e -> logWarnRetry(
logContext, retryDelay, maxRetry, e.getAttemptCount()))
.onRetriesExceeded(e -> logErrorOnMaxRetry(
logContext, retryDelay, maxRetry));
return Failsafe.with(retryPolicy)
.get(supplier);
}

private void logWarnRetry(String context, long retryDelay, int maxRetry, int attempt) {
log.warn("Failed to {}, about to retry [retryDelay:{}ms, maxRetry:{}" +
", attempt:{}]", context, retryDelay, maxRetry, attempt);
private void logWarnRetry(final String context, final long retryDelay, final int maxRetry, final int attempt) {
log.warn("Failed to \"{}\", about to retry [retryDelay:{}ms, maxRetry:{}, attempt:{}]",
context, retryDelay, maxRetry, attempt);
}

private void logErrorOnMaxRetry(String context, long retryDelay, int maxRetry) {
log.error("Failed to {} after max retry [retryDelay:{}ms, maxRetry:{}]",
private void logErrorOnMaxRetry(final String context, final long retryDelay, final int maxRetry) {
log.error("Failed to \"{}\" after max retry [retryDelay:{}ms, maxRetry:{}]",
context, retryDelay, maxRetry);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 IEXEC BLOCKCHAIN TECH
* Copyright 2020-2025 IEXEC BLOCKCHAIN TECH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package com.iexec.commons.poco.chain;

import com.iexec.commons.poco.contract.generated.IexecHubContract;
import com.iexec.commons.poco.dapp.DappType;
import com.iexec.commons.poco.task.TaskDescription;
import com.iexec.commons.poco.utils.BytesUtils;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -133,7 +134,7 @@
void repeatGetChainDealWithSuccess() {
ChainDeal chainDeal = getMockDeal();

when(iexecHubAbstractService.getChainDealWithDetails(CHAIN_DEAL_ID))
when(iexecHubAbstractService.getChainDeal(CHAIN_DEAL_ID))
.thenReturn(Optional.empty())
.thenReturn(Optional.empty())
.thenReturn(Optional.of(chainDeal));
Expand All @@ -145,12 +146,12 @@

assertThat(foundDeal).isEqualTo(Optional.of(chainDeal));
verify(iexecHubAbstractService, times(3))
.getChainDealWithDetails(CHAIN_DEAL_ID);
.getChainDeal(CHAIN_DEAL_ID);
}

@Test
void repeatGetChainDealWithFailure() {
when(iexecHubAbstractService.getChainDealWithDetails(CHAIN_DEAL_ID))
when(iexecHubAbstractService.getChainDeal(CHAIN_DEAL_ID))
.thenReturn(Optional.empty());
when(iexecHubAbstractService.repeatGetChainDeal(CHAIN_DEAL_ID, RETRY_DELAY, MAX_RETRY))
.thenCallRealMethod();
Expand All @@ -160,26 +161,44 @@

assertThat(foundDeal).isEmpty();
verify(iexecHubAbstractService, times(1 + MAX_RETRY))
.getChainDealWithDetails(CHAIN_DEAL_ID);
.getChainDeal(CHAIN_DEAL_ID);
}

@Test
void repeatGetTaskDescriptionFromChainWithSuccess() {
ChainTask task = getMockTask();
ChainDeal deal = getMockDeal();
final ChainTask task = getMockTask();
final ChainDeal deal = getMockDeal();

when(iexecHubAbstractService.repeatGetChainTask(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY))
.thenReturn(Optional.of(task));
when(iexecHubAbstractService.repeatGetChainDeal(CHAIN_DEAL_ID, RETRY_DELAY, MAX_RETRY))
.thenReturn(Optional.of(deal));
when(iexecHubAbstractService.getChainCategory(anyLong()))
.thenReturn(Optional.of(ChainCategory.builder().build()));
when(iexecHubAbstractService.getChainApp(anyString()))
.thenReturn(Optional.of(ChainApp.builder().build()));
when(iexecHubAbstractService.getChainDataset(anyString()))
.thenReturn(Optional.of(ChainDataset.builder().build()));

when(iexecHubAbstractService.repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY))
.thenCallRealMethod();
Optional<TaskDescription> taskDescription =
iexecHubAbstractService.repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY);
final TaskDescription taskDescription = iexecHubAbstractService
.repeatGetTaskDescriptionFromChain(CHAIN_TASK_ID, RETRY_DELAY, MAX_RETRY)
.orElse(null);

final TaskDescription expectedTaskDescription = TaskDescription.builder()
.chainTaskId(CHAIN_TASK_ID)
.appType(DappType.DOCKER)
.appAddress(deal.getDappPointer())
.datasetAddress(deal.getDataPointer())
.category(deal.getCategory())
.dealParams(DealParams.builder().build())
.startTime(deal.getStartTime().intValue())
.botFirstIndex(deal.getBotFirst().intValue())
.botSize(deal.getBotSize().intValue())
.build();

assertThat(taskDescription.map(TaskDescription::getChainTaskId)).hasValue(task.getChainTaskId());
assertThat(taskDescription.map(TaskDescription::getBotSize)).hasValue(deal.getBotSize().intValue());
assertThat(taskDescription).isEqualTo(expectedTaskDescription);
}

@Test
Expand Down Expand Up @@ -275,12 +294,15 @@

private ChainDeal getMockDeal() {
return ChainDeal.builder()
.chainApp(ChainApp.builder().multiaddr("").build())

Check warning on line 297 in src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this use of "chainApp"; it is deprecated.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIr8zu17z5OCyyfU&open=AZrKBIr8zu17z5OCyyfU&pullRequest=163
.params(DealParams.builder().build())
.chainCategory(ChainCategory.builder().build())

Check warning on line 298 in src/test/java/com/iexec/commons/poco/chain/IexecHubAbstractServiceTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this use of "chainCategory"; it is deprecated.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrKBIr8zu17z5OCyyfV&open=AZrKBIr8zu17z5OCyyfV&pullRequest=163
.dappPointer("0x1")
.dataPointer(BytesUtils.EMPTY_ADDRESS)
.category(BigInteger.ZERO)
.params(DealParams.builder().build())
.startTime(BigInteger.TEN)
.botSize(BigInteger.ONE)
.botFirst(BigInteger.ONE)
.botSize(BigInteger.ONE)
.build();
}
}
}
Loading