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)

Reply via email to