Adapteur XSLX en erreur

Bonjour,
j’essaie d’importer des données via un adapteur par une tâche cron.

new Integration().importADP(getGrant(), "ImportBCSIDeployment", 
							Tool.toInputStream(Tool.readUrl("urlVersMonFichier")), this.getName(), null);

et mon adapteur :

public class ImportBCSIDeployment extends SimpleXLSXAdapter {
	private static final long serialVersionUID = 1L;

	
	@Override
	public String processCell(XSSFCell cell) throws InterruptedException {
		try {
AppLog.info("processCell " , Grant.getSystemAdmin());
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
			return "";
	}
	
	@Override
	public void startProcessRow(XSSFRow row)  throws InterruptedException {
		try {
AppLog.info("startProcessRow " , Grant.getSystemAdmin());
			
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
	
	@Override
	public void endProcessRow(XSSFRow row)  throws InterruptedException {
		try {
AppLog.info("endProcessRow " , Grant.getSystemAdmin());
			
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
	
		@Override
	public void startProcessSheet(XSSFSheet sheet)  throws InterruptedException {
		try {
			
AppLog.info("startProcessSheet " , Grant.getSystemAdmin());
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
	
		@Override
	public void endProcessSheet(XSSFSheet sheet)  throws InterruptedException {
		try {
			
AppLog.info("endProcessSheet " , Grant.getSystemAdmin());
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
	
		
		@Override
	public void startProcessWorkbook(XSSFWorkbook workbook)  throws InterruptedException {
		try {
			
AppLog.info("workbook " , Grant.getSystemAdmin());
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
		@Override
	public void endProcessWorkbook(XSSFWorkbook workbook)  throws InterruptedException {
		try {
			
AppLog.info("endProcessWorkbook ", Grant.getSystemAdmin());
		} catch (Exception e) {
			AppLog.error(getClass(), "process", null, e, getGrant());
		}
	}
}

Exemple.xlsx (210.7 KB)

2021-02-18 21:01:01,824 INFO [com.simplicite.util.engine.Interface] SIMPLICITE|http://9bea7c2e2913:8080||ICOREIO001|p104635|com.simplicite.util.engine.Interface|importData||I/O info: Start scanning data, origin: BCSIMetaDataImporter
2021-02-18 21:01:01,705 ERROR [com.simplicite.adapters.BCSIModule_Meta.ImportBCSIDeployment ] SIMPLICITE|http://9bea7c2e2913:8080||ERROR|p104635|com.simplicite.adapters.BCSIModule_Meta.ImportBCSIDeployment |process||Event: Error during Excel workbook processing (at sheet -1, row -1, cell -1)
    java.util.zip.ZipException: invalid stored block lengths
     at org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.readFromInflater(ZipArchiveInputStream.java:586)
     at org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.readDeflated(ZipArchiveInputStream.java:551)
     at org.apache.commons.compress.archivers.zip.ZipArchiveInputStream.read(ZipArchiveInputStream.java:458)
     at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
     at org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.read(ZipArchiveThresholdInputStream.java:79)
     at org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:152)
     at org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:121)
     at org.apache.poi.openxml4j.util.ZipArchiveFakeEntry.<init>(ZipArchiveFakeEntry.java:47)
     at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:53)
     at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:106)
     at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:301)
     at org.apache.poi.ooxml.util.PackageHelper.open(PackageHelper.java:37)
     at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:303)
     at com.simplicite.util.integration.SimpleXLSXAdapter.process(SimpleXLSXAdapter.java:42)

Sauriez-vous pourquoi j’ai cette erreur ?
Au passage, pourriez-vous regénérer votre javadoc (celle sur la classe SimpleXLSXAdapter est incomplète).

Merci pour votre support
Amandine T.

[Platform]
Status=OK
Version=4.0.P25
BuiltOn=2021-02-03 12:18 (revision ad67c22c50ac1a7123b8ee2fba1ad4c4734f148a)
Encoding=UTF-8
EndpointIP=21.0.9.3
EndpointURL=http://9bea7c2e2913:8080
TimeZone=Europe/Paris
SystemDate=2021-02-18 21:16:34

La méthode Tool.readUrl est faite pour lire du texte pas du binaire.

Utilisez Tool.readUrlAsByteArray ou d’autres méthodes tierces qui lisent votre URL en byte[] ou directement en stream

PS: Assurez vous aussi que le fichier que vous essayez d’importer est bien format XLSX (= un ZIP) et au format legacy XLS.

Merci pour ce retour. J’ai bien fait la correction readUrlreadUrlAsByteArray.
J’ai toutefois la même erreur.
Je sais que mon fichier est correct car lorsque je passe par l’interface d’import xml


mon fichier est bien traité.
Est-ce possible que vous me fournissiez le code que vous appelez lorsque l’on clique sur le bouton “Importer” , svp ?

Merci d’avance

C’est bien cette méthode là qui est appelée par la page d’import : Integration

Genre:

try (InputStream in = Tool.toInputStream(Tool.readUrlAsByteArray(url, true))) { // true => binary content
   new Integration().importADP(g, "MyAdapter", in, "MyOrigin", null);
}

Il faut utiliser cette variante : Tool avec true pour dire que c’est un contenu binaire

Merci @david il me manquait bien le boolean.
Autre question liée aussi au ticket Changement du statut d’un adapteur non fonctionnel
Voici le code de mon adapteur :

package com.simplicite.adapters.BCSIModule_Meta;

import java.util.*;
import com.simplicite.util.*;
import com.simplicite.util.exceptions.*;
import com.simplicite.util.integration.*;
import com.simplicite.util.tools.*;

import org.apache.commons.lang3.StringUtils;

import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Adapter SHAREPOINT_BCSIDeployment
 */
public class SHAREPOINT_BCSIDeployment extends SimpleXLSXAdapter {
	private static final long serialVersionUID = 1L;

	private List<XSSFSheet> sheetToProcessList = new ArrayList();
	private boolean hasError = false;
	
	public void log(String text) {
		this.getLogWriter().println(text);
	}
	
	@Override
	public void startProcessWorkbook(XSSFWorkbook workbook)  throws InterruptedException {}
	
	@Override
	public void startProcessSheet(XSSFSheet sheet)  throws InterruptedException {
		log("Processing sheet " + sheet.getSheetName());
		XSSFRow firstRow = sheet.getRow(sheet.getFirstRowNum());
		if (firstRow != null) {
			int firstCellNum = firstRow.getFirstCellNum();
			XSSFCell cell = firstRow.getCell(firstCellNum);
			if (firstRow.getCell(firstCellNum) != null && "ASSET_ID".equals(firstRow.getCell(firstCellNum).getStringCellValue())
				&& firstRow.getCell(firstCellNum + 1) != null && "UPDATE Scope".equals(firstRow.getCell(firstCellNum + 1).getStringCellValue())
				&& firstRow.getCell(firstCellNum + 2) != null && "Lot migration".equals(firstRow.getCell(firstCellNum + 2 ).getStringCellValue())
			) {
				sheetToProcessList.add(sheet);
			}
		}
		if (sheetToProcessList.contains(sheet)) {
			log("Number of rows to process : " + sheet.getLastRowNum());
		} else {
			log("Ignoring sheet : it doesn't contain informations");
		}
	}

	@Override
	public void startProcessRow(XSSFRow row)  throws InterruptedException {
		if (sheetToProcessList.contains(row.getSheet()) && row.getRowNum() > row.getSheet().getFirstRowNum()) {
			int indexColServerName = row.getSheet().getRow(row.getSheet().getFirstRowNum()).getFirstCellNum();
			XSSFCell cell = row.getCell(indexColServerName);
			String cellValue = getCellValue(cell);
			if (StringUtils.isNotBlank(cellValue)) {
				ObjectDB deployment = this.getGrant().getTmpObject("BCSIDeployment");
				deployment.getField("DepServId.ServId").setFilter(cell.getStringCellValue());
				List<String[]> recordList = deployment.search();
				if (recordList != null) {
					cell = row.getCell(indexColServerName + 2);
					String lot = getCellValue(cell);
					if (cell != null && StringUtils.isNotBlank(cell.getStringCellValue())) {
						lot = cell.getStringCellValue();
					}
					int nbUpdated = 0;
					for (int i = 0; i < recordList.size(); i++) {
						deployment.setValues(recordList.get(i), true);
						if (!lot.equals(deployment.getFieldValue("DepMigLot"))) {
							deployment.getField("DepMigLot").setValue(lot);
							try {
								new BusinessObjectTool(deployment).validateAndSave();
								nbUpdated++;
							} catch (ValidateException | SaveException e) {
								log("Impossible to update  BCSIDeployment " + deployment.getRowId() + " with lot " + lot);
								log(e.toString());
								hasError = true;
							}
						}
					}
					log("Processing row " + row.getRowNum() + " : server id " + deployment.getField("DepServId.ServId").getFilter() + " " + nbUpdated + " app-server updated");
				} else {
					log("Ignoring row " + row.getRowNum() + " : unknown server id " + cell.getStringCellValue());
				}
			} else {
				log("Ignoring row " + row.getRowNum() + " : it doesn't contain server id");
			}
		}
	}
	
	private String getCellValue(XSSFCell cell) {
		String cellValue = "";
		if (cell != null) {
			if (CellType.STRING.equals(cell.getCellType())) {
				cellValue = cell.getStringCellValue();
			} else if (CellType.STRING.equals(cell.getCellType())) {
				cellValue = String.valueOf(cell.getNumericCellValue());
			} 
		}
		return cellValue; 
	}

	@Override
	public String processCell(XSSFCell cell) throws InterruptedException { return ""; }

	@Override
	public void endProcessRow(XSSFRow row)  throws InterruptedException {}
	
	@Override
	public void endProcessSheet(XSSFSheet sheet)  throws InterruptedException {}
	
	@Override
	public void endProcessWorkbook(XSSFWorkbook workbook)  throws InterruptedException {
		if (hasError) {
			// Doesn't work
			setStatus(SystemXML.SUPERVISOR_STATUS_IMPORT_ERROR);
			// throw new InterruptedException("Failure during the update.");
		}
	}
}

Dans la méthode endProcessWorkbook, je détecte s’il y a eu des erreurs fonctionnelles et souhaite que le statut passe à “Traité en erreur”.
Dans les logs, j’obtiens bien le statut E. Par contre le statut reste “Traitée sans erreur”


L’évolution faite dans le ticket Changement du statut d’un adapteur non fonctionnel n’a été faite que pour les adapteurs JSON ?

Cordialement.
Amandine T.

Grace à la date j’ai retrouvé le commit dont on parle, il ne concernait que les SimpleJSONAdapter et SimpleYAMLAdapter.

Il faut que je regarde pour voir si ce sujet est transposable dans le contexte du SimpleXLSXAdapter

en soi il faudra le transposer sur tous les types d’adapteurs.
Dans quel cas, l’instruction setStatus(SystemXML.SUPERVISOR_STATUS_IMPORT_ERROR); est elle utilisable ? Elle ne correspond pas au statut de l’import ? (Actuellement elle n’est pas prise en compte).