primer commit

This commit is contained in:
Isidoro Nevares Martín 2025-11-10 10:08:51 +01:00
commit d1a4e8c6e2
13 changed files with 615 additions and 0 deletions

41
.classpath Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-23">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target/
*.class

23
.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EjemploAWS</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

22
README.md Normal file
View File

@ -0,0 +1,22 @@
# Estructura del bucket S3 : s3-objetos-proyecto
| Identificador Proyecto | Número Hito | Nombre documento |
|-------------------------|-------------|---------------------------|
| 1 | 1 | Kingdom Town for Gods.pdf
**Clave del documento S3**: "/1/1/Kingdom Town for Gods.pdf"
# Estructura de la tabla de DynamoDb: ddb-hitos-proyecto
| Campo | Tipo DynamoDB | Ejemplo de valor |
|------------------|---------------------|--------------------------------------------------------------------------|
| id_proyecto | Number | 1 |
| numero_hito | Number | 2 |
| fecha_hito | String (S) | "2025-06-01T18:30:22Z" |
| fecha_envio | String (S) | "2025-06-01T18:30:22Z" |
| alumno_envio | Number | 5 |
| clave_documento | String (S) | "/1/1/Kingdom Town for Gods.pdf" |
| resumen_entrega | String (S) | "En este hito se ha añadido el índice..." |
| estado | String (S) | "Enviado" |

Binary file not shown.

View File

@ -0,0 +1,9 @@
id_proyecto|numero_hito|fecha_hito|fecha_envio|alumno_envio|url_documento|resumen_entrega|estado
1|1|"2025-03-10"|||||
1|2|"2025-04-10"|||||
1|3|"2025-05-10"|||||
1|4|"2025-06-15"|||||
2|1|"2025-03-15"|||||
2|2|"2025-04-15"|||||
2|3|"2025-05-20"|||||
2|4|"2025-06-20"|||||
1 id_proyecto numero_hito fecha_hito fecha_envio alumno_envio url_documento resumen_entrega estado
2 1 1 2025-03-10
3 1 2 2025-04-10
4 1 3 2025-05-10
5 1 4 2025-06-15
6 2 1 2025-03-15
7 2 2 2025-04-15
8 2 3 2025-05-20
9 2 4 2025-06-20

68
pom.xml Normal file
View File

@ -0,0 +1,68 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>EjemploIntegradorAWS</groupId>
<artifactId>EjemploIntegradorAWS</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.opencsv/opencsv -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>7.0.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver-sync -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>5.5.0</version>
</dependency>
<!-- AWS SDK v2 - Core (Necesario para todos los servicios) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>aws-core</artifactId>
<version>2.20.14</version> <!-- Usa la última versión disponible -->
</dependency>
<!-- Dependencia para S3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.20.14</version> <!-- Usa la misma versión que aws-core -->
</dependency>
<!-- Dependencia para DynamoDB -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId>
<version>2.20.14</version> <!-- Usa la misma versión que aws-core -->
</dependency>
<!-- Dependencia para la autenticación -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>auth</artifactId>
<version>2.20.14</version> <!-- Usa la misma versión que aws-core -->
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,311 @@
/**
*
*/
package org.lapaloma.proyectos;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.net.URL;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.lapaloma.proyectos.util.ConversorTipos;
import org.lapaloma.proyectos.util.GestorClientesServiciosAWS;
import com.opencsv.bean.CsvToBeanBuilder;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
/**
* Clase principal encargada de probar el acceso a datos con los servicios S3 y
* DynamoDb de AWS
*
* @author Programador: Isidoro Nevares Martín - Virgen de la Paloma
* @date 25 may 2025
* @version: 1.0
*/
public class ClasePrincipal {
private final static String NOMBRE_TABLA = "ddb-hitos-proyecto";
private final static String NOMBRE_BUCKET = "s3-objetos-proyecto";
/**
* @param args
*/
public static void main(String[] args) {
ClasePrincipal cp = new ClasePrincipal();
// Probar almacenamiento en DynamoDb (dentro se almacena documento en S3)
cp.almacenarEstructuraHitosDynamoDB();
// Ejemplo de hito obtenido de un interfaz gráfico.
Hito hito = new Hito();
hito.setIdProyecto(1);
hito.setNumeroHito(2);
Date fechaHito = ConversorTipos.convertirStringADate("2025-04-15T14:30:00");
hito.setFechaHito(fechaHito);
File documentoAEnviar = new File("ficheros//Kingdom Town for Gods.pdf");
hito.setDocumento(documentoAEnviar);
Date fechaEnvio = new Date(); // Contiene la fecha y hora actuales
hito.setFechaEnvio(fechaEnvio);
hito.setIdAlumnoEnvio(1); // Identificador del Alumn@ que realizó la entrega.
hito.setResumenEntrega("Cambios en el Diagrama de Casos de Uso.");
hito.setEstado("Enviado con retraso");
// Almacenamiento de un documento/imagen en un Bucket de S3
cp.almacenarDocumentacionHitoEnS3(hito);
// Actualizar información en DynamoDb con información Hito
cp.actualizarHitoDynamoDb(hito);
// Consultar hito en DynamoDB
hito = cp.obtenerHitoProyectoPorClave(hito.getIdProyecto(), hito.getNumeroHito());
System.out.println(hito);
// Obtener información de S3
String urlDocumentoS3 = cp.obtenerURLObjetoS3(hito.getClaveDocumentoS3());
System.out.println(urlDocumentoS3);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void almacenarEstructuraHitosDynamoDB() {
List<Hito> listaHitos = null;
try {
listaHitos = new CsvToBeanBuilder(new FileReader("ficheros/hitos-proyecto.csv")).withType(Hito.class)
.withSeparator('|').build().parse();
for (Hito hitoCSV : listaHitos) {
System.out.println(hitoCSV);
// Crear un registro en una tabla DynamoDB
crearHitoDynamoDb(hitoCSV);
}
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void crearHitoDynamoDb(Hito hito) {
// Crear el cliente de DynamoDB (usando SDK v2)
DynamoDbClient clienteDynamoDb = GestorClientesServiciosAWS.getClienteDynamoDB();
// Crear un ítem con los atributos de un Hito
String fechaHitoString = "";
if (hito.getFechaHito() != null)
fechaHitoString = ConversorTipos.convertirDateAString(hito.getFechaHito());
PutItemRequest putItemRequest = PutItemRequest.builder().tableName(NOMBRE_TABLA)
.item(Map.of("id_proyecto", AttributeValue.builder().n(String.valueOf(hito.getIdProyecto())).build(),
"numero_hito", AttributeValue.builder().n(String.valueOf(hito.getNumeroHito())).build(),
"fecha_hito", AttributeValue.builder().s(fechaHitoString).build()))
.build();
// Insertar el ítem en DynamoDB
try {
clienteDynamoDb.putItem(putItemRequest);
System.out.println("Ítem agregado exitosamente.");
} catch (DynamoDbException e) {
System.err.println("No se pudo insertar el ítem: " + e.getMessage());
e.printStackTrace();
} finally {
clienteDynamoDb.close();
}
}
private void actualizarHitoDynamoDb(Hito hito) {
// Crear el cliente de DynamoDB (usando SDK v2)
DynamoDbClient clienteDynamoDb = GestorClientesServiciosAWS.getClienteDynamoDB();
// Crear un ítem con los atributos de un Hito
String fechaHitoString = "";
if (hito.getFechaHito() != null)
fechaHitoString = ConversorTipos.convertirDateAString(hito.getFechaHito());
String fechaEnvioString = "";
if (hito.getFechaEnvio() != null)
fechaEnvioString = ConversorTipos.convertirDateAString(hito.getFechaEnvio());
String sIdAlumno = "";
if (hito.getIdAlumnoEnvio() != null)
sIdAlumno = String.valueOf(hito.getIdAlumnoEnvio());
// Información del bucket y del archivo a subir
String claveDocumento = hito.getIdProyecto() + "/" + hito.getNumeroHito() + "/" + hito.getDocumento().getName();
PutItemRequest putItemRequest = PutItemRequest.builder().tableName(NOMBRE_TABLA)
.item(Map.of("id_proyecto", AttributeValue.builder().n(String.valueOf(hito.getIdProyecto())).build(),
"numero_hito", AttributeValue.builder().n(String.valueOf(hito.getNumeroHito())).build(),
"fecha_hito", AttributeValue.builder().s(fechaHitoString).build(),
"fecha_envio", AttributeValue.builder().s(fechaEnvioString).build(),
"id_alumno_envio", AttributeValue.builder().s(sIdAlumno).build(),
"clave_documento", AttributeValue.builder().s(claveDocumento).build(),
"resumen_entrega", AttributeValue.builder().s(hito.getResumenEntrega()).build(),
"estado", AttributeValue.builder().s(String.valueOf(hito.getEstado())).build()))
.build();
// Insertar el ítem en DynamoDB
try {
clienteDynamoDb.putItem(putItemRequest);
System.out.println("Ítem agregado exitosamente.");
} catch (DynamoDbException e) {
System.err.println("No se pudo insertar el ítem: " + e.getMessage());
e.printStackTrace();
} finally {
clienteDynamoDb.close();
}
}
private void almacenarDocumentacionHitoEnS3(Hito hito) {
// Crear el cliente de S3 (usando SDK v2)
S3Client clienteS3 = GestorClientesServiciosAWS.getClienteBucketS3();
// Información del bucket y del archivo a subir
String claveDocumento = hito.getIdProyecto() + "/" + hito.getNumeroHito() + "/" + hito.getDocumento().getName();
// Solicitud para subir el archivo
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(NOMBRE_BUCKET).key(claveDocumento)
.build();
try {
// Realizar la carga del archivo
PutObjectResponse response = clienteS3.putObject(putObjectRequest, hito.getDocumento().toPath());
// Imprimir respuesta de éxito
System.out.println("Archivo subido correctamente. ETag: " + response.eTag());
} catch (S3Exception e) {
System.err.println("No se pudo insertar el ítem: " + e.getMessage());
e.printStackTrace();
} finally {
clienteS3.close();
}
}
public Hito obtenerHitoProyectoPorClave(int idProyecto, int numeroHito) {
Hito hito = null;
// Crear el cliente de DynamoDB (usando SDK v2)
DynamoDbClient clienteDynamoDb = GestorClientesServiciosAWS.getClienteDynamoDB();
// Clave para la consulta
Map<String, AttributeValue> clave = new HashMap<>();
clave.put("id_proyecto", AttributeValue.builder().n(String.valueOf(idProyecto)).build());
clave.put("numero_hito", AttributeValue.builder().n(String.valueOf(numeroHito)).build());
// Construir la petición
GetItemRequest request = GetItemRequest.builder().tableName(NOMBRE_TABLA).key(clave).build();
// Realizar consulta
GetItemResponse response = clienteDynamoDb.getItem(request);
if (response.hasItem()) {
hito = new Hito();
Map<String, AttributeValue> item = response.item();
// Recuperar valores
String sFechaHito = item.get("fecha_hito").s();
String sFechaEnvio = item.get("fecha_envio").s();
String idAlumnoEnvio = item.get("id_alumno_envio").s();
String claveDocumento = item.get("clave_documento").s();
String resumenEntrega = item.get("resumen_entrega").s();
String estado = item.get("estado").s();
Date fechaHito = ConversorTipos.convertirStringADate(sFechaHito);
Date fechaEnvio = ConversorTipos.convertirStringADate(sFechaEnvio);
hito.setIdProyecto(idProyecto);
hito.setNumeroHito(numeroHito);
hito.setFechaHito(fechaHito);
hito.setIdAlumnoEnvio(Integer.parseInt(idAlumnoEnvio));
hito.setFechaEnvio(fechaEnvio);
hito.setResumenEntrega(resumenEntrega);
hito.setEstado(estado);
hito.setClaveDocumentoS3(claveDocumento);
} else {
System.out.println("No se encontró el hito para la clave dada.");
}
clienteDynamoDb.close();
return hito;
}
private String obtenerURLObjetoS3(String claveDocumento) {
String urlObjetoS3 = null;
// Crear el cliente de S3 (usando SDK v2)
S3Client clienteS3 = GestorClientesServiciosAWS.getClienteBucketS3();
// Usar el perfil `learnerlab-profile` (el nombre del perfil en
// `~/.aws/credentials`)
ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create("default");
// Crear el cliente presigner de S3 con el perfil específico
S3Presigner presigner = S3Presigner.builder().region(GestorClientesServiciosAWS.REGION_AWS)
.credentialsProvider(credentialsProvider) // Usar el perfil especificado
.build();
// Crear la solicitud de obtención de objeto
GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(NOMBRE_BUCKET).key(claveDocumento)
.build();
// Generar la URL firmada
PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(
builder -> builder.getObjectRequest(getObjectRequest).signatureDuration(Duration.ofMinutes(60)) // Duración
// de la
// URL
// firmada
);
// Obtener la URL firmada
URL presignedUrl = presignedRequest.url();
urlObjetoS3 = presignedUrl.toString();
// Cerrar el presigner
presigner.close();
return urlObjetoS3;
}
private void almacenarDocumentacionoEnS3(String claveDocumento, File ficheroDocumentoS3) {
// Crear el cliente de S3 (usando SDK v2)
S3Client clienteS3 = GestorClientesServiciosAWS.getClienteBucketS3();
// Solicitud para subir el archivo
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(NOMBRE_BUCKET).key(claveDocumento)
.build();
try {
// Realizar la carga del archivo
PutObjectResponse response = clienteS3.putObject(putObjectRequest, ficheroDocumentoS3.toPath());
// Imprimir respuesta de éxito
System.out.println("Archivo subido correctamente. ETag: " + response.eTag());
} catch (S3Exception e) {
System.err.println("No se pudo insertar el ítem: " + e.getMessage());
e.printStackTrace();
} finally {
clienteS3.close();
}
}
}

View File

@ -0,0 +1,40 @@
/**
*
*/
package org.lapaloma.proyectos;
import java.io.File;
import java.util.Date;
import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.CsvDate;
import lombok.Data;
/**
* Clase encargada de recoger información de negocio de Hito
*
* @author Programador: Isidoro Nevares Martín - Virgen de la Paloma
* @date 24 may 2025
* @version: 1.0
*/
@Data
public class Hito {
@CsvBindByName(column = "id_proyecto", required = true)
private int idProyecto;
@CsvBindByName(column = "numero_hito", required = true)
private int numeroHito;
@CsvBindByName(column = "fecha_hito", required = true)
@CsvDate("yyyy-MM-dd")
private Date fechaHito;
private Date fechaEnvio;
private Integer idAlumnoEnvio;
private File documento;
private String resumenEntrega;
private String estado;
private String claveDocumentoS3;
}

View File

@ -0,0 +1,47 @@
/**
*
*/
package org.lapaloma.proyectos.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* Clase de utilidad encargada de realizar conversión entre tipos.
*
* @author Programador: Isidoro Nevares Martín - Virgen de la Paloma
* @date 24 may 2025
* @version: 1.0
*/
public class ConversorTipos {
// Evita que pueda construirse un objeto de la clase.
private ConversorTipos() {
}
public static String convertirDateAString(Date fecha) {
String fechaString = null;
SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
fechaString = formato.format(fecha);
return fechaString;
}
public static Date convertirStringADate(String fechaString) {
Date fecha = null;
// Definir el formato en que está la fecha en el String
SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
// Convertir el String a Date
fecha = formato.parse(fechaString);
} catch (ParseException e) {
// Manejo de errores si el formato no es válido
System.err.println("Error al convertir la fecha: " + e.getMessage());
}
return fecha;
}
}

View File

@ -0,0 +1,40 @@
/**
*
*/
package org.lapaloma.proyectos.util;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.s3.S3Client;
/**
* Clase asociada a la gestión de clientes para servicios de AWS
*
* @author Programador: Isidoro Nevares Martín - Virgen de la Paloma
* @date 16 may 2025
* @version: 1.0
*/
public class GestorClientesServiciosAWS {
public final static Region REGION_AWS = Region.US_EAST_1;
// Evita que pueda construirse un objeto de la clase.
private GestorClientesServiciosAWS() {
}
public static S3Client getClienteBucketS3() {
S3Client clienteS3 = S3Client.builder()
.credentialsProvider(ProfileCredentialsProvider.create())
.region(REGION_AWS).build();
return clienteS3;
}
public static DynamoDbClient getClienteDynamoDB() {
// Crear el cliente de DynamoDB (usando SDK v2)
DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
.region(REGION_AWS)
.build();
return dynamoDbClient;
}
}