Skip to content

Commit 9adb4b9

Browse files
Make QA service configurable [ECR-3869] (#1237)
The integration tests are not added, as they require some dependencies (and it isn't definite if it make sense to create supervisor transactions here). The original test remains available in 015d820.
1 parent f0dd195 commit 9adb4b9

File tree

5 files changed

+45
-24
lines changed

5 files changed

+45
-24
lines changed

exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.exonum.binding.common.crypto.PublicKey;
2020
import com.exonum.binding.common.hash.HashCode;
21+
import com.exonum.binding.core.service.Configurable;
2122
import com.exonum.binding.core.service.Node;
2223
import com.exonum.binding.core.service.Service;
2324
import com.exonum.binding.core.transaction.RawTransaction;
@@ -29,7 +30,7 @@
2930
/**
3031
* A simple service for QA purposes.
3132
*/
32-
public interface QaService extends Service {
33+
public interface QaService extends Service, Configurable {
3334

3435
/**
3536
* Creates a new self-signed 'increment counter' transaction and submits

exonum-java-binding/qa-service/src/main/java/com/exonum/binding/qaservice/QaServiceImpl.java

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import com.exonum.binding.core.storage.indices.EntryIndexProxy;
3737
import com.exonum.binding.core.storage.indices.MapIndex;
3838
import com.exonum.binding.core.transaction.RawTransaction;
39-
import com.exonum.binding.qaservice.Config.InitialConfiguration;
39+
import com.exonum.binding.qaservice.Config.QaConfiguration;
4040
import com.exonum.binding.qaservice.transactions.IncrementCounterTx;
4141
import com.exonum.binding.qaservice.transactions.UnknownTx;
4242
import com.exonum.binding.time.TimeSchema;
@@ -101,7 +101,7 @@ public List<HashCode> getStateHashes(Snapshot snapshot) {
101101
@Override
102102
public void initialize(Fork fork, Configuration configuration) {
103103
// Init the time oracle
104-
initTimeOracle(fork, configuration);
104+
updateTimeOracle(fork, configuration);
105105

106106
// Add a default counter to the blockchain.
107107
createCounter(DEFAULT_COUNTER_NAME, fork);
@@ -110,20 +110,6 @@ public void initialize(Fork fork, Configuration configuration) {
110110
createCounter(AFTER_COMMIT_COUNTER_NAME, fork);
111111
}
112112

113-
private void initTimeOracle(Fork fork, Configuration configuration) {
114-
QaSchema schema = createDataSchema(fork);
115-
InitialConfiguration config = configuration.getAsMessage(InitialConfiguration.class);
116-
String timeOracleName = config.getTimeOracleName();
117-
// Check the time oracle name is non-empty.
118-
// We do *not* check if the time oracle is active to (a) allow running this service with
119-
// reduced read functionality without time oracle; (b) testing time schema when it is not
120-
// active.
121-
checkArgument(!Strings.isNullOrEmpty(timeOracleName), "Empty time oracle name: %s",
122-
timeOracleName);
123-
// Save the configuration
124-
schema.timeOracleName().set(timeOracleName);
125-
}
126-
127113
private void createCounter(String name, Fork fork) {
128114
QaSchema schema = createDataSchema(fork);
129115
MapIndex<HashCode, Long> counters = schema.counters();
@@ -231,4 +217,37 @@ private HashCode submitTransaction(RawTransaction rawTransaction) {
231217
private void checkBlockchainInitialized() {
232218
checkState(node != null, "Service has not been fully initialized yet");
233219
}
220+
221+
@Override
222+
public void verifyConfiguration(Fork fork, Configuration configuration) {
223+
QaConfiguration config = configuration.getAsMessage(QaConfiguration.class);
224+
checkConfiguration(config);
225+
}
226+
227+
@Override
228+
public void applyConfiguration(Fork fork, Configuration configuration) {
229+
updateTimeOracle(fork, configuration);
230+
}
231+
232+
private void checkConfiguration(QaConfiguration config) {
233+
String timeOracleName = config.getTimeOracleName();
234+
// Check the time oracle name is non-empty.
235+
// We do *not* check if the time oracle is active to (a) allow running this service with
236+
// reduced read functionality without time oracle; (b) testing time schema when it is not
237+
// active.
238+
checkArgument(!Strings.isNullOrEmpty(timeOracleName), "Empty time oracle name: %s",
239+
timeOracleName);
240+
}
241+
242+
private void updateTimeOracle(Fork fork, Configuration configuration) {
243+
QaSchema schema = createDataSchema(fork);
244+
QaConfiguration config = configuration.getAsMessage(QaConfiguration.class);
245+
246+
// Verify the configuration
247+
checkConfiguration(config);
248+
249+
// Save the configuration
250+
String timeOracleName = config.getTimeOracleName();
251+
schema.timeOracleName().set(timeOracleName);
252+
}
234253
}

exonum-java-binding/qa-service/src/main/proto/config.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ package exonum.qa;
44

55
option java_package = "com.exonum.binding.qaservice";
66

7-
message InitialConfiguration {
7+
// QA service configuration parameters.
8+
message QaConfiguration {
89
// The name of a time oracle service instance to use.
910
string time_oracle_name = 1;
1011
}

exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaArtifactInfo.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import static com.google.common.base.Preconditions.checkState;
2020

2121
import com.exonum.binding.core.runtime.ServiceArtifactId;
22-
import com.exonum.binding.qaservice.Config.InitialConfiguration;
22+
import com.exonum.binding.qaservice.Config.QaConfiguration;
2323
import com.exonum.binding.testkit.TestKit;
2424
import com.exonum.binding.testkit.TestKit.Builder;
2525
import com.exonum.binding.testkit.TimeProvider;
@@ -40,8 +40,8 @@ public final class QaArtifactInfo {
4040
public static final int TIME_SERVICE_ID = 100;
4141
public static final String QA_SERVICE_NAME = "qa";
4242
public static final int QA_SERVICE_ID = 101;
43-
public static final InitialConfiguration QA_SERVICE_INITIAL_CONFIG =
44-
InitialConfiguration.newBuilder()
43+
public static final QaConfiguration QA_SERVICE_INITIAL_CONFIG =
44+
QaConfiguration.newBuilder()
4545
.setTimeOracleName(TIME_SERVICE_NAME)
4646
.build();
4747

exonum-java-binding/qa-service/src/test/java/com/exonum/binding/qaservice/QaServiceImplTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
import com.exonum.binding.core.blockchain.Blockchain;
4646
import com.exonum.binding.core.storage.database.Snapshot;
4747
import com.exonum.binding.core.storage.indices.MapIndex;
48-
import com.exonum.binding.qaservice.Config.InitialConfiguration;
48+
import com.exonum.binding.qaservice.Config.QaConfiguration;
4949
import com.exonum.binding.testkit.EmulatedNode;
5050
import com.exonum.binding.testkit.FakeTimeProvider;
5151
import com.exonum.binding.testkit.TestKit;
@@ -96,7 +96,7 @@ void initialize() {
9696
.withArtifactsDirectory(QaArtifactInfo.ARTIFACT_DIR)
9797
.withDeployedArtifact(QaArtifactInfo.ARTIFACT_ID, QaArtifactInfo.ARTIFACT_FILENAME)
9898
.withService(QaArtifactInfo.ARTIFACT_ID, serviceName, 1,
99-
InitialConfiguration.newBuilder()
99+
QaConfiguration.newBuilder()
100100
.setTimeOracleName(timeServiceName)
101101
.build())
102102
.withTimeService(timeServiceName, 2, TimeProvider.systemTime())
@@ -130,7 +130,7 @@ void initializeBadConfig() {
130130
.withArtifactsDirectory(QaArtifactInfo.ARTIFACT_DIR)
131131
.withDeployedArtifact(QaArtifactInfo.ARTIFACT_ID, QaArtifactInfo.ARTIFACT_FILENAME)
132132
.withService(QaArtifactInfo.ARTIFACT_ID, serviceName, 1,
133-
InitialConfiguration.newBuilder()
133+
QaConfiguration.newBuilder()
134134
.setTimeOracleName(timeServiceName)
135135
.build());
136136

0 commit comments

Comments
 (0)