[CELUM-45] Download of CELUM Assets via Assets app completes, but all files are broken Created: 08/Jun/22  Updated: 19/Oct/22  Resolved: 19/Oct/22

Status: Closed
Project: Celum DAM Connector
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Neutral
Reporter: Christopher Chard Assignee: Raphael Falvo
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File screenshot-1.png     PNG File screenshot-2.png    
Template:
Acceptance criteria:
Empty
Date of First Response:

 Description   

The CELUM Assets app has the Download action.

Files seem to download fine.
However, when trying to open the files, they are corrupted and cannot be opened.

This is true for any asset. They are definitely NOT broken in the DAM, something is going wrong in the download process. Maybe a wrong url is used for downloading?

Log shows no errors.



 Comments   
Comment by Raphael Falvo [ 10/Jun/22 ]

Hello cchard ,

For assets that do not have a public URL it's working fine on my side.

May you please share the file that is downloaded, as well as the public URL of the related asset ? Thanks

Comment by Christopher Chard [ 13/Jun/22 ]

Hi rfalvo,
I tried uploading a sample file, [^unigarant__bric_(2018)_uip.pdf], but I get an error:

The downloaded files are 0 KB:

Obviously, in Celum they are NOT 0 KB. I suppose there is some kind of mismatch of where the Download-Action tries to take the file from...

Comment by Raphael Falvo [ 13/Jun/22 ]

Hi cchard ,

Can you share the public URL(s) of these assets ? The system is using the public URLs to download the assets, I want to ensure there is nothing wrong on those. Thanks

Comment by Raphael Falvo [ 28/Jun/22 ]

Hi cchard ,

I have been able to test on our side the download with an asset having a public URL, without being able to reproduce your issue.

I would suggest you to check if the public URL of the asset on which you are encountering the issue is not broken, or maybe checking if you don't have custom code for the download action (original action is info.magnolia.dam.app.action.DownloadAssetAction)

Comment by Raphael Falvo [ 01/Jul/22 ]

Hi cchard ,

Can you please provide here all the custom code you have which relates to public URL ? Thanks

Comment by Christopher Chard [ 05/Jul/22 ]

Here you go, this is our entire custom code:

ui-module-celum/src/main/java/com/ui/celum/CelumConstants.java

package com.ui.celum;

public class CelumConstants {
	public static final String CELUM_EXPORTER_PROVIDER = "celum-extension-exporter";
	public static final String CELUM_EXPORTER_INSTANCE = "";
	public static final String CELUM_DEFAULT_ASSET = "original";
	public static final Integer CELUM_FIELD_RELEVANT_FOR_CMS = 482;
	public static final Integer CELUM_ASSET_TYPE_CMS = 10011;
}

ui-module-celum/src/main/java/com/ui/celum/service/UiCelumServiceImpl.java

package com.ui.celum.service;

import static com.ui.celum.CelumConstants.CELUM_ASSET_TYPE_CMS;
import static com.ui.celum.CelumConstants.CELUM_DEFAULT_ASSET;
import static com.ui.celum.CelumConstants.CELUM_EXPORTER_INSTANCE;
import static com.ui.celum.CelumConstants.CELUM_EXPORTER_PROVIDER;
import static com.ui.celum.CelumConstants.CELUM_FIELD_RELEVANT_FOR_CMS;
import static java.lang.Long.parseLong;
import static java.util.Collections.EMPTY_LIST;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;

import java.util.Collection;
import java.util.Objects;
import java.util.stream.Stream;

import javax.inject.Inject;
import javax.inject.Provider;

import org.apache.commons.lang3.StringUtils;

import com.celum.api.identifiers.AssetId;
import com.celum.api.identifiers.AssetTypeId;
import com.celum.api.identifiers.InformationFieldId;
import com.celum.api.identifiers.NodeId;
import com.celum.api.model.AssetPublicUrl;
import com.celum.api.model.Node;
import com.celum.api.model.ProviderFilter;
import com.celum.api.queries.AssetPublicUrlsQuery;
import com.celum.api.queries.AssetSearchQuery;
import com.celum.api.queries.ChildNodesQuery;
import com.celum.api.queries.filters.AssetFilter;
import com.celum.api.queries.filters.AssetFilters;
import com.celum.api.remote.RemoteClient;
import com.celum.api.serialization.filters.AssetFiltersImpl;

import info.magnolia.addon.commons.cache.annotation.Cacheable;
import info.magnolia.dam.api.Item;
import info.magnolia.external.dam.celum.CelumAsset;
import info.magnolia.external.dam.celum.CelumAssetProvider;
import info.magnolia.external.dam.celum.CelumCredentialProvider;
import info.magnolia.external.dam.celum.CelumFolder;
import info.magnolia.external.dam.celum.DamCelumModule;
import info.magnolia.external.dam.celum.connection.CelumConnectionManager;
import info.magnolia.external.dam.celum.filters.AssetsSearchFilterFactory;
import info.magnolia.external.dam.celum.service.CelumJcrService;
import info.magnolia.external.dam.celum.service.CelumServiceImpl;
import info.magnolia.external.dam.celum.util.CelumUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UiCelumServiceImpl extends CelumServiceImpl {
	private final DamCelumModule module;
	private final Provider<CelumAssetProvider> celumAssetProvider;
	private final CelumConnectionManager celumConnectionManager;
	private final CelumJcrService celumJcrService;

	@Inject
	public UiCelumServiceImpl(
			final Provider<DamCelumModule> module,
			final Provider<CelumAssetProvider> celumAssetProvider,
			final CelumCredentialProvider credentialProvider,
			final CelumConnectionManager celumConnectionManager,
			final AssetsSearchFilterFactory searchFilterFactory,
			final CelumJcrService celumJcrService) {
		super(
				module,
				celumAssetProvider,
				credentialProvider,
				celumConnectionManager,
				searchFilterFactory,
				celumJcrService);
		this.module = module.get();
		this.celumAssetProvider = celumAssetProvider;
		this.celumConnectionManager = celumConnectionManager;
		this.celumJcrService = celumJcrService;
	}

	RemoteClient client() {
		return this.celumConnectionManager.getClientConnection();
	}

	@Override
	@Cacheable(cacheName = { "celum-assets-in-folder" })
	public Collection<Item> getAssetsInFolder(final String id, final String userId) {
		final NodeId nodeId = CelumUtil.getNodeId(id);

		if (this.client() == null || nodeId.getId() < 1L) {
			return EMPTY_LIST;
		}

		return Stream.concat(
				fetchChildFolders(nodeId),
				fetchChildAssets(nodeId))
				.collect(toList());

	}

	private Stream<Item> fetchChildFolders(final NodeId nodeId) {
		final ChildNodesQuery childNodesQuery = ChildNodesQuery
				.byUser(this.getCredentials())
				.fromParentNode(nodeId)
				.build();

		return stream(this.client().repository().query(childNodesQuery).spliterator(), false)
				.filter(Objects::nonNull)
				.map(this::toCelumFolder)
				.map(folder -> (Item) folder)
				.sorted(comparing(Item::getName));
	}

	private CelumFolder toCelumFolder(final Node node) {
		return new CelumFolder(this.celumAssetProvider.get(), node, false, this.module.getDefaultLocale());
	}

	private Stream<Item> fetchChildAssets(final NodeId nodeId) {
		final AssetFilters assetFilters = new AssetFiltersImpl();
		final AssetFilter onlyAvailableAssetsWithinCurrentFolder = assetFilters.and(
				assetFilters.assetsByNode(nodeId),
				assetFilters.assetsByAvailability().available(true));

		final AssetFilter onlyCmsAssets = assetFilters.or(
				assetFilters.assetsByBooleanField(InformationFieldId.of(CELUM_FIELD_RELEVANT_FOR_CMS))
						.withValue(true),
				assetFilters.assetsByAssetType(AssetTypeId.of(CELUM_ASSET_TYPE_CMS)));

		final AssetSearchQuery assetsSearchQuery = AssetSearchQuery
				.byUser(this.getCredentials())
				.withFilter(assetFilters.and(onlyAvailableAssetsWithinCurrentFolder, onlyCmsAssets))
				.build();

		return stream(this.client().repository().query(assetsSearchQuery).spliterator(), false)
				.filter(Objects::nonNull)
				.map(asset -> new CelumAsset(this.celumAssetProvider.get(), asset, nodeId.toString()))
				.map(asset -> (Item) asset)
				.sorted(comparing(Item::getName));

	}

	@Override
	public String getPublicUrlQuery(final String id, final String rendition) {
		return this.celumJcrService
				.getPublicUrlFromJcr(rendition, id)
				.orElseGet(() -> fetchPublicUrlAndSaveToJcr(id, rendition));
	}

	private String fetchPublicUrlAndSaveToJcr(final String id, final String rendition) {
		final AssetPublicUrlsQuery assetPublicUrlsQuery = AssetPublicUrlsQuery
				.byUser(this.getCredentials())
				.forAssets(singleton(AssetId.of(parseLong(id))))
				.forProvider(singletonList(new ProviderFilter(CELUM_EXPORTER_PROVIDER, CELUM_EXPORTER_INSTANCE)))
				.withDescription(CELUM_DEFAULT_ASSET)
				.build();

		return stream(this.client()
				.repository()
				.query(assetPublicUrlsQuery)
				.spliterator(), false)
						.findFirst()
						.map(this::writePublicUrlToJcr)
						.map(AssetPublicUrl::getUrl)
						.orElse(StringUtils.EMPTY);
	}

	private AssetPublicUrl writePublicUrlToJcr(final AssetPublicUrl publicUrl) {
		this.celumJcrService.savePublicUrlToJcr(
				publicUrl.getUrl(),
				publicUrl.getDescription(),
				publicUrl.getAssetId().toString());
		return publicUrl;
	}
}

Comment by Raphael Falvo [ 19/Oct/22 ]

Closing the issue as not reproducible within a fresh Magnolia instance.

Generated at Sun Feb 11 23:58:31 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.