📂 Alpura Back Java Library — Gestión de Archivos v5.1 (Alfresco + Oracle Object Storage)
Librería para integrar en microservicios Java 21 + Spring Boot 3.4.x (com.alpura.file:alpura-back-java-lib-file:5.1) con Alfresco (almacenamiento privado) y Oracle Cloud Object Storage (OCI) (almacenamiento público).
Provee un gateway unificado (IFileGateway) para subir, descargar, listar, actualizar y eliminar documentos.
🛠 Requisitos
- Java: 21 (Temurin recomendado)
- Spring Boot: 3.4.x
- Alpura BOM: 1.0.4
- Alfresco REST API v1 habilitado (para contenidos privados)
- OCI Tenancy con Object Storage (para contenidos públicos)
📥 Instalación
Opción A: Heredando versión desde Alpura BOM 1.0.4 (RECOMENDADO)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alpura</groupId>
<artifactId>bom</artifactId>
<version>1.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alpura.file</groupId>
<artifactId>alpura-back-java-lib-file</artifactId>
</dependency>
</dependencies>
Opción B: Uso directo (Standalone)
<dependency>
<groupId>com.alpura.file</groupId>
<artifactId>alpura-back-java-lib-file</artifactId>
<version>5.1</version>
</dependency>
Gradle:
implementation "com.alpura.file:alpura-back-java-lib-file:5.1"
Escaneo de componentes
Asegúrate de escanear el paquete de la librería:
@SpringBootApplication
@ComponentScan({
"com.alpura.file", // ⬅ obligatorio para encontrar los @Service de la lib
"com.alpura.utilities"
})
public class ExApplication {
public static void main(String[] args) {
SpringApplication.run(ExApplication.class, args);
}
}
🚀 ¿Qué hace la librería?
- Expone un gateway (
IFileGateway) que decide el backend:- Oracle Object Storage (OCI) si
isPublic = true - Alfresco si
isPublic = false
- Oracle Object Storage (OCI) si
- Resuelve rutas lógicas a partir de plantillas y placeholders (p. ej.
clientes/{clienteId}/facturas/{year}/{month}/). - Implementa operaciones: upload, download, list, delete, update.
- Soporta recursos personalizados de transferencia binaria con metadata de nombre (
NamedByteArrayResource).
📦 Integración de la librería de archivos en el EMF primario
En tu configuración estás incorporando repositorios y entidades que viven dentro de la librería de archivos. Los dos puntos clave son:
1) Escaneo de repositorios (Spring Data)
@EnableJpaRepositories(
basePackages = {
"com.alpura.java.arch.persistence",
"com.alpura.file.repository" // 👈 repos de la librería
}
)
public class PrimaryDataConfig {}
2) Escaneo de entidades (JPA)
localContainer.setPackagesToScan(
"com.alpura.model.entity",
"com.alpura.file.entity" // 👈 entidades de la librería
);
⚙️ Configuración (YAML)
1) Alfresco (privado)
alfresco:
host: https://alfresco.tuempresa.com
api-base-path: alfresco/api/-default-/public/alfresco/versions/1
username: usuario_servicio
password: "********"
2) Oracle Object Storage (público)
alpura:
oracle:
namespace: idhnamyewasy
bucket: ALOCIAPIFACELDEV
region: us-ashburn-1
auth:
tenancy-ocid: "ocid1.tenancy.oc1...."
user-ocid: "ocid1.user.oc1...."
fingerprint: "aa:bb:cc:dd:..."
private-key-path: "/seguro/oci_api_key.pem"
passphrase: ""
🧩 Objetos clave (request/response)
ManagedDocumentMessenger (subir/actualizar)
public class ManagedDocumentMessenger {
MultipartFile file; // archivo
DocumentType type; // p. ej. NOMINA
Map<String, String> placeholders; // { "clienteId":"001", "year":"2025", "month":"09" }
Boolean isPublic; // true=Oracle, false=Alfresco
}
DocumentDownloadRequest (descargar/eliminar)
public class DocumentDownloadRequest {
DocumentType type;
Map<String, String> placeholders;
String fileName; // nombre exacto con extensión
Boolean isPublic; // true=Oracle, false=Alfresco
}
🔁 Respuestas y manejo de descarga
La descarga te regresa los bytes con nombre preservado usando NamedByteArrayResource:
@PostMapping("/download")
public ResponseEntity<ByteArrayResource> download(@ModelAttribute DocumentDownloadRequest rq) {
ByteArrayResource body = gateway.downloadDocument(rq);
String filename = rq.getFileName();
return ResponseEntity.ok()
.header("Content-Disposition", "attachment; filename=\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.contentLength(body.contentLength())
.body(body);
}