Skip to content

Commit c18eea2

Browse files
committed
Merge branch 'main' into hedera-to-hiero
# Conflicts: # hiero-microprofile/src/main/java/com/openelements/hiero/microprofile/ClientProvider.java # hiero-microprofile/src/main/java/com/openelements/hiero/microprofile/HieroNetworkConfiguration.java # hiero-microprofile/src/main/java/com/openelements/hiero/microprofile/HieroOperatorConfiguration.java # hiero-microprofile/src/main/java/com/openelements/hiero/microprofile/implementation/HieroConfigImpl.java # hiero-microprofile/src/test/java/com/openelements/hiero/microprofile/test/FileClientTests.java # hiero-spring/src/main/java/com/openelements/hiero/spring/implementation/HederaAutoConfiguration.java # hiero-spring/src/main/java/com/openelements/hiero/spring/implementation/HieroConfigImpl.java
2 parents 834dcac + d9e9ceb commit c18eea2

File tree

13 files changed

+426
-191
lines changed

13 files changed

+426
-191
lines changed

.github/workflows/scorecard.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
persist-credentials: false
3838

3939
- name: "Run analysis"
40-
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
40+
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
4141
with:
4242
results_file: results.sarif
4343
results_format: sarif
@@ -59,7 +59,7 @@ jobs:
5959
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
6060
# format to the repository Actions tab.
6161
- name: "Upload artifact"
62-
uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
62+
uses: actions/upload-artifact@c24449f33cd45d4826c6702db7e49f7cdb9b551d # v3.pre.node20
6363
with:
6464
name: SARIF file
6565
path: results.sarif
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.openelements.hedera.base.config;
2+
3+
import com.hedera.hashgraph.sdk.AccountId;
4+
import java.util.Objects;
5+
import org.jspecify.annotations.NonNull;
6+
7+
public record ConsensusNode(@NonNull String ip, @NonNull String port, @NonNull String account) {
8+
9+
public ConsensusNode {
10+
Objects.requireNonNull(ip, "ip must not be null");
11+
Objects.requireNonNull(port, "port must not be null");
12+
Objects.requireNonNull(account, "account must not be null");
13+
}
14+
15+
public String getAddress() {
16+
return ip + ":" + port;
17+
}
18+
19+
public AccountId getAccountId() {
20+
return AccountId.fromString(account);
21+
}
22+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.openelements.hedera.base.config;
2+
3+
import com.hedera.hashgraph.sdk.AccountId;
4+
import com.hedera.hashgraph.sdk.Client;
5+
import com.openelements.hedera.base.Account;
6+
import com.openelements.hedera.base.implementation.HederaNetwork;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
import java.util.Set;
11+
import java.util.stream.Collectors;
12+
import org.jspecify.annotations.NonNull;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
public interface HieroConfig {
17+
18+
final static Logger log = LoggerFactory.getLogger(HieroConfig.class);
19+
20+
@NonNull Account getOperatorAccount();
21+
22+
@NonNull Optional<String> getNetworkName();
23+
24+
@NonNull List<String> getMirrornodeAddresses();
25+
26+
@NonNull Set<ConsensusNode> getConsensusNodes();
27+
28+
@NonNull HederaNetwork getNetwork();
29+
30+
@NonNull
31+
default Client createClient() {
32+
final HederaNetwork hederaNetwork = getNetwork();
33+
if (hederaNetwork != HederaNetwork.CUSTOM) {
34+
try {
35+
log.debug("Hedera network '{}' will be used", hederaNetwork.getName());
36+
Client client = Client.forName(hederaNetwork.getName());
37+
client.setOperator(getOperatorAccount().accountId(), getOperatorAccount().privateKey());
38+
return client;
39+
} catch (Exception e) {
40+
throw new IllegalArgumentException("Can not create client for network " + hederaNetwork.getName(),
41+
e);
42+
}
43+
} else {
44+
try {
45+
final Map<String, AccountId> nodes = getConsensusNodes().stream()
46+
.collect(Collectors.toMap(n -> n.getAddress(), n -> n.getAccountId()));
47+
final Client client = Client.forNetwork(nodes);
48+
client.setMirrorNetwork(getMirrornodeAddresses());
49+
client.setOperator(getOperatorAccount().accountId(), getOperatorAccount().privateKey());
50+
return client;
51+
} catch (Exception e) {
52+
throw new IllegalArgumentException("Can not create client for custom network", e);
53+
}
54+
}
55+
}
56+
57+
}

hiero-base/src/main/java/com/openelements/hiero/base/implementation/HederaNetwork.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.openelements.hiero.base.implementation;
22

3+
import java.util.Objects;
4+
import java.util.Optional;
5+
import java.util.stream.Stream;
6+
37
public enum HederaNetwork {
48

59
PREVIEWNET("previewnet", 297, "https://previewnet.mirrornode.hedera.com/", "https://previewnet.hashio.io/api"),
@@ -48,4 +52,11 @@ public String getName() {
4852
public String getMirrornodeEndpoint() {
4953
return mirrornodeEndpoint;
5054
}
55+
56+
public static Optional<HederaNetwork> findByName(final String name) {
57+
Objects.requireNonNull(name, "name must not be null");
58+
return Stream.of(HederaNetwork.values())
59+
.filter(v -> Objects.equals(v.name.toLowerCase(), name.toLowerCase()))
60+
.findAny();
61+
}
5162
}
Lines changed: 26 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,43 @@
1-
package com.openelements.hiero.microprofile;
1+
package com.openelements.hedera.microprofile;
22

3-
import com.hedera.hashgraph.sdk.AccountId;
4-
import com.hedera.hashgraph.sdk.Client;
5-
import com.hedera.hashgraph.sdk.PrivateKey;
6-
import com.openelements.hiero.base.Account;
7-
import com.openelements.hiero.base.AccountClient;
8-
import com.openelements.hiero.base.ContractVerificationClient;
9-
import com.openelements.hiero.base.FileClient;
10-
import com.openelements.hiero.base.SmartContractClient;
11-
import com.openelements.hiero.base.implementation.AccountClientImpl;
12-
import com.openelements.hiero.base.implementation.FileClientImpl;
13-
import com.openelements.hiero.base.implementation.HederaNetwork;
14-
import com.openelements.hiero.base.implementation.ProtocolLayerClientImpl;
15-
import com.openelements.hiero.base.implementation.SmartContractClientImpl;
16-
import com.openelements.hiero.base.protocol.ProtocolLayerClient;
17-
import com.openelements.hiero.microprofile.implementation.ContractVerificationClientImpl;
3+
import com.openelements.hedera.base.AccountClient;
4+
import com.openelements.hedera.base.ContractVerificationClient;
5+
import com.openelements.hedera.base.FileClient;
6+
import com.openelements.hedera.base.SmartContractClient;
7+
import com.openelements.hedera.base.config.HieroConfig;
8+
import com.openelements.hedera.base.implementation.AccountClientImpl;
9+
import com.openelements.hedera.base.implementation.FileClientImpl;
10+
import com.openelements.hedera.base.implementation.ProtocolLayerClientImpl;
11+
import com.openelements.hedera.base.implementation.SmartContractClientImpl;
12+
import com.openelements.hedera.base.protocol.ProtocolLayerClient;
13+
import com.openelements.hedera.microprofile.implementation.ContractVerificationClientImpl;
14+
import com.openelements.hedera.microprofile.implementation.HieroConfigImpl;
1815
import jakarta.enterprise.context.ApplicationScoped;
1916
import jakarta.enterprise.inject.Produces;
2017
import jakarta.inject.Inject;
21-
import java.util.Arrays;
22-
import java.util.Objects;
23-
import org.eclipse.microprofile.config.inject.ConfigProperty;
18+
import org.eclipse.microprofile.config.inject.ConfigProperties;
2419
import org.jspecify.annotations.NonNull;
2520

2621
public class ClientProvider {
2722

2823
@Inject
29-
@ConfigProperty(name = "hedera.accountId")
30-
private String accountIdAsString;
24+
@ConfigProperties
25+
private HieroOperatorConfiguration configuration;
3126

3227
@Inject
33-
@ConfigProperty(name = "hedera.privateKey")
34-
private String privateKeyAsString;
28+
@ConfigProperties
29+
private HieroNetworkConfiguration networkConfiguration;
3530

36-
@Inject
37-
@ConfigProperty(name = "hedera.network")
38-
private String network;
39-
40-
private AccountId getAccountId() {
41-
try {
42-
return AccountId.fromString(accountIdAsString);
43-
} catch (Exception e) {
44-
throw new IllegalArgumentException("Can not parse 'hedera.newAccountId' property", e);
45-
}
46-
}
47-
48-
private PrivateKey getPrivateKey() {
49-
try {
50-
return PrivateKey.fromString(privateKeyAsString);
51-
} catch (Exception e) {
52-
throw new IllegalArgumentException("Can not parse 'hedera.privateKey' property", e);
53-
}
54-
}
55-
56-
private HederaNetwork getHederaNetwork() {
57-
if (Arrays.stream(HederaNetwork.values()).anyMatch(v -> Objects.equals(v.getName(), network))) {
58-
try {
59-
return HederaNetwork.valueOf(network.toUpperCase());
60-
} catch (Exception e) {
61-
throw new IllegalArgumentException("Can not parse 'hedera.network' property", e);
62-
}
63-
} else {
64-
throw new IllegalArgumentException("'hedera.network' property must be set to a valid value");
65-
}
66-
}
67-
68-
private Client createClient() {
69-
final AccountId accountId = getAccountId();
70-
final PrivateKey privateKey = getPrivateKey();
71-
final HederaNetwork hederaNetwork = getHederaNetwork();
72-
return Client.forName(hederaNetwork.getName())
73-
.setOperator(accountId, privateKey);
31+
@Produces
32+
@ApplicationScoped
33+
HieroConfig createHieroConfig() {
34+
return new HieroConfigImpl(configuration, networkConfiguration);
7435
}
7536

7637
@Produces
7738
@ApplicationScoped
78-
ProtocolLayerClient createProtocolLayerClient() {
79-
final Account operator = Account.of(getAccountId(), getPrivateKey());
80-
return new ProtocolLayerClientImpl(createClient(), operator);
39+
ProtocolLayerClient createProtocolLayerClient(@NonNull final HieroConfig hieroConfig) {
40+
return new ProtocolLayerClientImpl(hieroConfig.createClient(), hieroConfig.getOperatorAccount());
8141
}
8242

8343
@Produces
@@ -101,8 +61,7 @@ AccountClient createAccountClient(@NonNull final ProtocolLayerClient protocolLay
10161

10262
@Produces
10363
@ApplicationScoped
104-
ContractVerificationClient createContractVerificationClient(@NonNull final ProtocolLayerClient protocolLayerClient,
105-
@NonNull final FileClient fileClient) {
106-
return new ContractVerificationClientImpl(getHederaNetwork());
64+
ContractVerificationClient createContractVerificationClient(@NonNull final HieroConfig hieroConfig) {
65+
return new ContractVerificationClientImpl(hieroConfig.getNetwork());
10766
}
10867
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.openelements.hedera.microprofile;
2+
3+
import com.openelements.hedera.base.config.ConsensusNode;
4+
import jakarta.enterprise.context.Dependent;
5+
import jakarta.inject.Inject;
6+
import java.util.Optional;
7+
import java.util.Set;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.Stream;
10+
import org.eclipse.microprofile.config.inject.ConfigProperties;
11+
import org.eclipse.microprofile.config.inject.ConfigProperty;
12+
13+
@ConfigProperties(prefix = "hiero.network")
14+
@Dependent
15+
public class HieroNetworkConfiguration {
16+
17+
private Optional<String> name;
18+
19+
@Inject
20+
@ConfigProperty(name = "nodes")
21+
private Optional<String> nodes;
22+
23+
@ConfigProperty(name = "mirrornode")
24+
private Optional<String> mirrornode;
25+
26+
public Optional<String> getName() {
27+
return name;
28+
}
29+
30+
public Optional<String> getMirrornode() {
31+
return mirrornode;
32+
}
33+
34+
public Set<ConsensusNode> getNodes() {
35+
return nodes.map(n -> n.split(","))
36+
.map(n -> Stream.of(n))
37+
.orElse(Stream.empty())
38+
.map(n -> {
39+
// 172.234.134.4:8080:0.0.3
40+
final String[] split = n.split(":");
41+
if (split.length != 3) {
42+
throw new IllegalStateException("Can not parse node for '" + n + "'");
43+
}
44+
final String ip = split[0];
45+
final String port = split[1];
46+
final String account = split[2];
47+
return new ConsensusNode(ip, port, account);
48+
}).collect(Collectors.toUnmodifiableSet());
49+
}
50+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.openelements.hedera.microprofile;
2+
3+
import jakarta.enterprise.context.Dependent;
4+
import org.eclipse.microprofile.config.inject.ConfigProperties;
5+
6+
@ConfigProperties(prefix = "hiero")
7+
@Dependent
8+
public class HieroOperatorConfiguration {
9+
10+
private String accountId;
11+
12+
private String privateKey;
13+
14+
public String getAccountId() {
15+
return accountId;
16+
}
17+
18+
public String getPrivateKey() {
19+
return privateKey;
20+
}
21+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.openelements.hedera.microprofile.implementation;
2+
3+
import com.hedera.hashgraph.sdk.AccountId;
4+
import com.hedera.hashgraph.sdk.PrivateKey;
5+
import com.openelements.hedera.base.Account;
6+
import com.openelements.hedera.base.config.ConsensusNode;
7+
import com.openelements.hedera.base.config.HieroConfig;
8+
import com.openelements.hedera.base.implementation.HederaNetwork;
9+
import com.openelements.hedera.microprofile.HieroNetworkConfiguration;
10+
import com.openelements.hedera.microprofile.HieroOperatorConfiguration;
11+
import java.util.Collections;
12+
import java.util.List;
13+
import java.util.Objects;
14+
import java.util.Optional;
15+
import java.util.Set;
16+
import org.jspecify.annotations.NonNull;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
19+
20+
public class HieroConfigImpl implements HieroConfig {
21+
22+
private final static Logger log = LoggerFactory.getLogger(HieroConfigImpl.class);
23+
24+
private final Account operatorAccount;
25+
26+
private final String networkName;
27+
28+
private final List<String> mirrorNodeAddresses;
29+
30+
private final Set<ConsensusNode> consensusNodes;
31+
32+
private final HederaNetwork hederaNetwork;
33+
34+
public HieroConfigImpl(@NonNull final HieroOperatorConfiguration configuration,
35+
@NonNull final HieroNetworkConfiguration networkConfiguration) {
36+
Objects.requireNonNull(configuration, "configuration must not be null");
37+
Objects.requireNonNull(networkConfiguration, "networkConfiguration must not be null");
38+
39+
final AccountId operatorAccountId = AccountId.fromString(configuration.getAccountId());
40+
final PrivateKey operatorPrivateKey = PrivateKey.fromString(configuration.getPrivateKey());
41+
operatorAccount = Account.of(operatorAccountId, operatorPrivateKey);
42+
networkName = networkConfiguration.getName().orElse(null);
43+
mirrorNodeAddresses = networkConfiguration.getMirrornode().map(List::of).orElse(List.of());
44+
consensusNodes = Collections.unmodifiableSet(networkConfiguration.getNodes());
45+
hederaNetwork = HederaNetwork.findByName(networkName)
46+
.orElse(HederaNetwork.CUSTOM);
47+
}
48+
49+
@Override
50+
public @NonNull Account getOperatorAccount() {
51+
return operatorAccount;
52+
}
53+
54+
@Override
55+
public @NonNull Optional<String> getNetworkName() {
56+
return Optional.ofNullable(networkName);
57+
}
58+
59+
@Override
60+
public @NonNull List<String> getMirrornodeAddresses() {
61+
return mirrorNodeAddresses;
62+
}
63+
64+
@Override
65+
public @NonNull Set<ConsensusNode> getConsensusNodes() {
66+
return consensusNodes;
67+
}
68+
69+
@Override
70+
public @NonNull HederaNetwork getNetwork() {
71+
return hederaNetwork;
72+
}
73+
}

0 commit comments

Comments
 (0)