Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 2912: Support folder browsing for static resources #2917

Merged
Prev Previous commit
Next Next commit
Issue 2912: Support folder browsing for static resources - freemarker…
… -> velocity
  • Loading branch information
okolesn committed Nov 8, 2022
commit 960af38c684067861ac265c17ed4129bfd701cda
4 changes: 2 additions & 2 deletions api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ task copyLocalDtsStartupScripts(type: Copy) {
}

task generateComponentsVersions(type: Exec) {
commandLine "bash",
commandLine "bash",
"$project.rootDir/scripts/pipeline-scripts/generate_components_versions.sh",
"$project.rootDir",
"$rootDir/api/src/main/resources/static/components_versions.json"
Expand Down Expand Up @@ -251,7 +251,7 @@ dependencies {
compile 'dnsjava:dnsjava:3.4.3'

//Template engine
compile group: 'org.freemarker', name: 'freemarker', version: '2.3.23'
compile group: 'org.apache.velocity', name: 'velocity', version: '1.7'
}

// >>>>> processes profiles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public class SystemPreferences {
private static final String MONITORING_GROUP = "Monitoring";
private static final String CLOUD = "Cloud";
private static final String CLOUD_REGION_GROUP = "Cloud region";
private static final String STATIC_RESOURCES_GROUP = "Static Resources";

private static final String STORAGE_FSBROWSER_BLACK_LIST_DEFAULT =
"/bin,/var,/home,/root,/sbin,/sys,/usr,/boot,/dev,/lib,/proc,/etc";
Expand Down Expand Up @@ -1089,6 +1090,15 @@ public class SystemPreferences {
new TypeReference<List<CloudAccessManagementConfig>>() {}, CLOUD,
isNullOrValidJson(new TypeReference<List<CloudAccessManagementConfig>>() {}));

// Static Resources Group
public static final StringPreference STATIC_RESOURCES_FOLDER_TEMPLATE_PATH =
new StringPreference("static.resources.folder.template.path", "classpath:views/",
STATIC_RESOURCES_GROUP, pass);
public static final StringPreference STATIC_RESOURCES_FOLDER_TEMPLATE =
new StringPreference("static.resources.folder.template", "folder.vm",
STATIC_RESOURCES_GROUP, pass);


private static final Pattern GIT_VERSION_PATTERN = Pattern.compile("(\\d)\\.(\\d)");

private static final Map<String, AbstractSystemPreference<?>> PREFERENCE_MAP;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,24 @@
import com.epam.pipeline.manager.datastorage.DataStorageManager;
import com.epam.pipeline.manager.preference.PreferenceManager;
import com.epam.pipeline.manager.preference.SystemPreferences;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import freemarker.template.TemplateException;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.epam.pipeline.controller.resource.StaticResourcesController.STATIC_RESOURCES;
Expand All @@ -55,9 +53,6 @@
public class StaticResourcesService {

private static final String DELIMITER = "/";
private static final String TEMPLATE = "folder.ftlh";
private static final String VERSION = "2.3.23";
private static final String TEMPLATES_FOLDER = "/views";

private final DataStorageManager dataStorageManager;
private final MessageHelper messageHelper;
Expand All @@ -76,32 +71,37 @@ public DataStorageStreamingContent getContent(final String path) {
if (Files.isDirectory(Paths.get(path))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check won't work for cloud resource, I will add a new method to check cloud object type

final List<AbstractDataStorageItem> items = dataStorageManager.getDataStorageItems(storage.getId(),
path, false, null, null).getResults();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix path -> filePath

final String html = buildHtml(items);
final String tmplPath = preferenceManager.getPreference(
SystemPreferences.STATIC_RESOURCES_FOLDER_TEMPLATE_PATH);
final String tmplName = preferenceManager.getPreference(SystemPreferences.STATIC_RESOURCES_FOLDER_TEMPLATE);
final String staticResourcesPrefix = preferenceManager.getPreference(SystemPreferences.BASE_API_HOST)
+ STATIC_RESOURCES;
final String html = buildHtml(items, tmplPath, tmplName, staticResourcesPrefix);
return new DataStorageStreamingContent(new ByteArrayInputStream(html.getBytes()), filePath);
}
dataStorageManager.checkDataStorageObjectExists(storage, filePath, null);
return dataStorageManager.getStreamingContent(storage.getId(), filePath, null);
}

public String buildHtml(final List<AbstractDataStorageItem> items) throws IOException, TemplateException {
final Configuration cfg = new Configuration(new Version(VERSION));

cfg.setClassForTemplateLoading(StaticResourcesService.class, TEMPLATES_FOLDER);
cfg.setDefaultEncoding("UTF-8");

final Template template = cfg.getTemplate(TEMPLATE);
final Map<String, Object> templateData = new HashMap<>();
templateData.put("items", getHtmlStorageItems(items));
public static String buildHtml(final List<AbstractDataStorageItem> items,
final String templatePath,
final String templateName,
final String staticResourcesPrefix) throws IOException{
final VelocityEngine engine = new VelocityEngine();
engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this configuration, classpath template is not loaded. We need to support both classpath and filesystem resources. Maybe it is easier to use an approach from SMTPNotificationManager where template is passed as a string to Velocity.evaluate method? In this case we can read template using ResourceUtils class or similar. In this case we can leave only one preference STATIC_RESOURCES_FOLDER_TEMPLATE_PATH with full path to template, e.g. classpath/views/folder.vm or /opt/api/templates/folder.html

engine.init();
final Template template = engine.getTemplate(templateName);
final VelocityContext velocityContext = new VelocityContext();
velocityContext.put("items", getHtmlStorageItems(items, staticResourcesPrefix));

try (StringWriter out = new StringWriter()) {
template.process(templateData, out);
template.merge(velocityContext, out);
return out.getBuffer().toString();
}
}

private List<HtmlStorageItem> getHtmlStorageItems(final List<AbstractDataStorageItem> items) {
final String staticResourcesPrefix = preferenceManager.getPreference(SystemPreferences.BASE_API_HOST)
+ STATIC_RESOURCES;
private static List<HtmlStorageItem> getHtmlStorageItems(final List<AbstractDataStorageItem> items,
final String staticResourcesPrefix) {
return items.stream()
.map(i -> HtmlStorageItem.builder()
.name(i.getName())
Expand All @@ -114,7 +114,7 @@ private List<HtmlStorageItem> getHtmlStorageItems(final List<AbstractDataStorage
.collect(Collectors.toList());
}

private String getFileSize(final AbstractDataStorageItem item) {
private static String getFileSize(final AbstractDataStorageItem item) {
return item.getType() == DataStorageItemType.File ?
FileUtils.byteCountToDisplaySize(((DataStorageFile) item).getSize()) : "";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
</tr>
</thead>
<tbody>
<#list items as item>
#foreach($item in $items)
<tr>
<td align="left"><a href="${item.path}">${item.name}</a></td>
<td align="left">${item.size}</td>
<td align="left">${item.changed}</td>
</tr>
</#list>
#end
</tbody>
</table>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,25 @@
import com.epam.pipeline.entity.datastorage.DataStorageFile;
import com.epam.pipeline.entity.datastorage.DataStorageFolder;
import org.junit.Test;

import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.epam.pipeline.manager.resource.StaticResourcesService.buildHtml;
import static org.assertj.core.api.Assertions.assertThat;

public class StaticResourceServiceTest extends AbstractSpringTest {

private static final String TEMPLATES_PATH = "classpath:views/";
private static final String TEMPLATE_NAME = "folder.vm";

@Autowired
private StaticResourcesService staticResourcesService;
private ApplicationContext context;

@Test
public void getHtmlContentTest() throws IOException, TemplateException {
public void getHtmlContentTest() throws IOException {
final List<AbstractDataStorageItem> items = new ArrayList<>();
final DataStorageFile file1 = getDataStorageFile("file1", "path1",
1234567899, "10/24/22, 9:27:20 PM");
Expand All @@ -51,7 +53,9 @@ public void getHtmlContentTest() throws IOException, TemplateException {
final DataStorageFile file2 = getDataStorageFile("file2", "path2",
123, "10/24/20, 9:27:20 PM");
items.add(file2);
assertThat(staticResourcesService.buildHtml(items)).isNotBlank();

assertThat(buildHtml(items, context.getResource(TEMPLATES_PATH).getFile().getAbsolutePath(),
TEMPLATE_NAME, "")).isNotBlank();
}

private DataStorageFolder getDataStorageFolder(final String name, final String path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
</tr>
</thead>
<tbody>
<#list items as item>
#foreach($item in $items)
<tr>
<td align="left"><a href="${item.path}">${item.name}</a></td>
<td align="left">${item.size}</td>
<td align="left">${item.changed}</td>
</tr>
</#list>
#end
</tbody>
</table>
</body>
Expand Down