Jonathan Sinovassin-Naïk created UNOMI-986:
----------------------------------------------
Summary: A one-shot CSV import uploaded through the REST endpoint
is never processed
Key: UNOMI-986
URL: https://issues.apache.org/jira/browse/UNOMI-986
Project: Apache Unomi
Issue Type: Bug
Reporter: Jonathan Sinovassin-Naïk
The endpoint that receives a one-shot CSV import and the Camel route that
consumes it disagree on
the path. The endpoint writes the file to the root of the upload directory, and
the route reads the
tenant from the name of the directory holding the file. The root directory is
not a tenant, so every
one-shot import uploaded through the documented endpoint is dropped.
The caller sees no failure. The upload answers 200, and the only trace is one
warning in the server
log.
h2. Where the two sides disagree
{{ImportConfigurationServiceEndPoint.processOneshotImportConfigurationCSV}}
writes the file to
{{<uploadDir>/<importConfigId>.csv}}:
{code:java}
java.nio.file.Path path =
Paths.get(configSharingService.getProperty(RouterConstants.IMPORT_ONESHOT_UPLOAD_DIR)
+ importConfigId + ".csv");
Files.deleteIfExists(path);
InputStream in = file.getObject(InputStream.class);
Files.copy(in, path);
{code}
{{ImportConfigByFileNameProcessor.process}} reads the tenant from the parent
directory of the file:
{code:java}
String tenantId = extractTenantId(filePath);
if (tenantId == null || !isValidTenantId(tenantId) || !isValidTenant(tenantId))
{
LOGGER.warn("Invalid or missing tenant ID in path: {}", filePath);
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);
return;
}
{code}
{{extractTenantId}} returns the name of the parent directory. For a file at the
root of the upload
directory that name is {{unomi_oneshot_import_configs}}, which is not a tenant.
The route already reads sub-directories, so the per-tenant directory is
expected and supported.
{{ProfileImportOneShotRouteBuilder}} declares:
{code:java}
from("file://" + uploadDir + "?recursive=true&moveFailed=.error&include=.*.csv")
{code}
h2. Steps to reproduce
# Start Apache Unomi 3.1.0-SNAPSHOT.
# Create a one-shot import configuration, and note its id.
# Upload a CSV for that configuration:
{code}
curl -u <admin> -F "importConfigId=<id>" -F "[email protected]" \
http://localhost:8181/cxs/importConfiguration/oneshot
{code}
# Read the server log, and search the profile index for the imported profiles.
h2. Expected result
The route reads the file, and the profiles named in the CSV are imported.
h2. Actual result
The upload answers 200. The route reads the file, refuses it, and moves it to
{{.camel}} unprocessed.
No profile is imported. The log carries one line:
{noformat}
WARN ImportConfigByFileNameProcessor | Invalid or missing tenant ID in path:
/opt/unomi/data/tmp/unomi_oneshot_import_configs/19d061b5-b03d-41ae-beeb-8d75c4f1bf22.csv
{noformat}
h2. Proposed fix
The endpoint resolves the current tenant, creates the directory named after it,
and writes the file
there:
{code:java}
String tenantId = executionContextManager.getCurrentContext().getTenantId();
java.nio.file.Path tenantDir =
Paths.get(String.valueOf(configSharingService.getProperty(RouterConstants.IMPORT_ONESHOT_UPLOAD_DIR)),
tenantId);
Files.createDirectories(tenantDir);
java.nio.file.Path path = tenantDir.resolve(importConfigId + ".csv");
{code}
Measured on 3.1.0-SNAPSHOT with that change. The upload writes
{{<uploadDir>/default/<importConfigId>.csv}}, the route reads it, and the
profiles of the CSV are
imported. An end to end test that drives the import through the user interface
went from failing to
passing.
h2. Note
{{ExportConfigurationServiceEndPoint}} carries a {{/oneshot}} path as well.
This report does not
cover the export side, and it is worth checking for the same disagreement.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)