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/175 Template Engine for HTML UIs #176

Merged
merged 43 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0302f07
added missing constants
hhund Feb 7, 2024
e5bd6ac
thymeleaf learning test
hhund Feb 7, 2024
a72e6e2
new thymeleaf based html generator implementation
hhund Feb 7, 2024
4818a40
removed not needed instanceof pattern variables
hhund Feb 7, 2024
66ef4d4
removed not needed method parameter
hhund Feb 7, 2024
3f27503
refactored code Arrays.asList -> List.of
hhund Feb 12, 2024
d5f25f8
status code only error handler for all mime-types
hhund Feb 12, 2024
ebe39ce
modified impl to directly reject non status requests on status port
hhund Feb 12, 2024
15574ff
allow optional questionnaire items
wetret Feb 12, 2024
0c834d3
remove semicolons at end of statements
wetret Feb 12, 2024
3e233f5
Merge branch 'issue/175_Template_Engine_for_HTML_UIs' of [email protected]
hhund Feb 12, 2024
c2feae8
remove not needed imports
hhund Feb 12, 2024
1b9977a
moved adapt... calls to existing if statements in main, code formatting
hhund Feb 12, 2024
feeb991
modified word-break behavior of h1 page title
hhund Feb 12, 2024
d813f9b
use expectedForbidden() or expectedBadRequest() instead of try-catch
wetret Feb 12, 2024
4b8c8fd
form.css and form.js only for QuestionnaireResponse and Task resources
hhund Feb 12, 2024
c17e8c8
Merge branch 'issue/175_Template_Engine_for_HTML_UIs' of [email protected]
hhund Feb 12, 2024
5b306c1
load html-tab as well if url ends with /
wetret Feb 12, 2024
f52d898
code formatting
hhund Feb 12, 2024
ef542cb
removed not needed escape chars, added support for trailing / chars
hhund Feb 12, 2024
f5d1962
improving Task.instantiates-canonical & ActivityDefinition.url patterns
hhund Feb 12, 2024
eea7abc
removed not needed escape chars, remote property injection defense
hhund Feb 12, 2024
c139df4
added TODO comments
hhund Feb 12, 2024
8ef8392
ui mod and theme feature, conf prop description changes, code formatting
hhund Feb 13, 2024
9e378a0
remove static bpe config file
hhund Feb 14, 2024
6a3d5fc
initial BPE UI, new common code, bpe rev proxy, test setups mods
hhund Feb 14, 2024
4a98aeb
margin fixes
hhund Feb 18, 2024
a9753cc
removed not needed line breaks and spaces from html
hhund Feb 18, 2024
e01549a
integrated bpmn.io viewer
hhund Feb 18, 2024
9918a8f
removed not needed RequestContextListener from servlet context
hhund Feb 18, 2024
50fd7c8
Merge remote-tracking branch 'origin/develop' into
hhund Feb 19, 2024
0146506
no more empty items in QuestionnaireResponse if items optional
hhund Feb 19, 2024
288e5e2
added default value for `dev.dsf.bpe.server.base.url` config parameter
hhund Feb 19, 2024
54487f4
improved code readability
hhund Feb 19, 2024
3a186a9
improved warn log message
hhund Feb 19, 2024
3ee24ab
removed not needed attribute, bpmn stored as data-url in download a-tag
hhund Feb 19, 2024
7e22ee5
formatting of RUN command aligned with bpe Dockerfile RUN command
hhund Feb 19, 2024
420a3cb
added missing empty ui folder to bpe docker image
hhund Feb 19, 2024
d26e31a
thymeleafContexts list entry sort order
hhund Feb 19, 2024
64b6a92
removed redundant mod.css files, now using fhir/bpe specific mod files
hhund Feb 19, 2024
36edc1e
removed static mod.css, mod.css only included in html if exists
hhund Feb 19, 2024
9f2dae0
removed not needed log message placeholders
hhund Feb 19, 2024
6ccd70d
simplified logic statement
hhund Feb 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dsf-bpe/dsf-bpe-server-jetty/process/*.jar
# dsf-fhir ignores
###
dsf-fhir/dsf-fhir-server-jetty/conf/bundle.xml
dsf-fhir/dsf-fhir-server-jetty/ui
dsf-fhir/dsf-fhir-server-jetty/conf/config.properties
dsf-fhir/dsf-fhir-server-jetty/docker/dsf_fhir.jar
dsf-fhir/dsf-fhir-server-jetty/docker/dsf_status_client.jar
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.dsf.bpe.config;

import java.util.Arrays;
import java.util.List;

import org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer;
Expand All @@ -20,6 +19,6 @@ protected String mavenServerModuleName()
@Override
protected List<Class<? extends ServletContainerInitializer>> servletContainerInitializers()
{
return Arrays.asList(JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class);
return List.of(JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package dev.dsf.bpe.config;

import java.util.Arrays;
import java.util.List;

import org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer;
Expand All @@ -20,6 +19,6 @@ protected String mavenServerModuleName()
@Override
protected List<Class<? extends ServletContainerInitializer>> servletContainerInitializers()
{
return Arrays.asList(JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class);
return List.of(JerseyServletContainerInitializer.class, SpringServletContainerInitializer.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ Resource getResource()
.compile(Pattern.quote(PLACEHOLDER_PREFIX_TMP));
private static final Pattern PLACEHOLDER_PREFIX_PATTERN = Pattern.compile(Pattern.quote(PLACEHOLDER_PREFIX));

private static final String ACTIVITY_DEFINITION_URL_PATTERN_STRING = "^(?<processUrl>http[s]{0,1}://(?<domain>(?:(?:[a-zA-Z0-9]{1,63}|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\\.)+(?:[a-zA-Z0-9]{1,63}))"
private static final String ACTIVITY_DEFINITION_URL_PATTERN_STRING = "^(?<processUrl>http[s]{0,1}://(?<domain>(?:(?:[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\\.)+(?:[a-zA-Z0-9]{1,63}))"
+ "/bpe/Process/(?<processName>[a-zA-Z0-9-]+))$";
private static final Pattern ACTIVITY_DEFINITION_URL_PATTERN = Pattern
.compile(ACTIVITY_DEFINITION_URL_PATTERN_STRING);

private static final String INSTANTIATES_CANONICAL_PATTERN_STRING = "(?<processUrl>http[s]{0,1}://(?<domain>(?:(?:[a-zA-Z0-9]{1,63}|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\\.)+(?:[a-zA-Z0-9]{1,63}))"
private static final String INSTANTIATES_CANONICAL_PATTERN_STRING = "(?<processUrl>http[s]{0,1}://(?<domain>(?:(?:[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\\.)+(?:[a-zA-Z0-9]{1,63}))"
+ "/bpe/Process/(?<processName>[a-zA-Z0-9-]+))\\|(?<processVersion>\\d+\\.\\d+)$";
private static final Pattern INSTANTIATES_CANONICAL_PATTERN = Pattern
.compile(INSTANTIATES_CANONICAL_PATTERN_STRING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ public class PropertiesConfig implements InitializingBean
{
private static final Logger logger = LoggerFactory.getLogger(PropertiesConfig.class);

@Documentation(required = true, description = "The address of the database used for the DSF BPE server", recommendation = "Change only if you don't use the provided docker-compose from the installation guide or made changes to the database settings/networking in the docker-compose", example = "jdbc:postgresql://db/bpe")
@Documentation(required = true, description = "Address of the database used for the DSF BPE server", recommendation = "Change only if you don't use the provided docker-compose from the installation guide or made changes to the database settings/networking in the docker-compose", example = "jdbc:postgresql://db/bpe")
@Value("${dev.dsf.bpe.db.url}")
private String dbUrl;

@Documentation(description = "The user name to access the database from the DSF BPE server")
@Documentation(description = "Username to access the database from the DSF BPE server")
@Value("${dev.dsf.bpe.db.user.username:bpe_server_user}")
private String dbUsername;

@Documentation(required = true, description = "The password to access the database from the DSF BPE server", recommendation = "Use docker secret file to configure using *${env_variable}_FILE*", example = "/run/secrets/db_user.password")
@Documentation(required = true, description = "Password to access the database from the DSF BPE server", recommendation = "Use docker secret file to configure using *${env_variable}_FILE*", example = "/run/secrets/db_user.password")
@Value("${dev.dsf.bpe.db.user.password}")
private char[] dbPassword;

@Documentation(description = "The user name to access the database from the DSF BPE server for camunda processes", recommendation = "Use a different user then in *DEV_DSF_BPE_DB_USER_USERNAME*")
@Documentation(description = "Username to access the database from the DSF BPE server for camunda processes", recommendation = "Use a different user then in *DEV_DSF_BPE_DB_USER_USERNAME*")
@Value("${dev.dsf.bpe.db.user.camunda.username:camunda_server_user}")
private String dbCamundaUsername;

@Documentation(required = true, description = "The password to access the database from the DSF BPE server for camunda processes", recommendation = "Use docker secret file to configure using *${env_variable}_FILE*", example = "/run/secrets/db_user_camunda.password")
@Documentation(required = true, description = "Password to access the database from the DSF BPE server for camunda processes", recommendation = "Use docker secret file to configure using *${env_variable}_FILE*", example = "/run/secrets/db_user_camunda.password")
@Value("${dev.dsf.bpe.db.user.camunda.password}")
private char[] dbCamundaPassword;

Expand All @@ -64,27 +64,27 @@ public class PropertiesConfig implements InitializingBean
@Value("${dev.dsf.bpe.fhir.client.certificate.private.key.password:#{null}}")
private char[] clientCertificatePrivateKeyFilePassword;

@Documentation(description = "The timeout in milliseconds until a reading a resource from a remote DSF FHIR server is aborted", recommendation = "Change default value only if timeout exceptions occur")
@Documentation(description = "Timeout in milliseconds until a reading a resource from a remote DSF FHIR server is aborted", recommendation = "Change default value only if timeout exceptions occur")
@Value("${dev.dsf.bpe.fhir.client.remote.timeout.read:60000}")
private int webserviceClientRemoteReadTimeout;

@Documentation(description = "The timeout in milliseconds until a connection is established with a remote DSF FHIR server", recommendation = "Change default value only if timeout exceptions occur")
@Documentation(description = "Timeout in milliseconds until a connection is established with a remote DSF FHIR server", recommendation = "Change default value only if timeout exceptions occur")
@Value("${dev.dsf.bpe.fhir.client.remote.timeout.connect:5000}")
private int webserviceClientRemoteConnectTimeout;

@Documentation(description = "To enable verbose logging of requests to and replies from remote DSF FHIR servers, set to `true`")
@Value("${dev.dsf.bpe.fhir.client.remote.verbose:false}")
private boolean webserviceClientRemoteVerbose;

@Documentation(required = true, description = "The base address of the local DSF FHIR server to read/store fhir resources", example = "https://foo.bar/fhir")
@Documentation(required = true, description = "Base address of the local DSF FHIR server to read/store fhir resources", example = "https://foo.bar/fhir")
@Value("${dev.dsf.bpe.fhir.server.base.url}")
private String serverBaseUrl;

@Documentation(description = "The timeout in milliseconds until reading a resource from the local DSF FHIR server is aborted", recommendation = "Change default value only if timeout exceptions occur")
@Documentation(description = "Timeout in milliseconds until reading a resource from the local DSF FHIR server is aborted", recommendation = "Change default value only if timeout exceptions occur")
@Value("${dev.dsf.bpe.fhir.client.local.timeout.read:60000}")
private int webserviceClientLocalReadTimeout;

@Documentation(description = "The timeout in milliseconds until a connection is established with the local DSF FHIR server", recommendation = "Change default value only if timeout exceptions occur")
@Documentation(description = "Timeout in milliseconds until a connection is established with the local DSF FHIR server", recommendation = "Change default value only if timeout exceptions occur")
@Value("${dev.dsf.bpe.fhir.client.local.timeout.connect:2000}")
private int webserviceClientLocalConnectTimeout;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ String getShortMessage()

public static final String TASK_VARIABLE = TaskHandler.class.getName() + ".task";

private static final String INSTANTIATES_CANONICAL_PATTERN_STRING = "(?<processUrl>http://(?<processDomain>(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9]))/bpe/Process/(?<processDefinitionKey>[-\\w]+))\\|(?<processVersion>\\d+\\.\\d+)";
private static final String INSTANTIATES_CANONICAL_PATTERN_STRING = "(?<processUrl>http[s]{0,1}://(?<domain>(?:(?:[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\\.)+(?:[a-zA-Z0-9]{1,63}))"
+ "/bpe/Process/(?<processName>[a-zA-Z0-9-]+))\\|(?<processVersion>\\d+\\.\\d+)$";
private static final Pattern INSTANTIATES_CANONICAL_PATTERN = Pattern
.compile(INSTANTIATES_CANONICAL_PATTERN_STRING);

Expand Down Expand Up @@ -125,8 +126,8 @@ public void onResource(Task task)
throw new IllegalStateException("InstantiatesCanonical of Task with id " + task.getIdElement().getIdPart()
+ " does not match " + INSTANTIATES_CANONICAL_PATTERN_STRING);

String processDomain = matcher.group("processDomain").replace(".", "");
String processDefinitionKey = matcher.group("processDefinitionKey");
String processDomain = matcher.group("domain").replace(".", "");
String processDefinitionKey = matcher.group("processName");
String processVersion = matcher.group("processVersion");

String messageName = getFirstInputParameter(task, BpmnMessage.messageName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public String getAuthMethod()
}

public boolean isStatusPortRequest(ServletRequest req)
{
HttpServletRequest request = (HttpServletRequest) req;
return statusPortSupplier.get() != null && statusPortSupplier.get() == request.getLocalPort();
}

private boolean isStatusPortAndPathGetRequest(ServletRequest req)
{
HttpServletRequest request = (HttpServletRequest) req;
return HttpMethod.GET.is(request.getMethod()) && STATUS_PATH.equals(request.getPathInfo())
Expand All @@ -55,7 +61,7 @@ public void prepareRequest(ServletRequest request)
public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory)
throws ServerAuthException
{
if (isStatusPortRequest(request))
if (isStatusPortAndPathGetRequest(request))
return new UserAuthentication(getAuthMethod(), null);
else
return Authentication.UNAUTHENTICATED;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dev.dsf.common.jetty;

import java.io.IOException;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.channels.ServerSocketChannel;
Expand All @@ -24,6 +23,7 @@
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConfiguration.Customizer;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
Expand All @@ -41,6 +41,7 @@
import jakarta.servlet.ServletContainerInitializer;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public final class JettyServer
{
Expand Down Expand Up @@ -325,8 +326,8 @@ private ErrorHandler statusCodeOnlyErrorHandler()
return new ErrorHandler()
{
@Override
protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message,
boolean showStacks) throws IOException
protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request,
HttpServletResponse response, int code, String message) throws IOException
{
logger.info("Error {}: {}", code, message);
}
Expand Down
Loading
Loading