Geta / geta-optimizely-contenttypeicons

Override to the built in "ImageUrlAttribute" that is used to specify preview images for the different contenttypes in your Optimizely project.
2 stars 5 forks source link

Content Type Icon thumbnails cannot be generated when application is hosted in Content Cloud (DXP) #10

Open mits-live opened 2 years ago

mits-live commented 2 years ago

Hi Together,

I'm experiencing an issue when the application (using CMS 12, EPiServer.CMS version 12.5.0) gets deployed to Integration/Preproduction/Production. The hosting is in DXP. The Geta.Optimizely.ContentTypeIcons plugin uses the [appDataPath] variable to create the paths to the image thumbnails and to the used fonts, and this works perfectly on the local development environment. But when the application gets deployed on f.e. Integration, then the images associated to page/block types cannot be load anymore: CMS_Edit_New_Page_Selection_List_01 The corresponding exceptions are like these...

If using version 2.0.1 of the plugin: System.IO.DirectoryNotFoundException: Could not find a part of the path '/app/App_Data/thumb_cache\831edaaf-49ab-5933-3456-c725623c8be1.png'.

After some manual fix on the CachePath value in the ContentTypeIconOptions: System.IO.DirectoryNotFoundException: Could not find a part of the path '/app/App_Data/thumb_cache/831edaaf-49ab-5933-3456-c725623c8be1.png'.

I've seen, the fixes in the version 2.0.2 does not cover that problem, so what are the next steps on this?

Many thanks and kind regards, MITS-Live

marisks commented 2 years ago

@mits-live But is there such path: '/app/App_Data/thumb_cache/831edaaf-49ab-5933-3456-c725623c8be1.png' on the disc?

marisks commented 2 years ago

@KevinJCandlert Does it work for you when you use 2.0.2? I do not have any DXP (or Linux) environment to test this out.

mits-live commented 2 years ago

@marisks there is no such path as the application runs on a Linux-based container hosted in the DXP. In the container there is no App_Data subfolder at all. That is actually the problem - the Geta-plugin tries to use the file system for the cached data it uses, while on a Cloud environment (like DXP) there is only the file system of the container (which is read-only) and all the assets and the dynamic stuff (like images, thumbnails, log files, etc.) gets operated from the Azure Blobs storage... But it seems the plugin does not know that and continues to look at the file system to find its cached data... There seems to be no way to let the Geta-plugin use the Blob Provider for its caches instead using the file system directly...

marisks commented 2 years ago

Ok. Then it seems that this is a bigger issue and requires quite a lot of changes. It should be implemented as some cache service interface with two implementations - one for file system and one for blobs. Then those can be switched based on the environment through code or app settings. Now, I do not have time for this, but we are happy to see PRs :)

mits-live commented 2 years ago

@marisks may be this is not that big - Optimizely CMS already has the two implementations FileBlobProvider and AzureBlobProvider. Both inherit the abstract class BlobProvider... The bigger change would be to utilize that BlobProvider abstraction instead of direct using the file system... Frankly speaking, I'd be happy to spend some time for this, but for me too there is pressure in the time and I need to provide QAP solutions... Can you create some kind of ticket (feature request or something alike) to have this as focus point, so that whenever there is time an implementation can be done... MAny thanks and kind regards, MITS-Live.

marisks commented 2 years ago

GitHub issue is a ticket. I have added a label - enhancement that basically means that this is a feature request.

LucGosso commented 2 years ago

Hello! Same problem, I self host Linux optimizely cms 12 in azure.

If the path is not found: System.IO.DirectoryNotFoundException: Could not find a part of the path '/home/site/wwwroot/App_Data/thumb_cache\e6ac59f1-b55c-b3ee-97e7-e71cd6cd12e2.png'. (i did not have apppath folder)

if path is found: System.IO.IOException: Invalid argument : '/home/site/wwwroot/img\6c6203e6-304c-32e2-5f5f-74295328d3c3.png'

at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func2 errorRewriter) at Interop.CheckIo(Error error, String path, Boolean isDirectory, Func2 errorRewriter) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize) at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize) at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize) at System.IO.File.Create(String path) at Geta.Optimizely.ContentTypeIcons.ContentTypeIconService.LoadIconImage(ContentTypeIconSettings settings) at Geta.Optimizely.ContentTypeIcons.Controllers.ContentTypeIconController.Index(ContentTypeIconSettings settings)

example link: /Geta_Optimizely_ContentTypeIcons?BackgroundColor=%23F3C905&ForegroundColor=%23ffffff&Width=120&Height=90&FontSize=40&Character=61893&CustomFontName=&EmbeddedFont=fa5%2fwebfonts%2ffa-solid-900.ttf&UseEmbeddedFont=True&Rotate=None

I guess the IO paths not working the same in Linux.

Do we need disk cache? why not disable it? In memory cache?

marisks commented 2 years ago

@LucGosso with the latest version? There was a fix for paths. But about full Linux support - I do not have time for it and no projects use it on Linux for us. PR is welcome :)

LucGosso commented 2 years ago

yes, latest version. if not fixing the path problem, is it an ok option to serve image from memorycache? with new prop option.UseDiscCache = false

marisks commented 2 years ago

The path problem was fixed. Do you use the latest version?

For the alternative caching it would be better to have a more flexible way:

LucGosso commented 2 years ago

I use version 2.0.2

Thats a good plan. I dont have time for now, but lets see we find someone else in the community that wants to help out.

mits-live commented 2 years ago

@marisks, in v.2.0.2 there is a change to use the Linux-style paths like public const string DefaultCustomFontPath = "[appDataPath]/fonts/";, which is quite suboptimal. Better would be to use the system variable for this - System.IO.Path.DirectorySeparatorChar. On itself, this solves the problem with the mixed style of the path separators, but in general it does not solve the problem of the missing App_Data folder. @LucGosso, I was able to solve this issue, by verifying the App_Data-path exists upon the application start - by using the Logger construction at application's startup and directing the logger to use the App_Data folder: Log.Logger = new LoggerConfiguration() .MinimumLevel.Warning() .WriteTo.Console() .WriteTo.File("App_Data/log.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); As the hosting of the application is on the Optimizely's DXP, this way is the only one I was able to validate and ensure the App_Data folder do exists whenever the hosting container gets recreated.

marisks commented 2 years ago

@mits-live As I understand Linux style paths work in all environments - Linux, Windows, and Mac. Using DirectorySeparatorChar would just make those strings less readable.

I thought that App_Data was part of every Optimizely CMS project (at least it was usually). Is it removed when deploying?

mits-live commented 2 years ago

@marisks Linux/Unix-style paths do work on Windows, mostly because the latest Windows OS versions provide support for it (look at the WSL) and using the declarations from the .NET framework itself is still the better way to ensure cross-OS compatibility (IMHO)... It seems with Optimizely CMS 12 there are many changes in the application architecture of a CMS 12-based application... What I know for sure is, the App_Data folder do not exists when the DXP hosting container gets created (or recreated). I don't know why the Optimizely-people did it this way, but it is just fact...

elivnjak commented 1 year ago

I'm using the latest version of Optimizely deployed to DXP server. Working fine for me.

LucGosso commented 1 year ago

Interesting @elivnjak

Could you help us, login to Kudu => https://[dxpINTEinstance].scm.azurewebsites.net/DebugConsole (you need access to dxp instance in azure portal)

Browse to app_data folder, can you see any thumbs folder? with the icons?

If not, where is the thumbs folder?

How is your startup config for ContentTypeIcons?

elivnjak commented 1 year ago

@LucGosso i have access to the Debug console but I dont see any of the website files within the folders. I think the DXP uses docker to host the websites.

I have it set up as follows:

StartUp.cs

In the ConfigureServices method i have

services.AddGetaCategories()

In the Configure method i have:

app.UseContentTypeIcons();

In my appsettings.json i have:

{ "Geta": { "ContentTypeIcons": { "EnableTreeIcons": true, "ForegroundColor": "#ffffff", "BackgroundColor": "#02423F", "FontSize": 40, "CachePath": "[appDataPath]/thumb_cache/", "CustomFontPath": "[appDataPath]/fonts/" } } }

LucGosso commented 1 year ago

looks like default

you can access it on this url no? https://[dxpINTEinstance].scm.azurewebsites.net/wwwroot/

where is the thumb_cache? Do you know if you have something other in the appDataPath ? Do you config the appDataPath i startup somehow?

elivnjak commented 1 year ago

If i go into wwwroot all i see is one file - hostingstart.html

We havent set up anything for appDataPath.

I dont think its using the cached image. When i look at the url of the icons it is:

/Geta_Optimizely_ContentTypeIcons?BackgroundColor=%2302423F&ForegroundColor=%23ffffff&Width=120&Height=90&FontSize=40&Character=61461&CustomFontName=&EmbeddedFont=fa5%2fwebfonts%2ffa-solid-900.ttf&UseEmbeddedFont=True&Rotate=None

I think its using Embedded Fonts.