Skip to content

Commit

Permalink
feat: info about the used weasyprint docker-image version (#115)
Browse files Browse the repository at this point in the history
Refs: #104
  • Loading branch information
pbezliapovich authored Jul 31, 2024
1 parent aa9156b commit 0669e8b
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.jetbrains.annotations.NotNull;

import javax.ws.rs.Path;
import java.util.List;

@Secured
@Path("/api")
Expand Down Expand Up @@ -39,7 +40,7 @@ public class ConfigurationApiController extends ConfigurationInternalController
}

@Override
public @NotNull ConfigurationStatus checkWeasyPrint() {
public @NotNull List<ConfigurationStatus> checkWeasyPrint() {
return polarionService.callPrivileged(super::checkWeasyPrint);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.List;

@Hidden
@Path("/internal")
Expand Down Expand Up @@ -61,7 +62,7 @@ public class ConfigurationInternalController {
@Produces(MediaType.APPLICATION_JSON)
@Path("/configuration/weasyprint")
@Operation(summary = "Checks WeasyPrint configuration")
public @NotNull ConfigurationStatus checkWeasyPrint() {
public @NotNull List<ConfigurationStatus> checkWeasyPrint() {
return ConfigurationStatusUtils.getWeasyPrintStatus();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ConfigurationStatus {
private Status status;
private String details;
private @NotNull String name;
private @NotNull Status status;
private @NotNull String details;

public ConfigurationStatus(Status status) {
this(status, "");
public ConfigurationStatus(@NotNull String name, @NotNull Status status) {
this(name, status, "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,34 @@
import ch.sbb.polarion.extension.generic.settings.SettingsService;
import ch.sbb.polarion.extension.generic.util.ScopeUtils;
import ch.sbb.polarion.extension.pdf.exporter.converter.HtmlToPdfConverter;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.configuration.Status;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.configuration.ConfigurationStatus;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.configuration.Status;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.conversion.Orientation;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.conversion.PaperSize;
import ch.sbb.polarion.extension.pdf.exporter.util.regex.RegexMatcher;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.WeasyPrintConverter;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model.WeasyPrintInfo;
import com.polarion.core.config.Configuration;
import com.polarion.subterra.base.location.ILocation;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.module.ModuleDescriptor;
import java.util.List;
import java.util.Set;

@UtilityClass
public class ConfigurationStatusUtils {
public static final String DEFAULT_SETTINGS = "Default Settings";
public static final String DOCUMENT_PROPERTIES_PANE = "Document Properties Pane";
public static final String DLE_TOOLBAR = "DLE Toolbar";
public static final String LIVE_REPORT_BUTTON = "LiveReport Button";
public static final String CORS = "CORS (Cross-Origin Resource Sharing)";
public static final List<String> WEASY_PRINT = List.of("WeasyPrint Python", "WeasyPrint", "WeasyPrint Service");

@SuppressWarnings("java:S1166") //need by design
public static @NotNull ConfigurationStatus getSettingsStatus(@NotNull String scope) {
ConfigurationStatus configurationStatus = new ConfigurationStatus(Status.OK, "");
ConfigurationStatus configurationStatus = new ConfigurationStatus(DEFAULT_SETTINGS, Status.OK, "");

NamedSettingsRegistry.INSTANCE.getAll().stream()
.map(GenericNamedSettings::getFeatureName)
Expand All @@ -47,9 +55,9 @@ public class ConfigurationStatusUtils {
if (content == null) {
location = ScopeUtils.getDefaultLocation().append(".polarion/documents/sidebar/document.xml");
content = new SettingsService().read(location, null);
return getConfigurationStatus(content, "<extension id=\"pdf-exporter\".*/>", new ConfigurationStatus(Status.WARNING, "Not configured neither for global scope nor for current project"));
return getConfigurationStatus(DOCUMENT_PROPERTIES_PANE, content, "<extension id=\"pdf-exporter\".*/>", new ConfigurationStatus(DOCUMENT_PROPERTIES_PANE, Status.WARNING, "Not configured neither for global scope nor for current project"));
} else {
return getConfigurationStatus(content, "<extension id=\"pdf-exporter\".*/>", new ConfigurationStatus(Status.WARNING, "Not configured for current project"));
return getConfigurationStatus(DOCUMENT_PROPERTIES_PANE, content, "<extension id=\"pdf-exporter\".*/>", new ConfigurationStatus(DOCUMENT_PROPERTIES_PANE, Status.WARNING, "Not configured for current project"));
}
}

Expand All @@ -58,27 +66,40 @@ public class ConfigurationStatusUtils {
final ILocation location = ScopeUtils.getDefaultLocation().append(".polarion/context.properties");
final String content = new SettingsService().read(location, null);

return getConfigurationStatus(content, "scriptInjection.dleEditorHead=<script src=\"/polarion/pdf-exporter/js/starter.js\"></script>.*<script>PdfExporterStarter.injectToolbar();</script>");
return getConfigurationStatus(DLE_TOOLBAR, content, "scriptInjection.dleEditorHead=<script src=\"/polarion/pdf-exporter/js/starter.js\"></script>.*<script>PdfExporterStarter.injectToolbar();</script>");
}

public static @NotNull ConfigurationStatus getLiveReportMainHeadStatus() {
final ILocation location = ScopeUtils.getDefaultLocation().append(".polarion/context.properties");
final String content = new SettingsService().read(location, null);

return getConfigurationStatus(content, "scriptInjection.mainHead=<script src=\"/polarion/pdf-exporter/js/starter.js\">");
return getConfigurationStatus(LIVE_REPORT_BUTTON, content, "scriptInjection.mainHead=<script src=\"/polarion/pdf-exporter/js/starter.js\">");
}

@SuppressWarnings("java:S1166") //need by design
public static @NotNull ConfigurationStatus getWeasyPrintStatus() {
public static @NotNull List<ConfigurationStatus> getWeasyPrintStatus() {
try {
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();
WeasyPrintConverter weasyPrintConverter = htmlToPdfConverter.getWeasyPrintConverter();

ModuleDescriptor.Version weasyPrintVersion = weasyPrintConverter.getWeasyPrintVersion();
WeasyPrintInfo weasyPrintInfo = weasyPrintConverter.getWeasyPrintInfo();
htmlToPdfConverter.convert("<html><body>test html</body></html>", Orientation.PORTRAIT, PaperSize.A4);
return new ConfigurationStatus(Status.OK, "Version: %s".formatted(weasyPrintVersion.toString()));

return List.of(
createWeasyPrintStatus(WEASY_PRINT.get(0), weasyPrintInfo.getPython()),
createWeasyPrintStatus(WEASY_PRINT.get(1), weasyPrintInfo.getWeasyprint()),
createWeasyPrintStatus(WEASY_PRINT.get(2), weasyPrintInfo.getWeasyprintService())
);
} catch (Exception e) {
return new ConfigurationStatus(Status.ERROR, e.getMessage());
return List.of(new ConfigurationStatus(WEASY_PRINT.get(0), Status.ERROR, e.getMessage()));
}
}

private static @NotNull ConfigurationStatus createWeasyPrintStatus(@NotNull String name, @Nullable String description) {
if (description == null) {
return new ConfigurationStatus(name, Status.WARNING, "Unknown");
} else {
return new ConfigurationStatus(name, Status.OK, description);
}
}

Expand All @@ -87,22 +108,22 @@ public class ConfigurationStatusUtils {
if (restEnabled) {
Set<String> corsAllowedOrigins = Configuration.getInstance().rest().corsAllowedOrigins();
if (corsAllowedOrigins.isEmpty()) {
return new ConfigurationStatus(Status.WARNING, "CORS allowed origins are not configured");
return new ConfigurationStatus(CORS, Status.WARNING, "CORS allowed origins are not configured");
} else {
return new ConfigurationStatus(Status.OK, "CORS allowed origins: %s".formatted(corsAllowedOrigins.stream().toList()));
return new ConfigurationStatus(CORS, Status.OK, "CORS allowed origins: %s".formatted(corsAllowedOrigins.stream().toList()));
}
} else {
return new ConfigurationStatus(Status.WARNING, "Polarion REST API is not enabled, so CORS is not enabled");
return new ConfigurationStatus(CORS, Status.WARNING, "Polarion REST API is not enabled, so CORS is not enabled");
}
}

private static @NotNull ConfigurationStatus getConfigurationStatus(@Nullable String content, @NotNull String regex) {
return getConfigurationStatus(content, regex, new ConfigurationStatus(Status.WARNING, "Not configured"));
private static @NotNull ConfigurationStatus getConfigurationStatus(@NotNull String name, @Nullable String content, @NotNull String regex) {
return getConfigurationStatus(name, content, regex, new ConfigurationStatus(name, Status.WARNING, "Not configured"));
}

private static @NotNull ConfigurationStatus getConfigurationStatus(@Nullable String content, @NotNull String regex, @NotNull ConfigurationStatus notOkStatus) {
private static @NotNull ConfigurationStatus getConfigurationStatus(@NotNull String name, @Nullable String content, @NotNull String regex, @NotNull ConfigurationStatus notOkStatus) {
if (content != null && contains(content, regex)) {
return new ConfigurationStatus(Status.OK);
return new ConfigurationStatus(name, Status.OK);
} else {
return notOkStatus;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package ch.sbb.polarion.extension.pdf.exporter.weasyprint;

import java.lang.module.ModuleDescriptor;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model.WeasyPrintInfo;

public interface WeasyPrintConverter {
byte[] convertToPdf(String htmlPage, WeasyPrintOptions weasyPrintOptions);

ModuleDescriptor.Version getWeasyPrintVersion();
WeasyPrintInfo getWeasyPrintInfo();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ch.sbb.polarion.extension.pdf.exporter.util.regex.RegexMatcher;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.WeasyPrintConverter;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.WeasyPrintOptions;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model.WeasyPrintInfo;
import com.polarion.core.util.logging.Logger;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
Expand Down Expand Up @@ -88,10 +89,14 @@ public byte[] convertToPdf(String htmlPage, WeasyPrintOptions weasyPrintOptions)
}

@Override
public ModuleDescriptor.Version getWeasyPrintVersion() {
public WeasyPrintInfo getWeasyPrintInfo() {
String weasyPrintExecutable = PdfExporterExtensionConfiguration.getInstance().getWeasyprintExecutable();
String[] executable = weasyPrintExecutable.split(" ");
return getExecutableVersion(executable);
ModuleDescriptor.Version executableVersion = getExecutableVersion(executable);

WeasyPrintInfo weasyPrintInfo = new WeasyPrintInfo();
weasyPrintInfo.setWeasyprint(executableVersion.toString());
return weasyPrintInfo;
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import ch.sbb.polarion.extension.pdf.exporter.properties.PdfExporterExtensionConfiguration;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.WeasyPrintConverter;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.WeasyPrintOptions;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model.WeasyPrintServiceVersion;
import ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model.WeasyPrintInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.polarion.core.util.logging.Logger;
Expand All @@ -16,17 +16,20 @@
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.lang.module.ModuleDescriptor;
import java.util.concurrent.atomic.AtomicReference;

import static com.polarion.core.util.StringUtils.isEmpty;

public class WeasyPrintServiceConnector implements WeasyPrintConverter {
private static final Logger logger = Logger.getLogger(WeasyPrintServiceConnector.class);
private static final String WEASYPRINT_VERSION_HEADER = "Weasyprint-Version";

private static final String PYTHON_VERSION_HEADER = "Python-Version";
private static final AtomicReference<String> weasyPrintVersion = new AtomicReference<>();
private static final String WEASYPRINT_VERSION_HEADER = "Weasyprint-Version";
private static final String WEASYPRINT_SERVICE_VERSION_HEADER = "Weasyprint-Service-Version";

private static final AtomicReference<String> pythonVersion = new AtomicReference<>();
private static final AtomicReference<String> weasyPrintVersion = new AtomicReference<>();
private static final AtomicReference<String> weasyPrintServiceVersion = new AtomicReference<>();

@Override
public byte[] convertToPdf(String htmlPage, WeasyPrintOptions weasyPrintOptions) {
Expand Down Expand Up @@ -62,7 +65,7 @@ public byte[] convertToPdf(String htmlPage, WeasyPrintOptions weasyPrintOptions)
}

@Override
public ModuleDescriptor.Version getWeasyPrintVersion() {
public WeasyPrintInfo getWeasyPrintInfo() {
Client client = null;
try {
client = ClientBuilder.newClient();
Expand All @@ -73,8 +76,7 @@ public ModuleDescriptor.Version getWeasyPrintVersion() {
String responseContent = response.readEntity(String.class);

try {
WeasyPrintServiceVersion weasyPrintServiceVersion = new ObjectMapper().readValue(responseContent, WeasyPrintServiceVersion.class);
return ModuleDescriptor.Version.parse(weasyPrintServiceVersion.getWeasyprint());
return new ObjectMapper().readValue(responseContent, WeasyPrintInfo.class);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Could not parse response", e);
}
Expand All @@ -94,19 +96,20 @@ private String getWeasyPrintServiceBaseUrl() {
}

private void logWeasyPrintVersionFromHeader(Response response) {
String actualWeasyPrintVersion = response.getHeaderString(WEASYPRINT_VERSION_HEADER);
String actualPythonVersion = response.getHeaderString(PYTHON_VERSION_HEADER);
String actualWeasyPrintVersion = response.getHeaderString(WEASYPRINT_VERSION_HEADER);
String actualWeasyPrintServiceVersion = response.getHeaderString(WEASYPRINT_SERVICE_VERSION_HEADER);

boolean hasWeasyPrintVersionChanged = hasVersionChanged(actualWeasyPrintVersion, weasyPrintVersion);
boolean hasPythonVersionChanged = hasVersionChanged(actualPythonVersion, pythonVersion);
boolean hasWeasyPrintVersionChanged = hasVersionChanged(actualWeasyPrintVersion, weasyPrintVersion);
boolean hasWeasyPrintServiceVersionChanged = hasVersionChanged(actualWeasyPrintServiceVersion, weasyPrintServiceVersion);

if (hasWeasyPrintVersionChanged || hasPythonVersionChanged) {
logger.info(String.format("WeasyPrintService uses WeasyPrint version '%s' and Python version '%s'", actualWeasyPrintVersion, actualPythonVersion));
if (hasWeasyPrintVersionChanged || hasPythonVersionChanged || hasWeasyPrintServiceVersionChanged) {
logger.info(String.format("WeasyPrintService started from Docker image version '%s' uses WeasyPrint version '%s' and Python version '%s'", actualWeasyPrintServiceVersion, actualWeasyPrintVersion, actualPythonVersion));
}
}

public boolean hasVersionChanged(String actualVersion, AtomicReference<String> version) {
return !isEmpty(actualVersion)
&& !actualVersion.equals(version.getAndSet(actualVersion));
return !isEmpty(actualVersion) && !actualVersion.equals(version.getAndSet(actualVersion));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ch.sbb.polarion.extension.pdf.exporter.weasyprint.service.model;

import lombok.Data;
import org.jetbrains.annotations.Nullable;

@Data
public class WeasyPrintInfo {
private @Nullable String python;
private @Nullable String weasyprint;
private @Nullable String weasyprintService;
}

This file was deleted.

Loading

0 comments on commit 0669e8b

Please sign in to comment.