com.scalar.dl.client.service.LedgerClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalardl-java-client-sdk Show documentation
Show all versions of scalardl-java-client-sdk Show documentation
A client-side Java library to interact with Scalar DL network.
/*
* This file is part of the Scalar DL client SDK.
* Copyright (c) 2019 Scalar, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* You can be released from the requirements of the license by purchasing
* a commercial license. For more information, please contact Scalar, Inc.
*/
package com.scalar.dl.client.service;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.scalar.dl.client.exception.ClientException;
import com.scalar.dl.ledger.asset.AssetProof;
import com.scalar.dl.ledger.database.TransactionState;
import com.scalar.dl.ledger.model.ContractExecutionResult;
import com.scalar.dl.ledger.model.LedgerValidationResult;
import com.scalar.dl.ledger.model.LedgersValidationResult;
import com.scalar.dl.ledger.rpc.ClientUtil;
import com.scalar.dl.ledger.service.StatusCode;
import com.scalar.dl.ledger.service.ThrowableConsumer;
import com.scalar.dl.ledger.service.ThrowableFunction;
import com.scalar.dl.ledger.util.JsonpSerDe;
import com.scalar.dl.rpc.AssetProofRetrievalRequest;
import com.scalar.dl.rpc.AssetProofRetrievalResponse;
import com.scalar.dl.rpc.CertificateRegistrationRequest;
import com.scalar.dl.rpc.ContractExecutionRequest;
import com.scalar.dl.rpc.ContractExecutionResponse;
import com.scalar.dl.rpc.ContractRegistrationRequest;
import com.scalar.dl.rpc.ContractsListingRequest;
import com.scalar.dl.rpc.ExecutionAbortRequest;
import com.scalar.dl.rpc.ExecutionAbortResponse;
import com.scalar.dl.rpc.FunctionRegistrationRequest;
import com.scalar.dl.rpc.LedgerGrpc;
import com.scalar.dl.rpc.LedgerPrivilegedGrpc;
import com.scalar.dl.rpc.LedgerValidationRequest;
import com.scalar.dl.rpc.LedgerValidationResponse;
import com.scalar.dl.rpc.LedgersValidationRequest;
import io.grpc.ManagedChannel;
import io.grpc.netty.NettyChannelBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.concurrent.Immutable;
import javax.json.Json;
import javax.json.JsonObject;
import javax.net.ssl.SSLException;
@Immutable
public class LedgerClient extends AbstractLedgerClient {
private final ManagedChannel channel;
private final ManagedChannel privilegedChannel;
private final LedgerGrpc.LedgerBlockingStub ledgerStub;
private final LedgerPrivilegedGrpc.LedgerPrivilegedBlockingStub ledgerPrivilegedStub;
@Inject
public LedgerClient(com.scalar.dl.ledger.config.ClientConfig config) throws SSLException {
NettyChannelBuilder builder =
NettyChannelBuilder.forAddress(config.getLedgerHost(), config.getLedgerPort());
ClientUtil.configureTls(builder, config.isTlsEnabled(), config.getTlsCaRootCert());
ClientUtil.configureHeader(builder, config.getAuthorizationCredential());
channel = builder.build();
ledgerStub = LedgerGrpc.newBlockingStub(channel);
privilegedChannel =
NettyChannelBuilder.forAddress(config.getLedgerHost(), config.getLedgerPrivilegedPort())
.usePlaintext()
.build();
ledgerPrivilegedStub = LedgerPrivilegedGrpc.newBlockingStub(privilegedChannel);
}
@VisibleForTesting
LedgerClient(
LedgerGrpc.LedgerBlockingStub ledgerStub,
LedgerPrivilegedGrpc.LedgerPrivilegedBlockingStub ledgerPrivilegedStub) {
this.channel = null;
this.privilegedChannel = null;
this.ledgerStub = ledgerStub;
this.ledgerPrivilegedStub = ledgerPrivilegedStub;
}
@Override
public void shutdown() {
try {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new ClientException(e.getMessage(), e, StatusCode.RUNTIME_ERROR);
}
}
@Override
public void register(CertificateRegistrationRequest request) {
ThrowableConsumer f =
r -> ledgerPrivilegedStub.registerCert(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public void register(FunctionRegistrationRequest request) {
ThrowableConsumer f =
r -> ledgerPrivilegedStub.registerFunction(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public void register(ContractRegistrationRequest request) {
ThrowableConsumer f = r -> ledgerStub.registerContract(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public JsonObject list(ContractsListingRequest request) {
try {
String jsonString = ledgerStub.listContracts(request).getJson();
return jsonString.isEmpty()
? Json.createObjectBuilder().build()
: new JsonpSerDe().deserialize(jsonString);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return Json.createObjectBuilder().build();
}
@Override
public ContractExecutionResult execute(ContractExecutionRequest request) {
return execute(request, DEFAULT_AUDITING_HOOK);
}
@Override
public ContractExecutionResult execute(
ContractExecutionRequest request,
ThrowableFunction auditingHook) {
try {
ContractExecutionResponse response = ledgerStub.executeContract(request);
ContractExecutionResponse auditorResponse = auditingHook.apply(response);
JsonObject result =
response.getResult().isEmpty()
? null
: new JsonpSerDe().deserialize(response.getResult());
List proofs = new ArrayList<>();
response.getProofsList().forEach(p -> proofs.add(new AssetProof(p)));
List auditorProofs = null;
if (auditorResponse != null) {
auditorProofs =
auditorResponse.getProofsList().stream()
.map(AssetProof::new)
.collect(Collectors.toList());
}
return new ContractExecutionResult(result, proofs, auditorProofs);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return new ContractExecutionResult(null, null, null);
}
@Override
public LedgerValidationResult validate(LedgerValidationRequest request) {
try {
LedgerValidationResponse response = ledgerStub.validateLedger(request);
AssetProof proof = response.hasProof() ? new AssetProof(response.getProof()) : null;
return new LedgerValidationResult(StatusCode.get(response.getStatusCode()), proof);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return new LedgerValidationResult(StatusCode.RUNTIME_ERROR, null);
}
@Override
public LedgersValidationResult validate(LedgersValidationRequest request) {
throw new RuntimeException("not supported for now");
}
@Override
public Optional retrieve(AssetProofRetrievalRequest request) {
try {
AssetProofRetrievalResponse response = ledgerStub.retrieveAssetProof(request);
AssetProof proof = response.hasProof() ? new AssetProof(response.getProof()) : null;
return Optional.ofNullable(proof);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return Optional.empty();
}
@Override
public TransactionState abort(ExecutionAbortRequest request) {
try {
ExecutionAbortResponse response = ledgerStub.abortExecution(request);
return TransactionState.getInstance(response.getState().getNumber());
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return TransactionState.UNKNOWN;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy