Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions core/src/main/java/org/apache/hop/core/Const.java
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,30 @@ public String getMessage() {

public static final String INTERNAL_VARIABLE_ACTION_ID = INTERNAL_VARIABLE_PREFIX + ".Action.ID";

/** The Hop server name as configured in hop-server.xml */
public static final String INTERNAL_VARIABLE_HOP_SERVER_NAME =
INTERNAL_VARIABLE_PREFIX + ".Server.Name";

/** The Hop server hostname */
public static final String INTERNAL_VARIABLE_HOP_SERVER_HOSTNAME =
INTERNAL_VARIABLE_PREFIX + ".Server.Hostname";

/** The Hop server HTTP port */
public static final String INTERNAL_VARIABLE_HOP_SERVER_PORT =
INTERNAL_VARIABLE_PREFIX + ".Server.Port";

/** The Hop server web application name */
public static final String INTERNAL_VARIABLE_HOP_SERVER_WEB_APP_NAME =
INTERNAL_VARIABLE_PREFIX + ".Server.WebAppName";

/** The Hop server username */
public static final String INTERNAL_VARIABLE_HOP_SERVER_USERNAME =
INTERNAL_VARIABLE_PREFIX + ".Server.Username";

/** Whether the Hop server is running in SSL mode */
public static final String INTERNAL_VARIABLE_HOP_SERVER_SSL_MODE =
INTERNAL_VARIABLE_PREFIX + ".Server.SslMode";

/** The default maximum for the nr of lines in the GUI logs */
public static final int MAX_NR_LOG_LINES = 5000;

Expand Down
15 changes: 15 additions & 0 deletions docs/hop-user-manual/modules/ROOT/pages/variables.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,18 @@ Additionally, the following environment variables can help you to add even more
|${Internal.Transform.BundleNr} |N |The bundle number for partitioned execution, helpful in load-balancing or distributing data across partitions.
|${Internal.Action.ID} |N |The unique ID of the current action (entry) in a workflow. Useful for tracking specific actions within a larger workflow.
|===

=== Hop server internal variables

The variables below are only set when a pipeline or workflow is executed on a Hop server. They are populated from the `hop-server.xml` configuration file at server startup and inherited by every pipeline and workflow that runs on that server, so you can reference the server's own coordinates from within your pipelines and workflows (for example to build callback URLs or to log the server that processed a request).

[%header, width="90%", cols="2,1,5"]
|===
|Variable |Default |Description
|${Internal.Server.Name} |N |The name of the Hop server as configured in `hop-server.xml` (the `<name>` element of the `hop-server` definition).
|${Internal.Server.Hostname} |N |The hostname the Hop server is bound to, as configured in `hop-server.xml`. If a `network_interface` was configured, this is the resolved IP address for that interface.
|${Internal.Server.Port} |N |The HTTP port the Hop server is listening on. This is the actual port the server bound to, which may differ from the value in `hop-server.xml` when the server was started with command-line overrides.
|${Internal.Server.WebAppName} |N |The web application name (context path) the Hop server is exposed under, as configured in `hop-server.xml`. Empty when no web app name was set.
|${Internal.Server.Username} |N |The username configured for the Hop server in `hop-server.xml`. Empty when authentication is not configured.
|${Internal.Server.SslMode} |N |`true` when the Hop server is configured to use SSL/TLS, `false` otherwise.
|===
5 changes: 5 additions & 0 deletions engine/src/main/java/org/apache/hop/www/HopServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ public void runHopServer() throws Exception {
}

if (allOK) {
// Expose the hop-server.xml details as Internal.Server.* variables so they
// are inherited by pipelines and workflows executing on this server.
config.setInternalHopServerVariables(config.getVariables(), port);
config.setInternalHopServerVariables(variables, port);

boolean shouldJoin = config.isJoining();
if (joinOverride != null) {
shouldJoin = joinOverride;
Expand Down
24 changes: 24 additions & 0 deletions engine/src/main/java/org/apache/hop/www/HopServerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,30 @@ public HopServerConfig(String hostname, int port, int shutdownPort, boolean join
hostname + ":" + port, hostname, "" + port, "" + shutdownPort, null, null);
}

/**
* Expose the configured Hop server details (hop-server.xml) as Internal.Server.* variables on the
* given variable space, so pipelines and workflows running on this server can reference them.
*
* @param variables the variable space to populate
* @param resolvedPort the actual HTTP port the server is bound to
*/
public void setInternalHopServerVariables(IVariables variables, int resolvedPort) {
if (variables == null || hopServer == null) {
return;
}
variables.setVariable(
Const.INTERNAL_VARIABLE_HOP_SERVER_NAME, Const.NVL(hopServer.getName(), ""));
variables.setVariable(
Const.INTERNAL_VARIABLE_HOP_SERVER_HOSTNAME, Const.NVL(hopServer.getHostname(), ""));
variables.setVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_PORT, Integer.toString(resolvedPort));
variables.setVariable(
Const.INTERNAL_VARIABLE_HOP_SERVER_WEB_APP_NAME, Const.NVL(hopServer.getWebAppName(), ""));
variables.setVariable(
Const.INTERNAL_VARIABLE_HOP_SERVER_USERNAME, Const.NVL(hopServer.getUsername(), ""));
variables.setVariable(
Const.INTERNAL_VARIABLE_HOP_SERVER_SSL_MODE, Boolean.toString(hopServer.isSslMode()));
}

/**
* @return the hop server.<br>
* The user name and password defined in here are used to contact this server by the masters.
Expand Down
71 changes: 71 additions & 0 deletions engine/src/test/java/org/apache/hop/www/HopServerConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
import java.util.Map.Entry;
import org.apache.hop.core.Const;
import org.apache.hop.core.exception.HopXmlException;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.core.variables.Variables;
import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.server.HopServerMeta;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -217,6 +220,74 @@ void testParseJettyOption_NoOptionsNode() throws HopXmlException {
assertNull(parseJettyOptions);
}

@Test
void testSetInternalHopServerVariables_populatesAllVariables() {
HopServerMeta meta =
new HopServerMeta("my-server", "host.example.com", "8181", "8180", "admin", "secret");
meta.setWebAppName("hop");
meta.setSslMode(true);
slServerConfig.setHopServer(meta);

IVariables variables = new Variables();
slServerConfig.setInternalHopServerVariables(variables, 8181);

assertEquals("my-server", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_NAME));
assertEquals(
"host.example.com", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_HOSTNAME));
assertEquals("8181", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_PORT));
assertEquals("hop", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_WEB_APP_NAME));
assertEquals("admin", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_USERNAME));
assertEquals("true", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_SSL_MODE));
}

@Test
void testSetInternalHopServerVariables_resolvedPortOverridesConfigured() {
HopServerMeta meta = new HopServerMeta("local8080", "localhost", "8080", "8079", null, null);
slServerConfig.setHopServer(meta);

IVariables variables = new Variables();
slServerConfig.setInternalHopServerVariables(variables, 9090);

assertEquals("9090", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_PORT));
}

@Test
void testSetInternalHopServerVariables_handlesEmptyOptionalFields() {
HopServerMeta meta = new HopServerMeta();
meta.setName("minimal");
meta.setHostname("localhost");
slServerConfig.setHopServer(meta);

IVariables variables = new Variables();
slServerConfig.setInternalHopServerVariables(variables, 8080);

assertEquals("minimal", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_NAME));
assertEquals("localhost", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_HOSTNAME));
assertEquals("", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_WEB_APP_NAME));
assertEquals("", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_USERNAME));
assertEquals("false", variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_SSL_MODE));
}

@Test
void testSetInternalHopServerVariables_nullServerIsNoop() {
// No HopServerMeta on the config — should not throw and should not set any variable.
IVariables variables = new Variables();
slServerConfig.setInternalHopServerVariables(variables, 8080);

assertNull(variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_NAME));
assertNull(variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_HOSTNAME));
assertNull(variables.getVariable(Const.INTERNAL_VARIABLE_HOP_SERVER_PORT));
}

@Test
void testSetInternalHopServerVariables_nullVariablesIsNoop() {
HopServerMeta meta = new HopServerMeta("server", "host", "8181", "8180", null, null);
slServerConfig.setHopServer(meta);

// Should not throw on null variables.
slServerConfig.setInternalHopServerVariables(null, 8181);
}

private Node getConfigNode(String configString) throws HopXmlException {
Document document = XmlHandler.loadXmlString(configString);
return XmlHandler.getSubNode(document, HopServerConfig.XML_TAG);
Expand Down
Loading