All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scalar.dl.client.service.ProxyClient Maven / Gradle / Ivy

There is a newer version: 3.10.0
Show newest version
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