Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.exonum.binding.common.crypto.PublicKey;
import com.exonum.binding.common.hash.HashCode;
import com.exonum.binding.core.service.Configurable;
import com.exonum.binding.core.service.Node;
import com.exonum.binding.core.service.Service;
import com.exonum.binding.core.transaction.RawTransaction;
Expand All @@ -29,7 +30,7 @@
/**
* A simple service for QA purposes.
*/
public interface QaService extends Service {
public interface QaService extends Service, Configurable {

/**
* Creates a new self-signed 'increment counter' transaction and submits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import com.exonum.binding.core.storage.indices.EntryIndexProxy;
import com.exonum.binding.core.storage.indices.MapIndex;
import com.exonum.binding.core.transaction.RawTransaction;
import com.exonum.binding.qaservice.Config.InitialConfiguration;
import com.exonum.binding.qaservice.Config.QaConfiguration;
import com.exonum.binding.qaservice.transactions.IncrementCounterTx;
import com.exonum.binding.qaservice.transactions.UnknownTx;
import com.exonum.binding.time.TimeSchema;
Expand Down Expand Up @@ -101,7 +101,7 @@ public List<HashCode> getStateHashes(Snapshot snapshot) {
@Override
public void initialize(Fork fork, Configuration configuration) {
// Init the time oracle
initTimeOracle(fork, configuration);
updateTimeOracle(fork, configuration);

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

private void initTimeOracle(Fork fork, Configuration configuration) {
QaSchema schema = createDataSchema(fork);
InitialConfiguration config = configuration.getAsMessage(InitialConfiguration.class);
String timeOracleName = config.getTimeOracleName();
// Check the time oracle name is non-empty.
// We do *not* check if the time oracle is active to (a) allow running this service with
// reduced read functionality without time oracle; (b) testing time schema when it is not
// active.
checkArgument(!Strings.isNullOrEmpty(timeOracleName), "Empty time oracle name: %s",
timeOracleName);
// Save the configuration
schema.timeOracleName().set(timeOracleName);
}

private void createCounter(String name, Fork fork) {
QaSchema schema = createDataSchema(fork);
MapIndex<HashCode, Long> counters = schema.counters();
Expand Down Expand Up @@ -231,4 +217,37 @@ private HashCode submitTransaction(RawTransaction rawTransaction) {
private void checkBlockchainInitialized() {
checkState(node != null, "Service has not been fully initialized yet");
}

@Override
public void verifyConfiguration(Fork fork, Configuration configuration) {
QaConfiguration config = configuration.getAsMessage(QaConfiguration.class);
checkConfiguration(config);
}

@Override
public void applyConfiguration(Fork fork, Configuration configuration) {
updateTimeOracle(fork, configuration);
}

private void checkConfiguration(QaConfiguration config) {
String timeOracleName = config.getTimeOracleName();
// Check the time oracle name is non-empty.
// We do *not* check if the time oracle is active to (a) allow running this service with
// reduced read functionality without time oracle; (b) testing time schema when it is not
// active.
checkArgument(!Strings.isNullOrEmpty(timeOracleName), "Empty time oracle name: %s",
timeOracleName);
}

private void updateTimeOracle(Fork fork, Configuration configuration) {
QaSchema schema = createDataSchema(fork);
QaConfiguration config = configuration.getAsMessage(QaConfiguration.class);

// Verify the configuration
checkConfiguration(config);

// Save the configuration
String timeOracleName = config.getTimeOracleName();
schema.timeOracleName().set(timeOracleName);
}
}
3 changes: 2 additions & 1 deletion exonum-java-binding/qa-service/src/main/proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ package exonum.qa;

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

message InitialConfiguration {
// QA service configuration parameters.
message QaConfiguration {
// The name of a time oracle service instance to use.
string time_oracle_name = 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import static com.google.common.base.Preconditions.checkState;

import com.exonum.binding.core.runtime.ServiceArtifactId;
import com.exonum.binding.qaservice.Config.InitialConfiguration;
import com.exonum.binding.qaservice.Config.QaConfiguration;
import com.exonum.binding.testkit.TestKit;
import com.exonum.binding.testkit.TestKit.Builder;
import com.exonum.binding.testkit.TimeProvider;
Expand All @@ -40,8 +40,8 @@ public final class QaArtifactInfo {
public static final int TIME_SERVICE_ID = 100;
public static final String QA_SERVICE_NAME = "qa";
public static final int QA_SERVICE_ID = 101;
public static final InitialConfiguration QA_SERVICE_INITIAL_CONFIG =
InitialConfiguration.newBuilder()
public static final QaConfiguration QA_SERVICE_INITIAL_CONFIG =
QaConfiguration.newBuilder()
.setTimeOracleName(TIME_SERVICE_NAME)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import com.exonum.binding.core.blockchain.Blockchain;
import com.exonum.binding.core.storage.database.Snapshot;
import com.exonum.binding.core.storage.indices.MapIndex;
import com.exonum.binding.qaservice.Config.InitialConfiguration;
import com.exonum.binding.qaservice.Config.QaConfiguration;
import com.exonum.binding.testkit.EmulatedNode;
import com.exonum.binding.testkit.FakeTimeProvider;
import com.exonum.binding.testkit.TestKit;
Expand Down Expand Up @@ -96,7 +96,7 @@ void initialize() {
.withArtifactsDirectory(QaArtifactInfo.ARTIFACT_DIR)
.withDeployedArtifact(QaArtifactInfo.ARTIFACT_ID, QaArtifactInfo.ARTIFACT_FILENAME)
.withService(QaArtifactInfo.ARTIFACT_ID, serviceName, 1,
InitialConfiguration.newBuilder()
QaConfiguration.newBuilder()
.setTimeOracleName(timeServiceName)
.build())
.withTimeService(timeServiceName, 2, TimeProvider.systemTime())
Expand Down Expand Up @@ -130,7 +130,7 @@ void initializeBadConfig() {
.withArtifactsDirectory(QaArtifactInfo.ARTIFACT_DIR)
.withDeployedArtifact(QaArtifactInfo.ARTIFACT_ID, QaArtifactInfo.ARTIFACT_FILENAME)
.withService(QaArtifactInfo.ARTIFACT_ID, serviceName, 1,
InitialConfiguration.newBuilder()
QaConfiguration.newBuilder()
.setTimeOracleName(timeServiceName)
.build());

Expand Down