mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-22 01:25:10 +00:00
Merge pull request #1 from FrancoPandolfo/parametrizacion
Parametrizacion
This commit is contained in:
commit
7085eff9f6
8 changed files with 163 additions and 169 deletions
|
|
@ -48,6 +48,17 @@
|
||||||
<artifactId>grpc-api</artifactId>
|
<artifactId>grpc-api</artifactId>
|
||||||
<version>1.59.0</version>
|
<version>1.59.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- gRPC core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-core</artifactId>
|
||||||
|
<version>1.59.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ package com.code.hyperledger;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import com.code.hyperledger.configs.FabricConfigProperties;
|
||||||
import com.code.hyperledger.models.Receta;
|
import com.code.hyperledger.models.Receta;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
@ -33,7 +35,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@EnableConfigurationProperties(FabricConfigProperties.class)
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class App {
|
public class App {
|
||||||
/*private static final String MSP_ID = System.getenv().getOrDefault("MSP_ID", "Org1MSP");
|
/*private static final String MSP_ID = System.getenv().getOrDefault("MSP_ID", "Org1MSP");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.code.hyperledger.configs;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ConfigurationProperties(prefix = "fabric")
|
||||||
|
public class FabricConfigProperties {
|
||||||
|
private String mspId;
|
||||||
|
private String channelName;
|
||||||
|
private String chaincodeName;
|
||||||
|
private String peerEndpoint;
|
||||||
|
private String overrideAuth;
|
||||||
|
|
||||||
|
private String cryptoPath;
|
||||||
|
private String certPath;
|
||||||
|
private String keyPath;
|
||||||
|
private String tlsCertPath;
|
||||||
|
}
|
||||||
|
|
@ -120,9 +120,6 @@ public class RecetaController {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Receta> recetas = recetaService.obtenerRecetasPorIds(ids);
|
List<Receta> recetas = recetaService.obtenerRecetasPorIds(ids);
|
||||||
|
|
||||||
// 🔍 Log de los IDs obtenidos desde el service
|
|
||||||
System.out.println("Recetas obtenidas del service con los siguientes IDs:");
|
|
||||||
for (Receta receta : recetas) {
|
for (Receta receta : recetas) {
|
||||||
System.out.println(" - " + receta.getId());
|
System.out.println(" - " + receta.getId());
|
||||||
}
|
}
|
||||||
|
|
@ -132,10 +129,19 @@ public class RecetaController {
|
||||||
recetasDto.add(mapToDto(receta));
|
recetasDto.add(mapToDto(receta));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("Recetas obtenidas del service con los siguientes IDs:");
|
||||||
|
|
||||||
return new ResponseEntity<>(recetasDto, HttpStatus.OK);
|
return new ResponseEntity<>(recetasDto, HttpStatus.OK);
|
||||||
|
|
||||||
|
// 🔍 Log de los IDs obtenidos desde el service
|
||||||
|
|
||||||
} catch (IOException | GatewayException e) {
|
} catch (IOException | GatewayException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Error en submitTransaction: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,6 +165,10 @@ public class RecetaController {
|
||||||
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/firmar")
|
@PutMapping("/firmar")
|
||||||
|
|
@ -182,9 +192,12 @@ public class RecetaController {
|
||||||
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/borrar")
|
@PostMapping("/borrar")
|
||||||
public ResponseEntity<RecetaDto> delete(@RequestBody Map<String, String> requestBody) {
|
public ResponseEntity<RecetaDto> delete(@RequestBody Map<String, String> requestBody) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -205,6 +218,10 @@ public class RecetaController {
|
||||||
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace(); // este bloque rara vez se ejecutaría si ya atrapás las anteriores
|
||||||
|
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecetaDto mapToDto(Receta receta) {
|
private RecetaDto mapToDto(Receta receta) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package main.java.com.code.hyperledger.models;
|
/*package com.code.hyperledger.models;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
@ -13,3 +13,4 @@ public class ResultadoPaginado<T> {
|
||||||
private List<T> recetas;
|
private List<T> recetas;
|
||||||
private String bookmark;
|
private String bookmark;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
@ -1,28 +1,26 @@
|
||||||
package com.code.hyperledger.services;
|
package com.code.hyperledger.services;
|
||||||
|
|
||||||
|
import io.grpc.TlsChannelCredentials;
|
||||||
|
import io.grpc.Grpc;
|
||||||
|
import io.grpc.ManagedChannel;
|
||||||
|
import com.code.hyperledger.configs.FabricConfigProperties;
|
||||||
import com.code.hyperledger.models.Receta;
|
import com.code.hyperledger.models.Receta;
|
||||||
import com.code.hyperledger.models.RecetaDto;
|
import com.code.hyperledger.models.RecetaDto;
|
||||||
|
//import com.code.hyperledger.models.ResultadoPaginado;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import io.grpc.Grpc;
|
|
||||||
import io.grpc.ManagedChannel;
|
|
||||||
import io.grpc.TlsChannelCredentials;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import main.java.com.code.hyperledger.models.ResultadoPaginado;
|
|
||||||
|
|
||||||
import org.hyperledger.fabric.client.*;
|
import org.hyperledger.fabric.client.*;
|
||||||
import org.hyperledger.fabric.client.identity.*;
|
import org.hyperledger.fabric.client.identity.*;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.io.Reader;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.*;
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.Identity;
|
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Signer;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -31,23 +29,20 @@ import java.util.concurrent.TimeUnit;
|
||||||
@Service
|
@Service
|
||||||
public class RecetaService {
|
public class RecetaService {
|
||||||
|
|
||||||
private static final String MSP_ID = System.getenv().getOrDefault("MSP_ID", "Org1MSP");
|
private final FabricConfigProperties config;
|
||||||
private static final String CHANNEL_NAME = System.getenv().getOrDefault("CHANNEL_NAME", "mychannel");
|
|
||||||
private static final String CHAINCODE_NAME = System.getenv().getOrDefault("CHAINCODE_NAME", "basic");
|
|
||||||
|
|
||||||
private static final Path CRYPTO_PATH = Paths
|
|
||||||
.get("../../test-network/organizations/peerOrganizations/org1.example.com");
|
|
||||||
private static final Path CERT_DIR_PATH = CRYPTO_PATH.resolve("users/User1@org1.example.com/msp/signcerts");
|
|
||||||
private static final Path KEY_DIR_PATH = CRYPTO_PATH.resolve("users/User1@org1.example.com/msp/keystore");
|
|
||||||
private static final Path TLS_CERT_PATH = CRYPTO_PATH.resolve("peers/peer0.org1.example.com/tls/ca.crt");
|
|
||||||
|
|
||||||
private static final String PEER_ENDPOINT = "localhost:7051";
|
|
||||||
private static final String OVERRIDE_AUTH = "peer0.org1.example.com";
|
|
||||||
|
|
||||||
private Contract contract;
|
private Contract contract;
|
||||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
private static Path getFirstFilePath(Path dirPath) throws IOException {
|
@Autowired
|
||||||
|
public RecetaService(FabricConfigProperties config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getPath(String relativePath) {
|
||||||
|
return Paths.get(config.getCryptoPath()).resolve(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getFirstFilePath(Path dirPath) throws IOException {
|
||||||
try (var keyFiles = Files.list(dirPath)) {
|
try (var keyFiles = Files.list(dirPath)) {
|
||||||
return keyFiles.findFirst().orElseThrow();
|
return keyFiles.findFirst().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
@ -58,49 +53,52 @@ public class RecetaService {
|
||||||
public void init() {
|
public void init() {
|
||||||
var channel = newGrpcConnection();
|
var channel = newGrpcConnection();
|
||||||
|
|
||||||
var builder = Gateway.newInstance()
|
var gateway = Gateway.newInstance()
|
||||||
.identity(newIdentity())
|
.identity(newIdentity())
|
||||||
.signer(newSigner())
|
.signer(newSigner())
|
||||||
.connection(channel)
|
.connection(channel)
|
||||||
.evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
|
.evaluateOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
|
||||||
.endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS))
|
.endorseOptions(options -> options.withDeadlineAfter(15, TimeUnit.SECONDS))
|
||||||
.submitOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
|
.submitOptions(options -> options.withDeadlineAfter(5, TimeUnit.SECONDS))
|
||||||
.commitStatusOptions(options -> options.withDeadlineAfter(1, TimeUnit.MINUTES));
|
.commitStatusOptions(options -> options.withDeadlineAfter(1, TimeUnit.MINUTES))
|
||||||
|
.connect();
|
||||||
|
|
||||||
try (var gateway = builder.connect()) {
|
this.setContract(gateway);
|
||||||
this.setContract(gateway);
|
this.initLedger();
|
||||||
this.initLedger();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ManagedChannel newGrpcConnection() throws IOException {
|
private ManagedChannel newGrpcConnection() throws IOException {
|
||||||
|
var tlsCertPath = getPath(config.getTlsCertPath());
|
||||||
var credentials = TlsChannelCredentials.newBuilder()
|
var credentials = TlsChannelCredentials.newBuilder()
|
||||||
.trustManager(TLS_CERT_PATH.toFile())
|
.trustManager(tlsCertPath.toFile())
|
||||||
.build();
|
.build();
|
||||||
return Grpc.newChannelBuilder(PEER_ENDPOINT, credentials)
|
|
||||||
.overrideAuthority(OVERRIDE_AUTH)
|
return Grpc.newChannelBuilder(config.getPeerEndpoint(), credentials)
|
||||||
|
.overrideAuthority(config.getOverrideAuth())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Identity newIdentity() throws IOException, CertificateException {
|
private Identity newIdentity() throws IOException, CertificateException {
|
||||||
try (var certReader = Files.newBufferedReader(getFirstFilePath(CERT_DIR_PATH))) {
|
Path certPath = getFirstFilePath(getPath(config.getCertPath()));
|
||||||
|
try (Reader certReader = Files.newBufferedReader(certPath)) {
|
||||||
var certificate = Identities.readX509Certificate(certReader);
|
var certificate = Identities.readX509Certificate(certReader);
|
||||||
return new X509Identity(MSP_ID, certificate);
|
return new X509Identity(config.getMspId(), certificate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Signer newSigner() throws IOException, InvalidKeyException {
|
private Signer newSigner() throws IOException, InvalidKeyException {
|
||||||
try (var keyReader = Files.newBufferedReader(getFirstFilePath(KEY_DIR_PATH))) {
|
Path keyPath = getFirstFilePath(getPath(config.getKeyPath()));
|
||||||
|
try (Reader keyReader = Files.newBufferedReader(keyPath)) {
|
||||||
var privateKey = Identities.readPrivateKey(keyReader);
|
var privateKey = Identities.readPrivateKey(keyReader);
|
||||||
return Signers.newPrivateKeySigner(privateKey);
|
return Signers.newPrivateKeySigner(privateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setContract(final Gateway gateway) {
|
private void setContract(final Gateway gateway) {
|
||||||
var network = gateway.getNetwork(CHANNEL_NAME);
|
var network = gateway.getNetwork(config.getChannelName());
|
||||||
contract = network.getContract(CHAINCODE_NAME);
|
contract = network.getContract(config.getChaincodeName());
|
||||||
}
|
}
|
||||||
|
// crea dos recetas default, borrar cuando no se necesite
|
||||||
private void initLedger() throws EndorseException, SubmitException, CommitStatusException, CommitException {
|
private void initLedger() throws EndorseException, SubmitException, CommitStatusException, CommitException {
|
||||||
contract.submitTransaction("InitLedger");
|
contract.submitTransaction("InitLedger");
|
||||||
}
|
}
|
||||||
|
|
@ -110,120 +108,56 @@ public class RecetaService {
|
||||||
try {
|
try {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
String recetaJson = objectMapper.writeValueAsString(receta);
|
String recetaJson = objectMapper.writeValueAsString(receta);
|
||||||
|
|
||||||
contract.submitTransaction("CreateReceta", recetaJson);
|
contract.submitTransaction("CreateReceta", recetaJson);
|
||||||
System.out.println("Receta creada correctamente");
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Error en submitTransaction: " + e.getMessage());
|
System.err.println("Error en submitTransaction: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Receta obtenerReceta(String recetaId) throws GatewayException, IOException {
|
public Receta obtenerReceta(String recetaId) throws Exception {
|
||||||
System.out.println("[INFO] Iniciando obtención de receta con ID: " + recetaId);
|
var evaluateResult = contract.evaluateTransaction("ReadReceta", recetaId);
|
||||||
|
return new ObjectMapper().readValue(evaluateResult, Receta.class);
|
||||||
try {
|
|
||||||
System.out.println("[DEBUG] Ejecutando transacción 'ReadReceta' con ID: " + recetaId);
|
|
||||||
var evaluateResult = contract.evaluateTransaction("ReadReceta", recetaId);
|
|
||||||
System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult));
|
|
||||||
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
Receta receta = objectMapper.readValue(evaluateResult, Receta.class);
|
|
||||||
System.out.println("[INFO] Receta parseada exitosamente para ID: " + recetaId);
|
|
||||||
|
|
||||||
return receta;
|
|
||||||
} catch (GatewayException e) {
|
|
||||||
System.err.println("[ERROR] GatewayException al obtener receta con ID: " + recetaId);
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
throw e;
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("[ERROR] IOException al parsear receta con ID: " + recetaId);
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
throw e;
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("[ERROR] Error inesperado al obtener receta con ID: " + recetaId);
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
throw new RuntimeException("Error inesperado al obtener la receta", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Receta> obtenerTodasLasRecetas() throws GatewayException, IOException {
|
public List<Receta> obtenerTodasLasRecetas() throws Exception {
|
||||||
var evaluateResult = contract.evaluateTransaction("GetAllRecetas");
|
var evaluateResult = contract.evaluateTransaction("GetAllRecetas");
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
return new ObjectMapper().readValue(evaluateResult,
|
||||||
return objectMapper.readValue(evaluateResult,
|
new ObjectMapper().getTypeFactory().constructCollectionType(List.class, Receta.class));
|
||||||
objectMapper.getTypeFactory().constructCollectionType(List.class, Receta.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Receta> obtenerRecetasPorIds(List<String> recetaIds) throws GatewayException, IOException {
|
public List<Receta> obtenerRecetasPorIds(List<String> recetaIds) throws Exception {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
String idsJson = new ObjectMapper().writeValueAsString(recetaIds);
|
||||||
|
|
||||||
System.out.println("Solicitando recetas con IDs: " + recetaIds);
|
|
||||||
|
|
||||||
String idsJson = objectMapper.writeValueAsString(recetaIds);
|
|
||||||
var evaluateResult = contract.evaluateTransaction("GetMultipleRecetas", idsJson);
|
var evaluateResult = contract.evaluateTransaction("GetMultipleRecetas", idsJson);
|
||||||
|
return new ObjectMapper().readValue(evaluateResult,
|
||||||
if (evaluateResult == null || evaluateResult.length == 0) {
|
new ObjectMapper().getTypeFactory().constructCollectionType(List.class, Receta.class));
|
||||||
System.err.println("GetMultipleRecetas devolvió una respuesta vacía.");
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Receta> recetas = objectMapper.readValue(
|
|
||||||
evaluateResult,
|
|
||||||
objectMapper.getTypeFactory().constructCollectionType(List.class, Receta.class));
|
|
||||||
|
|
||||||
System.out.println("Recetas obtenidas del contrato:");
|
|
||||||
for (Receta receta : recetas) {
|
|
||||||
System.out.println(" - ID: " + receta.getId() + " | Estado: " + receta.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
return recetas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void entregarReceta(String recetaId)
|
public void entregarReceta(String recetaId) throws Exception {
|
||||||
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
|
||||||
contract.submitTransaction("EntregarReceta", recetaId);
|
contract.submitTransaction("EntregarReceta", recetaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void firmarReceta(String recetaId, String signature)
|
public void firmarReceta(String recetaId, String signature) throws Exception {
|
||||||
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
contract.submitTransaction("FirmarReceta", recetaId, signature);
|
||||||
System.out.println("[INFO] Iniciando firma de receta con ID: " + recetaId);
|
|
||||||
try {
|
|
||||||
var evaluateResult = contract.submitTransaction("FirmarReceta", recetaId, signature);
|
|
||||||
System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult));
|
|
||||||
System.out.println("[INFO] Receta firmada exitosamente para ID: " + recetaId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("[ERROR] Error al firmar receta: " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void borrarReceta(String recetaId)
|
public void borrarReceta(String recetaId) throws Exception {
|
||||||
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
contract.submitTransaction("DeleteReceta", recetaId);
|
||||||
System.out.println("[INFO] Iniciando borrado de receta con ID: " + recetaId);
|
|
||||||
try {
|
|
||||||
var evaluateResult = contract.submitTransaction("DeleteReceta", recetaId);
|
|
||||||
System.out.println("[DEBUG] Resultado de transacción recibido: " + new String(evaluateResult));
|
|
||||||
System.out.println("[INFO] Receta borrada exitosamente para ID: " + recetaId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("[ERROR] Error al borrar receta: " + e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultadoPaginado<RecetaDto> obtenerRecetasPorDniYEstadoPaginado(
|
/*
|
||||||
String dni, String estado, int pageSize, String bookmark) throws GatewayException, IOException {
|
* public ResultadoPaginado<RecetaDto> obtenerRecetasPorDniYEstadoPaginado(
|
||||||
|
* String dni, String estado, int pageSize, String bookmark) throws Exception {
|
||||||
if (dni == null || dni.isBlank() || estado == null || estado.isBlank()) {
|
*
|
||||||
throw new IllegalArgumentException("DNI y estado son obligatorios");
|
* var result = contract.evaluateTransaction("GetRecetasPorDniYEstado", dni,
|
||||||
}
|
* estado,
|
||||||
|
* String.valueOf(pageSize), bookmark);
|
||||||
var result = contract.evaluateTransaction("GetRecetasPorDniYEstado", dni, estado, String.valueOf(pageSize),
|
*
|
||||||
bookmark);
|
* var type = new ObjectMapper()
|
||||||
|
* .getTypeFactory()
|
||||||
var type = new ObjectMapper()
|
* .constructParametricType(ResultadoPaginado.class, RecetaDto.class);
|
||||||
.getTypeFactory()
|
*
|
||||||
.constructParametricType(ResultadoPaginado.class, RecetaDto.class);
|
* return new ObjectMapper().readValue(result, type);
|
||||||
|
* }
|
||||||
return new ObjectMapper().readValue(result, type);
|
*/
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.code.hyperledger.services;
|
package com.code.hyperledger.services;
|
||||||
|
|
||||||
import com.code.hyperledger.models.Receta;
|
import com.code.hyperledger.configs.FabricConfigProperties;
|
||||||
import com.code.hyperledger.models.Vacuna;
|
import com.code.hyperledger.models.Vacuna;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
@ -9,17 +9,13 @@ import io.grpc.Grpc;
|
||||||
import io.grpc.ManagedChannel;
|
import io.grpc.ManagedChannel;
|
||||||
import io.grpc.TlsChannelCredentials;
|
import io.grpc.TlsChannelCredentials;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import com.code.hyperledger.models.VacunaDto;
|
|
||||||
|
|
||||||
import org.hyperledger.fabric.client.*;
|
import org.hyperledger.fabric.client.*;
|
||||||
import org.hyperledger.fabric.client.identity.*;
|
import org.hyperledger.fabric.client.identity.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.*;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -29,23 +25,15 @@ import java.util.concurrent.TimeUnit;
|
||||||
@Service
|
@Service
|
||||||
public class VacunaService {
|
public class VacunaService {
|
||||||
|
|
||||||
private static final String MSP_ID = System.getenv().getOrDefault("MSP_ID", "Org1MSP");
|
private final FabricConfigProperties config;
|
||||||
private static final String CHANNEL_NAME = System.getenv().getOrDefault("CHANNEL_NAME", "mychannel");
|
|
||||||
private static final String CHAINCODE_NAME = System.getenv().getOrDefault("CHAINCODE_NAME", "basic");
|
|
||||||
|
|
||||||
private static final Path CRYPTO_PATH = Paths
|
|
||||||
.get("../../test-network/organizations/peerOrganizations/org1.example.com");
|
|
||||||
private static final Path CERT_DIR_PATH = CRYPTO_PATH.resolve("users/User1@org1.example.com/msp/signcerts");
|
|
||||||
private static final Path KEY_DIR_PATH = CRYPTO_PATH.resolve("users/User1@org1.example.com/msp/keystore");
|
|
||||||
private static final Path TLS_CERT_PATH = CRYPTO_PATH.resolve("peers/peer0.org1.example.com/tls/ca.crt");
|
|
||||||
|
|
||||||
private static final String PEER_ENDPOINT = "localhost:7051";
|
|
||||||
private static final String OVERRIDE_AUTH = "peer0.org1.example.com";
|
|
||||||
|
|
||||||
private Contract contract;
|
private Contract contract;
|
||||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
private static Path getFirstFilePath(Path dirPath) throws IOException {
|
public VacunaService(FabricConfigProperties config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getFirstFilePath(Path dirPath) throws IOException {
|
||||||
try (var keyFiles = Files.list(dirPath)) {
|
try (var keyFiles = Files.list(dirPath)) {
|
||||||
return keyFiles.findFirst().orElseThrow();
|
return keyFiles.findFirst().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
@ -70,34 +58,39 @@ public class VacunaService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ManagedChannel newGrpcConnection() throws IOException {
|
private ManagedChannel newGrpcConnection() throws IOException {
|
||||||
|
Path tlsPath = Paths.get(config.getCryptoPath(), config.getTlsCertPath());
|
||||||
var credentials = TlsChannelCredentials.newBuilder()
|
var credentials = TlsChannelCredentials.newBuilder()
|
||||||
.trustManager(TLS_CERT_PATH.toFile())
|
.trustManager(tlsPath.toFile())
|
||||||
.build();
|
.build();
|
||||||
return Grpc.newChannelBuilder(PEER_ENDPOINT, credentials)
|
return Grpc.newChannelBuilder(config.getPeerEndpoint(), credentials)
|
||||||
.overrideAuthority(OVERRIDE_AUTH)
|
.overrideAuthority(config.getOverrideAuth())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Identity newIdentity() throws IOException, CertificateException {
|
private Identity newIdentity() throws IOException, CertificateException {
|
||||||
try (var certReader = Files.newBufferedReader(getFirstFilePath(CERT_DIR_PATH))) {
|
Path certPath = Paths.get(config.getCryptoPath(), config.getCertPath());
|
||||||
|
try (var certReader = Files.newBufferedReader(getFirstFilePath(certPath))) {
|
||||||
var certificate = Identities.readX509Certificate(certReader);
|
var certificate = Identities.readX509Certificate(certReader);
|
||||||
return new X509Identity(MSP_ID, certificate);
|
return new X509Identity(config.getMspId(), certificate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Signer newSigner() throws IOException, InvalidKeyException {
|
private Signer newSigner() throws IOException, InvalidKeyException {
|
||||||
try (var keyReader = Files.newBufferedReader(getFirstFilePath(KEY_DIR_PATH))) {
|
Path keyPath = Paths.get(config.getCryptoPath(), config.getKeyPath());
|
||||||
|
try (var keyReader = Files.newBufferedReader(getFirstFilePath(keyPath))) {
|
||||||
var privateKey = Identities.readPrivateKey(keyReader);
|
var privateKey = Identities.readPrivateKey(keyReader);
|
||||||
return Signers.newPrivateKeySigner(privateKey);
|
return Signers.newPrivateKeySigner(privateKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setContract(final Gateway gateway) {
|
private void setContract(final Gateway gateway) {
|
||||||
var network = gateway.getNetwork(CHANNEL_NAME);
|
var network = gateway.getNetwork(config.getChannelName());
|
||||||
contract = network.getContract(CHAINCODE_NAME);
|
contract = network.getContract(config.getChaincodeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todos los métodos siguientes permanecen idénticos...
|
||||||
|
|
||||||
public void cargarVacuna(Vacuna vacuna)
|
public void cargarVacuna(Vacuna vacuna)
|
||||||
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
throws CommitStatusException, EndorseException, CommitException, SubmitException {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,15 @@
|
||||||
spring.application.name=main
|
spring.application.name=main
|
||||||
|
|
||||||
|
# Fabric configs
|
||||||
|
fabric.mspId=Org1MSP
|
||||||
|
fabric.channelName=mychannel
|
||||||
|
fabric.chaincodeName=basic
|
||||||
|
fabric.peerEndpoint=localhost:7051
|
||||||
|
fabric.overrideAuth=peer0.org1.example.com
|
||||||
|
|
||||||
|
# Rutas a certificados y claves
|
||||||
|
fabric.cryptoPath=../../test-network/organizations/peerOrganizations/org1.example.com
|
||||||
|
fabric.certPath=users/User1@org1.example.com/msp/signcerts
|
||||||
|
fabric.keyPath=users/User1@org1.example.com/msp/keystore
|
||||||
|
fabric.tlsCertPath=peers/peer0.org1.example.com/tls/ca.crt
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue