diff --git a/src/main/java/com/webank/wecross/Generator.java b/src/main/java/com/webank/wecross/Generator.java index 8cd36fc4d..da2c4916b 100644 --- a/src/main/java/com/webank/wecross/Generator.java +++ b/src/main/java/com/webank/wecross/Generator.java @@ -3,6 +3,8 @@ import com.webank.wecross.config.StubManagerConfig; import com.webank.wecross.stub.StubFactory; import com.webank.wecross.stubmanager.StubManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -12,6 +14,7 @@ public class Generator { public static void main(String[] args) { context = new AnnotationConfigApplicationContext(StubManagerConfig.class); + Logger logger = LoggerFactory.getLogger(Generator.class); if (args.length < ARGS_LENGTH) { System.out.println("Usage: connection/account "); @@ -28,8 +31,10 @@ public static void main(String[] args) { StubFactory stubFactory = stubManager.getStubFactory(type); if (op.equals("connection")) { + logger.info("generateConnection: {}", path); stubFactory.generateConnection(path, new String[] {}); } else if (op.equals("account")) { + logger.info("generateAccount: {}", path); stubFactory.generateAccount(path, new String[] {}); } else { System.err.println("Unknown operation: " + op); diff --git a/src/main/java/com/webank/wecross/network/rpc/URIHandlerDispatcher.java b/src/main/java/com/webank/wecross/network/rpc/URIHandlerDispatcher.java index f95b8dac2..20babf400 100644 --- a/src/main/java/com/webank/wecross/network/rpc/URIHandlerDispatcher.java +++ b/src/main/java/com/webank/wecross/network/rpc/URIHandlerDispatcher.java @@ -73,6 +73,7 @@ public void initializeRequestMapper(WeCrossHost host) { new TransactionURIHandler(transactionFetcher, host.getAccountManager()); registerURIHandler(new URIMethod("GET", "/trans/getTransaction"), transactionURIHandler); registerURIHandler(new URIMethod("GET", "/trans/listTransactions"), transactionURIHandler); + registerURIHandler(new URIMethod("GET", "/trans/getBlock"), transactionURIHandler); ConnectionURIHandler connectionURIHandler = new ConnectionURIHandler(); connectionURIHandler.setP2PService(host.getP2PService()); diff --git a/src/main/java/com/webank/wecross/network/rpc/handler/ResourceURIHandler.java b/src/main/java/com/webank/wecross/network/rpc/handler/ResourceURIHandler.java index 42e9cbd12..88f63fed6 100644 --- a/src/main/java/com/webank/wecross/network/rpc/handler/ResourceURIHandler.java +++ b/src/main/java/com/webank/wecross/network/rpc/handler/ResourceURIHandler.java @@ -152,6 +152,12 @@ public void handle( return; } + logger.info( + "resource sendTransaction, path: {}, request: {}, ua: {}", + path, + restRequest.getData(), + ua.getName()); + resourceObj.asyncSendTransaction( transactionRequest, ua, @@ -186,6 +192,11 @@ public void handle( new TypeReference>() {}); restRequest.checkRestRequest(); + logger.info( + "resourceCall, path: {}, request: {}, ua: {}", + path, + restRequest.getData(), + ua.getName()); TransactionRequest transactionRequest = restRequest.getData(); Resource resourceObj = getResource(path); @@ -224,10 +235,6 @@ public void handle( } case "customcommand": { - if (logger.isDebugEnabled()) { - logger.debug("zone: {}, chain: {}", path.getZone(), path.getChain()); - } - ZoneManager zoneManager = host.getZoneManager(); Zone zone = zoneManager.getZone(path.getZone()); if (Objects.isNull(zone)) { @@ -244,6 +251,14 @@ public void handle( content, new TypeReference>() {}); + logger.info( + "resource customCommand, zone: {}, chain: {}, command:{}, args:{}, ua:{}", + path.getZone(), + path.getChain(), + restRequest.getData().getCommand(), + restRequest.getData().getArgs(), + ua.getName()); + chain.asyncCustomCommand( restRequest.getData().getCommand(), path, diff --git a/src/main/java/com/webank/wecross/network/rpc/handler/SystemInfoHandler.java b/src/main/java/com/webank/wecross/network/rpc/handler/SystemInfoHandler.java index 611da1d9f..36337719d 100644 --- a/src/main/java/com/webank/wecross/network/rpc/handler/SystemInfoHandler.java +++ b/src/main/java/com/webank/wecross/network/rpc/handler/SystemInfoHandler.java @@ -9,6 +9,8 @@ import com.webank.wecross.restserver.response.StubResponse; import com.webank.wecross.stubmanager.StubManager; import com.webank.wecross.zone.ZoneManager; +import java.io.File; +import java.lang.management.ManagementFactory; import java.security.Provider; import java.security.Security; import java.util.stream.Collectors; @@ -77,6 +79,13 @@ private class SystemStatus { private String namedGroups; private String disabledNamedGroups; + private String totalDiskSpace; + private String totalDiskFreeSpace; + private String totalDiskUsable; + + private String totalMemorySize; + private String freeMemorySize; + public String getOsName() { return osName; } @@ -164,6 +173,46 @@ public String getDisabledNamedGroups() { public void setDisabledNamedGroups(String disabledNamedGroups) { this.disabledNamedGroups = disabledNamedGroups; } + + public String getTotalDiskSpace() { + return totalDiskSpace; + } + + public void setTotalDiskSpace(String totalDiskSpace) { + this.totalDiskSpace = totalDiskSpace; + } + + public String getTotalDiskFreeSpace() { + return totalDiskFreeSpace; + } + + public void setTotalDiskFreeSpace(String totalDiskFreeSpace) { + this.totalDiskFreeSpace = totalDiskFreeSpace; + } + + public String getTotalDiskUsable() { + return totalDiskUsable; + } + + public void setTotalDiskUsable(String totalDiskUsable) { + this.totalDiskUsable = totalDiskUsable; + } + + public String getTotalMemorySize() { + return totalMemorySize; + } + + public void setTotalMemorySize(String totalMemorySize) { + this.totalMemorySize = totalMemorySize; + } + + public String getFreeMemorySize() { + return freeMemorySize; + } + + public void setFreeMemorySize(String freeMemorySize) { + this.freeMemorySize = freeMemorySize; + } } private void systemStatus( @@ -185,6 +234,32 @@ private void systemStatus( status.setProviderName(provider.getName()); status.setProviderVersion(String.valueOf(provider.getVersion())); + // disk space usage + File[] disks = File.listRoots(); + long total = 0; + long free = 0; + long usable = 0; + for (File disk : disks) { + // B to GB + total += disk.getTotalSpace() / 1024 / 1024 / 1024; + free += disk.getFreeSpace() / 1024 / 1024 / 1024; + usable += disk.getUsableSpace() / 1024 / 1024 / 1024; + } + status.setTotalDiskSpace(total + "GB"); + status.setTotalDiskFreeSpace(free + "GB"); + status.setTotalDiskUsable(usable + "GB"); + + // memory usage + com.sun.management.OperatingSystemMXBean operatingSystemMXBean = + (com.sun.management.OperatingSystemMXBean) + ManagementFactory.getOperatingSystemMXBean(); + long totalPhysicalMemorySize = + operatingSystemMXBean.getTotalPhysicalMemorySize() / 1024 / 1024 / 1024; + long freePhysicalMemorySize = + operatingSystemMXBean.getFreePhysicalMemorySize() / 1024 / 1024 / 1024; + status.setTotalMemorySize(totalPhysicalMemorySize + "GB"); + status.setFreeMemorySize(freePhysicalMemorySize + "GB"); + RestResponse restResponse = new RestResponse(); restResponse.setData(status); diff --git a/src/main/java/com/webank/wecross/network/rpc/handler/TransactionURIHandler.java b/src/main/java/com/webank/wecross/network/rpc/handler/TransactionURIHandler.java index be8748bea..45928f748 100644 --- a/src/main/java/com/webank/wecross/network/rpc/handler/TransactionURIHandler.java +++ b/src/main/java/com/webank/wecross/network/rpc/handler/TransactionURIHandler.java @@ -1,14 +1,19 @@ package com.webank.wecross.network.rpc.handler; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.webank.wecross.account.AccountAccessControlFilter; import com.webank.wecross.account.AccountManager; import com.webank.wecross.account.UniversalAccount; import com.webank.wecross.account.UserContext; import com.webank.wecross.common.NetworkQueryStatus; import com.webank.wecross.common.WeCrossDefault; +import com.webank.wecross.exception.WeCrossException; import com.webank.wecross.network.UriDecoder; +import com.webank.wecross.restserver.RestRequest; import com.webank.wecross.restserver.RestResponse; import com.webank.wecross.restserver.fetcher.TransactionFetcher; +import com.webank.wecross.restserver.request.BlockRequest; import com.webank.wecross.stub.*; import java.util.Objects; import org.slf4j.Logger; @@ -18,6 +23,7 @@ public class TransactionURIHandler implements URIHandler { private static final Logger logger = LoggerFactory.getLogger(TransactionURIHandler.class); + private final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); private TransactionFetcher transactionFetcher; @@ -211,6 +217,12 @@ public void handle( }); return; } + case "getBlock": + { + getBlockRequest( + userContext, callback, restResponse, uri, content, uriDecoder); + return; + } default: { logger.warn("Unsupported method: {}", method); @@ -226,4 +238,99 @@ public void handle( } callback.onResponse(restResponse); } + + private void getBlockRequest( + UserContext userContext, + Callback callback, + RestResponse restResponse, + String uri, + String content, + UriDecoder uriDecoder) { + String path; + long blockNumber; + + try { + if (uri.contains("path=") && uri.contains("blockNumber=")) { + try { + path = uriDecoder.getQueryBykey("path"); + blockNumber = Long.parseLong(uriDecoder.getQueryBykey("blockNumber")); + } catch (Exception e) { + restResponse.setErrorCode(NetworkQueryStatus.URI_QUERY_ERROR); + restResponse.setMessage(e.getMessage()); + callback.onResponse(restResponse); + return; + } + } else { + RestRequest blockRequest = + objectMapper.readValue( + content, new TypeReference>() {}); + blockRequest.checkRestRequest(); + blockNumber = blockRequest.getData().getBlockNumber(); + path = blockRequest.getData().getPath(); + } + Path chain; + try { + chain = Path.decode(path); + } catch (Exception e) { + logger.warn("Decode chain path error: {}", path); + restResponse.setErrorCode(NetworkQueryStatus.URI_QUERY_ERROR); + restResponse.setMessage("Decode chain path error"); + callback.onResponse(restResponse); + return; + } + // check permission + try { + UniversalAccount ua = accountManager.getUniversalAccount(userContext); + AccountAccessControlFilter filter = ua.getAccessControlFilter(); + if (!filter.hasPermission(path)) { + throw new Exception("Permission denied"); + } + } catch (Exception e) { + logger.warn("Verify permission failed. path:{} error: {}", path, e); + restResponse.setErrorCode(NetworkQueryStatus.URI_QUERY_ERROR); + restResponse.setMessage("Verify permission failed"); + callback.onResponse(restResponse); + return; + } + + transactionFetcher.asyncGetBlock( + chain, + blockNumber, + (fetchException, response) -> { + if (logger.isDebugEnabled()) { + logger.debug( + "getBlock, response: {}, fetchException: ", + response, + fetchException); + } + + if (Objects.nonNull(fetchException)) { + logger.warn("Failed to get block: ", fetchException); + restResponse.setErrorCode( + NetworkQueryStatus.TRANSACTION_ERROR + + fetchException.getErrorCode()); + restResponse.setMessage(fetchException.getMessage()); + } else { + try { + restResponse.setData(objectMapper.writeValueAsString(response)); + } catch (Exception e) { + restResponse.setErrorCode(NetworkQueryStatus.INTERNAL_ERROR); + restResponse.setMessage("Encode block error"); + } + } + + callback.onResponse(restResponse); + }); + } catch (WeCrossException e) { + logger.warn("Process request error: ", e); + restResponse.setErrorCode(NetworkQueryStatus.NETWORK_PACKAGE_ERROR + e.getErrorCode()); + restResponse.setMessage(e.getMessage()); + callback.onResponse(restResponse); + } catch (Exception e) { + logger.warn("Process request error: ", e); + restResponse.setErrorCode(NetworkQueryStatus.INTERNAL_ERROR); + restResponse.setMessage(e.getMessage()); + callback.onResponse(restResponse); + } + } } diff --git a/src/main/java/com/webank/wecross/restserver/fetcher/TransactionFetcher.java b/src/main/java/com/webank/wecross/restserver/fetcher/TransactionFetcher.java index 0b2a820fc..6ed12f6b1 100644 --- a/src/main/java/com/webank/wecross/restserver/fetcher/TransactionFetcher.java +++ b/src/main/java/com/webank/wecross/restserver/fetcher/TransactionFetcher.java @@ -5,6 +5,7 @@ import com.webank.wecross.exception.WeCrossException; import com.webank.wecross.restserver.response.CompleteTransactionResponse; import com.webank.wecross.restserver.response.TransactionListResponse; +import com.webank.wecross.stub.Block; import com.webank.wecross.stub.Driver; import com.webank.wecross.stub.Path; import com.webank.wecross.stub.StubConstant; @@ -113,6 +114,39 @@ public void asyncFetchTransaction( }); } + public interface FetchBlockCallback { + void onResponse(WeCrossException e, Block response); + } + + public void asyncGetBlock(Path chainPath, Long blockNumber, FetchBlockCallback callback) { + Chain chain = zoneManager.getChain(chainPath); + Driver driver = chain.getDriver(); + driver.asyncGetBlock( + blockNumber, + false, + chain.chooseConnection(), + (e, block) -> { + if (Objects.nonNull(e)) { + logger.warn( + "Failed to get block, chain: {}, blockNumber: {}, e:", + chainPath, + blockNumber, + e); + callback.onResponse( + new WeCrossException( + WeCrossException.ErrorCode.GET_BLOCK_ERROR, e.getMessage()), + null); + return; + } + + if (logger.isDebugEnabled()) { + logger.debug("getBlock, blockNumber: {}, block: {}", blockNumber, block); + } + + callback.onResponse(null, block); + }); + } + public interface FetchTransactionListCallback { void onResponse(WeCrossException e, TransactionListResponse response); } diff --git a/src/main/java/com/webank/wecross/restserver/request/BlockRequest.java b/src/main/java/com/webank/wecross/restserver/request/BlockRequest.java new file mode 100644 index 000000000..737c4f08e --- /dev/null +++ b/src/main/java/com/webank/wecross/restserver/request/BlockRequest.java @@ -0,0 +1,29 @@ +package com.webank.wecross.restserver.request; + +public class BlockRequest { + private long blockNumber; + private String path; + + public BlockRequest() {} + + public BlockRequest(long blockNumber, String path) { + this.blockNumber = blockNumber; + this.path = path; + } + + public long getBlockNumber() { + return blockNumber; + } + + public void setBlockNumber(long blockNumber) { + this.blockNumber = blockNumber; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} diff --git a/src/main/java/com/webank/wecross/stub/Block.java b/src/main/java/com/webank/wecross/stub/Block.java index 20f88681b..c00ff8ace 100644 --- a/src/main/java/com/webank/wecross/stub/Block.java +++ b/src/main/java/com/webank/wecross/stub/Block.java @@ -1,11 +1,12 @@ package com.webank.wecross.stub; +import com.fasterxml.jackson.annotation.JsonIgnore; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class Block { - public byte[] rawBytes; + @JsonIgnore public byte[] rawBytes; public BlockHeader blockHeader; public List transactionsHashes = new LinkedList<>(); diff --git a/src/test/java/com/webank/wecross/test/rpc/URIHandlerDispatcherTest.java b/src/test/java/com/webank/wecross/test/rpc/URIHandlerDispatcherTest.java index 175080ee6..40efc2bda 100644 --- a/src/test/java/com/webank/wecross/test/rpc/URIHandlerDispatcherTest.java +++ b/src/test/java/com/webank/wecross/test/rpc/URIHandlerDispatcherTest.java @@ -26,7 +26,7 @@ public void URIHandlerDispatcherTest() throws Exception { URIHandlerDispatcher uriHandlerDispatcher = new URIHandlerDispatcher(); uriHandlerDispatcher.initializeRequestMapper(host); - Assert.assertTrue(uriHandlerDispatcher.getRequestURIMapper().size() == 24); + Assert.assertTrue(uriHandlerDispatcher.getRequestURIMapper().size() == 25); Assert.assertTrue( Objects.nonNull(