cancel
Showing results for 
Search instead for 
Did you mean: 

Generar checksum en subida de documento

alex_grasset
Confirmed Champ
Confirmed Champ

Hola,

me han pedido que evalue la posibilidad de que Alfresco en el momento de subir un documento, me devuelva el checksum del documento generado.

Esto es para que podamos incluir algún tipo de control para asegurar que el documento no se haya truncado y se haya podido subir correctamente.

Existe esta posiblidad o tendría que incluirla desde código (estoy trabajando en Java con apache chemistry).

Muchas gracias.

1 ACCEPTED ANSWER

En ese método estás recibiendo el InputStream del fichero en la variable file.

Cando realizas el cálculo del checksum en DigestUtils.md5Hex(file) estás consumiendo el Stream, por eso cuando creas el contentStream se basa en un Stream vacío.

contentStream = session.getObjectFactory().createContentStream(fName, -1, mimeType, file);

Yo probaría a pasarle el objeto File a este método, así podrías abrir un InputStream para calcular el MD5 y volver a crear un nuevo InputStream de cero para construir el contentStream.

Hyland Developer Evangelist

View answer in original post

9 REPLIES 9

angelborroy
Community Manager Community Manager
Community Manager

Alfresco solo almacena el tamaño del documento que ha almacenado (en bytes) en la propiedad cm:content.size.

Si esto no es suficiente, si necesitas en realidad el checksum, deberías desarrollar un addon que realizase ese cálculo y lo almacenase en una propiedad personalizada.

Puedes echarle un vistazo a este proyecto:

http://sujayopillai.com/2015/03/25/alfresco-checksum.html

Hyland Developer Evangelist

Muchas gracias, justamente en eso estoy, calculando yo el checksum e informandolo en una custom property, pero me esta pasando una cosa muy extraña.

Desde que estoy informando el checksum como metadato en la property los documentos llegan a Alfresco vacios. Sin embargo, si pongo yo a mano el valor que retorna la función que calcula el checksum el documento se sube correctamente.

Para aclarar:

checksum = "77410bc0143eeb2748da1d8e738a5ea6"; -> BIEN

checksum = getMD5Hash(file); -> MAL (la funcion retorna un string con el valor del ejemplo anterior)

Por otro lado esa url que me pasas ya la vi y no entiendo nada de lo que allí explica, siento que me falta una base importante para entender ese manual. Al final soy un desarrollador java, de Alfresco no se nada XD

La mejor manera de realizar este cálculo es desarrollando un Behaviour.

En el ejemplo que te pasé, el behaviour se activa cuando se actualiza el contenido:

https://github.com/sujaypillai/alfchecksum/blob/master/chksum-repo/src/main/java/org/ootb/repo/Conte...

En este punto se asigna el hash a una propiedad personalizada del modelo de contenido:

https://github.com/sujaypillai/alfchecksum/blob/master/chksum-repo/src/main/java/org/ootb/repo/Conte...

Adicionalmente, utiliza un aspecto para marcar qué documentos deben calcular el hash.

¿Lo estás haciendo de esta manera o mediante otro mecanismo?

Hyland Developer Evangelist

Hola,

lo estoy haciendo desde Java.

En la daily acabamos de hablarlo y como el objetivo del checksum es comprobarsi el documento se ha subido correctamente o se ha truncado no nos serviria que Alfresco calculase el checksum con el behaviour como comentas puesto que el checksum calculado en Alfresco seria sobre un documento truncado.

Por tanto el problema que tengo ya no es como implementar el calculo del checksum ya que lo tengo hecho desde java, sino saber porque motivo si informo el checksum calculado en la customproperty con una constante "77410bc0143eeb2748da1d8e738a5ea6" funciona bien, pero si el que informa la property es la función de calculo del checksum con el mismo valor, sube el documento vacio.

Hay alguna manera de poder ver si esta creación del documento ha generado algún tipo de log de error o algo en Alfresco? Pongo mi método java que crea el documento por si ayuda:

public static Document createDocument(String folderName, InputStream file, String fName, Map<String, String> customProps) {

		if (getCurrentSession() == null) {
        	connect();
        }
		
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put(PropertyIds.OBJECT_TYPE_ID, CMIS_ELENA_DOCUMENT_TYPE);
		properties.put(PropertyIds.NAME, fName);

		for (Map.Entry<String, String> entry : customProps.entrySet()) {
			properties.put(entry.getKey(), entry.getValue());
		}
		
		//creamos checksum
		String checksum = "";
//		checksum = "77410bc0143eeb2748da1d8e738a5ea6"; //funciona
		try {
			checksum = DigestUtils.md5Hex(file); //falla (devuelve 77410bc0143eeb2748da1d8e738a5ea6)
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		properties.put("elena:17", checksum);
		
		ContentStream contentStream;
		Document doc = null;
		//obtenemos carpeta
		Folder folder = createFolder(folderName,MAIN_FOLDER_NAME);
		
		//obtenemos tipo documento
		String mimeType = MimeTypes.getMIMEType(FilenameUtils.getExtension(fName));
		
		//Creamos stream
		contentStream = session.getObjectFactory().createContentStream(fName, -1, mimeType, file);
//		contentStream = session.getObjectFactory().createContentStream(fName, -1, "application/octet-stream", file);
		
		//comprobamos si documento ya existe
		Document document = (Document) getChildByName(folder, fName);
		
		if(document == null) {
			//si no existe lo creamos
			doc = folder.createDocument(properties, contentStream, VersioningState.MAJOR);
		}else {
			//si ya esta lo versionamos

			//comprobamos si se puede hacer checkout
			boolean isCheckedOut = Boolean.TRUE.equals(document.isVersionSeriesCheckedOut());
			String checkedOutBy = document.getVersionSeriesCheckedOutBy();			
			//TODO AGC se puede usar control de quien tiene pillado el documento con isCheckedOut y checkedOutBy
			
			//check-out
			ObjectId pwcId = document.checkOut();
			Document pwc = (Document) session.getObject(pwcId);			

			//check-in
			ObjectId newVersionId = pwc.checkIn(true, properties, contentStream, "Nueva versión");
			doc = (Document) session.getObject(newVersionId);
		}
	
		return doc;
	}

Tiene pinta de que lo estás haciendo desde Chemistry.

El problema puede ser que, después de calcular el HASH de un Stream, el stream queda vacío y por eso lo sube sin datos. Prueba a abrir el stream, calcular el hash, cerrar el stream y volver a abrirlo antes de enviarlo a Alfresco.

Hyland Developer Evangelist

Si perdona, es con chemistry, y por cierto, toda la pinta de que es justo eso que comentas, voy a probar.

Mil gracias!

Hola, cuando dices abrir el stream, dado mi codigo, como seria? no soy capaz de ver el problema

Mil gracias.

En ese método estás recibiendo el InputStream del fichero en la variable file.

Cando realizas el cálculo del checksum en DigestUtils.md5Hex(file) estás consumiendo el Stream, por eso cuando creas el contentStream se basa en un Stream vacío.

contentStream = session.getObjectFactory().createContentStream(fName, -1, mimeType, file);

Yo probaría a pasarle el objeto File a este método, así podrías abrir un InputStream para calcular el MD5 y volver a crear un nuevo InputStream de cero para construir el contentStream.

Hyland Developer Evangelist

Hola, problema resuelto, como no era viable poder modificar el tipo de parametro que llegaba a mi método, lo que he hecho es clonar el inputstream y usar uno para calcular el checksum y otro para generar el content stream.

Muchas gracias.