Skip to content

Commit 3dea2f1

Browse files
authored
Merge branch 'master' into ecr-2867-1
2 parents da380b4 + 750cca1 commit 3dea2f1

File tree

19 files changed

+813
-250
lines changed

19 files changed

+813
-250
lines changed

exonum-java-binding/CHANGELOG.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2424
- `--jvm-debug` command line argument that allows JDWP debugging of node. (#629)
2525
- Support of separated messages format Exonum v0.10. (#574)
2626
- `ListIndexProxy#stream` to enable stream processing of list elements. (#661)
27+
- Support of Time oracle. Instruction on how to enable built-in services can be found
28+
[here](https://exonum.com/doc/version/0.4/get-started/java-binding/#built-in-services). (#667)
2729

2830
### Changed
2931
- `com.exonum.binding.storage.indices.MapEntry` moved to package
@@ -34,17 +36,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3436
`Generate-Config`. Also, the value of `--jvm-args-append` is not saved to any of the configuration
3537
files. (#629)
3638
- `Node#getPublicKey` to return `PublicKey` instead of `byte[]`. (#651)
37-
- `com.exonum.binding.transaction.Transaction#execute` now accepts
39+
- `com.exonum.binding.transaction.Transaction#execute` now accepts
3840
`com.exonum.binding.transaction.TransactionContext`
39-
instead of `com.exonum.binding.storage.database.View`
41+
instead of `com.exonum.binding.storage.database.View`
4042

4143
### Removed
4244
- `com.exonum.binding.common.proofs.map.MapEntry` — moved to package
4345
`com.exonum.binding.common.collect`.
4446
- `ViewModificationCounter` replaced with per-`View` modification counters to simplify
4547
their relationship and testing. (#658)
4648
- Exonum v0.9 message format related classes.
47-
49+
4850
### Fixed
4951
- A bug in the cryptocurrency demo frontend that sometimes resulted in rejected transactions and/or
5052
wrong response code (#621).

exonum-java-binding/core/rust/Cargo.lock

Lines changed: 126 additions & 110 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exonum-java-binding/core/rust/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ invocation = ["jni/invocation"]
1616

1717
[dependencies]
1818
exonum = "0.10"
19+
exonum-time = "0.10"
1920
failure = "0.1.1"
2021
toml = "0.4.6"
2122
# Point EJB to revision of master that introduces JNIEnv#clone()
@@ -29,3 +30,6 @@ serde_json = "1.0.38"
2930

3031
[profile.dev]
3132
rpath = true
33+
34+
[dev-dependencies]
35+
tempfile = "3"

exonum-java-binding/core/rust/ejb-app/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ authors = ["Exonum team <exonum@bitfury.com>"]
1111
java_bindings = { path = "..", features = ["invocation", "resource-manager"] }
1212
exonum-configuration = "0.10"
1313
exonum-btc-anchoring = "0.10"
14+
exonum-time = "0.10"
1415
toml = "0.4.6"
1516
serde = "1.0"
1617
serde_derive = "1.0"

exonum-java-binding/core/rust/ejb-app/src/main.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@
1616

1717
extern crate exonum_btc_anchoring;
1818
extern crate exonum_configuration;
19+
extern crate exonum_time;
1920
extern crate java_bindings;
20-
extern crate serde;
21-
#[macro_use]
22-
extern crate serde_derive;
23-
extern crate toml;
2421

2522
#[cfg(test)]
2623
extern crate tempfile;

exonum-java-binding/core/rust/ejb-app/src/node_builder.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,17 @@
1616

1717
use exonum_btc_anchoring::ServiceFactory as BtcAnchoringServiceFactory;
1818
use exonum_configuration::ServiceFactory as ConfigurationServiceFactory;
19+
use exonum_time::TimeServiceFactory;
1920
use java_bindings::exonum::helpers::fabric::{self, ServiceFactory};
21+
use java_bindings::utils::{
22+
load_enabled_services, BTC_ANCHORING_SERVICE, CONFIGURATION_SERVICE, EJB_SERVICE,
23+
PATH_TO_SERVICES_TO_ENABLE, TIME_SERVICE,
24+
};
2025
use java_bindings::JavaServiceFactory;
21-
use toml;
2226

2327
use std::collections::{HashMap, HashSet};
24-
use std::fs::File;
25-
use std::io::Read;
2628
use std::path::Path;
2729

28-
const PATH_TO_SERVICES_TO_ENABLE: &str = "ejb_app_services.toml";
29-
const CONFIGURATION_SERVICE: &str = "configuration";
30-
const BTC_ANCHORING_SERVICE: &str = "btc-anchoring";
31-
const EJB_SERVICE: &str = "ejb-service";
32-
33-
#[derive(Serialize, Deserialize)]
34-
struct ServicesToEnable {
35-
services: HashSet<String>,
36-
}
37-
3830
fn service_factories() -> HashMap<String, Box<ServiceFactory>> {
3931
let mut service_factories = HashMap::new();
4032
service_factories.insert(
@@ -45,6 +37,10 @@ fn service_factories() -> HashMap<String, Box<ServiceFactory>> {
4537
BTC_ANCHORING_SERVICE.to_owned(),
4638
Box::new(BtcAnchoringServiceFactory) as Box<ServiceFactory>,
4739
);
40+
service_factories.insert(
41+
TIME_SERVICE.to_owned(),
42+
Box::new(TimeServiceFactory) as Box<ServiceFactory>,
43+
);
4844
service_factories.insert(
4945
EJB_SERVICE.to_owned(),
5046
Box::new(JavaServiceFactory) as Box<ServiceFactory>,
@@ -55,17 +51,11 @@ fn service_factories() -> HashMap<String, Box<ServiceFactory>> {
5551
#[doc(hidden)]
5652
pub fn services_to_enable<P: AsRef<Path>>(path: P) -> HashSet<String> {
5753
// Return default list if config file not found.
58-
let mut services = if let Ok(mut file) = File::open(path) {
59-
let mut toml = String::new();
60-
file.read_to_string(&mut toml).unwrap();
61-
let ServicesToEnable { services } =
62-
toml::from_str(&toml).expect("Invalid list of services to enable");
63-
services
64-
} else {
54+
let mut services = load_enabled_services(path).unwrap_or_else(|_| {
6555
let mut services = HashSet::new();
6656
services.insert(CONFIGURATION_SERVICE.to_owned());
6757
services
68-
};
58+
});
6959

7060
// Add EJB_SERVICE if it's missing
7161
services.insert(EJB_SERVICE.to_owned());
@@ -149,13 +139,14 @@ mod tests {
149139
fn all_services() {
150140
let cfg = create_config(
151141
"all.toml",
152-
"services = [\"configuration\", \"btc-anchoring\"]",
142+
"services = [\"configuration\", \"btc-anchoring\", \"time\"]",
153143
);
154144
let services_to_enable = services_to_enable(cfg);
155-
assert_eq!(services_to_enable.len(), 3);
145+
assert_eq!(services_to_enable.len(), 4);
156146
assert!(services_to_enable.contains(EJB_SERVICE));
157147
assert!(services_to_enable.contains(CONFIGURATION_SERVICE));
158148
assert!(services_to_enable.contains(BTC_ANCHORING_SERVICE));
149+
assert!(services_to_enable.contains(TIME_SERVICE));
159150

160151
let service_factories = service_factories();
161152
for service in &services_to_enable {

exonum-java-binding/core/rust/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ extern crate serde;
3434
extern crate serde_derive;
3535
pub extern crate serde_json;
3636

37-
#[cfg(feature = "resource-manager")]
3837
#[macro_use]
3938
extern crate lazy_static;
4039

40+
#[cfg(test)]
41+
extern crate tempfile;
42+
4143
mod error;
4244
mod init;
4345
mod proxy;

exonum-java-binding/core/rust/src/proxy/service.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ impl Service for ServiceProxy {
197197

198198
fn wire_api(&self, builder: &mut ServiceApiBuilder) {
199199
assert!(builder.blockchain().is_some());
200+
200201
let node = NodeContext::new(
201202
self.exec.clone(),
202203
builder.blockchain().unwrap().clone(),

exonum-java-binding/core/rust/src/utils/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ mod jni;
2222
pub mod jni_cache;
2323
mod pair_iter;
2424
mod resource_manager;
25+
mod services;
26+
mod time_service;
2527

2628
pub use self::conversion::{convert_hash, convert_to_hash, convert_to_string};
2729
pub use self::errors::{
@@ -33,3 +35,7 @@ pub use self::handle::{as_handle, cast_handle, drop_handle, to_handle, Handle};
3335
pub use self::jni::{get_class_name, get_exception_message};
3436
pub use self::pair_iter::PairIter;
3537
pub use self::resource_manager::known_handles;
38+
pub use self::services::{
39+
is_service_enabled_in_config_file, load_enabled_services, BTC_ANCHORING_SERVICE,
40+
CONFIGURATION_SERVICE, EJB_SERVICE, PATH_TO_SERVICES_TO_ENABLE, TIME_SERVICE,
41+
};
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2019 The Exonum Team
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use std::{collections::HashSet, fs::File, io::Read, path::Path};
16+
17+
use toml;
18+
19+
pub const PATH_TO_SERVICES_TO_ENABLE: &str = "ejb_app_services.toml";
20+
pub const CONFIGURATION_SERVICE: &str = "configuration";
21+
pub const BTC_ANCHORING_SERVICE: &str = "btc-anchoring";
22+
pub const TIME_SERVICE: &str = "time";
23+
pub const EJB_SERVICE: &str = "ejb-service";
24+
25+
#[derive(Serialize, Deserialize)]
26+
struct ServicesToEnable {
27+
services: HashSet<String>,
28+
}
29+
30+
type Result<T> = std::result::Result<T, Box<std::error::Error>>;
31+
32+
/// Loads service names from a specific TOML configuration file
33+
pub fn load_enabled_services<P: AsRef<Path>>(path: P) -> Result<HashSet<String>> {
34+
let mut file = File::open(path)?;
35+
let mut toml = String::new();
36+
file.read_to_string(&mut toml)?;
37+
let ServicesToEnable { services } =
38+
toml::from_str(&toml).expect("Invalid list of services to enable");
39+
Ok(services)
40+
}
41+
42+
/// Determines whether particular service name is defined in the specific TOML configuration file.
43+
pub fn is_service_enabled_in_config_file<P: AsRef<Path>>(service_name: &str, path: P) -> bool {
44+
load_enabled_services(path)
45+
.map(|services| services.contains(service_name))
46+
.unwrap_or(false)
47+
}
48+
49+
#[cfg(test)]
50+
mod tests {
51+
use super::*;
52+
use std::io::Write;
53+
use tempfile::{Builder, TempPath};
54+
55+
#[test]
56+
fn no_config() {
57+
let res = load_enabled_services("nonexistent");
58+
assert!(res.is_err());
59+
}
60+
61+
#[test]
62+
fn all_services() {
63+
let cfg = create_config(
64+
"all_services_test.toml",
65+
"services = [\"ejb-service\", \"configuration\", \"btc-anchoring\", \"time\"]",
66+
);
67+
68+
let res = load_enabled_services(cfg);
69+
assert!(res.is_ok());
70+
let services_to_enable = res.unwrap();
71+
assert_eq!(services_to_enable.len(), 4);
72+
assert!(services_to_enable.contains(EJB_SERVICE));
73+
assert!(services_to_enable.contains(CONFIGURATION_SERVICE));
74+
assert!(services_to_enable.contains(BTC_ANCHORING_SERVICE));
75+
assert!(services_to_enable.contains(TIME_SERVICE));
76+
}
77+
78+
#[test]
79+
fn empty_list() {
80+
let cfg = create_config("empty_list.toml", "services = []");
81+
let res = load_enabled_services(cfg);
82+
assert!(res.is_ok());
83+
let services_to_enable = res.unwrap();
84+
assert_eq!(services_to_enable.len(), 0);
85+
}
86+
87+
#[test]
88+
fn check_service_enabled() {
89+
let cfg = create_config(
90+
"service_enabled_test.toml",
91+
"services = [\"ejb-service\", \"time\"]",
92+
);
93+
94+
assert!(is_service_enabled_in_config_file(EJB_SERVICE, &cfg));
95+
assert!(!is_service_enabled_in_config_file(
96+
CONFIGURATION_SERVICE,
97+
&cfg
98+
));
99+
assert!(!is_service_enabled_in_config_file(
100+
BTC_ANCHORING_SERVICE,
101+
&cfg
102+
));
103+
assert!(is_service_enabled_in_config_file(TIME_SERVICE, &cfg));
104+
}
105+
106+
fn create_config(filename: &str, cfg: &str) -> TempPath {
107+
let mut cfg_file = Builder::new().prefix(filename).tempfile().unwrap();
108+
writeln!(cfg_file, "{}", cfg).unwrap();
109+
cfg_file.into_temp_path()
110+
}
111+
}

0 commit comments

Comments
 (0)