Alma Pellett
Alma Pellett

Reputation: 314

How do I access environment variables in xquery?

My program in xquery has a few variables that are based on the environment where the function is being run. For example, dev points to "devserver", test to "testserver", prod to "server", etc.

How do I set this up in my application.xml file and how do I reference these in my .xqy functions?

"workaround" solution 1

use "switch" to determine host:

switch (xdmp:host-name(xdmp:host()))
    case <dev environment as string> return "devserver"
    case <test environment as string> return "testserver"
    .
    .
    .
    default return fn:error(xs:QName("ERROR"), "Unknown host: " || xdmp:host-name(xdmp:host()))

"workaround" solution 2

create an xml file in your project for each host, update your application.xml to place the xml file in a directory depending on the environment name, then refer to the document now built on installation.

application.xml:

<db dbName="!mydata-database">
   <dir name="/config/" permissionsMode="set">
       <uriPrivilege roles="*_uberuser"/>
       <permissions roles="*_uberuser" access="riu"/>
       <load env="DEV" root="/config/DEV/" merge="true" include="*.xml"/>
       <load env="TEST" root="/config/TEST/" merge="true" include="*.xml"/>

documents located in project directory /config//environment.xml

<environment>
   <services>
       <damApi>https://stage.mydam.org</damApi>
       <dimeApi>https://stage.mydime.org/api/Services</dimeApi>
   </services>
</environment>

usage when I need to get the value

fn:doc("/config/environment.xml")/environment/services/damApi/fn:string()

neither solution seems the best to me.

Upvotes: 2

Views: 693

Answers (4)

Alma Pellett
Alma Pellett

Reputation: 314

Not yet using gradle in our project, I managed to work out how to use maven profiles to find/replace the values I needed based on the environment it was deployed into. I just have to add to the proper profile the plugin to include, the files to update, and what to replace.

pom.xml:

<plugin>
  <groupId>com.google.code.maven-replacer-plugin</groupId>
  <artifactId>replacer</artifactId>
  <version>1.5.2</version>
  <executions>
    <execution>
      <phase>prepare-package</phase>
      <goals>
        <goal>replace</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <includes>
      <include>**/modules/runTasks.xqy</include>
      <include>**/imports/resetKey.xqy</include>
    </includes>
    <replacements>
      <replacement>
        <token>https://stage.mydime.org/api/Services</token>
        <value>https://www.mydime.org/api/Services</value>
      </replacement>
    </replacements>
  </configuration>
</plugin>

Upvotes: 0

Dave Cassel
Dave Cassel

Reputation: 8422

If you use ml-gradle to deploy your project, it can do substitutions in your code. That means you can set up an XQuery library with code like this:

declare variable $ENV = "%%environmentName%%";

You can then import that library wherever you need.

Upvotes: 2

hunterhacker
hunterhacker

Reputation: 7152

You can consider using the tiny “properties” library at https://github.com/marklogic-community/commons/tree/master/properties

We wrote it long, long ago for MarkMail.org with the belief we didn’t want to put the configuration into a database document because configuration should be separate from data. Data get backed up, restored somewhere else, and the new location may not be the same environment as the old.

So instead we did a little hack and put config into the static namespace context (which each group and app server has). The configured prefix is the property name. The configured value is the property value (including type information). Here’s a screen shot from a MarkMail deployment showing it’s a production server, to email on errors, what static file version to serve, and what domain to output as its base.

Example MarkMail configuration

This approach lets you configure properties administratively (via the Red GUI or REST) and they’re kept separate from the data. They’re statically available to the execution context without extra cost. You can configure them at the Group level or App Server level or both. The library is a convenience wrapper to pull the typed values.

Maybe by now there’s a better way like the XQuery 3.1 functions, but this one has been working well for 10+ years.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163655

Don't know if MarkLogic supports it, but XQuery 3.1 has functions available-environment-variables() and environment-variable().

Upvotes: 2

Related Questions