【问题标题】:How do I access environment variables in xquery?如何在 xquery 中访问环境变量?
【发布时间】:2019-11-13 16:26:48
【问题描述】:

我在 xquery 中的程序有一些变量,这些变量基于函数运行的环境。比如dev指向“devserver”,test指向“testserver”,prod指向“server”等

如何在 application.xml 文件中进行设置,如何在 .xqy 函数中引用这些内容?

“解决方法”解决方案 1

使用“switch”来确定主机:

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()))

“变通方法”解决方案2

在您的项目中为每个主机创建一个 xml 文件,更新您的 application.xml 以将 xml 文件放置在取决于环境名称的目录中,然后参考安装时构建的文档。

应用程序.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"/>

位于项目目录/config//environment.xml 中的文档

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

当我需要获取值时使用

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

在我看来,这两种解决方案都不是最好的。

【问题讨论】:

  • 我会尽量避免使其特定于主机。 MarkLogic 是一个集群解决方案,因此您在横向扩展或将集群迁移到不同的硬件或 vm ware 时会遇到麻烦。

标签: maven xquery marklogic


【解决方案1】:

如果你使用 ml-gradle 来部署你的项目,it can do substitutions in your code。这意味着您可以使用如下代码设置 XQuery 库:

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

然后,您可以在任何需要的地方导入该库。

【讨论】:

  • 这是 MarkLogic 中非常常见的方法,也适用于服务器端 JavaScript 文件。
  • 我们还没有使用 ml-gradle,但同样的事情应该适用于 Maven 和 Anthill,不是吗?
  • 它通过在部署之前在源代码中进行字符串替换来工作,所以是的,您应该能够使用其他工具来做到这一点。 (但我强烈鼓励使用 ml-gradle,因为它已被广泛使用并积极参与其中。)
【解决方案2】:

不知道 MarkLogic 是否支持,但 XQuery 3.1 有函数 available-environment-variables()environment-variable()

【讨论】:

  • MarkLogic 不支持这些方法,但请记住,MarkLogic 数据库可以跨多个主机集群。依赖环境设置可能很脆弱。我建议改用 MarkLogic 中保存的设置。
  • 是的,我们就如何指定环境变量进行了一些辩论,因为它们往往是进程的本地变量。
【解决方案3】:

您可以考虑使用https://github.com/marklogic-community/commons/tree/master/properties 上的小型“属性”库

我们很久很久以前就为 MarkMail.org 编写了它,我们认为我们不想将配置放入数据库文档中,因为配置应该与数据分开。数据得到备份,在其他地方恢复,新位置可能与旧位置不同。

因此,我们做了一些小改动,并将配置放入静态命名空间上下文(每个组和应用服务器都有)。配置的前缀是属性名称。配置的值是属性值(包括类型信息)。这是一个 MarkMail 部署的屏幕截图,显示它是一个生产服务器,用于发送错误电子邮件、服务的静态文件版本以及作为其基础输出的域。

这种方法允许您以管理方式配置属性(通过 Red GUI 或 REST),并且它们与数据保持分离。它们在执行上下文中静态可用,无需额外费用。您可以在组级别或应用服务器级别或两者配置它们。该库是提取类型值的便捷包装器。

也许现在有一种更好的方法,比如 XQuery 3.1 函数,但这个方法已经运行了 10 多年。

【讨论】:

  • 在文档中存储配置可能是好是坏。这取决于您存储的设置类型等细节。请记住,配置可以包含在克隆过程中以创建第二个环境,这是评估是否需要额外措施的好方法。
【解决方案4】:

我还没有在我们的项目中使用 gradle,但我设法弄清楚了如何使用 maven 配置文件根据部署到的环境来查找/替换我需要的值。我只需将要包含的插件、要更新的文件以及要替换的内容添加到正确的配置文件中。

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>

【讨论】:

    猜你喜欢
    • 2015-05-31
    • 2011-06-21
    • 2014-06-11
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多