com.scalar.dl.client.service.ProxyClient 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.
package com.scalar.dl.client.service;
import com.google.inject.Inject;
import com.scalar.dl.client.config.ClientConfig;
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.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.FunctionRegistrationRequest;
import com.scalar.dl.rpc.LedgerValidationRequest;
import com.scalar.dl.rpc.LedgersValidationRequest;
import com.scalar.dl.rpc.LedgersValidationResponse;
import com.scalar.dl.rpc.ProxyGrpc;
import io.grpc.ManagedChannel;
import io.grpc.netty.NettyChannelBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.json.JsonObject;
import javax.net.ssl.SSLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ProxyClient extends AbstractLedgerClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ProxyClient.class);
private final ManagedChannel channel;
private final ProxyGrpc.ProxyBlockingStub proxyStub;
@Inject
public ProxyClient(ClientConfig config) throws SSLException {
NettyChannelBuilder builder =
NettyChannelBuilder.forAddress(
config.getProxyServer().getHost(), config.getProxyServer().getPort());
ClientUtil.configureTls(builder, config.isTlsEnabled(), config.getTlsCaRootCert());
ClientUtil.configureHeader(builder, config.getAuthorizationCredential());
channel = builder.build();
proxyStub = ProxyGrpc.newBlockingStub(channel);
}
@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 -> proxyStub.registerCert(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public void register(FunctionRegistrationRequest request) {
ThrowableConsumer f = r -> proxyStub.registerFunction(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public void register(ContractRegistrationRequest request) {
ThrowableConsumer f = r -> proxyStub.registerContract(request);
try {
accept(f, request);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
}
@Override
public JsonObject list(ContractsListingRequest request) {
throw new RuntimeException("not supported for now");
}
@Override
public ContractExecutionResult execute(ContractExecutionRequest request) {
return execute(request, DEFAULT_AUDITING_HOOK);
}
@Override
public ContractExecutionResult execute(
ContractExecutionRequest request,
ThrowableFunction auditingHook) {
try {
ContractExecutionResponse response = proxyStub.executeContract(request);
// Arbitrary consumer can be hooked after executing the contract
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)));
return new ContractExecutionResult(result, proofs, null);
} 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) {
throw new RuntimeException("not supported for now");
}
@Override
public LedgersValidationResult validate(LedgersValidationRequest request) {
try {
LedgersValidationResponse response = proxyStub.validateLedgers(request);
Map proofs = new HashMap<>();
response
.getResponseList()
.forEach(r -> proofs.put(r.getLedgerName(), new AssetProof(r.getProof())));
StatusCode code = isAllSame(proofs) ? StatusCode.OK : StatusCode.INCONSISTENT_STATES;
return new LedgersValidationResult(code, proofs);
} catch (Exception e) {
throwExceptionWithStatusCode(e);
}
// Java compiler requires this line even though it won't come here
return new LedgersValidationResult(StatusCode.RUNTIME_ERROR, null);
}
@Override
public Optional retrieve(AssetProofRetrievalRequest request) {
throw new RuntimeException("not supported for now");
}
@Override
public TransactionState abort(ExecutionAbortRequest request) {
throw new RuntimeException("not supported for now");
}
private boolean isAllSame(Map proofs) {
AssetProof one = null;
if (proofs.size() <= 1) {
LOGGER.warn("The number of results is insufficient to validate.");
return false;
}
for (Map.Entry entry : proofs.entrySet()) {
AssetProof other = entry.getValue();
if (one == null) {
one = other;
continue;
}
if (!one.valueEquals(other)) {
return false;
}
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy