mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
Convert rx java to use LAPI v2 (#18341)
* use state service eliminate ledger-identity and ledger-configuration services update service event query and package services command service command completions command submission service time service clean-up * fix documentation example * format * adopt rx to changed java-bindings
This commit is contained in:
parent
b315b87755
commit
f0de92ba10
@ -493,19 +493,16 @@ packages/bindings-java-tutorial/static/com/daml/ledger/javaapi/data/InclusiveFil
|
||||
packages/bindings-java-tutorial/static/com/daml/ledger/javaapi/TransactionsClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/TransactionsClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/LedgerClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/LedgerClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/CommandClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/CommandClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/LedgerIdentityClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/LedgerIdentityClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/util/FlowableLogger.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/util/FlowableLogger.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/util/package-frame.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/util/package-frame.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/util/ClientPublisherFlowable.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/util/ClientPublisherFlowable.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/util/package-summary.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/util/package-summary.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/util/package-tree.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/util/package-tree.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/CommandSubmissionClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/CommandSubmissionClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/LedgerIdentityClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/LedgerIdentityClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/LedgerConfigurationClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/LedgerConfigurationClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/CommandClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/CommandClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/TransactionClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/TransactionClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/UpdateClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/UpdateClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/package-frame.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/package-frame.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/ActiveContractClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/ActiveContractClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/StateClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/StateClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/package-summary.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/package-summary.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/CommandCompletionClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/CommandCompletionClientImpl.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/PackageClientImpl.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/PackageClientImpl.html
|
||||
@ -515,7 +512,6 @@ app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/helpers/package-fram
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/helpers/package-summary.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/helpers/package-summary.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/helpers/TimestampComparator.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/helpers/TimestampComparator.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/grpc/helpers/package-tree.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/grpc/helpers/package-tree.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/LedgerConfigurationClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/LedgerConfigurationClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/CommandSubmissionClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/CommandSubmissionClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/package-frame.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/package-frame.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/package-summary.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/package-summary.html
|
||||
@ -526,14 +522,12 @@ app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/Bot.html -> /a
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/CreatedContractContext.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/CreatedContractContext.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/Pair.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/Pair.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/CommandsAndPendingSet.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/CommandsAndPendingSet.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/TransactionContext.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/TransactionContext.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/GetActiveContractsResponseContext.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/GetActiveContractsResponseContext.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/package-frame.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/package-frame.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/package-summary.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/package-summary.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/package-tree.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/package-tree.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/components/helpers/CreatedContract.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/components/helpers/CreatedContract.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/package-frame.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/package-frame.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/ActiveContractsClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/ActiveContractsClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/StateClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/StateClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/TimeClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/TimeClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/DamlLedgerClient.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/DamlLedgerClient.html
|
||||
app-dev/bindings-java/javadocs/com/daml/ledger/javaapi/package-tree.html -> /app-dev/bindings-java/javadocs/com/daml/ledger/rxjava/package-tree.html
|
||||
|
@ -47,22 +47,19 @@ public class IouMain {
|
||||
// Connects to the ledger and runs initial validation.
|
||||
client.connect();
|
||||
|
||||
String ledgerId = client.getLedgerId();
|
||||
|
||||
logger.info("ledger-id: {}", ledgerId);
|
||||
|
||||
AtomicLong idCounter = new AtomicLong(0);
|
||||
ConcurrentHashMap<Long, Iou> contracts = new ConcurrentHashMap<>();
|
||||
BiMap<Long, Iou.ContractId> idMap = Maps.synchronizedBiMap(HashBiMap.create());
|
||||
AtomicReference<LedgerOffset> acsOffset =
|
||||
new AtomicReference<>(LedgerOffset.LedgerBegin.getInstance());
|
||||
AtomicReference<ParticipantOffsetV2> acsOffset =
|
||||
new AtomicReference<>(ParticipantOffsetV2.ParticipantBegin.getInstance());
|
||||
|
||||
client
|
||||
.getActiveContractSetClient()
|
||||
.getStateClient()
|
||||
.getActiveContracts(Iou.contractFilter(), Collections.singleton(party), true)
|
||||
.blockingForEach(
|
||||
response -> {
|
||||
response.offset.ifPresent(offset -> acsOffset.set(new LedgerOffset.Absolute(offset)));
|
||||
response.offset.ifPresent(
|
||||
offset -> acsOffset.set(new ParticipantOffsetV2.Absolute(offset)));
|
||||
response.activeContracts.forEach(
|
||||
contract -> {
|
||||
long id = idCounter.getAndIncrement();
|
||||
@ -134,7 +131,7 @@ public class IouMain {
|
||||
|
||||
private static <U> U submit(LedgerClient client, String party, Update<U> update) {
|
||||
var updateSubmission =
|
||||
UpdateSubmission.create(APP_ID, randomUUID().toString(), update).withActAs(party);
|
||||
UpdateSubmissionV2.create(APP_ID, randomUUID().toString(), update).withActAs(party);
|
||||
|
||||
return client.getCommandClient().submitAndWaitForResult(updateSubmission).blockingGet();
|
||||
}
|
||||
|
@ -3,23 +3,23 @@
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmission;
|
||||
import com.daml.ledger.javaapi.data.Transaction;
|
||||
import com.daml.ledger.javaapi.data.TransactionTree;
|
||||
import com.daml.ledger.javaapi.data.UpdateSubmission;
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmissionV2;
|
||||
import com.daml.ledger.javaapi.data.TransactionTreeV2;
|
||||
import com.daml.ledger.javaapi.data.TransactionV2;
|
||||
import com.daml.ledger.javaapi.data.UpdateSubmissionV2;
|
||||
import com.google.protobuf.Empty;
|
||||
import io.reactivex.Single;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.CommandServiceGrpc} */
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v2.CommandServiceGrpc} */
|
||||
public interface CommandClient {
|
||||
Single<Empty> submitAndWait(CommandsSubmission submission);
|
||||
Single<Empty> submitAndWait(CommandsSubmissionV2 submission);
|
||||
|
||||
Single<String> submitAndWaitForTransactionId(CommandsSubmission submission);
|
||||
Single<String> submitAndWaitForTransactionId(CommandsSubmissionV2 submission);
|
||||
|
||||
Single<Transaction> submitAndWaitForTransaction(CommandsSubmission submission);
|
||||
Single<TransactionV2> submitAndWaitForTransaction(CommandsSubmissionV2 submission);
|
||||
|
||||
Single<TransactionTree> submitAndWaitForTransactionTree(CommandsSubmission submission);
|
||||
Single<TransactionTreeV2> submitAndWaitForTransactionTree(CommandsSubmissionV2 submission);
|
||||
|
||||
<U> Single<U> submitAndWaitForResult(@NonNull UpdateSubmission<U> submission);
|
||||
<U> Single<U> submitAndWaitForResult(@NonNull UpdateSubmissionV2<U> submission);
|
||||
}
|
||||
|
@ -3,28 +3,22 @@
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.CompletionEndResponse;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamResponse;
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamResponseV2;
|
||||
import com.daml.ledger.javaapi.data.ParticipantOffsetV2;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.CommandCompletionServiceGrpc} */
|
||||
public interface CommandCompletionClient {
|
||||
|
||||
Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, LedgerOffset offset, Set<String> parties);
|
||||
Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, ParticipantOffsetV2 offset, List<String> parties);
|
||||
|
||||
Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, LedgerOffset offset, Set<String> parties, String accessToken);
|
||||
Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, ParticipantOffsetV2 offset, List<String> parties, String accessToken);
|
||||
|
||||
Flowable<CompletionStreamResponse> completionStream(String applicationId, Set<String> parties);
|
||||
Flowable<CompletionStreamResponseV2> completionStream(String applicationId, List<String> parties);
|
||||
|
||||
Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, Set<String> parties, String accessToken);
|
||||
|
||||
Single<CompletionEndResponse> completionEnd();
|
||||
|
||||
Single<CompletionEndResponse> completionEnd(String accessToken);
|
||||
Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, List<String> parties, String accessToken);
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmission;
|
||||
import com.google.protobuf.Empty;
|
||||
import com.daml.ledger.api.v2.CommandSubmissionServiceOuterClass.SubmitResponse;
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmissionV2;
|
||||
import io.reactivex.Single;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.CommandSubmissionServiceGrpc} */
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v2.CommandSubmissionServiceGrpc} */
|
||||
public interface CommandSubmissionClient {
|
||||
|
||||
Single<Empty> submit(CommandsSubmission submission);
|
||||
Single<SubmitResponse> submit(CommandsSubmissionV2 submission);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
* <li>Call the method {@link DamlLedgerClient#connect()} to initialize the clients for that
|
||||
* particular ledger
|
||||
* <li>Retrieve one of the clients by using a getter, e.g. {@link
|
||||
* DamlLedgerClient#getActiveContractSetClient()}
|
||||
* DamlLedgerClient#getStateClient()}
|
||||
* </ol>
|
||||
*
|
||||
* <p>Alternatively to {@link DamlLedgerClient#newBuilder(String, int)}, you can use {@link
|
||||
@ -42,7 +42,6 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
public static final class Builder {
|
||||
|
||||
private final NettyChannelBuilder builder;
|
||||
private Optional<String> expectedLedgerId = Optional.empty();
|
||||
private Optional<String> accessToken = Optional.empty();
|
||||
private Optional<Duration> timeout = Optional.empty();
|
||||
|
||||
@ -57,18 +56,6 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.0 the ledger identifier has been deprecated as a fail-safe against
|
||||
* contacting an unexpected participant. You are recommended to use the participant
|
||||
* identifier in the access token as a way to validate that you are accessing the ledger
|
||||
* through the expected participant node (as well as authorize your calls).
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder withExpectedLedgerId(@NonNull String expectedLedgerId) {
|
||||
this.expectedLedgerId = Optional.of(expectedLedgerId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAccessToken(@NonNull String accessToken) {
|
||||
this.accessToken = Optional.of(accessToken);
|
||||
return this;
|
||||
@ -80,8 +67,7 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
}
|
||||
|
||||
public DamlLedgerClient build() {
|
||||
return new DamlLedgerClient(
|
||||
this.builder, this.expectedLedgerId, this.accessToken, this.timeout);
|
||||
return new DamlLedgerClient(this.builder, this.accessToken, this.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,79 +97,49 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
return new Builder(channelBuilder);
|
||||
}
|
||||
|
||||
private ActiveContractsClient activeContractsClient;
|
||||
private TransactionsClient transactionsClient;
|
||||
private StateClient stateServiceClient;
|
||||
private UpdateClient transactionsClient;
|
||||
private CommandCompletionClient commandCompletionClient;
|
||||
private CommandClient commandClient;
|
||||
private CommandSubmissionClient commandSubmissionClient;
|
||||
@Deprecated private LedgerIdentityClient ledgerIdentityClient;
|
||||
private EventQueryClient eventQueryClient;
|
||||
private PackageClient packageClient;
|
||||
private LedgerConfigurationClient ledgerConfigurationClient;
|
||||
private TimeClient timeClient;
|
||||
private UserManagementClient userManagementClient;
|
||||
private String expectedLedgerId;
|
||||
private Optional<String> accessToken;
|
||||
private final Optional<Duration> timeout;
|
||||
private final ManagedChannel channel;
|
||||
|
||||
private DamlLedgerClient(
|
||||
@NonNull NettyChannelBuilder channelBuilder,
|
||||
@NonNull Optional<String> expectedLedgerId,
|
||||
@NonNull Optional<String> accessToken,
|
||||
@NonNull Optional<Duration> timeout) {
|
||||
this.channel = channelBuilder.build();
|
||||
this.expectedLedgerId = expectedLedgerId.orElse(null);
|
||||
this.accessToken = accessToken;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/** Connects this instance of the {@link DamlLedgerClient} to the Ledger. */
|
||||
public void connect() {
|
||||
@SuppressWarnings("deprecation")
|
||||
var lic = new LedgerIdentityClientImpl(channel, this.accessToken, this.timeout);
|
||||
ledgerIdentityClient = lic;
|
||||
|
||||
String reportedLedgerId = ledgerIdentityClient.getLedgerIdentity().blockingGet();
|
||||
|
||||
if (this.expectedLedgerId != null && !this.expectedLedgerId.equals(reportedLedgerId)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"Configured ledger id [%s] is not the same as reported by the ledger [%s]",
|
||||
this.expectedLedgerId, reportedLedgerId));
|
||||
} else {
|
||||
this.expectedLedgerId = reportedLedgerId;
|
||||
}
|
||||
|
||||
activeContractsClient =
|
||||
new ActiveContractClientImpl(reportedLedgerId, channel, pool, this.accessToken);
|
||||
transactionsClient =
|
||||
new TransactionClientImpl(reportedLedgerId, channel, pool, this.accessToken);
|
||||
commandCompletionClient =
|
||||
new CommandCompletionClientImpl(reportedLedgerId, channel, pool, this.accessToken);
|
||||
stateServiceClient = new StateClientImpl(channel, pool, this.accessToken);
|
||||
transactionsClient = new UpdateClientImpl(channel, pool, this.accessToken);
|
||||
commandCompletionClient = new CommandCompletionClientImpl(channel, pool, this.accessToken);
|
||||
commandSubmissionClient =
|
||||
new CommandSubmissionClientImpl(reportedLedgerId, channel, this.accessToken, this.timeout);
|
||||
commandClient = new CommandClientImpl(reportedLedgerId, channel, this.accessToken);
|
||||
new CommandSubmissionClientImpl(channel, this.accessToken, this.timeout);
|
||||
commandClient = new CommandClientImpl(channel, this.accessToken);
|
||||
eventQueryClient = new EventQueryClientImpl(channel, this.accessToken);
|
||||
packageClient = new PackageClientImpl(reportedLedgerId, channel, this.accessToken);
|
||||
ledgerConfigurationClient =
|
||||
new LedgerConfigurationClientImpl(reportedLedgerId, channel, pool, this.accessToken);
|
||||
timeClient = new TimeClientImpl(reportedLedgerId, channel, pool, this.accessToken);
|
||||
packageClient = new PackageClientImpl(channel, this.accessToken);
|
||||
timeClient = new TimeClientImpl(channel, pool, this.accessToken);
|
||||
userManagementClient = new UserManagementClientImpl(channel, this.accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLedgerId() {
|
||||
return expectedLedgerId;
|
||||
public StateClient getStateClient() {
|
||||
return stateServiceClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActiveContractsClient getActiveContractSetClient() {
|
||||
return activeContractsClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionsClient getTransactionsClient() {
|
||||
public UpdateClient getTransactionsClient() {
|
||||
return transactionsClient;
|
||||
}
|
||||
|
||||
@ -202,12 +158,6 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
return commandSubmissionClient;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public LedgerIdentityClient getLedgerIdentityClient() {
|
||||
return ledgerIdentityClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventQueryClient getEventQueryClient() {
|
||||
return eventQueryClient;
|
||||
@ -218,11 +168,6 @@ public final class DamlLedgerClient implements LedgerClient {
|
||||
return packageClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LedgerConfigurationClient getLedgerConfigurationClient() {
|
||||
return ledgerConfigurationClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeClient getTimeClient() {
|
||||
return timeClient;
|
||||
|
@ -3,31 +3,15 @@
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractIdResponse;
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractKeyResponse;
|
||||
import com.daml.ledger.javaapi.data.Identifier;
|
||||
import com.daml.ledger.javaapi.data.Value;
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractIdResponseV2;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Set;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.PackageServiceGrpc} */
|
||||
public interface EventQueryClient {
|
||||
Single<GetEventsByContractIdResponse> getEventsByContractId(
|
||||
Single<GetEventsByContractIdResponseV2> getEventsByContractId(
|
||||
String contractId, Set<String> requestingParties);
|
||||
|
||||
Single<GetEventsByContractIdResponse> getEventsByContractId(
|
||||
Single<GetEventsByContractIdResponseV2> getEventsByContractId(
|
||||
String contractId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<GetEventsByContractKeyResponse> getEventsByContractKey(
|
||||
Value contractKey,
|
||||
Identifier templateId,
|
||||
Set<String> requestingParties,
|
||||
String continuationToken);
|
||||
|
||||
Single<GetEventsByContractKeyResponse> getEventsByContractKey(
|
||||
Value contractKey,
|
||||
Identifier templateId,
|
||||
Set<String> requestingParties,
|
||||
String continuationToken,
|
||||
String accessToken);
|
||||
}
|
||||
|
@ -7,11 +7,9 @@ package com.daml.ledger.rxjava;
|
||||
public interface LedgerClient {
|
||||
|
||||
/** @return The identifier of the Ledger connected to this {@link LedgerClient} */
|
||||
String getLedgerId();
|
||||
StateClient getStateClient();
|
||||
|
||||
ActiveContractsClient getActiveContractSetClient();
|
||||
|
||||
TransactionsClient getTransactionsClient();
|
||||
UpdateClient getTransactionsClient();
|
||||
|
||||
CommandClient getCommandClient();
|
||||
|
||||
@ -19,15 +17,10 @@ public interface LedgerClient {
|
||||
|
||||
CommandSubmissionClient getCommandSubmissionClient();
|
||||
|
||||
@Deprecated
|
||||
LedgerIdentityClient getLedgerIdentityClient();
|
||||
|
||||
EventQueryClient getEventQueryClient();
|
||||
|
||||
PackageClient getPackageClient();
|
||||
|
||||
LedgerConfigurationClient getLedgerConfigurationClient();
|
||||
|
||||
TimeClient getTimeClient();
|
||||
|
||||
UserManagementClient getUserManagementClient();
|
||||
|
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.api.v1.LedgerConfigurationServiceOuterClass;
|
||||
import io.reactivex.Flowable;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.LedgerConfigurationServiceGrpc} */
|
||||
public interface LedgerConfigurationClient {
|
||||
|
||||
Flowable<LedgerConfigurationServiceOuterClass.LedgerConfiguration> getLedgerConfiguration();
|
||||
|
||||
Flowable<LedgerConfigurationServiceOuterClass.LedgerConfiguration> getLedgerConfiguration(
|
||||
String accessToken);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import io.reactivex.Single;
|
||||
|
||||
// TODO #15208 remove
|
||||
/**
|
||||
* An RxJava version of {@link com.daml.ledger.api.v1.LedgerIdentityServiceGrpc}
|
||||
*
|
||||
* @deprecated Ledger identity string is optional for all ledger API requests, since Daml 2.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LedgerIdentityClient {
|
||||
|
||||
Single<String> getLedgerIdentity();
|
||||
|
||||
Single<String> getLedgerIdentity(String accessToken);
|
||||
}
|
@ -3,21 +3,19 @@
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.ActiveContracts;
|
||||
import com.daml.ledger.javaapi.data.ContractFilter;
|
||||
import com.daml.ledger.javaapi.data.GetActiveContractsResponse;
|
||||
import com.daml.ledger.javaapi.data.TransactionFilter;
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Set;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.ActiveContractsServiceGrpc} */
|
||||
public interface ActiveContractsClient {
|
||||
public interface StateClient {
|
||||
|
||||
Flowable<GetActiveContractsResponse> getActiveContracts(
|
||||
TransactionFilter filter, boolean verbose);
|
||||
Flowable<GetActiveContractsResponseV2> getActiveContracts(
|
||||
TransactionFilterV2 filter, boolean verbose);
|
||||
|
||||
Flowable<GetActiveContractsResponse> getActiveContracts(
|
||||
TransactionFilter filter, boolean verbose, String accessToken);
|
||||
Flowable<GetActiveContractsResponseV2> getActiveContracts(
|
||||
TransactionFilterV2 filter, boolean verbose, String accessToken);
|
||||
|
||||
/**
|
||||
* Get active Contracts
|
||||
@ -45,4 +43,8 @@ public interface ActiveContractsClient {
|
||||
*/
|
||||
<Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter, Set<String> parties, boolean verbose, String accessToken);
|
||||
|
||||
Single<ParticipantOffsetV2> getLedgerEnd();
|
||||
|
||||
Single<ParticipantOffsetV2> getLedgerEnd(String accessToken);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Set;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v1.TransactionServiceGrpc} */
|
||||
public interface TransactionsClient {
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, LedgerOffset end, TransactionFilter filter, boolean verbose);
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose);
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, String accessToken);
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
ContractFilter<?> contractFilter, LedgerOffset begin, Set<String> parties, boolean verbose);
|
||||
|
||||
Flowable<Transaction> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
LedgerOffset begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, LedgerOffset end, TransactionFilter filter, boolean verbose);
|
||||
|
||||
Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose);
|
||||
|
||||
Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, String accessToken);
|
||||
|
||||
Single<TransactionTree> getTransactionByEventId(String eventId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionTree> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<TransactionTree> getTransactionById(String transactionId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionTree> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<Transaction> getFlatTransactionByEventId(String eventId, Set<String> requestingParties);
|
||||
|
||||
Single<Transaction> getFlatTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<Transaction> getFlatTransactionById(String transactionId, Set<String> requestingParties);
|
||||
|
||||
Single<Transaction> getFlatTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<LedgerOffset> getLedgerEnd();
|
||||
|
||||
Single<LedgerOffset> getLedgerEnd(String accessToken);
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava;
|
||||
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Set;
|
||||
|
||||
/** An RxJava version of {@link com.daml.ledger.api.v2.UpdateServiceGrpc} */
|
||||
public interface UpdateClient {
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose);
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose);
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose, String accessToken);
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
ParticipantOffsetV2 begin,
|
||||
Set<String> parties,
|
||||
boolean verbose);
|
||||
|
||||
Flowable<TransactionV2> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
ParticipantOffsetV2 begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose);
|
||||
|
||||
Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
String accessToken);
|
||||
|
||||
Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose);
|
||||
|
||||
Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose, String accessToken);
|
||||
|
||||
Single<TransactionTreeV2> getTransactionTreeByEventId(
|
||||
String eventId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionTreeV2> getTransactionTreeByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<TransactionTreeV2> getTransactionTreeById(
|
||||
String transactionId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionTreeV2> getTransactionTreeById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<TransactionV2> getTransactionByEventId(String eventId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionV2> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken);
|
||||
|
||||
Single<TransactionV2> getTransactionById(String transactionId, Set<String> requestingParties);
|
||||
|
||||
Single<TransactionV2> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken);
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v1.ActiveContractsServiceGrpc;
|
||||
import com.daml.ledger.api.v1.ActiveContractsServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.ActiveContracts;
|
||||
import com.daml.ledger.javaapi.data.ContractFilter;
|
||||
import com.daml.ledger.javaapi.data.GetActiveContractsRequest;
|
||||
import com.daml.ledger.javaapi.data.GetActiveContractsResponse;
|
||||
import com.daml.ledger.javaapi.data.TransactionFilter;
|
||||
import com.daml.ledger.rxjava.ActiveContractsClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class ActiveContractClientImpl implements ActiveContractsClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final ActiveContractsServiceGrpc.ActiveContractsServiceStub serviceStub;
|
||||
private ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public ActiveContractClientImpl(
|
||||
String ledgerId,
|
||||
Channel channel,
|
||||
ExecutionSequencerFactory sequencerFactory,
|
||||
Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(ActiveContractsServiceGrpc.newStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<GetActiveContractsResponse> getActiveContracts(
|
||||
@NonNull TransactionFilter filter, boolean verbose, @NonNull Optional<String> accessToken) {
|
||||
ActiveContractsServiceOuterClass.GetActiveContractsRequest request =
|
||||
new GetActiveContractsRequest(ledgerId, filter, verbose).toProto();
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getActiveContracts,
|
||||
sequencerFactory)
|
||||
.map(GetActiveContractsResponse::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<GetActiveContractsResponse> getActiveContracts(
|
||||
@NonNull TransactionFilter filter, boolean verbose) {
|
||||
return getActiveContracts(filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<GetActiveContractsResponse> getActiveContracts(
|
||||
@NonNull TransactionFilter filter, boolean verbose, @NonNull String accessToken) {
|
||||
return getActiveContracts(filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionFilter filter = contractFilter.transactionFilter(parties);
|
||||
|
||||
Flowable<GetActiveContractsResponse> responses =
|
||||
getActiveContracts(filter, verbose, accessToken);
|
||||
return responses.map(
|
||||
response -> {
|
||||
List<Ct> activeContracts =
|
||||
response.getCreatedEvents().stream()
|
||||
.map(contractFilter::toContract)
|
||||
.collect(Collectors.toList());
|
||||
return new ActiveContracts<>(
|
||||
response.getOffset(), activeContracts, response.getWorkflowId());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter, Set<String> parties, boolean verbose) {
|
||||
return getActiveContracts(contractFilter, parties, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter, Set<String> parties, boolean verbose, String accessToken) {
|
||||
return getActiveContracts(contractFilter, parties, verbose, Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -6,8 +6,8 @@ package com.daml.ledger.rxjava.grpc;
|
||||
import static com.daml.ledger.javaapi.data.EventUtils.firstExercisedEvent;
|
||||
import static com.daml.ledger.javaapi.data.EventUtils.singleCreatedEvent;
|
||||
|
||||
import com.daml.ledger.api.v1.CommandServiceGrpc;
|
||||
import com.daml.ledger.api.v1.CommandServiceOuterClass;
|
||||
import com.daml.ledger.api.v2.CommandServiceGrpc;
|
||||
import com.daml.ledger.api.v2.CommandServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import com.daml.ledger.javaapi.data.codegen.Created;
|
||||
import com.daml.ledger.javaapi.data.codegen.Exercised;
|
||||
@ -22,20 +22,17 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class CommandClientImpl implements CommandClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final CommandServiceGrpc.CommandServiceFutureStub serviceStub;
|
||||
|
||||
public CommandClientImpl(
|
||||
@NonNull String ledgerId, @NonNull Channel channel, @NonNull Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
public CommandClientImpl(@NonNull Channel channel, @NonNull Optional<String> accessToken) {
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(CommandServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Empty> submitAndWait(CommandsSubmission submission) {
|
||||
public Single<Empty> submitAndWait(CommandsSubmissionV2 submission) {
|
||||
CommandServiceOuterClass.SubmitAndWaitRequest request =
|
||||
SubmitAndWaitRequest.toProto(this.ledgerId, submission);
|
||||
SubmitAndWaitRequestV2.toProto(submission);
|
||||
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, submission.getAccessToken())
|
||||
@ -43,41 +40,42 @@ public class CommandClientImpl implements CommandClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<String> submitAndWaitForTransactionId(CommandsSubmission submission) {
|
||||
public Single<String> submitAndWaitForTransactionId(CommandsSubmissionV2 submission) {
|
||||
CommandServiceOuterClass.SubmitAndWaitRequest request =
|
||||
SubmitAndWaitRequest.toProto(this.ledgerId, submission);
|
||||
SubmitAndWaitRequestV2.toProto(submission);
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, submission.getAccessToken())
|
||||
.submitAndWaitForTransactionId(request))
|
||||
.map(CommandServiceOuterClass.SubmitAndWaitForTransactionIdResponse::getTransactionId);
|
||||
.submitAndWaitForUpdateId(request))
|
||||
.map(CommandServiceOuterClass.SubmitAndWaitForUpdateIdResponse::getUpdateId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Transaction> submitAndWaitForTransaction(CommandsSubmission submission) {
|
||||
public Single<TransactionV2> submitAndWaitForTransaction(CommandsSubmissionV2 submission) {
|
||||
CommandServiceOuterClass.SubmitAndWaitRequest request =
|
||||
SubmitAndWaitRequest.toProto(this.ledgerId, submission);
|
||||
SubmitAndWaitRequestV2.toProto(submission);
|
||||
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, submission.getAccessToken())
|
||||
.submitAndWaitForTransaction(request))
|
||||
.map(CommandServiceOuterClass.SubmitAndWaitForTransactionResponse::getTransaction)
|
||||
.map(Transaction::fromProto);
|
||||
.map(TransactionV2::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTree> submitAndWaitForTransactionTree(CommandsSubmission submission) {
|
||||
public Single<TransactionTreeV2> submitAndWaitForTransactionTree(
|
||||
CommandsSubmissionV2 submission) {
|
||||
CommandServiceOuterClass.SubmitAndWaitRequest request =
|
||||
SubmitAndWaitRequest.toProto(this.ledgerId, submission);
|
||||
SubmitAndWaitRequestV2.toProto(submission);
|
||||
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, submission.getAccessToken())
|
||||
.submitAndWaitForTransactionTree(request))
|
||||
.map(CommandServiceOuterClass.SubmitAndWaitForTransactionTreeResponse::getTransaction)
|
||||
.map(TransactionTree::fromProto);
|
||||
.map(TransactionTreeV2::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> Single<U> submitAndWaitForResult(@NonNull UpdateSubmission<U> submission) {
|
||||
public <U> Single<U> submitAndWaitForResult(@NonNull UpdateSubmissionV2<U> submission) {
|
||||
return submission
|
||||
.getUpdate()
|
||||
.foldUpdate(
|
||||
|
@ -4,34 +4,26 @@
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v1.CommandCompletionServiceGrpc;
|
||||
import com.daml.ledger.api.v1.CommandCompletionServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.CompletionEndResponse;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamRequest;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamResponse;
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset;
|
||||
import com.daml.ledger.api.v2.CommandCompletionServiceGrpc;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamRequestV2;
|
||||
import com.daml.ledger.javaapi.data.CompletionStreamResponseV2;
|
||||
import com.daml.ledger.javaapi.data.ParticipantOffsetV2;
|
||||
import com.daml.ledger.rxjava.CommandCompletionClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class CommandCompletionClientImpl implements CommandCompletionClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final CommandCompletionServiceGrpc.CommandCompletionServiceStub serviceStub;
|
||||
private final CommandCompletionServiceGrpc.CommandCompletionServiceFutureStub serviceFutureStub;
|
||||
private final ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public CommandCompletionClientImpl(
|
||||
String ledgerId,
|
||||
Channel channel,
|
||||
ExecutionSequencerFactory sequencerFactory,
|
||||
Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
Channel channel, ExecutionSequencerFactory sequencerFactory, Optional<String> accessToken) {
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(CommandCompletionServiceGrpc.newStub(channel), accessToken);
|
||||
@ -39,61 +31,44 @@ public class CommandCompletionClientImpl implements CommandCompletionClient {
|
||||
StubHelper.authenticating(CommandCompletionServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<CompletionStreamResponse> completionStream(
|
||||
CompletionStreamRequest request, Optional<String> accessToken) {
|
||||
private Flowable<CompletionStreamResponseV2> completionStream(
|
||||
CompletionStreamRequestV2 request, Optional<String> accessToken) {
|
||||
return ClientPublisherFlowable.create(
|
||||
request.toProto(),
|
||||
StubHelper.authenticating(serviceStub, accessToken)::completionStream,
|
||||
sequencerFactory)
|
||||
.map(CompletionStreamResponse::fromProto);
|
||||
.map(CompletionStreamResponseV2::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, LedgerOffset offset, Set<String> parties) {
|
||||
public Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, ParticipantOffsetV2 offset, List<String> parties) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequest(ledgerId, applicationId, parties, offset), Optional.empty());
|
||||
new CompletionStreamRequestV2(applicationId, parties, offset), Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, LedgerOffset offset, Set<String> parties, String accessToken) {
|
||||
public Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, ParticipantOffsetV2 offset, List<String> parties, String accessToken) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequest(ledgerId, applicationId, parties, offset),
|
||||
new CompletionStreamRequestV2(applicationId, parties, offset), Optional.of(accessToken));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, List<String> parties) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequestV2(
|
||||
applicationId, parties, ParticipantOffsetV2.ParticipantBegin.getInstance()),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponseV2> completionStream(
|
||||
String applicationId, List<String> parties, String accessToken) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequestV2(
|
||||
applicationId, parties, ParticipantOffsetV2.ParticipantBegin.getInstance()),
|
||||
Optional.of(accessToken));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, Set<String> parties) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequest(ledgerId, applicationId, parties), Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<CompletionStreamResponse> completionStream(
|
||||
String applicationId, Set<String> parties, String accessToken) {
|
||||
return completionStream(
|
||||
new CompletionStreamRequest(ledgerId, applicationId, parties), Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<CompletionEndResponse> completionEnd(Optional<String> accessToken) {
|
||||
CommandCompletionServiceOuterClass.CompletionEndRequest request =
|
||||
CommandCompletionServiceOuterClass.CompletionEndRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.build();
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(serviceFutureStub, accessToken).completionEnd(request))
|
||||
.map(CompletionEndResponse::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<CompletionEndResponse> completionEnd() {
|
||||
return completionEnd(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<CompletionEndResponse> completionEnd(String accessToken) {
|
||||
return completionEnd(Optional.of(accessToken));
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,13 @@ package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import com.daml.ledger.api.v1.CommandSubmissionServiceGrpc;
|
||||
import com.daml.ledger.api.v1.CommandSubmissionServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmission;
|
||||
import com.daml.ledger.javaapi.data.SubmitRequest;
|
||||
import com.daml.ledger.api.v2.CommandSubmissionServiceGrpc;
|
||||
import com.daml.ledger.api.v2.CommandSubmissionServiceOuterClass;
|
||||
import com.daml.ledger.api.v2.CommandSubmissionServiceOuterClass.SubmitResponse;
|
||||
import com.daml.ledger.javaapi.data.CommandsSubmissionV2;
|
||||
import com.daml.ledger.javaapi.data.SubmitRequestV2;
|
||||
import com.daml.ledger.rxjava.CommandSubmissionClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.google.protobuf.Empty;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Single;
|
||||
import java.time.Duration;
|
||||
@ -20,25 +20,19 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class CommandSubmissionClientImpl implements CommandSubmissionClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final CommandSubmissionServiceGrpc.CommandSubmissionServiceFutureStub serviceStub;
|
||||
private final Optional<Duration> timeout;
|
||||
|
||||
public CommandSubmissionClientImpl(
|
||||
@NonNull String ledgerId,
|
||||
@NonNull Channel channel,
|
||||
Optional<String> accessToken,
|
||||
Optional<Duration> timeout) {
|
||||
this.ledgerId = ledgerId;
|
||||
@NonNull Channel channel, Optional<String> accessToken, Optional<Duration> timeout) {
|
||||
this.timeout = timeout;
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(CommandSubmissionServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Empty> submit(CommandsSubmission submission) {
|
||||
CommandSubmissionServiceOuterClass.SubmitRequest request =
|
||||
SubmitRequest.toProto(ledgerId, submission);
|
||||
public Single<SubmitResponse> submit(CommandsSubmissionV2 submission) {
|
||||
CommandSubmissionServiceOuterClass.SubmitRequest request = SubmitRequestV2.toProto(submission);
|
||||
CommandSubmissionServiceGrpc.CommandSubmissionServiceFutureStub stubWithTimeout =
|
||||
this.timeout
|
||||
.map(t -> this.serviceStub.withDeadlineAfter(t.toMillis(), MILLISECONDS))
|
||||
|
@ -3,12 +3,9 @@
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.ledger.api.v1.EventQueryServiceGrpc;
|
||||
import com.daml.ledger.api.v1.EventQueryServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractIdResponse;
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractKeyResponse;
|
||||
import com.daml.ledger.javaapi.data.Identifier;
|
||||
import com.daml.ledger.javaapi.data.Value;
|
||||
import com.daml.ledger.api.v1.EventQueryServiceOuterClass.GetEventsByContractIdRequest;
|
||||
import com.daml.ledger.api.v2.EventQueryServiceGrpc;
|
||||
import com.daml.ledger.javaapi.data.GetEventsByContractIdResponseV2;
|
||||
import com.daml.ledger.rxjava.EventQueryClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import io.grpc.Channel;
|
||||
@ -25,68 +22,27 @@ public class EventQueryClientImpl implements EventQueryClient {
|
||||
StubHelper.authenticating(EventQueryServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Single<GetEventsByContractIdResponse> getEventsByContractId(
|
||||
private Single<GetEventsByContractIdResponseV2> getEventsByContractId(
|
||||
String contractId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
EventQueryServiceOuterClass.GetEventsByContractIdRequest request =
|
||||
EventQueryServiceOuterClass.GetEventsByContractIdRequest.newBuilder()
|
||||
GetEventsByContractIdRequest request =
|
||||
GetEventsByContractIdRequest.newBuilder()
|
||||
.setContractId(contractId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, accessToken).getEventsByContractId(request))
|
||||
.map(GetEventsByContractIdResponse::fromProto);
|
||||
.map(GetEventsByContractIdResponseV2::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<GetEventsByContractIdResponse> getEventsByContractId(
|
||||
public Single<GetEventsByContractIdResponseV2> getEventsByContractId(
|
||||
String contractId, Set<String> requestingParties) {
|
||||
return getEventsByContractId(contractId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<GetEventsByContractIdResponse> getEventsByContractId(
|
||||
public Single<GetEventsByContractIdResponseV2> getEventsByContractId(
|
||||
String contractId, Set<String> requestingParties, String accessToken) {
|
||||
return getEventsByContractId(contractId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<GetEventsByContractKeyResponse> getEventsByContractKey(
|
||||
Value contractKey,
|
||||
Identifier templateId,
|
||||
Set<String> requestingParties,
|
||||
String continuationToken,
|
||||
Optional<String> accessToken) {
|
||||
EventQueryServiceOuterClass.GetEventsByContractKeyRequest request =
|
||||
EventQueryServiceOuterClass.GetEventsByContractKeyRequest.newBuilder()
|
||||
.setContractKey(contractKey.toProto())
|
||||
.setTemplateId(templateId.toProto())
|
||||
.setContinuationToken(continuationToken)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)
|
||||
.getEventsByContractKey(request))
|
||||
.map(GetEventsByContractKeyResponse::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<GetEventsByContractKeyResponse> getEventsByContractKey(
|
||||
Value contractKey,
|
||||
Identifier templateId,
|
||||
Set<String> requestingParties,
|
||||
String continuationToken) {
|
||||
return getEventsByContractKey(
|
||||
contractKey, templateId, requestingParties, continuationToken, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<GetEventsByContractKeyResponse> getEventsByContractKey(
|
||||
Value contractKey,
|
||||
Identifier templateId,
|
||||
Set<String> requestingParties,
|
||||
String continuationToken,
|
||||
String accessToken) {
|
||||
return getEventsByContractKey(
|
||||
contractKey, templateId, requestingParties, continuationToken, Optional.of(accessToken));
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v1.LedgerConfigurationServiceGrpc;
|
||||
import com.daml.ledger.api.v1.LedgerConfigurationServiceOuterClass;
|
||||
import com.daml.ledger.rxjava.LedgerConfigurationClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import java.util.Optional;
|
||||
|
||||
public class LedgerConfigurationClientImpl implements LedgerConfigurationClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final LedgerConfigurationServiceGrpc.LedgerConfigurationServiceStub serviceStub;
|
||||
private final ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public LedgerConfigurationClientImpl(
|
||||
String ledgerId,
|
||||
Channel channel,
|
||||
ExecutionSequencerFactory sequencerFactory,
|
||||
Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(LedgerConfigurationServiceGrpc.newStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<LedgerConfigurationServiceOuterClass.LedgerConfiguration> getLedgerConfiguration(
|
||||
Optional<String> accessToken) {
|
||||
LedgerConfigurationServiceOuterClass.GetLedgerConfigurationRequest request =
|
||||
LedgerConfigurationServiceOuterClass.GetLedgerConfigurationRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.build();
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getLedgerConfiguration,
|
||||
sequencerFactory)
|
||||
.map(
|
||||
LedgerConfigurationServiceOuterClass.GetLedgerConfigurationResponse
|
||||
::getLedgerConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<LedgerConfigurationServiceOuterClass.LedgerConfiguration>
|
||||
getLedgerConfiguration() {
|
||||
return getLedgerConfiguration(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<LedgerConfigurationServiceOuterClass.LedgerConfiguration> getLedgerConfiguration(
|
||||
String accessToken) {
|
||||
return getLedgerConfiguration(Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import com.daml.ledger.api.v1.LedgerIdentityServiceGrpc;
|
||||
import com.daml.ledger.api.v1.LedgerIdentityServiceOuterClass;
|
||||
import com.daml.ledger.rxjava.LedgerIdentityClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Single;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/** @deprecated ledger identity string is optional for all Ledger API requests since Daml 2.0.0 */
|
||||
@Deprecated
|
||||
public class LedgerIdentityClientImpl implements LedgerIdentityClient {
|
||||
|
||||
private LedgerIdentityServiceGrpc.LedgerIdentityServiceFutureStub serviceStub;
|
||||
private final Optional<Duration> timeout;
|
||||
|
||||
/**
|
||||
* @deprecated Pass a timeout or {@code Optional.empty()} as the third argument, since Daml 2.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
public LedgerIdentityClientImpl(Channel channel, Optional<String> accessToken) {
|
||||
this(channel, accessToken, Optional.empty());
|
||||
}
|
||||
|
||||
public LedgerIdentityClientImpl(
|
||||
Channel channel, Optional<String> accessToken, Optional<Duration> timeout) {
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(LedgerIdentityServiceGrpc.newFutureStub(channel), accessToken);
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
private Single<String> getLedgerIdentity(@NonNull Optional<String> accessToken) {
|
||||
this.serviceStub =
|
||||
this.timeout
|
||||
.map(t -> this.serviceStub.withDeadlineAfter(t.toMillis(), MILLISECONDS))
|
||||
.orElse(this.serviceStub);
|
||||
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)
|
||||
.getLedgerIdentity(
|
||||
LedgerIdentityServiceOuterClass.GetLedgerIdentityRequest.getDefaultInstance()))
|
||||
.map(LedgerIdentityServiceOuterClass.GetLedgerIdentityResponse::getLedgerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<String> getLedgerIdentity() {
|
||||
return getLedgerIdentity(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<String> getLedgerIdentity(@NonNull String accessToken) {
|
||||
return getLedgerIdentity(Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -3,8 +3,9 @@
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.ledger.api.v1.PackageServiceGrpc;
|
||||
import com.daml.ledger.api.v1.PackageServiceOuterClass;
|
||||
import com.daml.ledger.api.v1.PackageServiceOuterClass.ListPackagesResponse;
|
||||
import com.daml.ledger.api.v2.PackageServiceGrpc;
|
||||
import com.daml.ledger.api.v2.PackageServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.GetPackageResponse;
|
||||
import com.daml.ledger.javaapi.data.GetPackageStatusResponse;
|
||||
import com.daml.ledger.rxjava.PackageClient;
|
||||
@ -16,20 +17,18 @@ import java.util.Optional;
|
||||
|
||||
public class PackageClientImpl implements PackageClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final PackageServiceGrpc.PackageServiceFutureStub serviceStub;
|
||||
|
||||
public PackageClientImpl(String ledgerId, Channel channel, Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
public PackageClientImpl(Channel channel, Optional<String> accessToken) {
|
||||
serviceStub = StubHelper.authenticating(PackageServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<String> listPackages(Optional<String> accessToken) {
|
||||
PackageServiceOuterClass.ListPackagesRequest request =
|
||||
PackageServiceOuterClass.ListPackagesRequest.newBuilder().setLedgerId(ledgerId).build();
|
||||
PackageServiceOuterClass.ListPackagesRequest.newBuilder().build();
|
||||
return Flowable.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, accessToken).listPackages(request))
|
||||
.concatMapIterable(PackageServiceOuterClass.ListPackagesResponse::getPackageIdsList);
|
||||
.concatMapIterable(ListPackagesResponse::getPackageIdsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -44,10 +43,7 @@ public class PackageClientImpl implements PackageClient {
|
||||
|
||||
private Single<GetPackageResponse> getPackage(String packageId, Optional<String> accessToken) {
|
||||
PackageServiceOuterClass.GetPackageRequest request =
|
||||
PackageServiceOuterClass.GetPackageRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setPackageId(packageId)
|
||||
.build();
|
||||
PackageServiceOuterClass.GetPackageRequest.newBuilder().setPackageId(packageId).build();
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceStub, accessToken).getPackage(request))
|
||||
.map(GetPackageResponse::fromProto);
|
||||
@ -67,7 +63,6 @@ public class PackageClientImpl implements PackageClient {
|
||||
String packageId, Optional<String> accessToken) {
|
||||
PackageServiceOuterClass.GetPackageStatusRequest request =
|
||||
PackageServiceOuterClass.GetPackageStatusRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setPackageId(packageId)
|
||||
.build();
|
||||
return Single.fromFuture(
|
||||
|
@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v2.StateServiceGrpc;
|
||||
import com.daml.ledger.api.v2.StateServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import com.daml.ledger.rxjava.StateClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public class StateClientImpl implements StateClient {
|
||||
|
||||
private final StateServiceGrpc.StateServiceStub serviceStub;
|
||||
private final StateServiceGrpc.StateServiceFutureStub serviceFutureStub;
|
||||
private ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public StateClientImpl(
|
||||
Channel channel, ExecutionSequencerFactory sequencerFactory, Optional<String> accessToken) {
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub = StubHelper.authenticating(StateServiceGrpc.newStub(channel), accessToken);
|
||||
this.serviceFutureStub =
|
||||
StubHelper.authenticating(StateServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<GetActiveContractsResponseV2> getActiveContracts(
|
||||
@NonNull TransactionFilterV2 filter, boolean verbose, @NonNull Optional<String> accessToken) {
|
||||
StateServiceOuterClass.GetActiveContractsRequest request =
|
||||
new GetActiveContractsRequestV2(filter, verbose, "").toProto();
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getActiveContracts,
|
||||
sequencerFactory)
|
||||
.map(GetActiveContractsResponseV2::fromProto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<GetActiveContractsResponseV2> getActiveContracts(
|
||||
@NonNull TransactionFilterV2 filter, boolean verbose) {
|
||||
return getActiveContracts(filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<GetActiveContractsResponseV2> getActiveContracts(
|
||||
@NonNull TransactionFilterV2 filter, boolean verbose, @NonNull String accessToken) {
|
||||
return getActiveContracts(filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionFilterV2 filter = contractFilter.transactionFilterV2(parties);
|
||||
|
||||
Flowable<GetActiveContractsResponseV2> responses =
|
||||
getActiveContracts(filter, verbose, accessToken);
|
||||
return responses.map(
|
||||
response -> {
|
||||
List<Ct> activeContracts =
|
||||
response.getContractEntry().stream()
|
||||
.map(ce -> contractFilter.toContract(ce.getCreatedEvent()))
|
||||
.collect(Collectors.toList());
|
||||
return new ActiveContracts<>(
|
||||
response.getOffset(), activeContracts, response.getWorkflowId());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter, Set<String> parties, boolean verbose) {
|
||||
return getActiveContracts(contractFilter, parties, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <Ct> Flowable<ActiveContracts<Ct>> getActiveContracts(
|
||||
ContractFilter<Ct> contractFilter, Set<String> parties, boolean verbose, String accessToken) {
|
||||
return getActiveContracts(contractFilter, parties, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<ParticipantOffsetV2> getLedgerEnd(Optional<String> accessToken) {
|
||||
StateServiceOuterClass.GetLedgerEndRequest request =
|
||||
StateServiceOuterClass.GetLedgerEndRequest.newBuilder().build();
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken).getLedgerEnd(request))
|
||||
.map(GetLedgerEndResponseV2::fromProto)
|
||||
.map(GetLedgerEndResponseV2::getOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<ParticipantOffsetV2> getLedgerEnd() {
|
||||
return getLedgerEnd(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<ParticipantOffsetV2> getLedgerEnd(String accessToken) {
|
||||
return getLedgerEnd(Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v1.testing.TimeServiceGrpc;
|
||||
import com.daml.ledger.api.v1.testing.TimeServiceOuterClass;
|
||||
import com.daml.ledger.api.v2.testing.TimeServiceGrpc;
|
||||
import com.daml.ledger.api.v2.testing.TimeServiceOuterClass;
|
||||
import com.daml.ledger.rxjava.TimeClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
@ -19,17 +19,12 @@ import java.util.Optional;
|
||||
|
||||
public final class TimeClientImpl implements TimeClient {
|
||||
|
||||
private final String ledgerId;
|
||||
private final TimeServiceGrpc.TimeServiceFutureStub serviceFutureStub;
|
||||
private final TimeServiceGrpc.TimeServiceStub serviceStub;
|
||||
private final ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public TimeClientImpl(
|
||||
String ledgerId,
|
||||
Channel channel,
|
||||
ExecutionSequencerFactory sequencerFactory,
|
||||
Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
Channel channel, ExecutionSequencerFactory sequencerFactory, Optional<String> accessToken) {
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceFutureStub =
|
||||
StubHelper.authenticating(TimeServiceGrpc.newFutureStub(channel), accessToken);
|
||||
@ -43,7 +38,6 @@ public final class TimeClientImpl implements TimeClient {
|
||||
}
|
||||
TimeServiceOuterClass.SetTimeRequest request =
|
||||
TimeServiceOuterClass.SetTimeRequest.newBuilder()
|
||||
.setLedgerId(this.ledgerId)
|
||||
.setCurrentTime(
|
||||
Timestamp.newBuilder()
|
||||
.setSeconds(currentTime.getEpochSecond())
|
||||
@ -70,7 +64,7 @@ public final class TimeClientImpl implements TimeClient {
|
||||
|
||||
private Flowable<Instant> getTime(Optional<String> accessToken) {
|
||||
TimeServiceOuterClass.GetTimeRequest request =
|
||||
TimeServiceOuterClass.GetTimeRequest.newBuilder().setLedgerId(this.ledgerId).build();
|
||||
TimeServiceOuterClass.GetTimeRequest.newBuilder().build();
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getTime,
|
||||
|
@ -1,306 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v1.TransactionServiceGrpc;
|
||||
import com.daml.ledger.api.v1.TransactionServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import com.daml.ledger.rxjava.TransactionsClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public final class TransactionClientImpl implements TransactionsClient {
|
||||
private final String ledgerId;
|
||||
private final TransactionServiceGrpc.TransactionServiceStub serviceStub;
|
||||
private final TransactionServiceGrpc.TransactionServiceFutureStub serviceFutureStub;
|
||||
private final ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public TransactionClientImpl(
|
||||
String ledgerId,
|
||||
Channel channel,
|
||||
ExecutionSequencerFactory sequencerFactory,
|
||||
Optional<String> accessToken) {
|
||||
this.ledgerId = ledgerId;
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub =
|
||||
StubHelper.authenticating(TransactionServiceGrpc.newStub(channel), accessToken);
|
||||
this.serviceFutureStub =
|
||||
StubHelper.authenticating(TransactionServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private Flowable<Transaction> extractTransactions(
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request, Optional<String> accessToken) {
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getTransactions,
|
||||
sequencerFactory)
|
||||
.map(GetTransactionsResponse::fromProto)
|
||||
.concatMapIterable(GetTransactionsResponse::getTransactions);
|
||||
}
|
||||
|
||||
private Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request =
|
||||
new GetTransactionsRequest(ledgerId, begin, end, filter, verbose).toProto();
|
||||
return extractTransactions(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, LedgerOffset end, TransactionFilter filter, boolean verbose) {
|
||||
return getTransactions(begin, end, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactions(begin, end, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request =
|
||||
new GetTransactionsRequest(ledgerId, begin, filter, verbose).toProto();
|
||||
return extractTransactions(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose) {
|
||||
return getTransactions(begin, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<Transaction> getTransactions(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, String accessToken) {
|
||||
return getTransactions(begin, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<Transaction> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
LedgerOffset begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionFilter filter = contractFilter.transactionFilter(parties);
|
||||
return getTransactions(begin, filter, verbose, accessToken);
|
||||
}
|
||||
|
||||
public Flowable<Transaction> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
LedgerOffset begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactions(contractFilter, begin, parties, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
public Flowable<Transaction> getTransactions(
|
||||
ContractFilter<?> contractFilter, LedgerOffset begin, Set<String> parties, boolean verbose) {
|
||||
return getTransactions(contractFilter, begin, parties, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
private Flowable<TransactionTree> extractTransactionTrees(
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request, Optional<String> accessToken) {
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getTransactionTrees,
|
||||
sequencerFactory)
|
||||
.map(GetTransactionTreesResponse::fromProto)
|
||||
.concatMapIterable(GetTransactionTreesResponse::getTransactions);
|
||||
}
|
||||
|
||||
private Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request =
|
||||
new GetTransactionsRequest(ledgerId, begin, filter, verbose).toProto();
|
||||
return extractTransactionTrees(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose) {
|
||||
return getTransactionsTrees(begin, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, TransactionFilter filter, boolean verbose, String accessToken) {
|
||||
return getTransactionsTrees(begin, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionsRequest request =
|
||||
new GetTransactionsRequest(ledgerId, begin, end, filter, verbose).toProto();
|
||||
return extractTransactionTrees(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin, LedgerOffset end, TransactionFilter filter, boolean verbose) {
|
||||
return getTransactionsTrees(begin, end, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTree> getTransactionsTrees(
|
||||
LedgerOffset begin,
|
||||
LedgerOffset end,
|
||||
TransactionFilter filter,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactionsTrees(begin, end, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionTree> extractTransactionTree(
|
||||
Future<TransactionServiceOuterClass.GetTransactionResponse> future) {
|
||||
return Single.fromFuture(future)
|
||||
.map(GetTransactionResponse::fromProto)
|
||||
.map(GetTransactionResponse::getTransaction);
|
||||
}
|
||||
|
||||
private Single<TransactionTree> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionByEventIdRequest request =
|
||||
TransactionServiceOuterClass.GetTransactionByEventIdRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setEventId(eventId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransactionTree(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getTransactionByEventId(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTree> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties) {
|
||||
return getTransactionByEventId(eventId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTree> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionByEventId(eventId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionTree> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionByIdRequest request =
|
||||
TransactionServiceOuterClass.GetTransactionByIdRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setTransactionId(transactionId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransactionTree(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken).getTransactionById(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTree> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties) {
|
||||
return getTransactionById(transactionId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTree> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionById(transactionId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<Transaction> extractTransaction(
|
||||
Future<TransactionServiceOuterClass.GetFlatTransactionResponse> future) {
|
||||
return Single.fromFuture(future)
|
||||
.map(GetFlatTransactionResponse::fromProto)
|
||||
.map(GetFlatTransactionResponse::getTransaction);
|
||||
}
|
||||
|
||||
private Single<Transaction> getFlatTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionByEventIdRequest request =
|
||||
TransactionServiceOuterClass.GetTransactionByEventIdRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setEventId(eventId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransaction(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getFlatTransactionByEventId(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Transaction> getFlatTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties) {
|
||||
return getFlatTransactionByEventId(eventId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Transaction> getFlatTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken) {
|
||||
return getFlatTransactionByEventId(eventId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<Transaction> getFlatTransactionById(
|
||||
String transactionId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetTransactionByIdRequest request =
|
||||
TransactionServiceOuterClass.GetTransactionByIdRequest.newBuilder()
|
||||
.setLedgerId(ledgerId)
|
||||
.setTransactionId(transactionId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransaction(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getFlatTransactionById(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Transaction> getFlatTransactionById(
|
||||
String transactionId, Set<String> requestingParties) {
|
||||
return getFlatTransactionById(transactionId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<Transaction> getFlatTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken) {
|
||||
return getFlatTransactionById(transactionId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<LedgerOffset> getLedgerEnd(Optional<String> accessToken) {
|
||||
TransactionServiceOuterClass.GetLedgerEndRequest request =
|
||||
TransactionServiceOuterClass.GetLedgerEndRequest.newBuilder().setLedgerId(ledgerId).build();
|
||||
return Single.fromFuture(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken).getLedgerEnd(request))
|
||||
.map(GetLedgerEndResponse::fromProto)
|
||||
.map(GetLedgerEndResponse::getOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<LedgerOffset> getLedgerEnd() {
|
||||
return getLedgerEnd(Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<LedgerOffset> getLedgerEnd(String accessToken) {
|
||||
return getLedgerEnd(Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc;
|
||||
|
||||
import com.daml.grpc.adapter.ExecutionSequencerFactory;
|
||||
import com.daml.ledger.api.v2.UpdateServiceGrpc;
|
||||
import com.daml.ledger.api.v2.UpdateServiceOuterClass;
|
||||
import com.daml.ledger.javaapi.data.*;
|
||||
import com.daml.ledger.rxjava.UpdateClient;
|
||||
import com.daml.ledger.rxjava.grpc.helpers.StubHelper;
|
||||
import com.daml.ledger.rxjava.util.ClientPublisherFlowable;
|
||||
import io.grpc.Channel;
|
||||
import io.reactivex.Flowable;
|
||||
import io.reactivex.Single;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public final class UpdateClientImpl implements UpdateClient {
|
||||
private final UpdateServiceGrpc.UpdateServiceStub serviceStub;
|
||||
private final UpdateServiceGrpc.UpdateServiceFutureStub serviceFutureStub;
|
||||
private final ExecutionSequencerFactory sequencerFactory;
|
||||
|
||||
public UpdateClientImpl(
|
||||
Channel channel, ExecutionSequencerFactory sequencerFactory, Optional<String> accessToken) {
|
||||
this.sequencerFactory = sequencerFactory;
|
||||
this.serviceStub = StubHelper.authenticating(UpdateServiceGrpc.newStub(channel), accessToken);
|
||||
this.serviceFutureStub =
|
||||
StubHelper.authenticating(UpdateServiceGrpc.newFutureStub(channel), accessToken);
|
||||
}
|
||||
|
||||
private static <T> Iterable<T> toIterable(Optional<T> o) {
|
||||
return o.map(Collections::singleton).orElseGet(Collections::emptySet);
|
||||
}
|
||||
|
||||
private Flowable<TransactionV2> extractTransactions(
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request, Optional<String> accessToken) {
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getUpdates,
|
||||
sequencerFactory)
|
||||
.map(GetUpdatesResponseV2::fromProto)
|
||||
.map(GetUpdatesResponseV2::getTransaction)
|
||||
.concatMapIterable(UpdateClientImpl::toIterable);
|
||||
}
|
||||
|
||||
private Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request =
|
||||
new GetUpdatesRequestV2(begin, end, filter, verbose).toProto();
|
||||
return extractTransactions(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose) {
|
||||
return getTransactions(begin, end, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactions(begin, end, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request =
|
||||
new GetUpdatesRequestV2(
|
||||
begin, ParticipantOffsetV2.ParticipantEnd.getInstance(), filter, verbose)
|
||||
.toProto();
|
||||
return extractTransactions(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose) {
|
||||
return getTransactions(begin, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose, String accessToken) {
|
||||
return getTransactions(begin, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<TransactionV2> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
ParticipantOffsetV2 begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
TransactionFilterV2 filter = contractFilter.transactionFilterV2(parties);
|
||||
return getTransactions(begin, filter, verbose, accessToken);
|
||||
}
|
||||
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
ParticipantOffsetV2 begin,
|
||||
Set<String> parties,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactions(contractFilter, begin, parties, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
public Flowable<TransactionV2> getTransactions(
|
||||
ContractFilter<?> contractFilter,
|
||||
ParticipantOffsetV2 begin,
|
||||
Set<String> parties,
|
||||
boolean verbose) {
|
||||
return getTransactions(contractFilter, begin, parties, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
private Flowable<TransactionTreeV2> extractTransactionTrees(
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request, Optional<String> accessToken) {
|
||||
return ClientPublisherFlowable.create(
|
||||
request,
|
||||
StubHelper.authenticating(this.serviceStub, accessToken)::getUpdateTrees,
|
||||
sequencerFactory)
|
||||
.map(GetUpdateTreesResponseV2::fromProto)
|
||||
.map(GetUpdateTreesResponseV2::getTransactionTree)
|
||||
.concatMapIterable(UpdateClientImpl::toIterable);
|
||||
}
|
||||
|
||||
private Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request =
|
||||
new GetUpdatesRequestV2(
|
||||
begin, ParticipantOffsetV2.ParticipantEnd.getInstance(), filter, verbose)
|
||||
.toProto();
|
||||
return extractTransactionTrees(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose) {
|
||||
return getTransactionsTrees(begin, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin, TransactionFilterV2 filter, boolean verbose, String accessToken) {
|
||||
return getTransactionsTrees(begin, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetUpdatesRequest request =
|
||||
new GetUpdatesRequestV2(begin, end, filter, verbose).toProto();
|
||||
return extractTransactionTrees(request, accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose) {
|
||||
return getTransactionsTrees(begin, end, filter, verbose, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flowable<TransactionTreeV2> getTransactionsTrees(
|
||||
ParticipantOffsetV2 begin,
|
||||
ParticipantOffsetV2 end,
|
||||
TransactionFilterV2 filter,
|
||||
boolean verbose,
|
||||
String accessToken) {
|
||||
return getTransactionsTrees(begin, end, filter, verbose, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionTreeV2> extractTransactionTree(
|
||||
Future<UpdateServiceOuterClass.GetTransactionTreeResponse> future) {
|
||||
return Single.fromFuture(future)
|
||||
.map(GetTransactionTreeResponseV2::fromProto)
|
||||
.map(GetTransactionTreeResponseV2::getTransactionTree);
|
||||
}
|
||||
|
||||
private Single<TransactionTreeV2> getTransactionTreeByEventId(
|
||||
String eventId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetTransactionByEventIdRequest request =
|
||||
UpdateServiceOuterClass.GetTransactionByEventIdRequest.newBuilder()
|
||||
.setEventId(eventId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransactionTree(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getTransactionTreeByEventId(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTreeV2> getTransactionTreeByEventId(
|
||||
String eventId, Set<String> requestingParties) {
|
||||
return getTransactionTreeByEventId(eventId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTreeV2> getTransactionTreeByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionTreeByEventId(eventId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionTreeV2> getTransactionTreeById(
|
||||
String transactionId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetTransactionByIdRequest request =
|
||||
UpdateServiceOuterClass.GetTransactionByIdRequest.newBuilder()
|
||||
.setUpdateId(transactionId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransactionTree(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getTransactionTreeById(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTreeV2> getTransactionTreeById(
|
||||
String transactionId, Set<String> requestingParties) {
|
||||
return getTransactionTreeById(transactionId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionTreeV2> getTransactionTreeById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionTreeById(transactionId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionV2> extractTransaction(
|
||||
Future<UpdateServiceOuterClass.GetTransactionResponse> future) {
|
||||
return Single.fromFuture(future)
|
||||
.map(GetTransactionResponseV2::fromProto)
|
||||
.map(GetTransactionResponseV2::getTransaction);
|
||||
}
|
||||
|
||||
private Single<TransactionV2> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetTransactionByEventIdRequest request =
|
||||
UpdateServiceOuterClass.GetTransactionByEventIdRequest.newBuilder()
|
||||
.setEventId(eventId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransaction(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken)
|
||||
.getTransactionByEventId(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionV2> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties) {
|
||||
return getTransactionByEventId(eventId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionV2> getTransactionByEventId(
|
||||
String eventId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionByEventId(eventId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
|
||||
private Single<TransactionV2> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, Optional<String> accessToken) {
|
||||
UpdateServiceOuterClass.GetTransactionByIdRequest request =
|
||||
UpdateServiceOuterClass.GetTransactionByIdRequest.newBuilder()
|
||||
.setUpdateId(transactionId)
|
||||
.addAllRequestingParties(requestingParties)
|
||||
.build();
|
||||
return extractTransaction(
|
||||
StubHelper.authenticating(this.serviceFutureStub, accessToken).getTransactionById(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionV2> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties) {
|
||||
return getTransactionById(transactionId, requestingParties, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<TransactionV2> getTransactionById(
|
||||
String transactionId, Set<String> requestingParties, String accessToken) {
|
||||
return getTransactionById(transactionId, requestingParties, Optional.of(accessToken));
|
||||
}
|
||||
}
|
@ -4,29 +4,30 @@
|
||||
package com.daml.ledger.rxjava
|
||||
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset.Absolute
|
||||
|
||||
import com.daml.ledger.api.v1.command_completion_service.Checkpoint
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.javaapi.data.ParticipantOffsetV2.Absolute
|
||||
import com.daml.ledger.javaapi.data.{
|
||||
Command,
|
||||
CommandsSubmission,
|
||||
CommandsSubmissionV2,
|
||||
CreateCommand,
|
||||
DamlRecord,
|
||||
Identifier,
|
||||
}
|
||||
import com.daml.ledger.rxjava.grpc.helpers._
|
||||
import com.digitalasset.canton.ledger.api.auth.{AuthService, AuthServiceWildcard}
|
||||
import com.daml.ledger.api.v1.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v1.command_service.{
|
||||
SubmitAndWaitForTransactionIdResponse,
|
||||
import com.daml.ledger.api.v2.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v2.command_service.{
|
||||
SubmitAndWaitForTransactionResponse,
|
||||
SubmitAndWaitForTransactionTreeResponse,
|
||||
SubmitAndWaitForUpdateIdResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.event_query_service.{
|
||||
GetEventsByContractIdResponse,
|
||||
GetEventsByContractKeyResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.GetLedgerConfigurationResponse
|
||||
import com.daml.ledger.api.v2.event_query_service.GetEventsByContractIdResponse
|
||||
import com.daml.ledger.api.v1.package_service._
|
||||
import com.daml.ledger.api.v2.command_submission_service.SubmitResponse
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.protobuf.empty.Empty
|
||||
import io.grpc.Server
|
||||
@ -37,6 +38,7 @@ import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.chaining.scalaUtilChainingOps
|
||||
|
||||
class DamlLedgerClientTest
|
||||
extends AnyFlatSpec
|
||||
@ -47,23 +49,13 @@ class DamlLedgerClientTest
|
||||
|
||||
val ledgerServices = new LedgerServices(getClass.getSimpleName)
|
||||
|
||||
behavior of "DamlLedgerClient.forLedgerIdAndHost"
|
||||
behavior of "DamlLedgerClient.forHost"
|
||||
|
||||
it should "connect to an existing ledger-api grpc service with the correct ledgerId and pass the ledgerId to the clients" in {
|
||||
it should "connect to an existing ledger-api grpc service and use it in the clients" in {
|
||||
withFakeLedgerServer(AuthServiceWildcard) { (server, impls) =>
|
||||
val damlLedgerClient = DamlLedgerClient
|
||||
.newBuilder("localhost", server.getPort)
|
||||
.withExpectedLedgerId(ledgerServices.ledgerId)
|
||||
.build(): @annotation.nowarn(
|
||||
"cat=deprecation&origin=com\\.daml\\.ledger\\.rxjava\\.DamlLedgerClient\\.Builder\\.withExpectedLedgerId"
|
||||
)
|
||||
testDamlLedgerClient(damlLedgerClient, impls)
|
||||
}
|
||||
}
|
||||
|
||||
it should "connect to an existing ledger-api grpc service, autodiscover the ledgerId and pass it to the clients" in {
|
||||
withFakeLedgerServer(AuthServiceWildcard) { (server, impls) =>
|
||||
val damlLedgerClient = DamlLedgerClient.newBuilder("localhost", server.getPort).build()
|
||||
.build()
|
||||
testDamlLedgerClient(damlLedgerClient, impls)
|
||||
}
|
||||
}
|
||||
@ -72,16 +64,12 @@ class DamlLedgerClientTest
|
||||
withFakeLedgerServer(mockedAuthService) { (server, ledgerServicesImpls) =>
|
||||
val damlLedgerClient = DamlLedgerClient
|
||||
.newBuilder("localhost", server.getPort)
|
||||
.withExpectedLedgerId(ledgerServices.ledgerId)
|
||||
.withAccessToken(somePartyReadWriteToken)
|
||||
.build(): @annotation.nowarn(
|
||||
"cat=deprecation&origin=com\\.daml\\.ledger\\.rxjava\\.DamlLedgerClient\\.Builder\\.withExpectedLedgerId"
|
||||
)
|
||||
.build()
|
||||
damlLedgerClient.connect()
|
||||
damlLedgerClient.getLedgerId shouldBe ledgerServices.ledgerId
|
||||
testActiveContractSetClient(
|
||||
damlLedgerClient.getActiveContractSetClient,
|
||||
ledgerServicesImpls.activeContractsServiceImpl,
|
||||
testStateServiceClient(
|
||||
damlLedgerClient.getStateClient,
|
||||
ledgerServicesImpls.stateServiceImpl,
|
||||
)
|
||||
testCommandClient(damlLedgerClient.getCommandClient, ledgerServicesImpls.commandServiceImpl)
|
||||
testCommandCompletionClient(
|
||||
@ -92,11 +80,7 @@ class DamlLedgerClientTest
|
||||
damlLedgerClient.getCommandSubmissionClient,
|
||||
ledgerServicesImpls.commandSubmissionServiceImpl,
|
||||
)
|
||||
testLedgerConfigurationClient(
|
||||
damlLedgerClient.getLedgerConfigurationClient,
|
||||
ledgerServicesImpls.ledgerConfigurationServiceImpl,
|
||||
)
|
||||
testTimeClientGet(damlLedgerClient.getTimeClient, ledgerServicesImpls.timeServiceImpl)
|
||||
testTimeClientGet(damlLedgerClient.getTimeClient)
|
||||
expectPermissionDenied {
|
||||
testTimeClientSet(damlLedgerClient.getTimeClient, ledgerServicesImpls.timeServiceImpl)
|
||||
}
|
||||
@ -106,17 +90,16 @@ class DamlLedgerClientTest
|
||||
}
|
||||
|
||||
private def clueFor(clientName: String): String =
|
||||
s"DamlLedgerClient failed to propagate ledgerId to the $clientName:"
|
||||
s"DamlLedgerClient failed to activate $clientName:"
|
||||
|
||||
private def testDamlLedgerClient(
|
||||
damlLedgerClient: DamlLedgerClient,
|
||||
ledgerServicesImpls: LedgerServicesImpls,
|
||||
): Any = {
|
||||
damlLedgerClient.connect()
|
||||
damlLedgerClient.getLedgerId shouldBe ledgerServices.ledgerId
|
||||
testActiveContractSetClient(
|
||||
damlLedgerClient.getActiveContractSetClient,
|
||||
ledgerServicesImpls.activeContractsServiceImpl,
|
||||
testStateServiceClient(
|
||||
damlLedgerClient.getStateClient,
|
||||
ledgerServicesImpls.stateServiceImpl,
|
||||
)
|
||||
testCommandClient(damlLedgerClient.getCommandClient, ledgerServicesImpls.commandServiceImpl)
|
||||
testCommandCompletionClient(
|
||||
@ -127,28 +110,25 @@ class DamlLedgerClientTest
|
||||
damlLedgerClient.getCommandSubmissionClient,
|
||||
ledgerServicesImpls.commandSubmissionServiceImpl,
|
||||
)
|
||||
testLedgerConfigurationClient(
|
||||
damlLedgerClient.getLedgerConfigurationClient,
|
||||
ledgerServicesImpls.ledgerConfigurationServiceImpl,
|
||||
)
|
||||
testTimeClientGet(damlLedgerClient.getTimeClient, ledgerServicesImpls.timeServiceImpl)
|
||||
testTimeClientGet(damlLedgerClient.getTimeClient)
|
||||
testTimeClientSet(damlLedgerClient.getTimeClient, ledgerServicesImpls.timeServiceImpl)
|
||||
testPackageClient(damlLedgerClient.getPackageClient, ledgerServicesImpls.packageServiceImpl)
|
||||
damlLedgerClient.close()
|
||||
}
|
||||
|
||||
private def testActiveContractSetClient(
|
||||
activeContractSetClient: ActiveContractsClient,
|
||||
activeContractsServiceImpl: ActiveContractsServiceImpl,
|
||||
private def testStateServiceClient(
|
||||
stateServiceClient: StateClient,
|
||||
activeContractsServiceImpl: StateServiceImpl,
|
||||
): Assertion = {
|
||||
withClue(clueFor("ActiveContractsClient")) {
|
||||
activeContractSetClient
|
||||
withClue(clueFor("StateClient")) {
|
||||
stateServiceClient
|
||||
.getActiveContracts(filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.toList
|
||||
activeContractsServiceImpl.getLastRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
activeContractsServiceImpl.getLastRequest.value.filter
|
||||
.flatMap(_.filtersByParty.get(someParty)) should not be empty
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,20 +141,33 @@ class DamlLedgerClientTest
|
||||
val record = new DamlRecord(recordId, List.empty[DamlRecord.Field].asJava)
|
||||
val command = new CreateCommand(new Identifier("a", "a", "b"), record)
|
||||
val commands = genCommands(List(command), Option(someParty))
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
commandClient
|
||||
.submitAndWait(params)
|
||||
.timeout(1L, TimeUnit.SECONDS)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
commandServiceImpl.getLastRequest.value.getCommands.ledgerId shouldBe ledgerServices.ledgerId
|
||||
commandServiceImpl.getLastRequest.value.getCommands.domainId shouldBe domainId
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,15 +177,10 @@ class DamlLedgerClientTest
|
||||
): Assertion = {
|
||||
withClue(clueFor("CommandCompletionClient")) {
|
||||
commandCompletionClient
|
||||
.completionStream("applicationId", new Absolute(""), Set(someParty).asJava)
|
||||
.completionStream("applicationId", new Absolute(""), List(someParty).asJava)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
commandCompletionServiceImpl.getLastCompletionStreamRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
commandCompletionClient
|
||||
.completionEnd()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
commandCompletionServiceImpl.getLastCompletionEndRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
commandCompletionServiceImpl.getLastCompletionStreamRequest.value.applicationId shouldBe "applicationId"
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,32 +193,44 @@ class DamlLedgerClientTest
|
||||
val record = new DamlRecord(recordId, List.empty[DamlRecord.Field].asJava)
|
||||
val command = new CreateCommand(new Identifier("a", "a", "b"), record)
|
||||
val commands = genCommands(List[Command](command), Option(someParty))
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
commandSubmissionClient
|
||||
.submit(params)
|
||||
.timeout(1L, TimeUnit.SECONDS)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
commandSubmissionServiceImpl.getSubmittedRequest.value.getCommands.ledgerId shouldBe ledgerServices.ledgerId
|
||||
commandSubmissionServiceImpl.getSubmittedRequest.value.getCommands.domainId shouldBe domainId
|
||||
}
|
||||
}
|
||||
|
||||
private def testTimeClientGet(
|
||||
timeClient: TimeClient,
|
||||
timeServiceImpl: TimeServiceImpl,
|
||||
timeClient: TimeClient
|
||||
): Assertion = {
|
||||
withClue("TimeClientGet") {
|
||||
timeClient.getTime
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
timeServiceImpl.getLastGetTimeRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
succeed
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,23 +239,12 @@ class DamlLedgerClientTest
|
||||
timeServiceImpl: TimeServiceImpl,
|
||||
): Assertion = {
|
||||
withClue("TimeClientSet") {
|
||||
val newTime = Instant.ofEpochSecond(10L)
|
||||
timeClient
|
||||
.setTime(Instant.EPOCH, Instant.ofEpochSecond(10L))
|
||||
.setTime(Instant.EPOCH, newTime)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
timeServiceImpl.getLastSetTimeRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
private def testLedgerConfigurationClient(
|
||||
ledgerConfigurationClient: LedgerConfigurationClient,
|
||||
ledgerConfigurationServiceImpl: LedgerConfigurationServiceImpl,
|
||||
): Assertion = {
|
||||
withClue("LedgerConfigurationClient") {
|
||||
ledgerConfigurationClient.getLedgerConfiguration
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
ledgerConfigurationServiceImpl.getLastRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
timeServiceImpl.getLastSetTimeRequest.value.newTime.map(_.seconds) shouldBe Some(10L)
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,17 +257,16 @@ class DamlLedgerClientTest
|
||||
.listPackages()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
packageServiceImpl.getLastListPackageRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
packageClient
|
||||
.getPackage("packageId")
|
||||
.getPackage("packageIdA")
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
packageServiceImpl.getLastGetPackagesRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
packageServiceImpl.getLastGetPackagesRequest.value.packageId shouldBe "packageIdA"
|
||||
packageClient
|
||||
.getPackageStatus("packageId")
|
||||
.getPackageStatus("packageIdB")
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
packageServiceImpl.getLastGetPackageStatusRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
packageServiceImpl.getLastGetPackageStatusRequest.value.packageId shouldBe "packageIdB"
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,17 +277,19 @@ class DamlLedgerClientTest
|
||||
ledgerServices.withFakeLedgerServer(
|
||||
Observable.fromArray(genGetActiveContractsResponse),
|
||||
Observable.empty(),
|
||||
Future.successful(SubmitResponse.defaultInstance),
|
||||
List(
|
||||
CompletionStreamResponse(
|
||||
Some(Checkpoint(offset = Some(LedgerOffset(LedgerOffset.Value.Absolute("1"))))),
|
||||
None,
|
||||
)
|
||||
),
|
||||
Future.successful(Empty.defaultInstance),
|
||||
List(CompletionStreamResponse(None, Seq())),
|
||||
genCompletionEndResponse("completionEndResponse"),
|
||||
Future.successful(Empty.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionIdResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForUpdateIdResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionTreeResponse.defaultInstance),
|
||||
List(genGetTimeResponse),
|
||||
Seq(GetLedgerConfigurationResponse.defaultInstance),
|
||||
Future.successful(genGetTimeResponse),
|
||||
Future.successful(GetEventsByContractIdResponse.defaultInstance),
|
||||
Future.successful(GetEventsByContractKeyResponse.defaultInstance),
|
||||
Future.successful(ListPackagesResponse(Seq("id1"))),
|
||||
Future.successful(GetPackageResponse(HashFunction.SHA256, ByteString.EMPTY)),
|
||||
Future.successful(GetPackageStatusResponse(PackageStatus.values.head)),
|
||||
|
@ -1,113 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import io.reactivex.Observable
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
class ActiveContractClientImplTest
|
||||
extends AnyFlatSpec
|
||||
with Matchers
|
||||
with AuthMatchers
|
||||
with OptionValues
|
||||
with DataLayerHelpers {
|
||||
|
||||
val ledgerServices = new LedgerServices("active-contract-service-ledger")
|
||||
implicit val ec: ExecutionContext = ledgerServices.executionContext
|
||||
|
||||
behavior of "[1.1] ActiveContractClientImpl.getActiveContracts"
|
||||
|
||||
it should "support the empty ACS" in {
|
||||
ledgerServices.withACSClient(Observable.empty()) { (acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 0
|
||||
}
|
||||
}
|
||||
|
||||
it should "support ACS with one element" in {
|
||||
ledgerServices.withACSClient(Observable.fromArray(genGetActiveContractsResponse)) {
|
||||
(acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 1
|
||||
}
|
||||
}
|
||||
|
||||
it should "support ACS with 10 elements" in {
|
||||
val acsResponses = List.fill(10)(genGetActiveContractsResponse)
|
||||
ledgerServices.withACSClient(Observable.fromArray(acsResponses: _*)) { (acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 10
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[1.2] ActiveContractClientImpl.getActiveContracts"
|
||||
|
||||
it should "pass the transaction filter and the verbose flag to the ledger" in {
|
||||
ledgerServices.withACSClient(Observable.empty()) { (acsClient, acsImpl) =>
|
||||
val verbose = true
|
||||
acsClient
|
||||
.getActiveContracts(filterNothing, verbose)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
acsImpl.getLastRequest.value.getFilter.filtersByParty shouldBe filterNothing.getPartyToFilters.asScala
|
||||
acsImpl.getLastRequest.value.verbose shouldBe verbose
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[1.3] ActiveContractClientImpl.getActiveContracts"
|
||||
|
||||
it should "send requests with the correct ledger ID" in {
|
||||
ledgerServices.withACSClient(Observable.empty()) { (acsClient, acsImpl) =>
|
||||
val verbose = true
|
||||
acsClient
|
||||
.getActiveContracts(filterNothing, verbose)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
acsImpl.getLastRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
"ActiveContractClientImpl.getActiveContracts" should "fail with insufficient authorization" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), mockedAuthService) { (acsClient, _) =>
|
||||
expectUnauthenticated {
|
||||
acsClient
|
||||
.getActiveContracts(filterFor(someParty), false, emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"ActiveContractClientImpl.getActiveContracts" should "succeed with sufficient authorization" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), mockedAuthService) { (acsClient, _) =>
|
||||
acsClient
|
||||
.getActiveContracts(filterFor(someParty), false, somePartyReadToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size shouldEqual 0
|
||||
}
|
||||
}
|
||||
}
|
@ -4,14 +4,14 @@
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.{AuthService, AuthServiceWildcard}
|
||||
import com.daml.ledger.api.v1.command_service.{
|
||||
SubmitAndWaitForTransactionIdResponse,
|
||||
import com.daml.ledger.api.v2.command_service.{
|
||||
SubmitAndWaitForTransactionResponse,
|
||||
SubmitAndWaitForTransactionTreeResponse,
|
||||
SubmitAndWaitForUpdateIdResponse,
|
||||
}
|
||||
import com.daml.ledger.javaapi.data.{
|
||||
Command,
|
||||
CommandsSubmission,
|
||||
CommandsSubmissionV2,
|
||||
CreateCommand,
|
||||
DamlRecord,
|
||||
Identifier,
|
||||
@ -23,12 +23,13 @@ import io.reactivex.Single
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import java.util.UUID.randomUUID
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.Optional
|
||||
import java.util.{Optional, UUID}
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.chaining.scalaUtilChainingOps
|
||||
|
||||
class CommandClientImplTest
|
||||
extends AnyFlatSpec
|
||||
@ -42,7 +43,7 @@ class CommandClientImplTest
|
||||
private def withCommandClient(authService: AuthService = AuthServiceWildcard) = {
|
||||
ledgerServices.withCommandClient(
|
||||
Future.successful(Empty.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionIdResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForUpdateIdResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionResponse.defaultInstance),
|
||||
Future.successful(SubmitAndWaitForTransactionTreeResponse.defaultInstance),
|
||||
authService,
|
||||
@ -58,12 +59,25 @@ class CommandClientImplTest
|
||||
it should "send the given command to the Ledger" in {
|
||||
withCommandClient() { (client, service) =>
|
||||
val commands = genCommands(List.empty)
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val domainId = UUID.randomUUID().toString
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
client
|
||||
.submitAndWait(params)
|
||||
@ -82,14 +96,27 @@ class CommandClientImplTest
|
||||
val record = new DamlRecord(recordId, List.empty[DamlRecord.Field].asJava)
|
||||
val command = new CreateCommand(new Identifier("a", "a", "b"), record)
|
||||
val commands = genCommands(List(command))
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withWorkflowId(commands.getWorkflowId)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
client
|
||||
.submitAndWait(params)
|
||||
@ -103,7 +130,7 @@ class CommandClientImplTest
|
||||
service.getLastRequest.value.getCommands.readAs shouldBe commands.getReadAs.asScala
|
||||
commands.getActAs.get(0) shouldBe commands.getParty
|
||||
service.getLastRequest.value.getCommands.workflowId shouldBe commands.getWorkflowId
|
||||
service.getLastRequest.value.getCommands.ledgerId shouldBe ledgerServices.ledgerId
|
||||
service.getLastRequest.value.getCommands.domainId shouldBe domainId
|
||||
service.getLastRequest.value.getCommands.minLedgerTimeRel
|
||||
.map(_.seconds) shouldBe commands.getMinLedgerTimeRelative.asScala.map(_.getSeconds)
|
||||
service.getLastRequest.value.getCommands.minLedgerTimeRel
|
||||
@ -133,19 +160,20 @@ class CommandClientImplTest
|
||||
List(command).asJava
|
||||
}
|
||||
|
||||
private type SubmitAndWait[A] = CommandsSubmission => Single[A]
|
||||
private type SubmitAndWait[A] = CommandsSubmissionV2 => Single[A]
|
||||
|
||||
private def submitAndWaitFor[A](
|
||||
submit: SubmitAndWait[A]
|
||||
)(commands: java.util.List[Command], party: String, token: Option[String]) = {
|
||||
val params = CommandsSubmission
|
||||
val params = CommandsSubmissionV2
|
||||
.create(
|
||||
randomUUID().toString,
|
||||
randomUUID().toString,
|
||||
randomUUID().toString,
|
||||
token.fold(dummyCommands)(_ => commands),
|
||||
)
|
||||
.withActAs(party)
|
||||
.withAccessToken(Optional.ofNullable(token.orNull))
|
||||
.pipe(p => token.fold(p)(p.withAccessToken))
|
||||
|
||||
submit(params).timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS).blockingGet()
|
||||
}
|
||||
|
@ -3,15 +3,16 @@
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset.LedgerBegin
|
||||
import com.daml.ledger.api.v1.command_completion_service.Checkpoint
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.javaapi.data.ParticipantOffsetV2.ParticipantBegin
|
||||
import com.daml.ledger.javaapi.data.LedgerOffset.Absolute
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import com.daml.ledger.api.v1.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v1.completion.Completion
|
||||
import com.daml.ledger.api.v2.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v2.completion.Completion
|
||||
import com.google.rpc.status.Status
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
@ -27,34 +28,8 @@ class CommandCompletionClientImplTest
|
||||
with DataLayerHelpers {
|
||||
|
||||
val ledgerServices = new LedgerServices("command-completion-service-ledger")
|
||||
|
||||
behavior of "[4.1] CommandCompletionClientImpl.getLedgerEnd"
|
||||
|
||||
it should "return the ledger end" in {
|
||||
val offset = "offset"
|
||||
val response = genCompletionEndResponse(offset)
|
||||
ledgerServices.withCommandCompletionClient(List.empty, response) { (client, _) =>
|
||||
val end = client
|
||||
.completionEnd()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
end.getOffset shouldBe a[LedgerOffset.Absolute]
|
||||
end.getOffset.asInstanceOf[LedgerOffset.Absolute].getOffset shouldBe offset
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[4.2] CommandCompletionClientImpl.completionEnd"
|
||||
|
||||
it should "send the request with the correct ledgerId" in {
|
||||
ledgerServices.withCommandCompletionClient(List.empty, genCompletionEndResponse("")) {
|
||||
(client, serviceImpl) =>
|
||||
client
|
||||
.completionEnd()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
serviceImpl.getLastCompletionEndRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
private val offset1 = LedgerOffset(LedgerOffset.Value.Absolute("1"))
|
||||
private val offset2 = LedgerOffset(LedgerOffset.Value.Absolute("2"))
|
||||
|
||||
behavior of "[4.3] CommandCompletionClientImpl.completionStream"
|
||||
|
||||
@ -62,50 +37,52 @@ class CommandCompletionClientImplTest
|
||||
val applicationId = "applicationId"
|
||||
val completion1 = Completion("cid1", Option(new Status(0)), "1")
|
||||
val completion2 = Completion("cid2", Option(new Status(1)))
|
||||
val completionResponse = CompletionStreamResponse(None, List(completion1, completion2))
|
||||
|
||||
val completionResponses = List(
|
||||
CompletionStreamResponse(Some(Checkpoint(offset = Some(offset1))), Some(completion1)),
|
||||
CompletionStreamResponse(Some(Checkpoint(offset = Some(offset2))), Some(completion2)),
|
||||
)
|
||||
ledgerServices.withCommandCompletionClient(
|
||||
List(completionResponse),
|
||||
genCompletionEndResponse(""),
|
||||
completionResponses
|
||||
) { (client, _) =>
|
||||
val completions = client
|
||||
.completionStream(applicationId, LedgerBegin.getInstance(), Set("Alice").asJava)
|
||||
.take(1)
|
||||
.completionStream(applicationId, ParticipantBegin.getInstance(), List("Alice").asJava)
|
||||
.take(2)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.iterator()
|
||||
.next()
|
||||
completions.getCheckpoint shouldBe Optional.empty()
|
||||
completions.getCompletions.size() shouldBe 2
|
||||
val receivedCompletion1 = completions.getCompletions.get(0)
|
||||
val receivedCompletion2 = completions.getCompletions.get(1)
|
||||
receivedCompletion1.getCommandId shouldBe completion1.commandId
|
||||
receivedCompletion1.getStatus.getCode shouldBe completion1.getStatus.code
|
||||
receivedCompletion1.getTransactionId shouldBe completion1.transactionId
|
||||
receivedCompletion2.getCommandId shouldBe completion2.commandId
|
||||
receivedCompletion2.getStatus.getCode shouldBe completion2.getStatus.code
|
||||
|
||||
val receivedCompletion1 = completions.next()
|
||||
val receivedCompletion2 = completions.next()
|
||||
receivedCompletion1.getCheckpoint.getOffset shouldBe new Absolute(offset1.getAbsolute)
|
||||
receivedCompletion1.getCompletion.getCommandId shouldBe completion1.commandId
|
||||
receivedCompletion1.getCompletion.getStatus.getCode shouldBe completion1.getStatus.code
|
||||
receivedCompletion1.getCompletion.getUpdateId shouldBe completion1.updateId
|
||||
receivedCompletion2.getCheckpoint.getOffset shouldBe new Absolute(offset2.getAbsolute)
|
||||
receivedCompletion2.getCompletion.getCommandId shouldBe completion2.commandId
|
||||
receivedCompletion2.getCompletion.getStatus.getCode shouldBe completion2.getStatus.code
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[4.4] CommandCompletionClientImpl.completionStream"
|
||||
|
||||
it should "send the request with the correct ledgerId" in {
|
||||
it should "send the request with the correct arguments" in {
|
||||
val applicationId = "applicationId"
|
||||
val completion1 = Completion("cid1", Option(new Status(0)))
|
||||
val completionResponse = CompletionStreamResponse(None, List(completion1))
|
||||
val parties = Set("Alice")
|
||||
val completionResponse =
|
||||
CompletionStreamResponse(Some(Checkpoint(offset = Some(offset1))), Some(completion1))
|
||||
val parties = List("Alice")
|
||||
ledgerServices.withCommandCompletionClient(
|
||||
List(completionResponse),
|
||||
genCompletionEndResponse(""),
|
||||
List(completionResponse)
|
||||
) { (client, serviceImpl) =>
|
||||
client
|
||||
.completionStream(applicationId, LedgerBegin.getInstance(), parties.asJava)
|
||||
.completionStream(applicationId, ParticipantBegin.getInstance(), parties.asJava)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
serviceImpl.getLastCompletionStreamRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
serviceImpl.getLastCompletionStreamRequest.value.applicationId shouldBe applicationId
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getOffset.getAbsolute shouldBe "" // grpc default string is empty string
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getOffset.getBoundary.isLedgerEnd shouldBe false
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getOffset.getBoundary.isLedgerBegin shouldBe true
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getBeginExclusive.getAbsolute shouldBe "" // grpc default string is empty string
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getBeginExclusive.getBoundary.isParticipantEnd shouldBe false
|
||||
serviceImpl.getLastCompletionStreamRequest.value.getBeginExclusive.getBoundary.isParticipantBegin shouldBe true
|
||||
serviceImpl.getLastCompletionStreamRequest.value.parties should contain theSameElementsAs parties
|
||||
}
|
||||
}
|
||||
@ -114,10 +91,10 @@ class CommandCompletionClientImplTest
|
||||
|
||||
def toAuthenticatedServer(fn: CommandCompletionClient => Any): Any = {
|
||||
val completion1 = Completion("cid1", Option(new Status(0)))
|
||||
val completionResponse = CompletionStreamResponse(None, List(completion1))
|
||||
val completionResponse =
|
||||
CompletionStreamResponse(Some(Checkpoint(offset = Some(offset1))), Some(completion1))
|
||||
ledgerServices.withCommandCompletionClient(
|
||||
List(completionResponse),
|
||||
genCompletionEndResponse(""),
|
||||
mockedAuthService,
|
||||
) { (client, _) =>
|
||||
fn(client)
|
||||
@ -129,7 +106,7 @@ class CommandCompletionClientImplTest
|
||||
withClue("completionStream") {
|
||||
expectUnauthenticated {
|
||||
client
|
||||
.completionStream("appId", LedgerBegin.getInstance(), Set(someParty).asJava)
|
||||
.completionStream("appId", ParticipantBegin.getInstance(), List(someParty).asJava)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
}
|
||||
@ -137,16 +114,11 @@ class CommandCompletionClientImplTest
|
||||
withClue("completionStream unbounded") {
|
||||
expectUnauthenticated {
|
||||
client
|
||||
.completionStream("appId", Set(someParty).asJava)
|
||||
.completionStream("appId", List(someParty).asJava)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
}
|
||||
}
|
||||
withClue("completionEnd") {
|
||||
expectUnauthenticated {
|
||||
client.completionEnd().blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,8 +129,8 @@ class CommandCompletionClientImplTest
|
||||
client
|
||||
.completionStream(
|
||||
"appId",
|
||||
LedgerBegin.getInstance(),
|
||||
Set(someParty).asJava,
|
||||
ParticipantBegin.getInstance(),
|
||||
List(someParty).asJava,
|
||||
someOtherPartyReadToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
@ -168,16 +140,11 @@ class CommandCompletionClientImplTest
|
||||
withClue("completionStream unbounded") {
|
||||
expectPermissionDenied {
|
||||
client
|
||||
.completionStream("appId", Set(someParty).asJava, someOtherPartyReadToken)
|
||||
.completionStream("appId", List(someParty).asJava, someOtherPartyReadToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
}
|
||||
}
|
||||
withClue("completionEnd") {
|
||||
expectUnauthenticated {
|
||||
client.completionEnd(emptyToken).blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,8 +154,8 @@ class CommandCompletionClientImplTest
|
||||
client
|
||||
.completionStream(
|
||||
"appId",
|
||||
LedgerBegin.getInstance(),
|
||||
Set(someParty).asJava,
|
||||
ParticipantBegin.getInstance(),
|
||||
List(someParty).asJava,
|
||||
somePartyReadToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
@ -196,13 +163,10 @@ class CommandCompletionClientImplTest
|
||||
}
|
||||
withClue("completionStream unbounded") {
|
||||
client
|
||||
.completionStream("appId", Set(someParty).asJava, somePartyReadToken)
|
||||
.completionStream("appId", List(someParty).asJava, somePartyReadToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
}
|
||||
withClue("completionEnd") {
|
||||
client.completionEnd(somePartyReadToken).blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,24 +5,26 @@ package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import com.daml.ledger.javaapi.data.{
|
||||
Command,
|
||||
CommandsSubmission,
|
||||
CommandsSubmissionV2,
|
||||
CreateCommand,
|
||||
DamlRecord,
|
||||
Identifier,
|
||||
}
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import com.google.protobuf.empty.Empty
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import java.time.Duration
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.Optional
|
||||
import java.util.{Optional, UUID}
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.api.v2.command_submission_service.SubmitResponse
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.util.chaining.scalaUtilChainingOps
|
||||
|
||||
class CommandSubmissionClientImplTest
|
||||
extends AnyFlatSpec
|
||||
@ -47,13 +49,26 @@ class CommandSubmissionClientImplTest
|
||||
timeout = Optional.of(Duration.of(5, ChronoUnit.SECONDS)),
|
||||
) { (client, _) =>
|
||||
val commands = genCommands(List.empty)
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
withClue("The first command should be stuck") {
|
||||
expectDeadlineExceeded(
|
||||
@ -79,14 +94,27 @@ class CommandSubmissionClientImplTest
|
||||
it should "send a commands to the ledger" in {
|
||||
ledgerServices.withCommandSubmissionClient(alwaysSucceed) { (client, serviceImpl) =>
|
||||
val commands = genCommands(List.empty)
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withWorkflowId(commands.getWorkflowId)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
|
||||
client
|
||||
.submit(params)
|
||||
@ -95,7 +123,7 @@ class CommandSubmissionClientImplTest
|
||||
|
||||
val receivedCommands = serviceImpl.getSubmittedRequest.value.getCommands
|
||||
|
||||
receivedCommands.ledgerId shouldBe ledgerServices.ledgerId
|
||||
receivedCommands.domainId shouldBe domainId
|
||||
receivedCommands.applicationId shouldBe commands.getApplicationId
|
||||
receivedCommands.workflowId shouldBe commands.getWorkflowId
|
||||
receivedCommands.commandId shouldBe commands.getCommandId
|
||||
@ -136,14 +164,27 @@ class CommandSubmissionClientImplTest
|
||||
val record = new DamlRecord(recordId, List.empty[DamlRecord.Field].asJava)
|
||||
val command = new CreateCommand(new Identifier("a", "a", "b"), record)
|
||||
val commands = genCommands(List[Command](command), Option(someParty))
|
||||
val domainId = UUID.randomUUID().toString
|
||||
|
||||
val params = CommandsSubmission
|
||||
.create(commands.getApplicationId, commands.getCommandId, commands.getCommands)
|
||||
val params = CommandsSubmissionV2
|
||||
.create(commands.getApplicationId, commands.getCommandId, domainId, commands.getCommands)
|
||||
.withActAs(commands.getParty)
|
||||
.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute)
|
||||
.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative)
|
||||
.withDeduplicationTime(commands.getDeduplicationTime)
|
||||
.withAccessToken(Optional.ofNullable(accessToken.orNull))
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeAbsolute.isPresent)
|
||||
p.withMinLedgerTimeAbs(commands.getMinLedgerTimeAbsolute.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getMinLedgerTimeRelative.isPresent)
|
||||
p.withMinLedgerTimeRel(commands.getMinLedgerTimeRelative.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p =>
|
||||
if (commands.getDeduplicationTime.isPresent)
|
||||
p.withDeduplicationDuration(commands.getDeduplicationTime.get())
|
||||
else p
|
||||
)
|
||||
.pipe(p => accessToken.fold(p)(p.withAccessToken))
|
||||
|
||||
client
|
||||
.submit(params)
|
||||
@ -189,11 +230,14 @@ object CommandSubmissionClientImplTest {
|
||||
|
||||
private val stuck = Future.never
|
||||
|
||||
private val success = Future.successful(Empty.defaultInstance)
|
||||
private val success = Future.successful(SubmitResponse.defaultInstance)
|
||||
|
||||
private val alwaysSucceed: () => Future[Empty] = () => success
|
||||
private val alwaysSucceed: () => Future[SubmitResponse] = () => success
|
||||
|
||||
private def sequence(first: Future[Empty], following: Future[Empty]*): () => Future[Empty] = {
|
||||
private def sequence(
|
||||
first: Future[SubmitResponse],
|
||||
following: Future[SubmitResponse]*
|
||||
): () => Future[SubmitResponse] = {
|
||||
val it = Iterator.single(first) ++ Iterator(following: _*)
|
||||
() =>
|
||||
try {
|
||||
|
@ -5,11 +5,7 @@ package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.{AuthService, AuthServiceWildcard}
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TestConfiguration
|
||||
import com.daml.ledger.api.v1.event_query_service.{
|
||||
GetEventsByContractIdResponse,
|
||||
GetEventsByContractKeyResponse,
|
||||
}
|
||||
import com.daml.ledger.javaapi.data._
|
||||
import com.daml.ledger.api.v2.event_query_service.GetEventsByContractIdResponse
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices}
|
||||
import org.scalatest.OptionValues
|
||||
@ -18,7 +14,6 @@ import org.scalatest.matchers.should.Matchers
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scala.concurrent.Future
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.jdk.OptionConverters._
|
||||
|
||||
class EventQueryClientImplTest
|
||||
extends AnyFlatSpec
|
||||
@ -32,13 +27,10 @@ class EventQueryClientImplTest
|
||||
private def withEventQueryClient(authService: AuthService = AuthServiceWildcard) = {
|
||||
ledgerServices.withEventQueryClient(
|
||||
Future.successful(GetEventsByContractIdResponse.defaultInstance),
|
||||
Future.successful(GetEventsByContractKeyResponse.defaultInstance),
|
||||
authService,
|
||||
) _
|
||||
}
|
||||
|
||||
private val contractKey = Bool.TRUE
|
||||
private val identifier = new Identifier("recordPackageId", "recordModuleName", "recordEntityName")
|
||||
private val contractId = "contract_id"
|
||||
private val parties = java.util.Set.of("party_1")
|
||||
|
||||
@ -51,28 +43,6 @@ class EventQueryClientImplTest
|
||||
.blockingGet()
|
||||
service.getLastGetEventsByContractIdRequest.value.contractId shouldBe contractId
|
||||
service.getLastGetEventsByContractIdRequest.value.requestingParties.toSet shouldBe parties.asScala
|
||||
|
||||
client
|
||||
.getEventsByContractKey(contractKey, identifier, parties, "1")
|
||||
.blockingGet()
|
||||
service.getLastGetEventsByContractKeyRequest.value.contractKey
|
||||
.flatMap(_.sum.bool) shouldBe contractKey.asBool().toScala.map(_.getValue)
|
||||
service.getLastGetEventsByContractKeyRequest.value.templateId.map(_.packageId) shouldBe Some(
|
||||
identifier.getPackageId
|
||||
)
|
||||
service.getLastGetEventsByContractKeyRequest.value.templateId.map(_.entityName) shouldBe Some(
|
||||
identifier.getEntityName
|
||||
)
|
||||
service.getLastGetEventsByContractKeyRequest.value.templateId.map(_.moduleName) shouldBe Some(
|
||||
identifier.getModuleName
|
||||
)
|
||||
service.getLastGetEventsByContractKeyRequest.value.requestingParties.toSet shouldBe parties.asScala
|
||||
service.getLastGetEventsByContractKeyRequest.value.continuationToken shouldBe "1"
|
||||
client
|
||||
.getEventsByContractKey(contractKey, identifier, parties, "")
|
||||
.blockingGet()
|
||||
service.getLastGetEventsByContractKeyRequest.value.continuationToken shouldBe ""
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,14 +58,6 @@ class EventQueryClientImplTest
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
withClue("getEventsByContractKey") {
|
||||
expectUnauthenticated {
|
||||
client
|
||||
.getEventsByContractKey(contractKey, identifier, parties, "")
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,20 +71,6 @@ class EventQueryClientImplTest
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
withClue("getEventsByContractKey") {
|
||||
expectPermissionDenied {
|
||||
client
|
||||
.getEventsByContractKey(
|
||||
contractKey,
|
||||
identifier,
|
||||
parties,
|
||||
"",
|
||||
someOtherPartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,12 +82,6 @@ class EventQueryClientImplTest
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
}
|
||||
withClue("getEventsByContractKey") {
|
||||
client
|
||||
.getEventsByContractKey(contractKey, identifier, parties, "", somePartyReadWriteToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{LedgerServices, TestConfiguration}
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.GetLedgerConfigurationResponse
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
final class LedgerConfigurationClientImplTest
|
||||
extends AnyFlatSpec
|
||||
with Matchers
|
||||
with AuthMatchers
|
||||
with OptionValues {
|
||||
|
||||
private val ledgerServices = new LedgerServices("ledger-configuration-service-ledger")
|
||||
|
||||
behavior of "[5.1] LedgerConfigurationClientImpl.getLedgerConfiguration"
|
||||
|
||||
it should "send the request to the Ledger" in {
|
||||
ledgerServices.withConfigurationClient(Seq(GetLedgerConfigurationResponse.defaultInstance)) {
|
||||
(client, _) =>
|
||||
// to test that we send a request to the Ledger, we check if there is a response
|
||||
client.getLedgerConfiguration
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[5.2] LedgerConfigurationClientImpl.getLedgerConfiguration"
|
||||
|
||||
it should "send the request with the correct ledger ID" in {
|
||||
|
||||
ledgerServices.withConfigurationClient(Seq(GetLedgerConfigurationResponse.defaultInstance)) {
|
||||
(client, service) =>
|
||||
client.getLedgerConfiguration
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
service.getLastRequest.value.ledgerId shouldEqual ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "Authorization"
|
||||
|
||||
def toAuthenticatedServer(fn: LedgerConfigurationClient => Any): Any =
|
||||
ledgerServices.withConfigurationClient(
|
||||
Seq(GetLedgerConfigurationResponse.defaultInstance),
|
||||
mockedAuthService,
|
||||
) { (client, _) =>
|
||||
fn(client)
|
||||
}
|
||||
|
||||
it should "deny access without a token" in {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getLedgerConfiguration
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it should "deny access with insufficient authorization" in {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getLedgerConfiguration(emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it should "allow access with sufficient authorization" in {
|
||||
toAuthenticatedServer(
|
||||
_.getLedgerConfiguration(publicToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.time.Duration
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{LedgerServices, TestConfiguration}
|
||||
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
@deprecated("Ledger identity string is optional for all ledger API requests", since = "2.0.0")
|
||||
final class LedgerIdentityClientTest extends AnyFlatSpec with Matchers with AuthMatchers {
|
||||
|
||||
import LedgerIdentityClientTest._
|
||||
|
||||
private val ledgerServices = new LedgerServices(ledgerId)
|
||||
|
||||
behavior of "[6.1] LedgerIdentityClient.getLedgerIdentity"
|
||||
|
||||
it should "return ledger-id when requested" in ledgerServices.withLedgerIdentityClient(
|
||||
alwaysSucceed
|
||||
) { (binding, _) =>
|
||||
binding.getLedgerIdentity
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet() shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
|
||||
it should "return ledger-id when requested with authorization" in ledgerServices
|
||||
.withLedgerIdentityClient(alwaysSucceed, mockedAuthService) { (binding, _) =>
|
||||
binding
|
||||
.getLedgerIdentity(publicToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet() shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
|
||||
it should "deny ledger-id queries with insufficient authorization" in ledgerServices
|
||||
.withLedgerIdentityClient(alwaysSucceed, mockedAuthService) { (binding, _) =>
|
||||
expectUnauthenticated {
|
||||
binding
|
||||
.getLedgerIdentity(emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
}
|
||||
}
|
||||
|
||||
it should "timeout should work as expected across calls" in {
|
||||
ledgerServices.withLedgerIdentityClient(
|
||||
stepThrough(stuck, success),
|
||||
timeout = Optional.of(Duration.of(5, ChronoUnit.SECONDS)),
|
||||
) { (client, _) =>
|
||||
withClue("The first command should be stuck") {
|
||||
expectDeadlineExceeded(
|
||||
client
|
||||
.getLedgerIdentity(emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
|
||||
withClue("The second command should go through") {
|
||||
val res = Option(
|
||||
client
|
||||
.getLedgerIdentity(emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
)
|
||||
res should not be empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object LedgerIdentityClientTest {
|
||||
|
||||
private val ledgerId = "ledger-identity-service-ledger"
|
||||
|
||||
private val stuck = Future.never
|
||||
|
||||
private val success = Future.successful(ledgerId)
|
||||
|
||||
private val alwaysSucceed: () => Future[String] = () => success
|
||||
|
||||
private def stepThrough[A](first: A, following: A*): () => A = {
|
||||
val it = Iterator.single(first) ++ Iterator(following: _*)
|
||||
() =>
|
||||
try {
|
||||
it.next()
|
||||
} catch {
|
||||
case e: NoSuchElementException =>
|
||||
throw new RuntimeException("LedgerIdentityClientImplTest.sequence exhausted", e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -34,22 +34,6 @@ class PackageClientImplTest extends AnyFlatSpec with Matchers with AuthMatchers
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[7.2] PackageClientImpl.listPackages"
|
||||
|
||||
it should "request the list of packages with the correct ledger ID" in {
|
||||
ledgerServices.withPackageClient(
|
||||
listPackageResponseFuture("first"),
|
||||
defaultGetPackageResponseFuture,
|
||||
defaultGetPackageStatusResponseFuture,
|
||||
) { (client, service) =>
|
||||
client
|
||||
.listPackages()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
service.getLastListPackageRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[7.3] PackageClientImpl.getPackage"
|
||||
|
||||
it should "return the package from the Ledger" in {
|
||||
@ -69,7 +53,7 @@ class PackageClientImplTest extends AnyFlatSpec with Matchers with AuthMatchers
|
||||
|
||||
behavior of "[7.4] PackageClientImpl.getPackage"
|
||||
|
||||
it should "request the package with the correct ledger ID and package ID" in {
|
||||
it should "request the package with the correct package ID" in {
|
||||
ledgerServices.withPackageClient(
|
||||
listPackageResponseFuture(),
|
||||
defaultGetPackageResponseFuture,
|
||||
@ -79,7 +63,6 @@ class PackageClientImplTest extends AnyFlatSpec with Matchers with AuthMatchers
|
||||
.getPackage("packageId")
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
service.getLastGetPackagesRequest.value.ledgerId shouldEqual ledgerServices.ledgerId
|
||||
service.getLastGetPackagesRequest.value.packageId shouldEqual "packageId"
|
||||
}
|
||||
}
|
||||
@ -102,7 +85,7 @@ class PackageClientImplTest extends AnyFlatSpec with Matchers with AuthMatchers
|
||||
|
||||
behavior of "[7.6] PackageClientImpl.getPackageStatus"
|
||||
|
||||
it should "send a request with the correct ledger ID and packageID" in {
|
||||
it should "send a request with the correct packageID" in {
|
||||
ledgerServices.withPackageClient(
|
||||
listPackageResponseFuture(),
|
||||
defaultGetPackageResponseFuture,
|
||||
@ -112,7 +95,6 @@ class PackageClientImplTest extends AnyFlatSpec with Matchers with AuthMatchers
|
||||
.getPackageStatus("packageId")
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingGet()
|
||||
service.getLastGetPackageStatusRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
service.getLastGetPackageStatusRequest.value.packageId shouldBe "packageId"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.javaapi.data.ParticipantOffsetV2
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionGenerator.nonEmptyLedgerContent
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import io.reactivex.Observable
|
||||
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
|
||||
import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
class StateClientImplTest
|
||||
extends AnyFlatSpec
|
||||
with ScalaCheckDrivenPropertyChecks
|
||||
with Matchers
|
||||
with AuthMatchers
|
||||
with OptionValues
|
||||
with DataLayerHelpers {
|
||||
|
||||
val ledgerServices = new LedgerServices("state-service-ledger")
|
||||
implicit val ec: ExecutionContext = ledgerServices.executionContext
|
||||
|
||||
behavior of "[1.1] StateClientImpl.getActiveContracts"
|
||||
|
||||
it should "support the empty ACS" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), Observable.empty()) { (acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 0
|
||||
}
|
||||
}
|
||||
|
||||
it should "support ACS with one element" in {
|
||||
ledgerServices.withACSClient(
|
||||
Observable.fromArray(genGetActiveContractsResponse),
|
||||
Observable.empty(),
|
||||
) { (acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 1
|
||||
}
|
||||
}
|
||||
|
||||
it should "support ACS with 10 elements" in {
|
||||
val acsResponses = List.fill(10)(genGetActiveContractsResponse)
|
||||
ledgerServices.withACSClient(Observable.fromArray(acsResponses: _*), Observable.empty()) {
|
||||
(acsClient, _) =>
|
||||
val acs = acsClient
|
||||
.getActiveContracts(filterNothing, true)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
acs.blockingIterable().asScala.size shouldBe 10
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[1.2] StateClientImpl.getActiveContracts"
|
||||
|
||||
it should "pass the transaction filter and the verbose flag to the ledger" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), Observable.empty()) { (acsClient, acsImpl) =>
|
||||
val verbose = true
|
||||
acsClient
|
||||
.getActiveContracts(filterNothing, verbose)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
acsImpl.getLastRequest.value.getFilter.filtersByParty shouldBe filterNothing.getPartyToFilters.asScala
|
||||
acsImpl.getLastRequest.value.verbose shouldBe verbose
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[1.3] StateClientImpl.getActiveContracts"
|
||||
|
||||
"StateClientImpl.getActiveContracts" should "fail with insufficient authorization" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), Observable.empty(), mockedAuthService) {
|
||||
(acsClient, _) =>
|
||||
expectUnauthenticated {
|
||||
acsClient
|
||||
.getActiveContracts(filterFor(someParty), false, emptyToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"StateClientImpl.getActiveContracts" should "succeed with sufficient authorization" in {
|
||||
ledgerServices.withACSClient(Observable.empty(), Observable.empty(), mockedAuthService) {
|
||||
(acsClient, _) =>
|
||||
acsClient
|
||||
.getActiveContracts(filterFor(someParty), false, somePartyReadToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size shouldEqual 0
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[1.3] StateClientImpl.getLedgerEnd"
|
||||
|
||||
it should "provide ledger end from the ledger" in forAll(nonEmptyLedgerContent) {
|
||||
case (ledgerContent, transactions) =>
|
||||
ledgerServices.withACSClient(
|
||||
Observable.empty(),
|
||||
Observable.fromIterable(ledgerContent.asJava),
|
||||
) { (stateClient, _) =>
|
||||
val expectedOffset = new ParticipantOffsetV2.Absolute(transactions.last.getOffset)
|
||||
stateClient.getLedgerEnd.blockingGet() shouldBe expectedOffset
|
||||
}
|
||||
}
|
||||
|
||||
it should "provide LEDGER_BEGIN from empty ledger" in
|
||||
ledgerServices.withACSClient(Observable.empty(), Observable.empty()) { (transactionClient, _) =>
|
||||
transactionClient.getLedgerEnd.blockingGet() shouldBe
|
||||
ParticipantOffsetV2.ParticipantBegin.getInstance()
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import org.scalatest.OptionValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class TimeClientImplTest
|
||||
extends AnyFlatSpec
|
||||
@ -26,9 +26,12 @@ final class TimeClientImplTest
|
||||
|
||||
behavior of "[9.1] TimeClientImpl.setTime"
|
||||
|
||||
it should "send requests with the correct ledger ID, current time and new time" in {
|
||||
it should "send requests with the correct current time and new time" in {
|
||||
val (timeService, timeServiceImpl) =
|
||||
TimeServiceImpl.createWithRef(Seq.empty, ledgerServices.authorizer)
|
||||
TimeServiceImpl.createWithRef(
|
||||
Future.failed(new UnsupportedOperationException),
|
||||
ledgerServices.authorizer,
|
||||
)
|
||||
ledgerServices.withTimeClient(Seq(timeService)) { timeClient =>
|
||||
val currentLedgerTimeSeconds = 1L
|
||||
val currentLedgerTimeNanos = 2L
|
||||
@ -45,7 +48,6 @@ final class TimeClientImplTest
|
||||
timeServiceImpl.getLastSetTimeRequest.value.getCurrentTime.nanos shouldBe currentLedgerTimeNanos
|
||||
timeServiceImpl.getLastSetTimeRequest.value.getNewTime.seconds shouldBe newLedgerTimeSeconds
|
||||
timeServiceImpl.getLastSetTimeRequest.value.getNewTime.nanos shouldBe newLedgerTimeNanos
|
||||
timeServiceImpl.getLastSetTimeRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +56,11 @@ final class TimeClientImplTest
|
||||
it should "return the responses received" in {
|
||||
val getTimeResponse = genGetTimeResponse
|
||||
ledgerServices.withTimeClient(
|
||||
Seq(TimeServiceImpl.createWithRef(Seq(getTimeResponse), ledgerServices.authorizer)._1)
|
||||
Seq(
|
||||
TimeServiceImpl
|
||||
.createWithRef(Future.successful(getTimeResponse), ledgerServices.authorizer)
|
||||
._1
|
||||
)
|
||||
) { timeClient =>
|
||||
val response = timeClient.getTime
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
@ -64,27 +70,18 @@ final class TimeClientImplTest
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[9.3] TimeClientImpl.getTime"
|
||||
|
||||
it should "send requests with the correct ledger ID" in {
|
||||
val getTimeResponse =
|
||||
genGetTimeResponse // we use the first element to block on the first element
|
||||
val (service, impl) =
|
||||
TimeServiceImpl.createWithRef(Seq(getTimeResponse), ledgerServices.authorizer)
|
||||
ledgerServices.withTimeClient(Seq(service)) { timeClient =>
|
||||
val _ = timeClient
|
||||
.getTime()
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingFirst()
|
||||
impl.getLastGetTimeRequest.value.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "[9.4] TimeClientImpl.setTime"
|
||||
|
||||
it should "return an error without sending a request when the time to set if bigger than the current time" in {
|
||||
ledgerServices.withTimeClient(
|
||||
Seq(TimeServiceImpl.createWithRef(Seq.empty, ledgerServices.authorizer)._1)
|
||||
Seq(
|
||||
TimeServiceImpl
|
||||
.createWithRef(
|
||||
Future.failed(new UnsupportedOperationException),
|
||||
ledgerServices.authorizer,
|
||||
)
|
||||
._1
|
||||
)
|
||||
) { timeClient =>
|
||||
val currentTime = Instant.ofEpochSecond(1L, 2L)
|
||||
intercept[RuntimeException](
|
||||
@ -100,7 +97,11 @@ final class TimeClientImplTest
|
||||
|
||||
def toAuthenticatedServer(fn: TimeClient => Any): Any =
|
||||
ledgerServices.withTimeClient(
|
||||
Seq(TimeServiceImpl.createWithRef(Seq(genGetTimeResponse), ledgerServices.authorizer)._1),
|
||||
Seq(
|
||||
TimeServiceImpl
|
||||
.createWithRef(Future.successful(genGetTimeResponse), ledgerServices.authorizer)
|
||||
._1
|
||||
),
|
||||
mockedAuthService,
|
||||
)(fn)
|
||||
|
||||
|
@ -1,524 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.daml.ledger.javaapi.data
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionGenerator._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset.Value.Absolute
|
||||
import com.daml.ledger.api.v1.transaction_filter.TemplateFilter
|
||||
import com.daml.ledger.api.v1.value.Identifier
|
||||
import io.reactivex.Observable
|
||||
import org.scalacheck.Shrink
|
||||
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
final class TransactionsClientImplTest
|
||||
extends AnyFlatSpec
|
||||
with ScalaCheckDrivenPropertyChecks
|
||||
with Matchers
|
||||
with AuthMatchers
|
||||
with DataLayerHelpers {
|
||||
|
||||
override val ledgerServices = new LedgerServices("transaction-service-ledger")
|
||||
|
||||
implicit def tupleNoShrink[A, B]: Shrink[(A, B)] = Shrink.shrinkAny
|
||||
|
||||
private val ledgerBegin = data.LedgerOffset.LedgerBegin.getInstance()
|
||||
private val ledgerEnd = data.LedgerOffset.LedgerEnd.getInstance()
|
||||
private val emptyFilter = new data.FiltersByParty(Map.empty[String, data.Filter].asJava)
|
||||
|
||||
behavior of "8.1 TransactionClient.getTransactions"
|
||||
|
||||
it should "return transactions from the ledger" in forAll(ledgerContentGen) {
|
||||
case (ledgerContent, expectedTransactions) =>
|
||||
ledgerServices.withTransactionsClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, _) =>
|
||||
transactionClient
|
||||
.getTransactions(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.toList shouldBe expectedTransactions
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.2 TransactionClient.getTransactions"
|
||||
|
||||
it should "pass start offset, end offset, transaction filter and verbose flag with the request" in {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
val begin = new data.LedgerOffset.Absolute("1")
|
||||
val end = new data.LedgerOffset.Absolute("2")
|
||||
|
||||
val transactionFilter = new data.FiltersByParty(
|
||||
Map[String, data.Filter](
|
||||
"Alice" -> data.InclusiveFilter.ofTemplateIds(
|
||||
Set(
|
||||
new data.Identifier("p1", "m1", "e1"),
|
||||
new data.Identifier("p2", "m2", "e2"),
|
||||
).asJava
|
||||
)
|
||||
).asJava
|
||||
)
|
||||
|
||||
transactionClient
|
||||
.getTransactions(begin, end, transactionFilter, true)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
val request = transactionService.lastTransactionsRequest.get()
|
||||
request.begin shouldBe Some(LedgerOffset(Absolute("1")))
|
||||
request.end shouldBe Some(LedgerOffset(Absolute("2")))
|
||||
val filter = request.filter.get.filtersByParty
|
||||
filter.keySet shouldBe Set("Alice")
|
||||
filter("Alice").inclusive.get.templateFilters.toSet shouldBe Set(
|
||||
TemplateFilter(
|
||||
Some(Identifier("p1", moduleName = "m1", entityName = "e1")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
TemplateFilter(
|
||||
Some(Identifier("p2", moduleName = "m2", entityName = "e2")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
)
|
||||
request.verbose shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.3 TransactionClient.getTransactions"
|
||||
|
||||
it should "request stream with the correct ledger id" in {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactions(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionsRequest.get().ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.5 TransactionClient.getTransactionsTrees"
|
||||
|
||||
it should "return transaction trees from the ledger" ignore forAll(ledgerContentTreeGen) {
|
||||
case (ledgerContent, expectedTransactionsTrees) =>
|
||||
ledgerServices.withTransactionsClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, _) =>
|
||||
transactionClient
|
||||
.getTransactionsTrees(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.toList shouldBe expectedTransactionsTrees
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.6 TransactionClient.getTransactionsTrees"
|
||||
|
||||
it should "pass start offset, end offset, transaction filter and verbose flag with the request" in {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
val begin = new data.LedgerOffset.Absolute("1")
|
||||
val end = new data.LedgerOffset.Absolute("2")
|
||||
|
||||
val transactionFilter = new data.FiltersByParty(
|
||||
Map[String, data.Filter](
|
||||
"Alice" -> data.InclusiveFilter.ofTemplateIds(
|
||||
Set(
|
||||
new data.Identifier("p1", "m1", "e1"),
|
||||
new data.Identifier("p2", "m2", "e2"),
|
||||
).asJava
|
||||
)
|
||||
).asJava
|
||||
)
|
||||
|
||||
transactionClient
|
||||
.getTransactionsTrees(begin, end, transactionFilter, true)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
val request = transactionService.lastTransactionsTreesRequest.get()
|
||||
request.begin shouldBe Some(LedgerOffset(Absolute("1")))
|
||||
request.end shouldBe Some(LedgerOffset(Absolute("2")))
|
||||
val filter = request.filter.get.filtersByParty
|
||||
filter.keySet shouldBe Set("Alice")
|
||||
filter("Alice").inclusive.get.templateFilters.toSet shouldBe Set(
|
||||
TemplateFilter(
|
||||
Some(Identifier("p1", moduleName = "m1", entityName = "e1")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
TemplateFilter(
|
||||
Some(Identifier("p2", moduleName = "m2", entityName = "e2")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
)
|
||||
request.verbose shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.7 TransactionClient.getTransactionsTrees"
|
||||
|
||||
it should "request stream with the correct ledger ID" in {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionsTrees(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionsTreesRequest
|
||||
.get()
|
||||
.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.9 TransactionClient.getTransactionByEventId"
|
||||
|
||||
it should "look up transaction by event ID" ignore forAll(ledgerContentWithEventIdGen) {
|
||||
case (ledgerContent, eventId, transactionTree) =>
|
||||
ledgerServices.withTransactionsClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionByEventId(eventId, Set.empty[String].asJava)
|
||||
.blockingGet() shouldBe transactionTree
|
||||
|
||||
transactionService.lastTransactionByEventIdRequest.get().eventId shouldBe eventId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.10 TransactionClient.getTransactionByEventId"
|
||||
|
||||
it should "pass the requesting parties with the request" ignore {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
val requestingParties = Set("Alice", "Bob")
|
||||
|
||||
transactionClient.getTransactionByEventId("eventId", requestingParties.asJava).blockingGet()
|
||||
|
||||
transactionService.lastTransactionByEventIdRequest
|
||||
.get()
|
||||
.requestingParties
|
||||
.toSet shouldBe requestingParties
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.11 TransactionClient.getTransactionByEventId"
|
||||
|
||||
it should "send the correct ledger ID with the request" ignore {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient.getTransactionByEventId("eventId", Set.empty[String].asJava).blockingGet()
|
||||
|
||||
transactionService.lastTransactionByEventIdRequest
|
||||
.get()
|
||||
.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.12 TransactionClient.getTransactionById"
|
||||
|
||||
it should "look up transaction by transaction ID" ignore forAll(
|
||||
ledgerContentWithTransactionIdGen
|
||||
) { case (ledgerContent, transactionId, transactionTree) =>
|
||||
ledgerServices.withTransactionsClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionById(transactionId, Set.empty[String].asJava)
|
||||
.blockingGet() shouldBe transactionTree
|
||||
|
||||
transactionService.lastTransactionByIdRequest.get().transactionId shouldBe transactionId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.13 TransactionClient.getTransactionById"
|
||||
|
||||
it should "pass the requesting parties with the request" ignore {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
val requestingParties = Set("Alice", "Bob")
|
||||
|
||||
transactionClient
|
||||
.getTransactionById("transactionId", requestingParties.asJava)
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionByIdRequest
|
||||
.get()
|
||||
.requestingParties
|
||||
.toSet shouldBe requestingParties
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.14 TransactionClient.getTransactionById"
|
||||
|
||||
it should "send the correct ledger ID with the request" ignore {
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionById("transactionId", Set.empty[String].asJava)
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionByIdRequest
|
||||
.get()
|
||||
.ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.15 TransactionClient.getLedgerEnd"
|
||||
|
||||
it should "provide ledger end from the ledger" in forAll(nonEmptyLedgerContent) {
|
||||
case (ledgerContent, transactions) =>
|
||||
ledgerServices.withTransactionsClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, _) =>
|
||||
val expectedOffset = new data.LedgerOffset.Absolute(transactions.last.getOffset)
|
||||
transactionClient.getLedgerEnd.blockingGet() shouldBe expectedOffset
|
||||
}
|
||||
}
|
||||
|
||||
it should "provide LEDGER_BEGIN from empty ledger" in
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) { (transactionClient, _) =>
|
||||
transactionClient.getLedgerEnd.blockingGet() shouldBe
|
||||
data.LedgerOffset.LedgerBegin.getInstance()
|
||||
}
|
||||
|
||||
behavior of "8.15 TransactionClient.getLedgerEnd"
|
||||
|
||||
it should "request ledger end with correct ledger ID" in
|
||||
ledgerServices.withTransactionsClient(Observable.empty()) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient.getLedgerEnd.blockingGet()
|
||||
transactionService.lastLedgerEndRequest.get().ledgerId shouldBe ledgerServices.ledgerId
|
||||
}
|
||||
|
||||
behavior of "Authentication"
|
||||
|
||||
def toAuthenticatedServer(fn: TransactionsClient => Any): Any =
|
||||
ledgerServices.withTransactionsClient(Observable.empty(), mockedAuthService) { (client, _) =>
|
||||
fn(client)
|
||||
}
|
||||
|
||||
it should "deny access without a token" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, ledgerEnd, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(ledgerBegin, ledgerEnd, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getTransactionByEventId("...", Set(someParty).asJava).blockingGet())
|
||||
}
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getTransactionById("...", Set(someParty).asJava).blockingGet())
|
||||
}
|
||||
}
|
||||
withClue("getFlatTransactionByEventId") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getFlatTransactionByEventId("...", Set(someParty).asJava).blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getFlatTransactionById") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getFlatTransactionById("...", Set(someParty).asJava).blockingGet())
|
||||
}
|
||||
}
|
||||
withClue("getLedgerEnd") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getLedgerEnd.blockingGet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "deny access with insufficient authorization" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
someOtherPartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false, someOtherPartyReadWriteToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
someOtherPartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionByEventId("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionById("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getFlatTransactionByEventId") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getFlatTransactionByEventId("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getFlatTransactionById") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getFlatTransactionById("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getLedgerEnd") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getLedgerEnd(emptyToken).blockingGet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "allow access with sufficient authorization" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
somePartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false, somePartyReadWriteToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
somePartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionByEventId("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionById("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getFlatTransactionByEventId") {
|
||||
toAuthenticatedServer(
|
||||
_.getFlatTransactionByEventId("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getFlatTransactionById") {
|
||||
toAuthenticatedServer(
|
||||
_.getFlatTransactionById("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getLedgerEnd") {
|
||||
toAuthenticatedServer(_.getLedgerEnd(publicToken).blockingGet())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,428 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.daml.ledger.javaapi.data
|
||||
import com.daml.ledger.rxjava._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionGenerator._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.{DataLayerHelpers, LedgerServices, TestConfiguration}
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset.Value.Absolute
|
||||
import com.daml.ledger.api.v1.transaction_filter.TemplateFilter
|
||||
import com.daml.ledger.api.v1.value.Identifier
|
||||
import io.reactivex.Observable
|
||||
import org.scalacheck.Shrink
|
||||
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
final class UpdateClientImplTest
|
||||
extends AnyFlatSpec
|
||||
with ScalaCheckDrivenPropertyChecks
|
||||
with Matchers
|
||||
with AuthMatchers
|
||||
with DataLayerHelpers {
|
||||
|
||||
override val ledgerServices = new LedgerServices("update-service-ledger")
|
||||
|
||||
implicit def tupleNoShrink[A, B]: Shrink[(A, B)] = Shrink.shrinkAny
|
||||
|
||||
private val ledgerBegin = data.ParticipantOffsetV2.ParticipantBegin.getInstance()
|
||||
private val ledgerEnd = data.ParticipantOffsetV2.ParticipantEnd.getInstance()
|
||||
private val emptyFilter = new data.FiltersByPartyV2(Map.empty[String, data.Filter].asJava)
|
||||
|
||||
behavior of "8.1 TransactionClient.getTransactions"
|
||||
|
||||
it should "return transactions from the ledger" in forAll(ledgerContentGen) {
|
||||
case (ledgerContent, expectedTransactions) =>
|
||||
ledgerServices.withUpdateClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, _) =>
|
||||
transactionClient
|
||||
.getTransactions(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.toList shouldBe expectedTransactions
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.2 TransactionClient.getTransactions"
|
||||
|
||||
it should "pass start offset, end offset, transaction filter and verbose flag with the request" in {
|
||||
ledgerServices.withUpdateClient(Observable.empty()) { (transactionClient, transactionService) =>
|
||||
val begin = new data.ParticipantOffsetV2.Absolute("1")
|
||||
val end = new data.ParticipantOffsetV2.Absolute("2")
|
||||
|
||||
val transactionFilter = new data.FiltersByPartyV2(
|
||||
Map[String, data.Filter](
|
||||
"Alice" -> data.InclusiveFilter.ofTemplateIds(
|
||||
Set(
|
||||
new data.Identifier("p1", "m1", "e1"),
|
||||
new data.Identifier("p2", "m2", "e2"),
|
||||
).asJava
|
||||
)
|
||||
).asJava
|
||||
)
|
||||
|
||||
transactionClient
|
||||
.getTransactions(begin, end, transactionFilter, true)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
val request = transactionService.lastUpdatesRequest.get()
|
||||
request.beginExclusive shouldBe Some(ParticipantOffset(Absolute("1")))
|
||||
request.endInclusive shouldBe Some(ParticipantOffset(Absolute("2")))
|
||||
val filter = request.filter.get.filtersByParty
|
||||
filter.keySet shouldBe Set("Alice")
|
||||
filter("Alice").inclusive.get.templateFilters.toSet shouldBe Set(
|
||||
TemplateFilter(
|
||||
Some(Identifier("p1", moduleName = "m1", entityName = "e1")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
TemplateFilter(
|
||||
Some(Identifier("p2", moduleName = "m2", entityName = "e2")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
)
|
||||
request.verbose shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.5 TransactionClient.getTransactionsTrees"
|
||||
|
||||
it should "return transaction trees from the ledger" ignore forAll(ledgerContentTreeGen) {
|
||||
case (ledgerContent, expectedTransactionsTrees) =>
|
||||
ledgerServices.withUpdateClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, _) =>
|
||||
transactionClient
|
||||
.getTransactionsTrees(ledgerBegin, ledgerEnd, emptyFilter, false)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.toList shouldBe expectedTransactionsTrees
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.6 TransactionClient.getTransactionsTrees"
|
||||
|
||||
it should "pass start offset, end offset, transaction filter and verbose flag with the request" in {
|
||||
ledgerServices.withUpdateClient(Observable.empty()) { (transactionClient, transactionService) =>
|
||||
val begin = new data.ParticipantOffsetV2.Absolute("1")
|
||||
val end = new data.ParticipantOffsetV2.Absolute("2")
|
||||
|
||||
val transactionFilter = new data.FiltersByPartyV2(
|
||||
Map[String, data.Filter](
|
||||
"Alice" -> data.InclusiveFilter.ofTemplateIds(
|
||||
Set(
|
||||
new data.Identifier("p1", "m1", "e1"),
|
||||
new data.Identifier("p2", "m2", "e2"),
|
||||
).asJava
|
||||
)
|
||||
).asJava
|
||||
)
|
||||
|
||||
transactionClient
|
||||
.getTransactionsTrees(begin, end, transactionFilter, true)
|
||||
.toList()
|
||||
.blockingGet()
|
||||
|
||||
val request = transactionService.lastUpdatesTreesRequest.get()
|
||||
request.beginExclusive shouldBe Some(ParticipantOffset(Absolute("1")))
|
||||
request.endInclusive shouldBe Some(ParticipantOffset(Absolute("2")))
|
||||
val filter = request.filter.get.filtersByParty
|
||||
filter.keySet shouldBe Set("Alice")
|
||||
filter("Alice").inclusive.get.templateFilters.toSet shouldBe Set(
|
||||
TemplateFilter(
|
||||
Some(Identifier("p1", moduleName = "m1", entityName = "e1")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
TemplateFilter(
|
||||
Some(Identifier("p2", moduleName = "m2", entityName = "e2")),
|
||||
includeCreatedEventBlob = false,
|
||||
),
|
||||
)
|
||||
request.verbose shouldBe true
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.9 TransactionClient.getTransactionTreeByEventId"
|
||||
|
||||
it should "look up transaction by event ID" ignore forAll(ledgerContentWithEventIdGen) {
|
||||
case (ledgerContent, eventId, transactionTree) =>
|
||||
ledgerServices.withUpdateClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionTreeByEventId(eventId, Set.empty[String].asJava)
|
||||
.blockingGet() shouldBe transactionTree
|
||||
|
||||
transactionService.lastTransactionTreeByEventIdRequest.get().eventId shouldBe eventId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.10 TransactionClient.getTransactionTreeByEventId"
|
||||
|
||||
it should "pass the requesting parties with the request" ignore {
|
||||
ledgerServices.withUpdateClient(Observable.empty()) { (transactionClient, transactionService) =>
|
||||
val requestingParties = Set("Alice", "Bob")
|
||||
|
||||
transactionClient
|
||||
.getTransactionTreeByEventId("eventId", requestingParties.asJava)
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionTreeByEventIdRequest
|
||||
.get()
|
||||
.requestingParties
|
||||
.toSet shouldBe requestingParties
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.12 TransactionClient.getTransactionTreeById"
|
||||
|
||||
it should "look up transaction by transaction ID" ignore forAll(
|
||||
ledgerContentWithTransactionIdGen
|
||||
) { case (ledgerContent, transactionId, transactionTree) =>
|
||||
ledgerServices.withUpdateClient(Observable.fromIterable(ledgerContent.asJava)) {
|
||||
(transactionClient, transactionService) =>
|
||||
transactionClient
|
||||
.getTransactionTreeById(transactionId, Set.empty[String].asJava)
|
||||
.blockingGet() shouldBe transactionTree
|
||||
|
||||
transactionService.lastTransactionTreeByIdRequest.get().updateId shouldBe transactionId
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "8.13 TransactionClient.getTransactionTreeById"
|
||||
|
||||
it should "pass the requesting parties with the request" ignore {
|
||||
ledgerServices.withUpdateClient(Observable.empty()) { (transactionClient, transactionService) =>
|
||||
val requestingParties = Set("Alice", "Bob")
|
||||
|
||||
transactionClient
|
||||
.getTransactionTreeById("transactionId", requestingParties.asJava)
|
||||
.blockingGet()
|
||||
|
||||
transactionService.lastTransactionTreeByIdRequest
|
||||
.get()
|
||||
.requestingParties
|
||||
.toSet shouldBe requestingParties
|
||||
}
|
||||
}
|
||||
|
||||
behavior of "Authentication"
|
||||
|
||||
def toAuthenticatedServer(fn: UpdateClient => Any): Any =
|
||||
ledgerServices.withUpdateClient(Observable.empty(), mockedAuthService) { (client, _) =>
|
||||
fn(client)
|
||||
}
|
||||
|
||||
it should "deny access without a token" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, ledgerEnd, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(ledgerBegin, ledgerEnd, filterFor(someParty), false)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionTreeByEventId") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionTreeByEventId("...", Set(someParty).asJava).blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionTreeById") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getTransactionTreeById("...", Set(someParty).asJava).blockingGet())
|
||||
}
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionByEventId("...", Set(someParty).asJava).blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
expectUnauthenticated {
|
||||
toAuthenticatedServer(_.getTransactionById("...", Set(someParty).asJava).blockingGet())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "deny access with insufficient authorization" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
someOtherPartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false, someOtherPartyReadWriteToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
someOtherPartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionTreeByEventId") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionTreeByEventId("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionTreeById") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionTreeById("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionByEventId("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
expectPermissionDenied {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionById("...", Set(someParty).asJava, someOtherPartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "allow access with sufficient authorization" in {
|
||||
withClue("getTransactions specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
somePartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactions without specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactions(ledgerBegin, filterFor(someParty), false, somePartyReadWriteToken)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactionsTree specifying end") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionsTrees(
|
||||
ledgerBegin,
|
||||
ledgerEnd,
|
||||
filterFor(someParty),
|
||||
false,
|
||||
somePartyReadWriteToken,
|
||||
)
|
||||
.timeout(TestConfiguration.timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.blockingIterable()
|
||||
.asScala
|
||||
.size
|
||||
)
|
||||
}
|
||||
withClue("getTransactionTreeByEventId") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionTreeByEventId("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getTransactionTreeById") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionTreeById("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getTransactionByEventId") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionByEventId("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
withClue("getTransactionById") {
|
||||
toAuthenticatedServer(
|
||||
_.getTransactionById("...", Set(someParty).asJava, somePartyReadWriteToken)
|
||||
.blockingGet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.ActiveContractsServiceAuthorization
|
||||
import com.daml.ledger.api.v1.active_contracts_service.ActiveContractsServiceGrpc.ActiveContractsService
|
||||
import com.daml.ledger.api.v1.active_contracts_service.{
|
||||
ActiveContractsServiceGrpc,
|
||||
GetActiveContractsRequest,
|
||||
GetActiveContractsResponse,
|
||||
}
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.{Observable, Observer}
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
final class ActiveContractsServiceImpl(
|
||||
getActiveContractsResponses: Observable[GetActiveContractsResponse]
|
||||
) extends ActiveContractsService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
private var lastRequest = Option.empty[GetActiveContractsRequest]
|
||||
|
||||
override def getActiveContracts(
|
||||
request: GetActiveContractsRequest,
|
||||
responseObserver: StreamObserver[GetActiveContractsResponse],
|
||||
): Unit = {
|
||||
lastRequest = Option(request)
|
||||
getActiveContractsResponses.subscribe(new Observer[GetActiveContractsResponse] {
|
||||
override def onSubscribe(d: Disposable): Unit = ()
|
||||
override def onNext(t: GetActiveContractsResponse): Unit = responseObserver.onNext(t)
|
||||
override def onError(e: Throwable): Unit = responseObserver.onError(e)
|
||||
override def onComplete(): Unit = responseObserver.onCompleted()
|
||||
})
|
||||
}
|
||||
|
||||
def getLastRequest: Option[GetActiveContractsRequest] = this.lastRequest
|
||||
}
|
||||
|
||||
object ActiveContractsServiceImpl {
|
||||
|
||||
/** Return the ServerServiceDefinition and the underlying ActiveContractsServiceImpl for inspection */
|
||||
def createWithRef(
|
||||
getActiveContractsResponses: Observable[GetActiveContractsResponse],
|
||||
authorizer: Authorizer,
|
||||
)(implicit ec: ExecutionContext): (ServerServiceDefinition, ActiveContractsServiceImpl) = {
|
||||
val impl = new ActiveContractsServiceImpl(getActiveContractsResponses)
|
||||
val authImpl = new ActiveContractsServiceAuthorization(impl, authorizer)
|
||||
(ActiveContractsServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
|
||||
}
|
@ -4,22 +4,20 @@
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandCompletionServiceAuthorization
|
||||
import com.daml.ledger.api.v1.command_completion_service.CommandCompletionServiceGrpc.CommandCompletionService
|
||||
import com.daml.ledger.api.v1.command_completion_service._
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandCompletionServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.command_completion_service.CommandCompletionServiceGrpc.CommandCompletionService
|
||||
import com.daml.ledger.api.v2.command_completion_service._
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.stub.StreamObserver
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
final class CommandCompletionServiceImpl(
|
||||
completions: List[CompletionStreamResponse],
|
||||
end: CompletionEndResponse,
|
||||
completions: List[CompletionStreamResponse]
|
||||
) extends CommandCompletionService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
private var lastCompletionStreamRequest: Option[CompletionStreamRequest] = None
|
||||
private var lastCompletionEndRequest: Option[CompletionEndRequest] = None
|
||||
|
||||
override def completionStream(
|
||||
request: CompletionStreamRequest,
|
||||
@ -29,24 +27,17 @@ final class CommandCompletionServiceImpl(
|
||||
completions.foreach(responseObserver.onNext)
|
||||
}
|
||||
|
||||
override def completionEnd(request: CompletionEndRequest): Future[CompletionEndResponse] = {
|
||||
this.lastCompletionEndRequest = Some(request)
|
||||
Future.successful(end)
|
||||
}
|
||||
|
||||
def getLastCompletionStreamRequest: Option[CompletionStreamRequest] =
|
||||
this.lastCompletionStreamRequest
|
||||
def getLastCompletionEndRequest: Option[CompletionEndRequest] = this.lastCompletionEndRequest
|
||||
}
|
||||
|
||||
object CommandCompletionServiceImpl {
|
||||
def createWithRef(
|
||||
completions: List[CompletionStreamResponse],
|
||||
end: CompletionEndResponse,
|
||||
authorizer: Authorizer,
|
||||
)(implicit ec: ExecutionContext): (ServerServiceDefinition, CommandCompletionServiceImpl) = {
|
||||
val impl = new CommandCompletionServiceImpl(completions, end)
|
||||
val authImpl = new CommandCompletionServiceAuthorization(impl, authorizer)
|
||||
val impl = new CommandCompletionServiceImpl(completions)
|
||||
val authImpl = new CommandCompletionServiceV2Authorization(impl, authorizer)
|
||||
(CommandCompletionServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandServiceAuthorization
|
||||
import com.daml.ledger.api.v1.command_service.CommandServiceGrpc.CommandService
|
||||
import com.daml.ledger.api.v1.command_service._
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.command_service.CommandServiceGrpc.CommandService
|
||||
import com.daml.ledger.api.v2.command_service._
|
||||
import com.google.protobuf.empty.Empty
|
||||
import io.grpc.ServerServiceDefinition
|
||||
|
||||
@ -14,7 +14,7 @@ import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class CommandServiceImpl(
|
||||
submitAndWaitResponse: Future[Empty],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForTransactionIdResponse],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForUpdateIdResponse],
|
||||
submitAndWaitForTransactionResponse: Future[SubmitAndWaitForTransactionResponse],
|
||||
submitAndWaitForTransactionTreeResponse: Future[SubmitAndWaitForTransactionTreeResponse],
|
||||
) extends CommandService
|
||||
@ -27,9 +27,9 @@ final class CommandServiceImpl(
|
||||
submitAndWaitResponse
|
||||
}
|
||||
|
||||
override def submitAndWaitForTransactionId(
|
||||
override def submitAndWaitForUpdateId(
|
||||
request: SubmitAndWaitRequest
|
||||
): Future[SubmitAndWaitForTransactionIdResponse] = {
|
||||
): Future[SubmitAndWaitForUpdateIdResponse] = {
|
||||
this.lastRequest = Some(request)
|
||||
submitAndWaitForTransactionIdResponse
|
||||
}
|
||||
@ -55,7 +55,7 @@ object CommandServiceImpl {
|
||||
|
||||
def createWithRef(
|
||||
submitAndWaitResponse: Future[Empty],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForTransactionIdResponse],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForUpdateIdResponse],
|
||||
submitAndWaitForTransactionResponse: Future[SubmitAndWaitForTransactionResponse],
|
||||
submitAndWaitForTransactionTreeResponse: Future[SubmitAndWaitForTransactionTreeResponse],
|
||||
authorizer: Authorizer,
|
||||
@ -66,7 +66,7 @@ object CommandServiceImpl {
|
||||
submitAndWaitForTransactionResponse,
|
||||
submitAndWaitForTransactionTreeResponse,
|
||||
)
|
||||
val authImpl = new CommandServiceAuthorization(impl, authorizer)
|
||||
val authImpl = new CommandServiceV2Authorization(impl, authorizer)
|
||||
(CommandServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -4,38 +4,44 @@
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandSubmissionServiceAuthorization
|
||||
import com.daml.ledger.api.v1.command_submission_service.CommandSubmissionServiceGrpc.CommandSubmissionService
|
||||
import com.daml.ledger.api.v1.command_submission_service.{
|
||||
import com.digitalasset.canton.ledger.api.auth.services.CommandSubmissionServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.command_submission_service.CommandSubmissionServiceGrpc.CommandSubmissionService
|
||||
import com.daml.ledger.api.v2.command_submission_service.{
|
||||
CommandSubmissionServiceGrpc,
|
||||
SubmitReassignmentRequest,
|
||||
SubmitReassignmentResponse,
|
||||
SubmitRequest,
|
||||
SubmitResponse,
|
||||
}
|
||||
import com.google.protobuf.empty.Empty
|
||||
import io.grpc.ServerServiceDefinition
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class CommandSubmissionServiceImpl(getResponse: () => Future[Empty])
|
||||
final class CommandSubmissionServiceImpl(getResponse: () => Future[SubmitResponse])
|
||||
extends CommandSubmissionService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
@volatile private var submittedRequest: Option[SubmitRequest] = None
|
||||
|
||||
override def submit(request: SubmitRequest): Future[Empty] = {
|
||||
override def submit(request: SubmitRequest): Future[SubmitResponse] = {
|
||||
this.submittedRequest = Some(request)
|
||||
getResponse()
|
||||
}
|
||||
|
||||
def getSubmittedRequest: Option[SubmitRequest] = submittedRequest
|
||||
|
||||
override def submitReassignment(
|
||||
request: SubmitReassignmentRequest
|
||||
): Future[SubmitReassignmentResponse] = Future.failed(new UnsupportedOperationException())
|
||||
}
|
||||
|
||||
object CommandSubmissionServiceImpl {
|
||||
|
||||
def createWithRef(getResponse: () => Future[Empty], authorizer: Authorizer)(implicit
|
||||
def createWithRef(getResponse: () => Future[SubmitResponse], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, CommandSubmissionServiceImpl) = {
|
||||
val impl = new CommandSubmissionServiceImpl(getResponse)
|
||||
val authImpl = new CommandSubmissionServiceAuthorization(impl, authorizer)
|
||||
val authImpl = new CommandSubmissionServiceV2Authorization(impl, authorizer)
|
||||
(CommandSubmissionServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,9 @@ package com.daml.ledger.rxjava.grpc.helpers
|
||||
import java.util.Optional
|
||||
|
||||
import com.daml.ledger.javaapi.data._
|
||||
import com.daml.ledger.api.v1.active_contracts_service.GetActiveContractsResponse
|
||||
import com.daml.ledger.api.v1.command_completion_service.CompletionEndResponse
|
||||
import com.daml.ledger.api.v1.event.CreatedEvent
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset.Value.Absolute
|
||||
import com.daml.ledger.api.v1.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.state_service.{ActiveContract, GetActiveContractsResponse}
|
||||
import com.daml.ledger.api.v2.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.state_service.GetActiveContractsResponse.ContractEntry
|
||||
import com.google.protobuf.timestamp.Timestamp
|
||||
|
||||
import scala.jdk.CollectionConverters._
|
||||
@ -24,7 +21,13 @@ trait DataLayerHelpers {
|
||||
new GetActiveContractsResponse(
|
||||
"",
|
||||
"workflowId",
|
||||
Seq[CreatedEvent](),
|
||||
ContractEntry.ActiveContract(
|
||||
new ActiveContract(
|
||||
createdEvent = TransactionGenerator.createdEventGen.sample.map(_._1.value),
|
||||
domainId = "someDomain",
|
||||
reassignmentCounter = 0,
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@ -44,16 +47,11 @@ trait DataLayerHelpers {
|
||||
commands.asJava,
|
||||
)
|
||||
}
|
||||
def genLedgerOffset(absVal: String): LedgerOffset =
|
||||
new LedgerOffset(Absolute(absVal))
|
||||
|
||||
def genCompletionEndResponse(absVal: String): CompletionEndResponse =
|
||||
new CompletionEndResponse(Some(genLedgerOffset(absVal)))
|
||||
val filterNothing: FiltersByPartyV2 = new FiltersByPartyV2(Map[String, Filter]().asJava)
|
||||
|
||||
val filterNothing: FiltersByParty = new FiltersByParty(Map[String, Filter]().asJava)
|
||||
|
||||
def filterFor(party: String): FiltersByParty =
|
||||
new FiltersByParty(
|
||||
def filterFor(party: String): FiltersByPartyV2 =
|
||||
new FiltersByPartyV2(
|
||||
Map(party -> (InclusiveFilter.ofTemplateIds(Set.empty[Identifier].asJava): Filter)).asJava
|
||||
)
|
||||
}
|
||||
|
@ -3,22 +3,24 @@
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.daml.ledger.api.v1.event_query_service.GetEventsByContractIdRequest
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.EventQueryServiceAuthorization
|
||||
import com.daml.ledger.api.v1.event_query_service.EventQueryServiceGrpc.EventQueryService
|
||||
import com.daml.ledger.api.v1.event_query_service._
|
||||
import com.digitalasset.canton.ledger.api.auth.services.EventQueryServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.event_query_service.EventQueryServiceGrpc.EventQueryService
|
||||
import com.daml.ledger.api.v2.event_query_service.{
|
||||
EventQueryServiceGrpc,
|
||||
GetEventsByContractIdResponse,
|
||||
}
|
||||
import io.grpc.ServerServiceDefinition
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class EventQueryServiceImpl(
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse],
|
||||
getEventsByContractKeyResponse: Future[GetEventsByContractKeyResponse],
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse]
|
||||
) extends EventQueryService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
private var lastGetEventsByContractIdRequest: Option[GetEventsByContractIdRequest] = None
|
||||
private var lastGetEventsByContractKeyRequest: Option[GetEventsByContractKeyRequest] = None
|
||||
|
||||
override def getEventsByContractId(
|
||||
request: GetEventsByContractIdRequest
|
||||
@ -27,28 +29,18 @@ final class EventQueryServiceImpl(
|
||||
getEventsByContractIdResponse
|
||||
}
|
||||
|
||||
override def getEventsByContractKey(
|
||||
request: GetEventsByContractKeyRequest
|
||||
): Future[GetEventsByContractKeyResponse] = {
|
||||
this.lastGetEventsByContractKeyRequest = Some(request)
|
||||
getEventsByContractKeyResponse
|
||||
}
|
||||
|
||||
def getLastGetEventsByContractIdRequest: Option[GetEventsByContractIdRequest] =
|
||||
this.lastGetEventsByContractIdRequest
|
||||
def getLastGetEventsByContractKeyRequest: Option[GetEventsByContractKeyRequest] =
|
||||
this.lastGetEventsByContractKeyRequest
|
||||
}
|
||||
|
||||
object EventQueryServiceImpl {
|
||||
def createWithRef(
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse],
|
||||
getEventsByContractKeyResponse: Future[GetEventsByContractKeyResponse],
|
||||
authorizer: Authorizer,
|
||||
)(implicit ec: ExecutionContext): (ServerServiceDefinition, EventQueryServiceImpl) = {
|
||||
val impl =
|
||||
new EventQueryServiceImpl(getEventsByContractIdResponse, getEventsByContractKeyResponse)
|
||||
val authImpl = new EventQueryServiceAuthorization(impl, authorizer)
|
||||
new EventQueryServiceImpl(getEventsByContractIdResponse)
|
||||
val authImpl = new EventQueryServiceV2Authorization(impl, authorizer)
|
||||
(EventQueryServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.LedgerConfigurationServiceAuthorization
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.LedgerConfigurationServiceGrpc.LedgerConfigurationService
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.{
|
||||
GetLedgerConfigurationRequest,
|
||||
GetLedgerConfigurationResponse,
|
||||
LedgerConfigurationServiceGrpc,
|
||||
}
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.stub.StreamObserver
|
||||
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
class LedgerConfigurationServiceImpl(responses: Seq[GetLedgerConfigurationResponse])
|
||||
extends LedgerConfigurationService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
private var lastRequest: Option[GetLedgerConfigurationRequest] = None
|
||||
|
||||
override def getLedgerConfiguration(
|
||||
request: GetLedgerConfigurationRequest,
|
||||
responseObserver: StreamObserver[GetLedgerConfigurationResponse],
|
||||
): Unit = {
|
||||
this.lastRequest = Some(request)
|
||||
responses.foreach(responseObserver.onNext)
|
||||
}
|
||||
|
||||
def getLastRequest: Option[GetLedgerConfigurationRequest] = this.lastRequest
|
||||
}
|
||||
|
||||
object LedgerConfigurationServiceImpl {
|
||||
def createWithRef(responses: Seq[GetLedgerConfigurationResponse], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, LedgerConfigurationServiceImpl) = {
|
||||
val impl = new LedgerConfigurationServiceImpl(responses)
|
||||
val authImpl = new LedgerConfigurationServiceAuthorization(impl, authorizer)
|
||||
(LedgerConfigurationServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.LedgerIdentityServiceAuthorization
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.LedgerIdentityServiceGrpc.LedgerIdentityService
|
||||
import com.daml.ledger.api.v1.ledger_identity_service.{
|
||||
GetLedgerIdentityRequest,
|
||||
GetLedgerIdentityResponse,
|
||||
LedgerIdentityServiceGrpc,
|
||||
}
|
||||
import io.grpc.ServerServiceDefinition
|
||||
|
||||
import scala.annotation.nowarn
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class LedgerIdentityServiceImpl private (getResponse: () => Future[String])(implicit
|
||||
ec: ExecutionContext
|
||||
) extends LedgerIdentityService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
@nowarn("cat=deprecation&origin=com\\.daml\\.ledger\\.api\\.v1\\.ledger_identity_service\\..*")
|
||||
override def getLedgerIdentity(
|
||||
request: GetLedgerIdentityRequest
|
||||
): Future[GetLedgerIdentityResponse] = {
|
||||
getResponse().map(ledgerId => GetLedgerIdentityResponse(ledgerId))
|
||||
}
|
||||
}
|
||||
|
||||
object LedgerIdentityServiceImpl {
|
||||
|
||||
def createWithRef(getResponse: () => Future[String], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, LedgerIdentityServiceImpl) = {
|
||||
val impl = new LedgerIdentityServiceImpl(
|
||||
getResponse
|
||||
)
|
||||
val authImpl = new LedgerIdentityServiceAuthorization(impl, authorizer)
|
||||
(LedgerIdentityServiceGrpc.bindService(authImpl, ec), impl): @nowarn(
|
||||
"cat=deprecation&origin=com\\.daml\\.ledger\\.api\\.v1\\.ledger_identity_service\\..*"
|
||||
)
|
||||
}
|
||||
}
|
@ -9,13 +9,8 @@ import java.util.concurrent.TimeUnit
|
||||
|
||||
import org.apache.pekko.actor.ActorSystem
|
||||
import com.daml.ledger.rxjava.grpc._
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionsServiceImpl.LedgerItem
|
||||
import com.daml.ledger.rxjava.{
|
||||
CommandCompletionClient,
|
||||
EventQueryClient,
|
||||
LedgerConfigurationClient,
|
||||
PackageClient,
|
||||
}
|
||||
import com.daml.ledger.rxjava.grpc.helpers.UpdateServiceImpl.LedgerItem
|
||||
import com.daml.ledger.rxjava.{CommandCompletionClient, EventQueryClient, PackageClient}
|
||||
import com.daml.grpc.adapter.{ExecutionSequencerFactory, SingleThreadExecutionSequencerPool}
|
||||
import com.digitalasset.canton.ledger.api.auth.interceptor.{
|
||||
AuthorizationInterceptor,
|
||||
@ -27,27 +22,21 @@ import com.digitalasset.canton.ledger.api.auth.{
|
||||
Authorizer,
|
||||
ClaimSet,
|
||||
}
|
||||
import com.daml.ledger.api.v1.active_contracts_service.GetActiveContractsResponse
|
||||
import com.daml.ledger.api.v1.command_completion_service.{
|
||||
CompletionEndResponse,
|
||||
CompletionStreamResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.command_service.{
|
||||
SubmitAndWaitForTransactionIdResponse,
|
||||
import com.daml.ledger.api.v2.state_service.GetActiveContractsResponse
|
||||
import com.daml.ledger.api.v2.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v2.command_service.{
|
||||
SubmitAndWaitForTransactionResponse,
|
||||
SubmitAndWaitForTransactionTreeResponse,
|
||||
SubmitAndWaitForUpdateIdResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.event_query_service.{
|
||||
GetEventsByContractIdResponse,
|
||||
GetEventsByContractKeyResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.GetLedgerConfigurationResponse
|
||||
import com.daml.ledger.api.v2.event_query_service.GetEventsByContractIdResponse
|
||||
import com.daml.ledger.api.v1.package_service.{
|
||||
GetPackageResponse,
|
||||
GetPackageStatusResponse,
|
||||
ListPackagesResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.command_submission_service.SubmitResponse
|
||||
import com.daml.tracing.NoOpTelemetry
|
||||
import com.digitalasset.canton.logging.{LoggingContextWithTrace, NamedLoggerFactory}
|
||||
import com.digitalasset.canton.ledger.localstore.InMemoryUserManagementStore
|
||||
@ -59,19 +48,19 @@ import io.reactivex.Observable
|
||||
import scala.concurrent.ExecutionContext.global
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class LedgerServices(val ledgerId: String) {
|
||||
final class LedgerServices(val name: String) {
|
||||
|
||||
import LedgerServices._
|
||||
|
||||
val executionContext: ExecutionContext = global
|
||||
private val esf: ExecutionSequencerFactory = new SingleThreadExecutionSequencerPool(ledgerId)
|
||||
private val esf: ExecutionSequencerFactory = new SingleThreadExecutionSequencerPool(name)
|
||||
private val pekkoSystem = ActorSystem("LedgerServicesParticipant")
|
||||
private val participantId = "LedgerServicesParticipant"
|
||||
private val loggerFactory = NamedLoggerFactory.root
|
||||
val authorizer: Authorizer =
|
||||
new Authorizer(
|
||||
now = () => Clock.systemUTC().instant(),
|
||||
ledgerId = ledgerId,
|
||||
ledgerId = name,
|
||||
participantId = participantId,
|
||||
userManagementStore = new InMemoryUserManagementStore(createAdmin = false, loggerFactory),
|
||||
ec = executionContext,
|
||||
@ -149,15 +138,16 @@ final class LedgerServices(val ledgerId: String) {
|
||||
|
||||
def withACSClient(
|
||||
getActiveContractsResponses: Observable[GetActiveContractsResponse],
|
||||
ledgerContent: Observable[LedgerItem],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: (ActiveContractClientImpl, ActiveContractsServiceImpl) => Any): Any = {
|
||||
)(f: (StateClientImpl, StateServiceImpl) => Any): Any = {
|
||||
val (service, serviceImpl) =
|
||||
ActiveContractsServiceImpl.createWithRef(getActiveContractsResponses, authorizer)(
|
||||
StateServiceImpl.createWithRef(getActiveContractsResponses, ledgerContent, authorizer)(
|
||||
executionContext
|
||||
)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new ActiveContractClientImpl(ledgerId, channel, esf, accessToken), serviceImpl)
|
||||
f(new StateClientImpl(channel, esf, accessToken), serviceImpl)
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,11 +157,11 @@ final class LedgerServices(val ledgerId: String) {
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: TimeClientImpl => Any): Any =
|
||||
withServerAndChannel(authService, services) { channel =>
|
||||
f(new TimeClientImpl(ledgerId, channel, esf, accessToken))
|
||||
f(new TimeClientImpl(channel, esf, accessToken))
|
||||
}
|
||||
|
||||
def withCommandSubmissionClient(
|
||||
getResponse: () => Future[Empty],
|
||||
getResponse: () => Future[SubmitResponse],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
timeout: java.util.Optional[Duration] = java.util.Optional.empty[Duration],
|
||||
@ -179,33 +169,30 @@ final class LedgerServices(val ledgerId: String) {
|
||||
val (service, serviceImpl) =
|
||||
CommandSubmissionServiceImpl.createWithRef(getResponse, authorizer)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new CommandSubmissionClientImpl(ledgerId, channel, accessToken, timeout), serviceImpl)
|
||||
f(new CommandSubmissionClientImpl(channel, accessToken, timeout), serviceImpl)
|
||||
}
|
||||
}
|
||||
|
||||
def withCommandCompletionClient(
|
||||
completions: List[CompletionStreamResponse],
|
||||
end: CompletionEndResponse,
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: (CommandCompletionClient, CommandCompletionServiceImpl) => Any): Any = {
|
||||
val (service, impl) =
|
||||
CommandCompletionServiceImpl.createWithRef(completions, end, authorizer)(executionContext)
|
||||
CommandCompletionServiceImpl.createWithRef(completions, authorizer)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new CommandCompletionClientImpl(ledgerId, channel, esf, accessToken), impl)
|
||||
f(new CommandCompletionClientImpl(channel, esf, accessToken), impl)
|
||||
}
|
||||
}
|
||||
|
||||
def withEventQueryClient(
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse],
|
||||
getEventsByContractKeyResponse: Future[GetEventsByContractKeyResponse],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: (EventQueryClient, EventQueryServiceImpl) => Any): Any = {
|
||||
val (service, impl) =
|
||||
EventQueryServiceImpl.createWithRef(
|
||||
getEventsByContractIdResponse,
|
||||
getEventsByContractKeyResponse,
|
||||
authorizer,
|
||||
)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
@ -228,13 +215,13 @@ final class LedgerServices(val ledgerId: String) {
|
||||
authorizer,
|
||||
)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new PackageClientImpl(ledgerId, channel, accessToken), impl)
|
||||
f(new PackageClientImpl(channel, accessToken), impl)
|
||||
}
|
||||
}
|
||||
|
||||
def withCommandClient(
|
||||
submitAndWaitResponse: Future[Empty],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForTransactionIdResponse],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForUpdateIdResponse],
|
||||
submitAndWaitForTransactionResponse: Future[SubmitAndWaitForTransactionResponse],
|
||||
submitAndWaitForTransactionTreeResponse: Future[SubmitAndWaitForTransactionTreeResponse],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
@ -248,45 +235,19 @@ final class LedgerServices(val ledgerId: String) {
|
||||
authorizer,
|
||||
)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new CommandClientImpl(ledgerId, channel, accessToken), serviceImpl)
|
||||
f(new CommandClientImpl(channel, accessToken), serviceImpl)
|
||||
}
|
||||
}
|
||||
|
||||
def withConfigurationClient(
|
||||
responses: Seq[GetLedgerConfigurationResponse],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: (LedgerConfigurationClient, LedgerConfigurationServiceImpl) => Any): Any = {
|
||||
val (service, impl) =
|
||||
LedgerConfigurationServiceImpl.createWithRef(responses, authorizer)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new LedgerConfigurationClientImpl(ledgerId, channel, esf, accessToken), impl)
|
||||
}
|
||||
}
|
||||
|
||||
@deprecated("ledger identity service", since = "2.0.0")
|
||||
def withLedgerIdentityClient(
|
||||
getResponse: () => Future[String],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
timeout: java.util.Optional[Duration] = java.util.Optional.empty[Duration],
|
||||
)(f: (LedgerIdentityClientImpl, LedgerIdentityServiceImpl) => Any): Any = {
|
||||
val (service, serviceImpl) =
|
||||
LedgerIdentityServiceImpl.createWithRef(getResponse, authorizer)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new LedgerIdentityClientImpl(channel, accessToken, timeout), serviceImpl)
|
||||
}
|
||||
}
|
||||
|
||||
def withTransactionsClient(
|
||||
def withUpdateClient(
|
||||
ledgerContent: Observable[LedgerItem],
|
||||
authService: AuthService = AuthServiceWildcard,
|
||||
accessToken: java.util.Optional[String] = java.util.Optional.empty[String],
|
||||
)(f: (TransactionClientImpl, TransactionsServiceImpl) => Any): Any = {
|
||||
)(f: (UpdateClientImpl, UpdateServiceImpl) => Any): Any = {
|
||||
val (service, serviceImpl) =
|
||||
TransactionsServiceImpl.createWithRef(ledgerContent, authorizer)(executionContext)
|
||||
UpdateServiceImpl.createWithRef(ledgerContent, authorizer)(executionContext)
|
||||
withServerAndChannel(authService, Seq(service)) { channel =>
|
||||
f(new TransactionClientImpl(ledgerId, channel, esf, accessToken), serviceImpl)
|
||||
f(new UpdateClientImpl(channel, esf, accessToken), serviceImpl)
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,37 +265,30 @@ final class LedgerServices(val ledgerId: String) {
|
||||
def withFakeLedgerServer(
|
||||
getActiveContractsResponse: Observable[GetActiveContractsResponse],
|
||||
transactions: Observable[LedgerItem],
|
||||
commandSubmissionResponse: Future[Empty],
|
||||
commandSubmissionResponse: Future[SubmitResponse],
|
||||
completions: List[CompletionStreamResponse],
|
||||
completionsEnd: CompletionEndResponse,
|
||||
submitAndWaitResponse: Future[Empty],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForTransactionIdResponse],
|
||||
submitAndWaitForUpdateIdResponse: Future[SubmitAndWaitForUpdateIdResponse],
|
||||
submitAndWaitForTransactionResponse: Future[SubmitAndWaitForTransactionResponse],
|
||||
submitAndWaitForTransactionTreeResponse: Future[SubmitAndWaitForTransactionTreeResponse],
|
||||
getTimeResponses: List[GetTimeResponse],
|
||||
getLedgerConfigurationResponses: Seq[GetLedgerConfigurationResponse],
|
||||
getTimeResponse: Future[GetTimeResponse],
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse],
|
||||
getEventsByContractKeyResponse: Future[GetEventsByContractKeyResponse],
|
||||
listPackagesResponse: Future[ListPackagesResponse],
|
||||
getPackageResponse: Future[GetPackageResponse],
|
||||
getPackageStatusResponse: Future[GetPackageStatusResponse],
|
||||
authService: AuthService,
|
||||
)(f: (Server, LedgerServicesImpls) => Any): Any = {
|
||||
val (services, impls) = LedgerServicesImpls.createWithRef(
|
||||
Future.successful(ledgerId),
|
||||
getActiveContractsResponse,
|
||||
transactions,
|
||||
commandSubmissionResponse,
|
||||
completions,
|
||||
completionsEnd,
|
||||
submitAndWaitResponse,
|
||||
submitAndWaitForTransactionIdResponse,
|
||||
submitAndWaitForUpdateIdResponse,
|
||||
submitAndWaitForTransactionResponse,
|
||||
submitAndWaitForTransactionTreeResponse,
|
||||
getTimeResponses,
|
||||
getLedgerConfigurationResponses,
|
||||
getTimeResponse,
|
||||
getEventsByContractIdResponse,
|
||||
getEventsByContractKeyResponse,
|
||||
listPackagesResponse,
|
||||
getPackageResponse,
|
||||
getPackageStatusResponse,
|
||||
|
@ -4,27 +4,21 @@
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.daml.ledger.api.v1.active_contracts_service.GetActiveContractsResponse
|
||||
import com.daml.ledger.api.v1.command_completion_service.{
|
||||
CompletionEndResponse,
|
||||
CompletionStreamResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.command_service.{
|
||||
SubmitAndWaitForTransactionIdResponse,
|
||||
import com.daml.ledger.api.v2.state_service.GetActiveContractsResponse
|
||||
import com.daml.ledger.api.v2.command_completion_service.CompletionStreamResponse
|
||||
import com.daml.ledger.api.v2.command_service.{
|
||||
SubmitAndWaitForTransactionResponse,
|
||||
SubmitAndWaitForTransactionTreeResponse,
|
||||
SubmitAndWaitForUpdateIdResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.event_query_service.{
|
||||
GetEventsByContractIdResponse,
|
||||
GetEventsByContractKeyResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.ledger_configuration_service.GetLedgerConfigurationResponse
|
||||
import com.daml.ledger.api.v2.event_query_service.GetEventsByContractIdResponse
|
||||
import com.daml.ledger.api.v1.package_service.{
|
||||
GetPackageResponse,
|
||||
GetPackageStatusResponse,
|
||||
ListPackagesResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v1.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.testing.time_service.GetTimeResponse
|
||||
import com.daml.ledger.api.v2.command_submission_service.SubmitResponse
|
||||
import com.google.protobuf.empty.Empty
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.reactivex.Observable
|
||||
@ -32,13 +26,11 @@ import io.reactivex.Observable
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
case class LedgerServicesImpls(
|
||||
ledgerIdentityServiceImpl: LedgerIdentityServiceImpl,
|
||||
activeContractsServiceImpl: ActiveContractsServiceImpl,
|
||||
transactionServiceImpl: TransactionsServiceImpl,
|
||||
stateServiceImpl: StateServiceImpl,
|
||||
transactionServiceImpl: UpdateServiceImpl,
|
||||
commandSubmissionServiceImpl: CommandSubmissionServiceImpl,
|
||||
commandCompletionServiceImpl: CommandCompletionServiceImpl,
|
||||
commandServiceImpl: CommandServiceImpl,
|
||||
ledgerConfigurationServiceImpl: LedgerConfigurationServiceImpl,
|
||||
timeServiceImpl: TimeServiceImpl,
|
||||
eventQueryServiceImpl: EventQueryServiceImpl,
|
||||
packageServiceImpl: PackageServiceImpl,
|
||||
@ -47,50 +39,41 @@ case class LedgerServicesImpls(
|
||||
object LedgerServicesImpls {
|
||||
|
||||
def createWithRef(
|
||||
ledgerIdResponse: Future[String],
|
||||
getActiveContractsResponse: Observable[GetActiveContractsResponse],
|
||||
transactions: Observable[TransactionsServiceImpl.LedgerItem],
|
||||
commandSubmissionResponse: Future[Empty],
|
||||
transactions: Observable[UpdateServiceImpl.LedgerItem],
|
||||
commandSubmissionResponse: Future[SubmitResponse],
|
||||
completions: List[CompletionStreamResponse],
|
||||
completionsEnd: CompletionEndResponse,
|
||||
submitAndWaitResponse: Future[Empty],
|
||||
submitAndWaitForTransactionIdResponse: Future[SubmitAndWaitForTransactionIdResponse],
|
||||
submitAndWaitForUpdateIdResponse: Future[SubmitAndWaitForUpdateIdResponse],
|
||||
submitAndWaitForTransactionResponse: Future[SubmitAndWaitForTransactionResponse],
|
||||
submitAndWaitForTransactionTreeResponse: Future[SubmitAndWaitForTransactionTreeResponse],
|
||||
getTimeResponses: List[GetTimeResponse],
|
||||
getLedgerConfigurationResponses: Seq[GetLedgerConfigurationResponse],
|
||||
getTimeResponse: Future[GetTimeResponse],
|
||||
getEventsByContractIdResponse: Future[GetEventsByContractIdResponse],
|
||||
getEventsByContractKeyResponse: Future[GetEventsByContractKeyResponse],
|
||||
listPackagesResponse: Future[ListPackagesResponse],
|
||||
getPackageResponse: Future[GetPackageResponse],
|
||||
getPackageStatusResponse: Future[GetPackageStatusResponse],
|
||||
authorizer: Authorizer,
|
||||
)(implicit ec: ExecutionContext): (Seq[ServerServiceDefinition], LedgerServicesImpls) = {
|
||||
val (iServiceDef, iService) =
|
||||
LedgerIdentityServiceImpl.createWithRef(() => ledgerIdResponse, authorizer)(ec)
|
||||
val (acsServiceDef, acsService) =
|
||||
ActiveContractsServiceImpl.createWithRef(getActiveContractsResponse, authorizer)(ec)
|
||||
val (stateServiceDef, stateService) =
|
||||
StateServiceImpl.createWithRef(getActiveContractsResponse, transactions, authorizer)(ec)
|
||||
val (tsServiceDef, tsService) =
|
||||
TransactionsServiceImpl.createWithRef(transactions, authorizer)(ec)
|
||||
UpdateServiceImpl.createWithRef(transactions, authorizer)(ec)
|
||||
val (csServiceDef, csService) =
|
||||
CommandSubmissionServiceImpl.createWithRef(() => commandSubmissionResponse, authorizer)(ec)
|
||||
val (ccServiceDef, ccService) =
|
||||
CommandCompletionServiceImpl.createWithRef(completions, completionsEnd, authorizer)(ec)
|
||||
CommandCompletionServiceImpl.createWithRef(completions, authorizer)(ec)
|
||||
val (cServiceDef, cService) = CommandServiceImpl.createWithRef(
|
||||
submitAndWaitResponse,
|
||||
submitAndWaitForTransactionIdResponse,
|
||||
submitAndWaitForUpdateIdResponse,
|
||||
submitAndWaitForTransactionResponse,
|
||||
submitAndWaitForTransactionTreeResponse,
|
||||
authorizer,
|
||||
)(ec)
|
||||
val (lcServiceDef, lcService) =
|
||||
LedgerConfigurationServiceImpl.createWithRef(getLedgerConfigurationResponses, authorizer)(ec)
|
||||
val (timeServiceDef, timeService) =
|
||||
TimeServiceImpl.createWithRef(getTimeResponses, authorizer)(ec)
|
||||
TimeServiceImpl.createWithRef(getTimeResponse, authorizer)(ec)
|
||||
val (eventQueryServiceDef, eventQueryService) =
|
||||
EventQueryServiceImpl.createWithRef(
|
||||
getEventsByContractIdResponse,
|
||||
getEventsByContractKeyResponse,
|
||||
authorizer,
|
||||
)(ec)
|
||||
val (packageServiceDef, packageService) =
|
||||
@ -102,25 +85,21 @@ object LedgerServicesImpls {
|
||||
)(ec)
|
||||
|
||||
val services = Seq(
|
||||
iServiceDef,
|
||||
acsServiceDef,
|
||||
stateServiceDef,
|
||||
tsServiceDef,
|
||||
csServiceDef,
|
||||
ccServiceDef,
|
||||
cServiceDef,
|
||||
lcServiceDef,
|
||||
timeServiceDef,
|
||||
eventQueryServiceDef,
|
||||
packageServiceDef,
|
||||
)
|
||||
val impls = new LedgerServicesImpls(
|
||||
iService,
|
||||
acsService,
|
||||
stateService,
|
||||
tsService,
|
||||
csService,
|
||||
ccService,
|
||||
cService,
|
||||
lcService,
|
||||
timeService,
|
||||
eventQueryService,
|
||||
packageService,
|
||||
|
@ -3,10 +3,20 @@
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.daml.ledger.api.v1.package_service.{
|
||||
GetPackageResponse,
|
||||
GetPackageStatusResponse,
|
||||
ListPackagesResponse,
|
||||
}
|
||||
import com.daml.ledger.api.v2.package_service.{
|
||||
GetPackageRequest,
|
||||
GetPackageStatusRequest,
|
||||
ListPackagesRequest,
|
||||
PackageServiceGrpc,
|
||||
}
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.PackageServiceAuthorization
|
||||
import com.daml.ledger.api.v1.package_service.PackageServiceGrpc.PackageService
|
||||
import com.daml.ledger.api.v1.package_service._
|
||||
import com.digitalasset.canton.ledger.api.auth.services.PackageServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.package_service.PackageServiceGrpc.PackageService
|
||||
import io.grpc.ServerServiceDefinition
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
@ -55,7 +65,7 @@ object PackageServiceImpl {
|
||||
)(implicit ec: ExecutionContext): (ServerServiceDefinition, PackageServiceImpl) = {
|
||||
val impl =
|
||||
new PackageServiceImpl(listPackagesResponse, getPackageResponse, getPackageStatusResponse)
|
||||
val authImpl = new PackageServiceAuthorization(impl, authorizer)
|
||||
val authImpl = new PackageServiceV2Authorization(impl, authorizer)
|
||||
(PackageServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset.ParticipantBoundary.PARTICIPANT_BEGIN
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset.Value.{Absolute, Boundary}
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.StateServiceAuthorization
|
||||
import com.daml.ledger.api.v2.state_service.StateServiceGrpc.StateService
|
||||
import com.daml.ledger.api.v2.state_service.{
|
||||
GetActiveContractsRequest,
|
||||
GetActiveContractsResponse,
|
||||
GetConnectedDomainsRequest,
|
||||
GetConnectedDomainsResponse,
|
||||
GetLatestPrunedOffsetsRequest,
|
||||
GetLatestPrunedOffsetsResponse,
|
||||
GetLedgerEndRequest,
|
||||
GetLedgerEndResponse,
|
||||
StateServiceGrpc,
|
||||
}
|
||||
import com.daml.ledger.rxjava.grpc.helpers.UpdateServiceImpl.LedgerItem
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.{Observable, Observer}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
|
||||
final class StateServiceImpl(
|
||||
getActiveContractsResponses: Observable[GetActiveContractsResponse],
|
||||
ledgerContent: Observable[LedgerItem],
|
||||
) extends StateService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
private var lastRequest = Option.empty[GetActiveContractsRequest]
|
||||
|
||||
override def getActiveContracts(
|
||||
request: GetActiveContractsRequest,
|
||||
responseObserver: StreamObserver[GetActiveContractsResponse],
|
||||
): Unit = {
|
||||
lastRequest = Option(request)
|
||||
getActiveContractsResponses.subscribe(new Observer[GetActiveContractsResponse] {
|
||||
override def onSubscribe(d: Disposable): Unit = ()
|
||||
override def onNext(t: GetActiveContractsResponse): Unit = responseObserver.onNext(t)
|
||||
override def onError(e: Throwable): Unit = responseObserver.onError(e)
|
||||
override def onComplete(): Unit = responseObserver.onCompleted()
|
||||
})
|
||||
}
|
||||
|
||||
def getLastRequest: Option[GetActiveContractsRequest] = this.lastRequest
|
||||
|
||||
override def getLedgerEnd(request: GetLedgerEndRequest): Future[GetLedgerEndResponse] = {
|
||||
val promise = Promise[GetLedgerEndResponse]()
|
||||
val result =
|
||||
ledgerContent
|
||||
.map[GetLedgerEndResponse](t =>
|
||||
GetLedgerEndResponse(Option(ParticipantOffset(Absolute(t.offset))))
|
||||
)
|
||||
.last(GetLedgerEndResponse(Option(ParticipantOffset(Boundary(PARTICIPANT_BEGIN)))))
|
||||
result.subscribe(promise.success _, promise.failure _)
|
||||
promise.future
|
||||
}
|
||||
|
||||
override def getConnectedDomains(
|
||||
request: GetConnectedDomainsRequest
|
||||
): Future[GetConnectedDomainsResponse] = ???
|
||||
|
||||
override def getLatestPrunedOffsets(
|
||||
request: GetLatestPrunedOffsetsRequest
|
||||
): Future[GetLatestPrunedOffsetsResponse] = ???
|
||||
}
|
||||
|
||||
object StateServiceImpl {
|
||||
|
||||
/** Return the ServerServiceDefinition and the underlying ActiveContractsServiceImpl for inspection */
|
||||
def createWithRef(
|
||||
getActiveContractsResponses: Observable[GetActiveContractsResponse],
|
||||
ledgerContent: Observable[LedgerItem],
|
||||
authorizer: Authorizer,
|
||||
)(implicit ec: ExecutionContext): (ServerServiceDefinition, StateServiceImpl) = {
|
||||
val impl = new StateServiceImpl(getActiveContractsResponses, ledgerContent)
|
||||
val authImpl = new StateServiceAuthorization(impl, authorizer)
|
||||
(StateServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
|
||||
}
|
@ -4,9 +4,9 @@
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.TimeServiceAuthorization
|
||||
import com.daml.ledger.api.v1.testing.time_service.TimeServiceGrpc.TimeService
|
||||
import com.daml.ledger.api.v1.testing.time_service.{
|
||||
import com.digitalasset.canton.ledger.api.auth.services.TimeServiceV2Authorization
|
||||
import com.daml.ledger.api.v2.testing.time_service.TimeServiceGrpc.TimeService
|
||||
import com.daml.ledger.api.v2.testing.time_service.{
|
||||
GetTimeRequest,
|
||||
GetTimeResponse,
|
||||
SetTimeRequest,
|
||||
@ -14,11 +14,10 @@ import com.daml.ledger.api.v1.testing.time_service.{
|
||||
}
|
||||
import com.google.protobuf.empty.Empty
|
||||
import io.grpc.ServerServiceDefinition
|
||||
import io.grpc.stub.StreamObserver
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future};
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class TimeServiceImpl(getTimeResponses: Seq[GetTimeResponse])
|
||||
final class TimeServiceImpl(getTimeResponse: Future[GetTimeResponse])
|
||||
extends TimeService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
@ -26,12 +25,10 @@ final class TimeServiceImpl(getTimeResponses: Seq[GetTimeResponse])
|
||||
private var lastSetTimeRequest: Option[SetTimeRequest] = None
|
||||
|
||||
override def getTime(
|
||||
request: GetTimeRequest,
|
||||
responseObserver: StreamObserver[GetTimeResponse],
|
||||
): Unit = {
|
||||
request: GetTimeRequest
|
||||
): Future[GetTimeResponse] = {
|
||||
this.lastGetTimeRequest = Some(request)
|
||||
getTimeResponses.foreach(responseObserver.onNext)
|
||||
responseObserver.onCompleted()
|
||||
getTimeResponse
|
||||
}
|
||||
|
||||
override def setTime(request: SetTimeRequest): Future[Empty] = {
|
||||
@ -45,11 +42,11 @@ final class TimeServiceImpl(getTimeResponses: Seq[GetTimeResponse])
|
||||
}
|
||||
|
||||
object TimeServiceImpl {
|
||||
def createWithRef(getTimeResponses: Seq[GetTimeResponse], authorizer: Authorizer)(implicit
|
||||
def createWithRef(getTimeResponse: Future[GetTimeResponse], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, TimeServiceImpl) = {
|
||||
val impl = new TimeServiceImpl(getTimeResponses)
|
||||
val authImpl = new TimeServiceAuthorization(impl, authorizer)
|
||||
val impl = new TimeServiceImpl(getTimeResponse)
|
||||
val authImpl = new TimeServiceV2Authorization(impl, authorizer)
|
||||
(TimeServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,21 @@ import com.daml.ledger.api.v1.transaction.TreeEvent.Kind.Exercised
|
||||
import com.daml.ledger.api.v1.value
|
||||
import com.daml.ledger.api.v1.value.Value.Sum
|
||||
import com.daml.ledger.api.v1.value.{Identifier, Record, RecordField, Value, Variant}
|
||||
import com.daml.ledger.api.v1.trace_context.TraceContext
|
||||
import com.daml.ledger.javaapi.data
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionsServiceImpl.LedgerItem
|
||||
import com.daml.ledger.rxjava.grpc.helpers.UpdateServiceImpl.LedgerItem
|
||||
import com.google.protobuf.ByteString
|
||||
import com.google.protobuf.empty.Empty
|
||||
import com.google.protobuf.timestamp.{Timestamp => ScalaTimestamp}
|
||||
import com.google.rpc.status.{Status => SStatus}
|
||||
import com.google.rpc.{Status => JStatus}
|
||||
import org.scalacheck.{Arbitrary, Gen, Shrink}
|
||||
|
||||
import java.time.Instant
|
||||
import java.util
|
||||
import java.util.Collections
|
||||
|
||||
import com.daml.ledger.javaapi.data.Utils
|
||||
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.jdk.OptionConverters._
|
||||
|
||||
@ -203,7 +206,7 @@ object TransactionGenerator {
|
||||
(javaInterfaceId, statusOrRecord.left.map(_._2).map(_._2)),
|
||||
)
|
||||
|
||||
private val createdEventGen: Gen[(Created, data.CreatedEvent)] = for {
|
||||
val createdEventGen: Gen[(Created, data.CreatedEvent)] = for {
|
||||
eventId <- nonEmptyId
|
||||
contractId <- nonEmptyId
|
||||
contractKey <- Gen.option(valueGen(0))
|
||||
@ -312,62 +315,95 @@ object TransactionGenerator {
|
||||
case (scalaEvent, javaEvent) => (List(scalaEvent), List(javaEvent).asJava)
|
||||
}
|
||||
|
||||
val transactionGen: Gen[(LedgerItem, data.Transaction)] = for {
|
||||
transactionId <- nonEmptyId
|
||||
val transactionGen: Gen[(LedgerItem, data.TransactionV2)] = for {
|
||||
updateId <- nonEmptyId
|
||||
commandId <- nonEmptyId
|
||||
workflowId <- nonEmptyId
|
||||
(scalaTimestamp, javaTimestamp) <- timestampGen
|
||||
(scalaEvents, javaEvents) <- eventsGen
|
||||
offset <- Gen.numStr
|
||||
domainId <- Gen.alphaNumStr
|
||||
traceContext <- Gen.const(Utils.newProtoTraceContext("parent", "state"))
|
||||
} yield (
|
||||
LedgerItem(transactionId, commandId, workflowId, scalaTimestamp, scalaEvents, offset),
|
||||
new data.Transaction(transactionId, commandId, workflowId, javaTimestamp, javaEvents, offset),
|
||||
)
|
||||
|
||||
val transactionTreeGen: Gen[(LedgerItem, data.TransactionTree)] = for {
|
||||
transactionId <- nonEmptyId
|
||||
commandId <- nonEmptyId
|
||||
workflowId <- nonEmptyId
|
||||
(scalaTimestamp, javaTimestamp) <- timestampGen
|
||||
(scalaEvents, javaEvents) <- eventsGen
|
||||
offset <- Gen.numStr
|
||||
} yield (
|
||||
LedgerItem(transactionId, commandId, workflowId, scalaTimestamp, scalaEvents, offset),
|
||||
new data.TransactionTree(
|
||||
transactionId,
|
||||
LedgerItem(
|
||||
updateId,
|
||||
commandId,
|
||||
workflowId,
|
||||
scalaTimestamp,
|
||||
scalaEvents,
|
||||
offset,
|
||||
domainId,
|
||||
TraceContext.fromJavaProto(traceContext),
|
||||
),
|
||||
new data.TransactionV2(
|
||||
updateId,
|
||||
commandId,
|
||||
workflowId,
|
||||
javaTimestamp,
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyList(),
|
||||
javaEvents,
|
||||
offset,
|
||||
domainId,
|
||||
traceContext,
|
||||
),
|
||||
)
|
||||
|
||||
val ledgerContentGen: Gen[(List[LedgerItem], List[data.Transaction])] =
|
||||
val transactionTreeGen: Gen[(LedgerItem, data.TransactionTreeV2)] = for {
|
||||
updateId <- nonEmptyId
|
||||
commandId <- nonEmptyId
|
||||
workflowId <- nonEmptyId
|
||||
(scalaTimestamp, javaTimestamp) <- timestampGen
|
||||
(scalaEvents, javaEvents) <- eventsGen
|
||||
offset <- Gen.numStr
|
||||
domainId <- Gen.alphaNumStr
|
||||
traceContext <- Gen.const(Utils.newProtoTraceContext("parent", "state"))
|
||||
} yield (
|
||||
LedgerItem(
|
||||
updateId,
|
||||
commandId,
|
||||
workflowId,
|
||||
scalaTimestamp,
|
||||
scalaEvents,
|
||||
offset,
|
||||
domainId,
|
||||
TraceContext.fromJavaProto(traceContext),
|
||||
),
|
||||
new data.TransactionTreeV2(
|
||||
updateId,
|
||||
commandId,
|
||||
workflowId,
|
||||
javaTimestamp,
|
||||
offset,
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyList(),
|
||||
domainId,
|
||||
traceContext,
|
||||
),
|
||||
)
|
||||
|
||||
val ledgerContentGen: Gen[(List[LedgerItem], List[data.TransactionV2])] =
|
||||
Gen.listOf(transactionGen).map(_.unzip)
|
||||
|
||||
val ledgerContentTreeGen: Gen[(List[LedgerItem], List[data.TransactionTree])] =
|
||||
val ledgerContentTreeGen: Gen[(List[LedgerItem], List[data.TransactionTreeV2])] =
|
||||
Gen.listOf(transactionTreeGen).map(_.unzip)
|
||||
|
||||
val ledgerContentWithEventIdGen: Gen[(List[LedgerItem], String, data.TransactionTree)] = for {
|
||||
val ledgerContentWithEventIdGen: Gen[(List[LedgerItem], String, data.TransactionTreeV2)] = for {
|
||||
(arbitraryLedgerContent, _) <- ledgerContentTreeGen
|
||||
(queriedLedgerContent, queriedTransaction) <- transactionTreeGen.suchThat(_._1.events.nonEmpty)
|
||||
ledgerContent = arbitraryLedgerContent :+ queriedLedgerContent
|
||||
eventIds = queriedLedgerContent.events.map(TransactionsServiceImpl.eventId)
|
||||
eventIds = queriedLedgerContent.events.map(UpdateServiceImpl.eventId)
|
||||
eventIdList <- Gen.pick(1, eventIds)
|
||||
eventId = eventIdList.head
|
||||
} yield (ledgerContent, eventId, queriedTransaction)
|
||||
|
||||
val ledgerContentWithTransactionIdGen: Gen[(List[LedgerItem], String, data.TransactionTree)] =
|
||||
val ledgerContentWithTransactionIdGen: Gen[(List[LedgerItem], String, data.TransactionTreeV2)] =
|
||||
for {
|
||||
(arbitraryLedgerContent, _) <- ledgerContentTreeGen
|
||||
(queriedLedgerContent, queriedTransaction) <- transactionTreeGen
|
||||
ledgerContent = arbitraryLedgerContent :+ queriedLedgerContent
|
||||
transactionId = queriedLedgerContent.transactionId
|
||||
} yield (ledgerContent, transactionId, queriedTransaction)
|
||||
updateId = queriedLedgerContent.updateId
|
||||
} yield (ledgerContent, updateId, queriedTransaction)
|
||||
|
||||
val nonEmptyLedgerContent: Gen[(List[LedgerItem], List[data.Transaction])] =
|
||||
val nonEmptyLedgerContent: Gen[(List[LedgerItem], List[data.TransactionV2])] =
|
||||
Gen.nonEmptyListOf(transactionGen).map(_.unzip)
|
||||
|
||||
}
|
||||
|
@ -1,200 +0,0 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
import com.daml.ledger.rxjava.grpc.helpers.TransactionsServiceImpl.{
|
||||
LedgerItem,
|
||||
ledgerOffsetOrdering,
|
||||
}
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.TransactionServiceAuthorization
|
||||
import com.daml.ledger.api.v1.event.Event
|
||||
import com.daml.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset.LedgerBoundary.{
|
||||
LEDGER_BEGIN,
|
||||
LEDGER_END,
|
||||
Unrecognized,
|
||||
}
|
||||
import com.daml.ledger.api.v1.ledger_offset.LedgerOffset.Value.{Absolute, Boundary}
|
||||
import com.daml.ledger.api.v1.transaction.Transaction
|
||||
import com.daml.ledger.api.v1.transaction_service.TransactionServiceGrpc.TransactionService
|
||||
import com.daml.ledger.api.v1.transaction_service._
|
||||
import com.google.protobuf.timestamp.Timestamp
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.grpc.{Metadata, ServerServiceDefinition, Status}
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.{Observable, Observer}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
|
||||
final class TransactionsServiceImpl(ledgerContent: Observable[LedgerItem])
|
||||
extends TransactionService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
val lastTransactionsRequest = new AtomicReference[GetTransactionsRequest]()
|
||||
val lastTransactionsTreesRequest = new AtomicReference[GetTransactionsRequest]()
|
||||
val lastTransactionByEventIdRequest = new AtomicReference[GetTransactionByEventIdRequest]()
|
||||
val lastTransactionByIdRequest = new AtomicReference[GetTransactionByIdRequest]()
|
||||
val lastFlatTransactionByEventIdRequest = new AtomicReference[GetTransactionByEventIdRequest]()
|
||||
val lastFlatTransactionByIdRequest = new AtomicReference[GetTransactionByIdRequest]()
|
||||
val lastLedgerEndRequest = new AtomicReference[GetLedgerEndRequest]()
|
||||
val lastLatestPrunedOffsetsRequest = new AtomicReference[GetLatestPrunedOffsetsRequest]
|
||||
|
||||
override def getTransactions(
|
||||
request: GetTransactionsRequest,
|
||||
responseObserver: StreamObserver[GetTransactionsResponse],
|
||||
): Unit = {
|
||||
lastTransactionsRequest.set(request)
|
||||
|
||||
if (request.end.exists(end => ledgerOffsetOrdering.gt(request.getBegin, end))) {
|
||||
val metadata = new Metadata()
|
||||
metadata.put(
|
||||
Metadata.Key.of("cause", Metadata.ASCII_STRING_MARSHALLER),
|
||||
s"BEGIN should be strictly smaller than END. Found BEGIN '${request.getBegin}' and END '${request.getEnd}'",
|
||||
)
|
||||
responseObserver.onError(Status.INVALID_ARGUMENT.asRuntimeException(metadata))
|
||||
} else {
|
||||
ledgerContent.subscribe(new Observer[LedgerItem] {
|
||||
override def onSubscribe(d: Disposable): Unit = ()
|
||||
override def onNext(t: LedgerItem): Unit =
|
||||
responseObserver.onNext(GetTransactionsResponse(List(t.toTransaction)))
|
||||
override def onError(t: Throwable): Unit = responseObserver.onError(t)
|
||||
override def onComplete(): Unit = responseObserver.onCompleted()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override def getTransactionTrees(
|
||||
request: GetTransactionsRequest,
|
||||
responseObserver: StreamObserver[GetTransactionTreesResponse],
|
||||
): Unit = {
|
||||
lastTransactionsTreesRequest.set(request)
|
||||
responseObserver.onCompleted()
|
||||
}
|
||||
|
||||
override def getTransactionByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[GetTransactionResponse] = {
|
||||
lastTransactionByEventIdRequest.set(request)
|
||||
Future.successful(new GetTransactionResponse(None)) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getTransactionById(
|
||||
request: GetTransactionByIdRequest
|
||||
): Future[GetTransactionResponse] = {
|
||||
lastTransactionByIdRequest.set(request)
|
||||
Future.successful(new GetTransactionResponse(None)) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getFlatTransactionByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[GetFlatTransactionResponse] = {
|
||||
lastFlatTransactionByEventIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetFlatTransactionResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getFlatTransactionById(
|
||||
request: GetTransactionByIdRequest
|
||||
): Future[GetFlatTransactionResponse] = {
|
||||
lastFlatTransactionByIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetFlatTransactionResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getLedgerEnd(request: GetLedgerEndRequest): Future[GetLedgerEndResponse] = {
|
||||
lastLedgerEndRequest.set(request)
|
||||
val promise = Promise[GetLedgerEndResponse]()
|
||||
val result =
|
||||
ledgerContent
|
||||
.map[GetLedgerEndResponse](t =>
|
||||
GetLedgerEndResponse(Option(LedgerOffset(Absolute(t.offset))))
|
||||
)
|
||||
.last(GetLedgerEndResponse(Option(LedgerOffset(Boundary(LEDGER_BEGIN)))))
|
||||
result.subscribe(promise.success _, promise.failure _)
|
||||
promise.future
|
||||
}
|
||||
|
||||
override def getLatestPrunedOffsets(
|
||||
request: GetLatestPrunedOffsetsRequest
|
||||
): Future[GetLatestPrunedOffsetsResponse] = {
|
||||
lastLatestPrunedOffsetsRequest.set(request)
|
||||
Future.successful(
|
||||
new GetLatestPrunedOffsetsResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object TransactionsServiceImpl {
|
||||
|
||||
final case class LedgerItem(
|
||||
transactionId: String,
|
||||
commandId: String,
|
||||
workflowId: String,
|
||||
effectiveAt: Timestamp,
|
||||
events: Seq[Event],
|
||||
offset: String,
|
||||
) {
|
||||
|
||||
def toTransaction =
|
||||
Transaction(
|
||||
transactionId,
|
||||
commandId,
|
||||
workflowId,
|
||||
Some(effectiveAt),
|
||||
events,
|
||||
offset,
|
||||
)
|
||||
}
|
||||
|
||||
def eventId(event: Event): String = event.event match {
|
||||
case Archived(archivedEvent) => archivedEvent.eventId
|
||||
case Created(createdEvent) => createdEvent.eventId
|
||||
case Empty => ""
|
||||
}
|
||||
|
||||
def createWithRef(ledgerContent: Observable[LedgerItem], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, TransactionsServiceImpl) = {
|
||||
val impl = new TransactionsServiceImpl(ledgerContent)
|
||||
val authImpl = new TransactionServiceAuthorization(impl, authorizer)
|
||||
(TransactionServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
|
||||
val ledgerOffsetOrdering: Ordering[LedgerOffset] = (x: LedgerOffset, y: LedgerOffset) => {
|
||||
if (x.equals(y)) 0
|
||||
else {
|
||||
x.getAbsolute match {
|
||||
case "" =>
|
||||
x.getBoundary match {
|
||||
case LEDGER_BEGIN => -1
|
||||
case LEDGER_END => 1
|
||||
case Unrecognized(value) =>
|
||||
throw new RuntimeException(
|
||||
s"Found boundary that is neither BEGIN or END (value: $value)"
|
||||
)
|
||||
}
|
||||
case xAbs =>
|
||||
y.getAbsolute match {
|
||||
case "" =>
|
||||
y.getBoundary match {
|
||||
case LEDGER_BEGIN => 1
|
||||
case LEDGER_END => -1
|
||||
case Unrecognized(value) =>
|
||||
throw new RuntimeException(
|
||||
s"Found boundary that is neither BEGIN or END (value: $value)"
|
||||
)
|
||||
}
|
||||
case yAbs => xAbs.compareTo(yAbs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.daml.ledger.rxjava.grpc.helpers
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
import com.daml.ledger.api.v1.trace_context.TraceContext
|
||||
import com.daml.ledger.rxjava.grpc.helpers.UpdateServiceImpl.{LedgerItem, participantOffsetOrdering}
|
||||
import com.digitalasset.canton.ledger.api.auth.Authorizer
|
||||
import com.digitalasset.canton.ledger.api.auth.services.UpdateServiceAuthorization
|
||||
import com.daml.ledger.api.v1.event.Event
|
||||
import com.daml.ledger.api.v1.event.Event.Event.{Archived, Created, Empty}
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset
|
||||
import com.daml.ledger.api.v2.participant_offset.ParticipantOffset.ParticipantBoundary.{
|
||||
PARTICIPANT_BEGIN,
|
||||
PARTICIPANT_END,
|
||||
Unrecognized,
|
||||
}
|
||||
import com.daml.ledger.api.v2.transaction.Transaction
|
||||
import com.daml.ledger.api.v2.update_service.UpdateServiceGrpc.UpdateService
|
||||
import com.daml.ledger.api.v2.update_service._
|
||||
import com.google.protobuf.timestamp.Timestamp
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.grpc.{Metadata, ServerServiceDefinition, Status}
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.{Observable, Observer}
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
final class UpdateServiceImpl(ledgerContent: Observable[LedgerItem])
|
||||
extends UpdateService
|
||||
with FakeAutoCloseable {
|
||||
|
||||
val lastUpdatesRequest = new AtomicReference[GetUpdatesRequest]()
|
||||
val lastUpdatesTreesRequest = new AtomicReference[GetUpdatesRequest]()
|
||||
val lastTransactionTreeByEventIdRequest = new AtomicReference[GetTransactionByEventIdRequest]()
|
||||
val lastTransactionTreeByIdRequest = new AtomicReference[GetTransactionByIdRequest]()
|
||||
val lastTransactionByEventIdRequest = new AtomicReference[GetTransactionByEventIdRequest]()
|
||||
val lastTransactionByIdRequest = new AtomicReference[GetTransactionByIdRequest]()
|
||||
|
||||
override def getUpdates(
|
||||
request: GetUpdatesRequest,
|
||||
responseObserver: StreamObserver[GetUpdatesResponse],
|
||||
): Unit = {
|
||||
lastUpdatesRequest.set(request)
|
||||
|
||||
if (
|
||||
request.endInclusive
|
||||
.exists(end => participantOffsetOrdering.gt(request.getBeginExclusive, end))
|
||||
) {
|
||||
val metadata = new Metadata()
|
||||
metadata.put(
|
||||
Metadata.Key.of("cause", Metadata.ASCII_STRING_MARSHALLER),
|
||||
s"BEGIN should be strictly smaller than END. Found BEGIN '${request.getBeginExclusive}' and END '${request.getEndInclusive}'",
|
||||
)
|
||||
responseObserver.onError(Status.INVALID_ARGUMENT.asRuntimeException(metadata))
|
||||
} else {
|
||||
ledgerContent.subscribe(new Observer[LedgerItem] {
|
||||
override def onSubscribe(d: Disposable): Unit = ()
|
||||
override def onNext(t: LedgerItem): Unit =
|
||||
responseObserver.onNext(
|
||||
GetUpdatesResponse(GetUpdatesResponse.Update.Transaction(t.toTransaction))
|
||||
)
|
||||
override def onError(t: Throwable): Unit = responseObserver.onError(t)
|
||||
override def onComplete(): Unit = responseObserver.onCompleted()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override def getUpdateTrees(
|
||||
request: GetUpdatesRequest,
|
||||
responseObserver: StreamObserver[GetUpdateTreesResponse],
|
||||
): Unit = {
|
||||
lastUpdatesTreesRequest.set(request)
|
||||
responseObserver.onCompleted()
|
||||
}
|
||||
|
||||
override def getTransactionTreeByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[GetTransactionTreeResponse] = {
|
||||
lastTransactionTreeByEventIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetTransactionTreeResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getTransactionTreeById(
|
||||
request: GetTransactionByIdRequest
|
||||
): Future[GetTransactionTreeResponse] = {
|
||||
lastTransactionTreeByIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetTransactionTreeResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getTransactionByEventId(
|
||||
request: GetTransactionByEventIdRequest
|
||||
): Future[GetTransactionResponse] = {
|
||||
lastTransactionByEventIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetTransactionResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
|
||||
override def getTransactionById(
|
||||
request: GetTransactionByIdRequest
|
||||
): Future[GetTransactionResponse] = {
|
||||
lastTransactionByIdRequest.set(request)
|
||||
Future.successful(
|
||||
new GetTransactionResponse(None)
|
||||
) // just a mock, not intended for consumption
|
||||
}
|
||||
}
|
||||
|
||||
object UpdateServiceImpl {
|
||||
|
||||
final case class LedgerItem(
|
||||
updateId: String,
|
||||
commandId: String,
|
||||
workflowId: String,
|
||||
effectiveAt: Timestamp,
|
||||
events: Seq[Event],
|
||||
offset: String,
|
||||
domainId: String,
|
||||
traceContext: TraceContext,
|
||||
) {
|
||||
|
||||
def toTransaction =
|
||||
Transaction(
|
||||
updateId,
|
||||
commandId,
|
||||
workflowId,
|
||||
Some(effectiveAt),
|
||||
events,
|
||||
offset,
|
||||
domainId,
|
||||
Some(traceContext),
|
||||
)
|
||||
}
|
||||
|
||||
def eventId(event: Event): String = event.event match {
|
||||
case Archived(archivedEvent) => archivedEvent.eventId
|
||||
case Created(createdEvent) => createdEvent.eventId
|
||||
case Empty => ""
|
||||
}
|
||||
|
||||
def createWithRef(ledgerContent: Observable[LedgerItem], authorizer: Authorizer)(implicit
|
||||
ec: ExecutionContext
|
||||
): (ServerServiceDefinition, UpdateServiceImpl) = {
|
||||
val impl = new UpdateServiceImpl(ledgerContent)
|
||||
val authImpl = new UpdateServiceAuthorization(impl, authorizer)
|
||||
(UpdateServiceGrpc.bindService(authImpl, ec), impl)
|
||||
}
|
||||
|
||||
val participantOffsetOrdering: Ordering[ParticipantOffset] =
|
||||
(x: ParticipantOffset, y: ParticipantOffset) => {
|
||||
if (x.equals(y)) 0
|
||||
else {
|
||||
x.getAbsolute match {
|
||||
case "" =>
|
||||
x.getBoundary match {
|
||||
case PARTICIPANT_BEGIN => -1
|
||||
case PARTICIPANT_END => 1
|
||||
case Unrecognized(value) =>
|
||||
throw new RuntimeException(
|
||||
s"Found boundary that is neither BEGIN or END (value: $value)"
|
||||
)
|
||||
}
|
||||
case xAbs =>
|
||||
y.getAbsolute match {
|
||||
case "" =>
|
||||
y.getBoundary match {
|
||||
case PARTICIPANT_BEGIN => 1
|
||||
case PARTICIPANT_END => -1
|
||||
case Unrecognized(value) =>
|
||||
throw new RuntimeException(
|
||||
s"Found boundary that is neither BEGIN or END (value: $value)"
|
||||
)
|
||||
}
|
||||
case yAbs => xAbs.compareTo(yAbs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user