BlockTemplate.java
/*
* @copyright defined in LICENSE.txt
*/
package hera.client;
import static hera.api.function.Functions.identify;
import static hera.client.ClientConstants.BLOCK_GET_BLOCK_BY_HASH;
import static hera.client.ClientConstants.BLOCK_GET_BLOCK_BY_HEIGHT;
import static hera.client.ClientConstants.BLOCK_GET_METADATA_BY_HASH;
import static hera.client.ClientConstants.BLOCK_GET_METADATA_BY_HEIGHT;
import static hera.client.ClientConstants.BLOCK_LIST_METADATAS_BY_HASH;
import static hera.client.ClientConstants.BLOCK_LIST_METADATAS_BY_HEIGHT;
import static hera.client.ClientConstants.BLOCK_SUBSCRIBE_BLOCK;
import static hera.client.ClientConstants.BLOCK_SUBSCRIBE_BLOCKMETADATA;
import hera.ContextProvider;
import hera.ContextProviderInjectable;
import hera.annotation.ApiAudience;
import hera.annotation.ApiStability;
import hera.api.BlockOperation;
import hera.api.function.Function1;
import hera.api.function.Function2;
import hera.api.model.Block;
import hera.api.model.BlockHash;
import hera.api.model.BlockMetadata;
import hera.api.model.StreamObserver;
import hera.api.model.Subscription;
import hera.client.internal.BlockBaseTemplate;
import hera.exception.RpcException;
import hera.exception.RpcExceptionConverter;
import hera.strategy.PriorityProvider;
import hera.strategy.StrategyApplier;
import hera.util.ExceptionConverter;
import io.grpc.ManagedChannel;
import java.util.List;
import java.util.concurrent.Future;
import lombok.AccessLevel;
import lombok.Getter;
@ApiAudience.Private
@ApiStability.Unstable
public class BlockTemplate
implements BlockOperation, ChannelInjectable, ContextProviderInjectable {
protected final ExceptionConverter<RpcException> exceptionConverter = new RpcExceptionConverter();
protected BlockBaseTemplate blockBaseTemplate = new BlockBaseTemplate();
protected ContextProvider contextProvider;
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final StrategyApplier strategyApplier =
StrategyApplier.of(contextProvider.get(), PriorityProvider.get());
@Override
public void setChannel(final ManagedChannel channel) {
this.blockBaseTemplate.setChannel(channel);
}
@Override
public void setContextProvider(ContextProvider contextProvider) {
this.contextProvider = contextProvider;
this.blockBaseTemplate.setContextProvider(contextProvider);
}
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<BlockHash, Future<BlockMetadata>> blockMetadataByHashFunction =
getStrategyApplier()
.apply(identify(this.blockBaseTemplate.getBlockMetatdataByHashFunction(),
BLOCK_GET_METADATA_BY_HASH));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<Long, Future<BlockMetadata>> blockMetadataByHeightFunction =
getStrategyApplier().apply(
identify(this.blockBaseTemplate.getBlockMetadataByHeightFunction(),
BLOCK_GET_METADATA_BY_HEIGHT));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<BlockHash, Integer,
Future<List<BlockMetadata>>> listBlockMetadatasByHashFunction =
getStrategyApplier()
.apply(identify(this.blockBaseTemplate.getListBlockMetadatasByHashFunction(),
BLOCK_LIST_METADATAS_BY_HASH));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<Long, Integer,
Future<List<BlockMetadata>>> listBlockMetadatasByHeightFunction =
getStrategyApplier()
.apply(identify(this.blockBaseTemplate.getListBlockMetadatasByHeightFunction(),
BLOCK_LIST_METADATAS_BY_HEIGHT));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<BlockHash, Future<Block>> blockByHashFunction =
getStrategyApplier()
.apply(
identify(this.blockBaseTemplate.getBlockByHashFunction(), BLOCK_GET_BLOCK_BY_HASH));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<Long, Future<Block>> blockByHeightFunction =
getStrategyApplier().apply(
identify(this.blockBaseTemplate.getBlockByHeightFunction(), BLOCK_GET_BLOCK_BY_HEIGHT));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<StreamObserver<BlockMetadata>,
Future<Subscription<BlockMetadata>>> subscribeBlockMetadataFunction =
getStrategyApplier().apply(
identify(this.blockBaseTemplate.getSubscribeBlockMetadataFunction(),
BLOCK_SUBSCRIBE_BLOCKMETADATA));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<StreamObserver<Block>,
Future<Subscription<Block>>> subscribeBlockFunction =
getStrategyApplier().apply(
identify(this.blockBaseTemplate.getSubscribeBlockFunction(), BLOCK_SUBSCRIBE_BLOCK));
@Override
public BlockMetadata getBlockMetadata(final BlockHash blockHash) {
try {
return getBlockMetadataByHashFunction().apply(blockHash).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public BlockMetadata getBlockMetadata(final long height) {
try {
return getBlockMetadataByHeightFunction().apply(height).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public List<BlockMetadata> listBlockMetadatas(final BlockHash blockHash,
final int size) {
try {
return getListBlockMetadatasByHashFunction().apply(blockHash, size).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public List<BlockMetadata> listBlockMetadatas(final long height,
final int size) {
try {
return getListBlockMetadatasByHeightFunction().apply(height, size).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public Block getBlock(final BlockHash blockHash) {
try {
return getBlockByHashFunction().apply(blockHash).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public Block getBlock(final long height) {
try {
return getBlockByHeightFunction().apply(height).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public Subscription<BlockMetadata> subscribeNewBlockMetadata(
final StreamObserver<BlockMetadata> observer) {
try {
return getSubscribeBlockMetadataFunction().apply(observer).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public Subscription<Block> subscribeNewBlock(final StreamObserver<Block> observer) {
try {
return getSubscribeBlockFunction().apply(observer).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
}