Skip to content

Commit 14c72b5

Browse files
committed
Refactor client CLIs (#324)
1 parent f1c1cfa commit 14c72b5

30 files changed

+454
-680
lines changed

client/src/main/java/com/scalar/dl/client/error/ClientError.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public enum ClientError implements ScalarDlError {
116116
StatusCode.RUNTIME_ERROR, "004", "Processing JSON failed. Details: %s", "", ""),
117117
CLASS_FILE_LOAD_FAILED(
118118
StatusCode.RUNTIME_ERROR, "005", "Failed to load the class file. File: %s", "", ""),
119+
WRITING_RESULT_TO_FILE_FAILED(
120+
StatusCode.RUNTIME_ERROR, "006", "Failed to write the result to a file. Details: %s", "", ""),
119121
;
120122

121123
private static final String COMPONENT_NAME = "DL-CLIENT";
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.scalar.dl.client.tool;
2+
3+
import com.google.common.annotations.VisibleForTesting;
4+
import com.scalar.dl.client.config.ClientConfig;
5+
import com.scalar.dl.client.config.GatewayClientConfig;
6+
import com.scalar.dl.client.exception.ClientException;
7+
import com.scalar.dl.client.service.ClientService;
8+
import com.scalar.dl.client.service.ClientServiceFactory;
9+
import java.io.File;
10+
import java.util.concurrent.Callable;
11+
12+
public abstract class AbstractClientCommand extends CommonOptions implements Callable<Integer> {
13+
14+
@Override
15+
public final Integer call() throws Exception {
16+
return call(new ClientServiceFactory());
17+
}
18+
19+
@VisibleForTesting
20+
public final Integer call(ClientServiceFactory factory) throws Exception {
21+
try {
22+
ClientService service =
23+
useGateway
24+
? factory.create(new GatewayClientConfig(new File(properties)))
25+
: factory.create(new ClientConfig(new File(properties)));
26+
return execute(service);
27+
} catch (ClientException e) {
28+
Common.printError(e);
29+
printStackTrace(e);
30+
return 1;
31+
} finally {
32+
factory.close();
33+
}
34+
}
35+
36+
/**
37+
* Executes the specific command logic.
38+
*
39+
* @param service the client service to use for execution.
40+
* @return the exit code.
41+
* @throws ClientException if the execution fails.
42+
*/
43+
protected abstract Integer execute(ClientService service) throws ClientException;
44+
}
Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,18 @@
11
package com.scalar.dl.client.tool;
22

3-
import com.google.common.annotations.VisibleForTesting;
4-
import com.scalar.dl.client.config.ClientConfig;
5-
import com.scalar.dl.client.config.GatewayClientConfig;
63
import com.scalar.dl.client.exception.ClientException;
74
import com.scalar.dl.client.service.ClientService;
8-
import com.scalar.dl.client.service.ClientServiceFactory;
9-
import java.io.File;
10-
import java.util.concurrent.Callable;
115
import picocli.CommandLine.Command;
126

137
@Command(
148
name = "bootstrap",
159
description = "Bootstrap the ledger by registering identity and system contracts.")
16-
public class Bootstrap extends CommonOptions implements Callable<Integer> {
10+
public class Bootstrap extends AbstractClientCommand {
1711

1812
@Override
19-
public Integer call() throws Exception {
20-
return call(new ClientServiceFactory());
21-
}
22-
23-
@VisibleForTesting
24-
Integer call(ClientServiceFactory factory) throws Exception {
25-
ClientService service =
26-
useGateway
27-
? factory.create(new GatewayClientConfig(new File(properties)))
28-
: factory.create(new ClientConfig(new File(properties)));
29-
return call(factory, service);
30-
}
31-
32-
@VisibleForTesting
33-
Integer call(ClientServiceFactory factory, ClientService service) {
34-
try {
35-
service.bootstrap();
36-
Common.printOutput(null);
37-
return 0;
38-
} catch (ClientException e) {
39-
Common.printError(e);
40-
printStackTrace(e);
41-
return 1;
42-
} finally {
43-
factory.close();
44-
}
13+
protected Integer execute(ClientService service) throws ClientException {
14+
service.bootstrap();
15+
Common.printOutput(null);
16+
return 0;
4517
}
4618
}
Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,22 @@
11
package com.scalar.dl.client.tool;
22

3-
import com.google.common.annotations.VisibleForTesting;
4-
import com.scalar.dl.client.config.ClientConfig;
5-
import com.scalar.dl.client.config.GatewayClientConfig;
63
import com.scalar.dl.client.exception.ClientException;
74
import com.scalar.dl.client.service.ClientService;
8-
import com.scalar.dl.client.service.ClientServiceFactory;
9-
import java.io.File;
10-
import java.util.concurrent.Callable;
115
import picocli.CommandLine;
126
import picocli.CommandLine.Command;
137

148
@Command(name = "register-cert", description = "Register a specified certificate.")
15-
public class CertificateRegistration extends CommonOptions implements Callable<Integer> {
9+
public class CertificateRegistration extends AbstractClientCommand {
1610

1711
public static void main(String[] args) {
1812
int exitCode = new CommandLine(new CertificateRegistration()).execute(args);
1913
System.exit(exitCode);
2014
}
2115

2216
@Override
23-
public Integer call() throws Exception {
24-
return call(new ClientServiceFactory());
25-
}
26-
27-
@VisibleForTesting
28-
Integer call(ClientServiceFactory factory) throws Exception {
29-
ClientService service =
30-
useGateway
31-
? factory.create(new GatewayClientConfig(new File(properties)))
32-
: factory.create(new ClientConfig(new File(properties)));
33-
return call(factory, service);
34-
}
35-
36-
@VisibleForTesting
37-
Integer call(ClientServiceFactory factory, ClientService service) {
38-
try {
39-
service.registerCertificate();
40-
Common.printOutput(null);
41-
return 0;
42-
} catch (ClientException e) {
43-
Common.printError(e);
44-
printStackTrace(e);
45-
return 1;
46-
} finally {
47-
factory.close();
48-
}
17+
protected Integer execute(ClientService service) throws ClientException {
18+
service.registerCertificate();
19+
Common.printOutput(null);
20+
return 0;
4921
}
5022
}

client/src/main/java/com/scalar/dl/client/tool/ContractExecution.java

Lines changed: 32 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,15 @@
22

33
import com.fasterxml.jackson.databind.JsonNode;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.google.common.annotations.VisibleForTesting;
6-
import com.scalar.dl.client.config.ClientConfig;
7-
import com.scalar.dl.client.config.GatewayClientConfig;
85
import com.scalar.dl.client.exception.ClientException;
96
import com.scalar.dl.client.service.ClientService;
10-
import com.scalar.dl.client.service.ClientServiceFactory;
117
import com.scalar.dl.ledger.model.ContractExecutionResult;
128
import com.scalar.dl.ledger.util.JacksonSerDe;
13-
import java.io.File;
14-
import java.util.concurrent.Callable;
159
import picocli.CommandLine;
1610
import picocli.CommandLine.Command;
1711

1812
@Command(name = "execute-contract", description = "Execute a specified contract.")
19-
public class ContractExecution extends CommonOptions implements Callable<Integer> {
13+
public class ContractExecution extends AbstractClientCommand {
2014

2115
@CommandLine.Option(
2216
names = {"--contract-id"},
@@ -61,63 +55,41 @@ public static void main(String[] args) {
6155
}
6256

6357
@Override
64-
public Integer call() throws Exception {
65-
return call(new ClientServiceFactory());
66-
}
67-
68-
@VisibleForTesting
69-
Integer call(ClientServiceFactory factory) throws Exception {
70-
ClientService service =
71-
useGateway
72-
? factory.create(new GatewayClientConfig(new File(properties)))
73-
: factory.create(new ClientConfig(new File(properties)));
74-
return call(factory, service);
75-
}
76-
77-
@VisibleForTesting
78-
Integer call(ClientServiceFactory factory, ClientService service) throws Exception {
58+
protected Integer execute(ClientService service) throws ClientException {
7959
JacksonSerDe serde = new JacksonSerDe(new ObjectMapper());
8060

81-
try {
82-
if (deserializationFormat == DeserializationFormat.JSON) {
83-
JsonNode jsonContractArgument = serde.deserialize(contractArgument);
84-
JsonNode jsonFunctionArgument = null;
85-
if (functionArgument != null) {
86-
jsonFunctionArgument = serde.deserialize(functionArgument);
87-
}
88-
ContractExecutionResult result =
89-
service.executeContract(
90-
contractId, jsonContractArgument, functionId, jsonFunctionArgument);
91-
92-
result
93-
.getContractResult()
94-
.ifPresent(
95-
r -> {
96-
System.out.println("Contract result:");
97-
Common.printJson(serde.deserialize(r));
98-
});
99-
result
100-
.getFunctionResult()
101-
.ifPresent(
102-
r -> {
103-
System.out.println("Function result:");
104-
Common.printJson(serde.deserialize(r));
105-
});
106-
} else if (deserializationFormat == DeserializationFormat.STRING) {
107-
ContractExecutionResult result =
108-
service.executeContract(contractId, contractArgument, functionId, functionArgument);
109-
110-
result.getContractResult().ifPresent(r -> System.out.println("Contract result: " + r));
111-
result.getFunctionResult().ifPresent(r -> System.out.println("Function result: " + r));
61+
if (deserializationFormat == DeserializationFormat.JSON) {
62+
JsonNode jsonContractArgument = serde.deserialize(contractArgument);
63+
JsonNode jsonFunctionArgument = null;
64+
if (functionArgument != null) {
65+
jsonFunctionArgument = serde.deserialize(functionArgument);
11266
}
67+
ContractExecutionResult result =
68+
service.executeContract(
69+
contractId, jsonContractArgument, functionId, jsonFunctionArgument);
11370

114-
return 0;
115-
} catch (ClientException e) {
116-
Common.printError(e);
117-
printStackTrace(e);
118-
return 1;
119-
} finally {
120-
factory.close();
71+
result
72+
.getContractResult()
73+
.ifPresent(
74+
r -> {
75+
System.out.println("Contract result:");
76+
Common.printJson(serde.deserialize(r));
77+
});
78+
result
79+
.getFunctionResult()
80+
.ifPresent(
81+
r -> {
82+
System.out.println("Function result:");
83+
Common.printJson(serde.deserialize(r));
84+
});
85+
} else if (deserializationFormat == DeserializationFormat.STRING) {
86+
ContractExecutionResult result =
87+
service.executeContract(contractId, contractArgument, functionId, functionArgument);
88+
89+
result.getContractResult().ifPresent(r -> System.out.println("Contract result: " + r));
90+
result.getFunctionResult().ifPresent(r -> System.out.println("Function result: " + r));
12191
}
92+
93+
return 0;
12294
}
12395
}

client/src/main/java/com/scalar/dl/client/tool/ContractRegistration.java

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@
22

33
import com.fasterxml.jackson.databind.JsonNode;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5-
import com.google.common.annotations.VisibleForTesting;
6-
import com.scalar.dl.client.config.ClientConfig;
7-
import com.scalar.dl.client.config.GatewayClientConfig;
85
import com.scalar.dl.client.exception.ClientException;
96
import com.scalar.dl.client.service.ClientService;
10-
import com.scalar.dl.client.service.ClientServiceFactory;
117
import com.scalar.dl.ledger.util.JacksonSerDe;
12-
import java.io.File;
13-
import java.util.concurrent.Callable;
148
import picocli.CommandLine;
159
import picocli.CommandLine.Command;
1610

1711
@Command(name = "register-contract", description = "Register a specified contract.")
18-
public class ContractRegistration extends CommonOptions implements Callable<Integer> {
12+
public class ContractRegistration extends AbstractClientCommand {
1913

2014
@CommandLine.Option(
2115
names = {"--contract-id"},
@@ -60,42 +54,21 @@ public static void main(String[] args) {
6054
}
6155

6256
@Override
63-
public Integer call() throws Exception {
64-
return call(new ClientServiceFactory());
65-
}
66-
67-
@VisibleForTesting
68-
Integer call(ClientServiceFactory factory) throws Exception {
69-
ClientService service =
70-
useGateway
71-
? factory.create(new GatewayClientConfig(new File(properties)))
72-
: factory.create(new ClientConfig(new File(properties)));
73-
return call(factory, service);
74-
}
75-
76-
Integer call(ClientServiceFactory factory, ClientService service) {
57+
protected Integer execute(ClientService service) throws ClientException {
7758
JacksonSerDe serde = new JacksonSerDe(new ObjectMapper());
7859

79-
try {
80-
if (deserializationFormat == DeserializationFormat.JSON) {
81-
JsonNode jsonContractProperties = null;
82-
if (contractProperties != null) {
83-
jsonContractProperties = serde.deserialize(contractProperties);
84-
}
85-
service.registerContract(
86-
contractId, contractBinaryName, contractClassFile, jsonContractProperties);
87-
} else if (deserializationFormat == DeserializationFormat.STRING) {
88-
service.registerContract(
89-
contractId, contractBinaryName, contractClassFile, contractProperties);
60+
if (deserializationFormat == DeserializationFormat.JSON) {
61+
JsonNode jsonContractProperties = null;
62+
if (contractProperties != null) {
63+
jsonContractProperties = serde.deserialize(contractProperties);
9064
}
91-
Common.printOutput(null);
92-
return 0;
93-
} catch (ClientException e) {
94-
Common.printError(e);
95-
printStackTrace(e);
96-
return 1;
97-
} finally {
98-
factory.close();
65+
service.registerContract(
66+
contractId, contractBinaryName, contractClassFile, jsonContractProperties);
67+
} else if (deserializationFormat == DeserializationFormat.STRING) {
68+
service.registerContract(
69+
contractId, contractBinaryName, contractClassFile, contractProperties);
9970
}
71+
Common.printOutput(null);
72+
return 0;
10073
}
10174
}

0 commit comments

Comments
 (0)