如何在 Spring Java 应用程序中将网络实例传递给使用者



我有一个Spring java应用程序,其中包含初始化网络的服务。

package com.victor.simple.events.services;
import org.hyperledger.fabric.gateway.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@Service
public class HyperledgerNetworkService {
@Value("${fabric.wallet.path}")
private String walletPath;
@Value("${fabric.wallet.privateKey}")
private String privateKeyPath;
@Value("${fabric.wallet.x509Cert}")
private String x509CertPath;
@Value("${fabric.wallet.certificate.type}")
private String certType;
@Value("${fabric.org.msp}")
private String mspId;
@Value("${fabric.org.networkProfile}")
private String networkProfilePath;
private static final String ADMIN_LABEL = "admin";
@Bean
public Gateway initialize() throws IOException,CertificateException, InvalidKeyException {
System.out.println("Initializing Gateway");
//Load an existing wallet holding identities used to access the network.
Path walletDirectory = Paths.get(walletPath);
try (FileInputStream certificate = new FileInputStream(walletDirectory.toAbsolutePath()+x509CertPath);
FileInputStream privateKey = new FileInputStream(walletDirectory.toAbsolutePath()+privateKeyPath)) {
CertificateFactory fac = CertificateFactory.getInstance(certType);
X509Certificate cert = (X509Certificate) fac.generateCertificate(certificate);
PrivateKey pk = Identities.readPrivateKey(new InputStreamReader(privateKey));
Identity identity = Identities.newX509Identity(mspId,cert,pk);
Wallet wallet = Wallets.newInMemoryWallet();
if(wallet.get(ADMIN_LABEL) == null)
wallet.put(ADMIN_LABEL, identity);
//Path to a common connection profile describing the network.
Path networkConfigFile = Paths.get(networkProfilePath);
System.out.println(networkConfigFile);
//Configure the gateway connection used to access the network.
Gateway.Builder builder = Gateway.createBuilder()
.identity(wallet,"admin")
//.discovery(true)
.networkConfig(networkConfigFile);
return builder.connect();
}
}
}

然后我有一个控制器来处理该网络上的合约事件:

@RequiredArgsConstructor
@RestController
public class EventController {
@Autowired
private Consumer<ContractEvent> eventConsumer;
private final Gateway networkService;
@Value("${fabric.channel.contract}")
private String contractName;
@Value("${fabric.channel.name}")
private String channelName;
@PostConstruct
private void registerEvent() throws ContractException{
System.out.println("PostConstruct registerEvent() in EventController execution start");
//Instantiating networks and chaincodes
Network network = networkService.getNetwork(channelName);
Contract contract = network.getContract(contractName);
//Capture contract events
contract.addContractListener(eventConsumer);
}

}

您可以看到,当事件发生时,这是由事件使用者管理的:


@Component
public class EventConsumer implements Consumer<ContractEvent> {

@Override
public void accept(ContractEvent contractEvent) {
System.out.println("New event received in the EventConsumer");

}
}

我想做的是能够将网络的实例传递给 EventConsumer,以便我可以在识别事件后从那里对该网络进行操作。

类似的东西

谢谢

请尝试为网络创建一个 bean。

@Configuration
public class FabricConfig {
@Value("${fabric.channel.name}")
private String channelName;
@Bean
public Gateway getGateway() {
return ...;
}
@Bean
public Network getNetwork(Gateway gateway) {
return gateway.getNetwork(channelName);
}
}

此 bean 可以在 EventConsumer 类中使用。

@Component
@AllArgsConstructor
public class EventConsumer implements Consumer<ContractEvent> {
private Network network;

请注意,如果您具有@Autowired注释,则不需要注释 构造 函数。Spring 将尝试通过构造函数注入 bean,即使它没有注释为@Autowired

不幸的是,我无法验证它是否有效。没有Hyperledger Fabric Blockchain的经验。

最新更新