Loading TOC...
Scripting Administrative Tasks Guide (PDF)

Scripting Administrative Tasks Guide — Chapter 6

Server Maintenance Operations

This chapter describes how to use the Admin API to automate some of the operations you might want to perform on an existing MarkLogic Server configuration.

The main topics in this chapter are:

Group Maintenance Operations

The operations for creating and deleting groups are described in Creating and Configuring Groups. This section describes how to use the Admin API to automate some of the operations you might want to perform on an existing group.

The topics in this section are:

Enabling Auditing on a Group

The following script enables auditing of user-configuration-change and user-role-addition events on the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
(: Set user-configuration-change and user-role-addition events to be audited in the 'Default' group. :)
let $config := admin:group-enable-audit-event-type(
  $config, 
  $groupid, 
  ("user-configuration-change","user-role-addition"))
(: Enable auditing for the 'Default' group. :)
return admin:save-configuration(
  admin:group-set-audit-enabled($config, $groupid, fn:true()))

Disabling Auditing on a Group

The following script disables auditing of all events on the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return admin:save-configuration(
  admin:group-set-audit-enabled($config, $groupid, fn:false()))

Removing Events to be Audited on a Group

The following script disables auditing of user-configuration-change and user-role-addition events on the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return admin:save-configuration(
  admin:group-disable-audit-event-type(
    $config, 
    $groupid, 
    ("user-configuration-change","user-role-addition")))

Adding a Namespace to a Group

The following script creates a new namespace, named 'myprefix,' and adds it to the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin"
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return admin:save-configuration( 
  admin:group-add-namespace(
    $config, 
    $groupid,
    admin:group-namespace("myprefix", "http://myuri/namespace")))

Returning the Namespace Settings on a Group

The following script returns the namespaces set for the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin"
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return admin:group-get-namespaces($config, $groupid)

Deleting a Namespace from a Group

The following script deletes the 'myprefix' namespace from the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin"
  at "/MarkLogic/admin.xqy";
declare namespace group = "http://marklogic.com/xdmp/group";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return admin:save-configuration( 
  admin:group-delete-namespace(
    $config, 
    $groupid,
    admin:group-get-namespaces($config, $groupid)
      [group:prefix eq "myprefix"]))

Returning the System Log Settings

The following script returns the current system log settings for the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
return 
  admin:group-get-system-log-level($config, $groupid)
return (
  fn:concat("Log Level Setting: ",
    admin:group-get-system-log-level($config, $groupid)),
  fn:concat("Number of Log Files Kept: ",
    admin:group-get-keep-log-files($config, $groupid)),
  fn:concat("Log File Rotation Frequency: ",
    admin:group-get-rotate-log-files($config, $groupid)))

Resetting the System Log Settings

The following script resets the system log settings for the 'Default' group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id(
  $config, 
  "Default")
let $config := admin:group-set-system-log-level(
  $config, 
  $groupid, 
  "debug")
let $config := admin:group-set-keep-log-files(
  $config, 
  $groupid, 
  3)
return admin:save-configuration(
  admin:group-set-rotate-log-files(
    $config, 
    $groupid, 
    "friday"))

Creating a New Hourly Task

The following script creates an hourly scheduled task to invoke the Scheduler_test.xqy module every two hours and adds it to the "Default" group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration() 
let $task := admin:group-hourly-scheduled-task(
  "Scheduler_test.xqy",
  "/Docs",
  2,
  30,
  xdmp:database("Sample-Database"),
  0,
  xdmp:user("Jim"),
  0)
let $config := admin:group-add-scheduled-task(
  $config, 
  admin:group-get-id($config, "Default"), 
  $task)
return admin:save-configuration($config)

Deleting all Scheduled Tasks from a Group

The following script deletes all of the scheduled tasks in the "Default" group:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $group := admin:group-get-id($config, "Default")
let $tasks := admin:group-get-scheduled-tasks($config, $group)
return admin:group-delete-scheduled-task($config, $group, $tasks)

App Server Maintenance Operations

The operations for creating and deleting App Servers are described in Creating and Configuring App Servers. This section describes how to use the Admin API to automate some of the operations you might want to perform on an existing App Server.

The topics are:

Modifying the App Server Root for an HTTP App Server

The following example modifies an App Server configuration by changing its root from the relative path myRoot to the absolute path /space/myRoot.

xquery version "1.0-ml";

import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
let $appserverid := admin:appserver-get-id(
  $config, 
  $groupid,
  "Sample-Server")
let $config := admin:appserver-set-root(
  $config, 
  $appserverid,
  "/space/myRoot")
return admin:save-configuration($config)

Changing the App Server Root and Cloning the Changed App Server

The following example does the same thing as the previous example (modifies the HTTP App Server root), and then it also takes that modified configuration and creates another App Server with the same settings but a different name.

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
    at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $groupid := admin:group-get-id($config, "Default")
let $appserverid := admin:appserver-get-id(
  $config, 
  $groupid,
  "Sample-Server")
let $config := admin:appserver-set-root(
  $config, 
  $appserverid,
  "/space/myRoot")
let $config := admin:appserver-copy(
  $config, 
  $appserverid, 
  (), 
  "newHTTPServer", 
  9021)
return admin:save-configuration($config)

This will result in both changes to the configuration, the change in root to Sample-Server and the newHTTPServer being created.

Enabling SSL on an App Server

The Configuring SSL on App Servers chapter in the Administrator's Guide describes how to use the Admin UI to enable SSL on an App Server. The following sections describe how to enable SSL on an App Server using the Admin and PKI APIs:

Creating a Certificate Template

The following script creates a new certificate template, named newTemplate, and inserts it into the Security database:

xquery version "1.0-ml";
import module namespace pki = "http://marklogic.com/xdmp/pki" 
  at "/MarkLogic/pki.xqy";
declare namespace x509 = "http://marklogic.com/xdmp/x509";
declare namespace ssl = "http://marklogic.com/xdmp/ssl";
let $x509 := 
  <x509:req>
    <x509:version>2</x509:version>
    <x509:subject>
      <x509:countryName>US</x509:countryName>
      <x509:stateOrProvinceName>CA</x509:stateOrProvinceName>
      <x509:localityName>San Carlos</x509:localityName>
      <x509:organizationName>MarkLogic</x509:organizationName>
      <x509:organizationalUnitName>
          Engineering
      </x509:organizationalUnitName>
      <x509:commonName>my.host.com</x509:commonName>
      <x509:emailAddress>user@marklogic.com</x509:emailAddress>
    </x509:subject>
    <x509:v3ext>
      <x509:nsCertType critical="false">SSL Server</x509:nsCertType>
      <x509:subjectAltName>
          DNS:marklogic.com, IP:127.0.0.1 
      </x509:subjectAltName>
    </x509:v3ext>
  </x509:req>
let $options := 
  <pki:key-options xmlns="ssl:options">
    <key-length>2048</key-length>
  </pki:key-options>
return pki:insert-template(
  pki:create-template(
    "newTemplate",
    "Creating a new template",
    "rsa",
    $options,
    $x509))
Generating a Certificate Request

The following script generates a certificate request from the certificate template created in Enabling SSL on an App Server:

xquery version "1.0-ml"; 
import module namespace pki = "http://marklogic.com/xdmp/pki"
  at "/MarkLogic/pki.xqy"; 
let $tid := pki:template-get-id(
  pki:get-template-by-name("newTemplate"))
return pki:generate-certificate-request(
  $tid, 
  (), 
  "marklogic.com", 
  "127.0.0.1")
Importing a Signed Certificate into the Database

The following script imports the PEM-encoded signed certificate from the Sample_cert.cer file into the Security database:

xquery version "1.0-ml"; 
import module namespace pki = "http://marklogic.com/xdmp/pki" 
  at "/MarkLogic/pki.xqy";
pki:insert-signed-certificates(
  xdmp:document-get(
    "c:\SignedCertificates\Sample_cert.cer", 
    <options xmlns="xdmp:document-get">
      <format>text</format>
    </options>))
Setting a Certificate Template on an App Server

The following script sets the PEM-encoded signed certificate in the Security database on the Sample-Server App Server:

xquery version "1.0-ml"; 
import module namespace pki = "http://marklogic.com/xdmp/pki" 
  at "/MarkLogic/pki.xqy";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $appServer := admin:appserver-get-id(
  $config, 
  admin:group-get-id($config, "Default"), 
  "Sample-Server")
let $tid := pki:template-get-id(pki:get-template-by-name("mycert"))
return admin:save-configuration(
  admin:appserver-set-ssl-certificate-template(
    $config, 
    $appServer, 
    $tid))

Database Maintenance Operations

The operations for creating and deleting forests and databases are described in Creating and Configuring Forests and Databases. This section describes how to use the Admin API to automate some of the operations you might want to perform on an existing database and/or forest.

The topics in this section are:

Creating a Database by Cloning an Existing Database Configuration

The following example creates a new database with the exact same setup (including index settings, fragmentation, range indexes, and so on) as an existing database. It uses the admin:database-copy function to clone the database.

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
    at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $config := admin:database-copy(
  $config,
  xdmp:database("myOldDatabase"), 
  "myNewDatabase")
return admin:save-configuration($config)

After running this XQuery program, a new database configuration named myNewDatabase is created with the same settings as the database named myOldDatabase. Note that this database will not have any forests attached to it, as forests can only be attached to a single database.

Returning the Size of the Forests in a Database

The following script returns the size of all of the forests in the 'Sample-Database' database:

xquery version "1.0-ml"; 
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
declare namespace forest = "http://marklogic.com/xdmp/status/forest";
(: Get all of the forests in the 'Sample-Database database. :)
for $forests in xdmp:forest-status(
  xdmp:database-forests(xdmp:database("Sample-Database")))
(: Get the remaining disk space for each forest device. :)
  let $space := $forests//forest:device-space
(: Get the name of each forest. :)
  let $f_name := $forests//forest:forest-name
(: The size of a forest is the sum of its stand sizes. :)
  for $stand in $forests//forest:stands
    let $f_size := fn:sum($stand/forest:stand/forest:disk-size)
(: Return the name and size for each forest and remaining 
   disk space. :)
return fn:concat(
  "Forest Name: ", 
  fn:string($f_name), 
  "  Forest Size: ", 
  fn:string($f_size),
  "  Disk Space Left: ", 
  $space)

Deleting Element and Attribute Range Indexes

The following script deletes the range element index and the range element attribute index created in the previous two examples from the 'Sample-Database' database:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $dbid := xdmp:database("Sample-Database")
let $elem-rangespec := admin:database-range-element-index(
  "date", 
  "/myco/employees",
  "birthday", 
  "",
  fn:false() )
let $elem-attr-rangespec :=
  admin:database-range-element-attribute-index(
    "date", 
    "/myco/employees",
    "Personal", 
    "", 
    "birthday hire-date", 
    "",
    fn:false())
let $config2 := admin:database-delete-range-element-index(
  $config, 
  $dbid, 
  $elem-rangespec)
return admin:save-configuration(
  admin:database-delete-range-element-attribute-index( 
    $config2, 
    $dbid, 
    $elem-attr-rangespec))

Adding a Fragment Root to a Database

The following script adds a fragment root specification for the 'TITLE' element to the 'Sample-Database' database:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $dbid := xdmp:database("Sample-Database")
let $fragspec := admin:database-fragment-root(
  "/shakespeare/plays", 
  "TITLE")
return   admin:save-configuration( 
  admin:database-add-fragment-root(
    $config, 
    $dbid, 
    $fragspec))

Returning the Fragment Roots Set in a Database

The following script returns the fragment root specifications set in the 'Sample-Database' database:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
return admin:database-get-fragment-roots(
  $config, 
  xdmp:database("Sample-Database"))

Deleting a Fragment Root from a Database

The following script deletes the fragment root specification for the 'TITLE' element from the 'Sample-Database' database:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $dbid := xdmp:database("Sample-Database")
let $fragspec := admin:database-fragment-root(
  "/shakespeare/plays", 
  "TITLE")
return admin:save-configuration( 
  admin:database-delete-fragment-root($config, $dbid, $fragspec))

Merging the Forests in a Database

The following script merges four forests in the database with the specification to not leave any single stand larger than 50MB. For example, if the forest size is 180 MB, this script would merge the content into four stands:

xquery version "1.0-ml";
xdmp:merge(
  <options xmlns="xdmp:merge">
    <merge-max-size>50</merge-max-size>
    <forests>
      <forest>{xdmp:forest("myforest1")}</forest>
      <forest>{xdmp:forest("myforest2")}</forest>
      <forest>{xdmp:forest("myforest3")}</forest>
      <forest>{xdmp:forest("myforest4")}</forest>
    </forests>
  </options>) 

Scheduling Forest Backups

The following script establishes a backup schedule for all of the forests in the 'Sample-Database' database:

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
(: Get the configuration :)
let $config := admin:get-configuration()
(: Set up the backup elements. :)
let $backup := admin:forest-weekly-backup(
  "/backup-dir", 
  "friday", 
  xs:time("23:00:00"))
(: Get all of the forests in the 'Sample-Database' database. :)
for $forest in admin:database-get-attached-forests(
  $config, 
  xdmp:database("Sample-Database"))
(: Add the backup elements to each forest configuration. :)
return admin:forest-add-backup(
  $config,
  $forest, 
  $backup)

Alerting the Administrator if the Forest Grows Beyond its Maximum Allowable Size

The following script checks the amount of disk space used by the forests in the 'Sample-Database' database against the available disk space on the forest devices. If the size of a forest surpasses its maximum allowable size, an event is logged and an email is sent to urgent@mycompany.com. Such a script could be executed periodically using the scheduling features described in Scheduling Tasks in the Administrator's Guide.

xquery version "1.0-ml"; 
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
declare namespace forest = "http://marklogic.com/xdmp/status/forest";
(: Get all of the forests in the 'Sample-Database' database. :)
   for $forests in xdmp:forest-status(
  xdmp:database-forests(xdmp:database("Sample-Database")))
(: Get the remaining disk space for each forest device. :)
  let $space := $forests//forest:device-space
(: Get the name of each forest. :)
  let $f_name := $forests//forest:forest-name
(: The size of a forest is the sum of its stand sizes. :)
  for $stand in $forests//forest:stands
     let $f_size := fn:sum($stand/forest:stand/forest:disk-size)
(: The maximum size of the forest is calculated by multiplying the 
   size of the forest by 3 and comparing that value against the
   available disk space - 1000 MB. If the forest grows beyond its
   maximum size, log the event and send an email alert to the
   administrator. :)
  return 
    if (($f_size * 3) > ($space - 1000))
    then (xdmp:log(
      fn:concat($f_name, " forest space check status: Failed"),
      "emergency"),
      xdmp:email(
         <em:Message
         xmlns:em="URN:ietf:params:email-xml:" 
         xmlns:rf="URN:ietf:params:rfc822:">
           <rf:subject>Forest Space Check Failure</rf:subject>
           <rf:from>
             <em:Address>
               <em:name>MarkLogic Server</em:name>
               <em:adrs>no_return@mycompany.com</em:adrs>
             </em:Address>
           </rf:from>
           <rf:to>
             <em:Address>
               <em:name>System Administrator</em:name>
               <em:adrs>urgent@mycompany.com</em:adrs>
             </em:Address>
           </rf:to>
           <em:content xml:space="preserve">
             {fn:concat($f_name, " forest space check status: Failed")}
           </em:content>
         </em:Message>))
    else (xdmp:log(
         fn:concat($f_name, " forest space check status: Passed")))

Rotating Forest Update Types

As described in Making a Forest Delete-Only, in the Administrator's Guide, there may be circumstances in which you have multiple forests in a database and you want to manage which forests change. The following script checks the status of each forest's update type in the database, 'Sample-Database,' and changes any forest with an update type of all to delete-only and any forest with an update type of delete-only to all. Such a script could be executed periodically as a scheduled task.

Applications that use a database containing delete-only forests must specify an updateable forest in the xdmp:document-insert function. Otherwise an insert to a document on a delete-only forest returns an error.

xquery version "1.0-ml"; 
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
declare namespace forest = "http://marklogic.com/xdmp/status/forest";
(: Get the configuration :)
let $config := admin:get-configuration()
(: Update the configuration :)
let $new-config :=
(: Get all of the forests in the 'Sample-Database' database. :)
for $forests in xdmp:forest-status(
  xdmp:database-forests(xdmp:database("Sample-Database")))
(: Get the id of each forest. :)
  let $f_id := $forests//forest:forest-id
(: Get the name of each forest. :)
  let $f_name := $forests//forest:forest-name
(: Get the updates allowed status of each forest. :)
  let $f_updates := $forests//forest:updates-allowed
(: Reset the update type for the 'delete-only' forests to 'all' and the 'all' forests to 'delete-only'. Add a log message for each update. :)
return
  if ($f_updates eq "all")
    then (
      xdmp:log(fn:concat(
         "Setting ", 
         $f_name, 
         " forest with updates set to ",
         $f_updates, 
         " to delete-only")),
      xdmp:set(
         $config, 
         admin:forest-set-updates-allowed(
            $config, 
            $f_id, 
            "delete-only")) )
    else ( 
      xdmp:log(fn:concat(
         "Setting ", 
         $f_name, 
         " forest with updates set to ",
         $f_updates, 
         " forest to 'all'")),
      xdmp:set($config, admin:forest-set-updates-allowed(
         $config,
         $f_id,
         "all"))
    )
return admin:save-configuration($config)

The example script below does the same thing as the above script using a different approach. The script above creates and sets the configuration once for each forest. The script below uses a function that returns a single configuration for all of the forests in the database. Though the script below contains more complex logic, it represents the type of script you would want to use in a production environment:

xquery version "1.0-ml"; 
declare namespace forest = "http://marklogic.com/xdmp/status/forest";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy"; 
(: Function accepts the empty configuration sequence and list of forests and returns the final configuration. :)
declare function local:change-update-types(
  $config as element(configuration)*,
  $forests as xs:unsignedLong*) as element(configuration)
{
(: The first time through the loop, get the configuration. After that, continue to build on the modified configuration. :)
if (fn:empty($config)) 
   then xdmp:set($config, admin:get-configuration()) 
   else (),
(: Reset the update type for the 'delete-only' forests to 'all' and 
   the 'all' forests to 'delete-only'. When complete, return the
   configuration. :)
(: Determine whether there are remaining forests. If not, return 
   the final configuration. :)
if (fn:count($forests) lt 1) 
   then ($config) 
(: Convert the update type for the next forest in the sequence. Add a log message for each conversion. :)
   else ( 
    let $f_updates := 
           xdmp:forest-status($forests[1])//forest:updates-allowed
    let $name := xdmp:forest-name($forests[1])
    return (
       if ($f_updates eq "all")
          then (
             xdmp:log(fn:concat(
               "Setting ", 
               $name, 
               " forest with updates set to ",
               $f_updates, 
               " to delete-only")),
             xdmp:set($config, admin:forest-set-updates-allowed(
               $config, 
               $forests[1],
               "delete-only")))
          else ( 
             xdmp:log(fn:concat(
               "Setting ", 
               $name, 
               " forest with updates set to ",
               $f_updates, " forest to 'all'")),
             xdmp:set($config, admin:forest-set-updates-allowed(
               $config,
               $forests[1],
               "all"))),
(: Function calls itself for each remaining forest in the sequence. :)
    local:change-update-types($config, $forests[2 to last()])
    )
  )
};
(: Main :)
(: Define $config as an empty sequence. The function uses this as a flag to determine whether or not to get the initial configuration. :)
let $config := ()
(: Obtain the id of each forest in the database. :)
let $forests :=   xdmp:database-forests(xdmp:database("Sample-Database"))
(: Call the change-update-types function and set the returned configuration. :)
return admin:save-configuration(
  local:change-update-types($config, $forests))

Host Maintenance Operations

This section describes how to use the Admin API to automate some of the operations you might want to perform on an existing host.

The topics in this section are:

Returning the Status of the Host

The following script returns the current status of the local host:

xquery version "1.0-ml"; 
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
return xdmp:host-status(
  admin:host-get-id($config, xdmp:host-name()))

Returning the Time Host was Last Started

The following script returns the time the local host was last started:

xquery version "1.0-ml"; 
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
declare namespace host = "http://marklogic.com/xdmp/status/host";
let $config := admin:get-configuration()
for $i in (xdmp:host-status(
  admin:host-get-id(
  $config, 
  xdmp:host-name())))//host:last-startup 
return 
  fn:string($i) 

Restarting MarkLogic Server on all Hosts in the Cluster

The following script restarts MarkLogic Server on all of the hosts in the cluster that contains the host invoking the script (including the invoking host):

xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin" 
  at "/MarkLogic/admin.xqy";
declare namespace host="http://marklogic.com/xdmp/status/host";
let $hostids := for $id in xdmp:host-status(xdmp:host())
  /host:hosts//host:host/host:host-id
    return fn:data($id)
return admin:restart-hosts($hostids)

User Maintenance Operations

This section describes the user and role maintenance operations that make use of the functions in the security.xqy library module. All calls to functions in the security.xqy library module must be executed against the Security database. For information on how to execute queries to databases other than the one set for your App Server, see Executing Queries in Select Databases.

The topics in this section are:

Removing all Users with a Specific Role

The following script removes all users assigned the role, Temporary:

(: run this against the Security database :)
xquery version "1.0-ml";
import module "http://marklogic.com/xdmp/security" 
  at "/MarkLogic/security.xqy";
for $user in fn:data(//sec:user-name)
  return 
    if (fn:matches(sec:user-get-roles($user), "Temporary"))
       then (fn:concat("Removed:  ", $user), sec:remove-user($user))
       else ()

Removing a Specific Role, if Present

The following script removes the role, Temporary, if present:

xquery version "1.0-ml";
import module "http://marklogic.com/xdmp/security" 
  at "/MarkLogic/security.xqy";
for $role in fn:data(//sec:role-name)
  return 
    if (fn:matches($role, "Temporary"))
      then (fn:concat("Removed:  ", $role), 
            sec:remove-role("Temporary"))
      else ()
return admin:save-configuration(
  admin:database-add-range-element-attribute-index(
    $config, 
    $dbid, 
    $rangespec))

Retrieving the Last-Login Information

The xdmp:user-last-login function returns an XML node with information about the last successful login, last unsuccessful login, and the number of unsuccessful login attempts for a user. If there is no last-login database configured, then the function returns the empty sequence.

The following is a very simple program that demonstrates how to use this information to add a message to your application. It uses the display-last-login field to determine whether to display anything.

xquery version "1.0-ml";
declare namespace ll="http://marklogic.com/xdmp/last-login";
let $last := xdmp:user-last-login()
return
( if ($last/ll:display-last-login/text() eq "true")
    then ( fn:concat("You are logged in as the user '", 
       xdmp:get-current-user(), 
       "' (", fn:data($last/ll:user-id), ") ", 
       "who last successfully logged in on ",
       $last/ll:last-successful-login, ".") )
    else ()  )

This script returns output similar to the following:

You are logged in as the user 'Jim' (893641345095093063) who last successfully logged in on 2008-07-15T16:13:54-07:00.

Backing Up and Restoring

This section provides examples using the Admin API for backup and restore tasks using full and incremental backups. This section includes the following parts:

Full Backup of a Database

The following script immediately does a full backup all of the forests in the 'Sample-Database' database to the /backup-dir directory:

xquery version "1.0-ml";
xdmp:database-backup(
  xdmp:database-forests(xdmp:database("Sample-Database")), 
  "c:/backup-dir")
=>
437302857479804813287

Incremental Backup of a Database

The following script does an immediate incremental backup of two forests (11183608861595735720 and 898513504988507762)to the /backups/Data directory:

xquery version "1.0-ml";
xdmp:database-incremental-backup(
  (11183608861595735720,898513504988507762),
  "/backups/Data")
=>
33030877979801813489

Restoring from a Full Backup

The following script restores the 'Sample-Database' database from the backup taken on 2014-09-15:

xquery version "1.0-ml";
xdmp:database-restore( 
  xdmp:database-forests(xdmp:database("Sample-Database")), 
  "c:/fullbackup-dir", xs:dateTime("2014-09-15T11:30:51.33885-05:00"),fn:false()
=>
33030877979801813489

Restoring from an Incremental Backup

This script restores a database from the incremental backup done on 2014-09-17.

xquery version "1.0-ml";
xdmp:database-restore(
xdmp:database-forests(xdmp:database("Documents")),
"c:/test-backup", xs:dateTime("2014-09-17T11:35:51.33882-07:00"),
fn:false()," ",fn:true(), "c:/test-backup") 
=>
35040877979801814489

Validating an Incremental Backup

This script validates that the specified list of forests (11183608861595735720 and 898513504988507762) can be backed up to the backup data directory (/backups/Data2):

xquery version "1.0-ml";
xdmp:database-incremental-backup-validate((11183608861595735720,898513504988507762),
  "/backups/Data", fn:false(), "/backups/Data2", fn:true())
=>
<bp:backup-plan
   xsi:schemaLocation="http://marklogic.com/xdmp/backup-plan backup-plan.xsd"
   xmlns:bp="http://marklogic.com/xdmp/backup-plan"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
  <bp:forest>
    <bp:forest-name>Documents</bp:forest-name>
    <bp:forest-id>9157142760003704384</bp:forest-id>
    <bp:forest-status>okay</bp:forest-status>
    <bp:directory-path>/backups/Data</bp:directory-path>
    <bp:directory-status>okay</bp:directory-status>
    <bp:action>incremental-backup</bp:action>
    <bp:incremental-backup>true</bp:incremental-backup>
    <bp:incremental-backup-path>/backups/Data2</bp:incremental-backup-path>
    <bp:journal-archiving>true</bp:journal-archiving>
    <bp:journal-archive-path>/tmp</bp:journal-archive-path>
    <bp:journal-archive-path-status>okay</bp:journal-archive-path-status>
    <bp:journal-archive-lag-limit>15</bp:journal-archive-lag-limit>
    <bp:journal-archive-lag-limit-status>okay</bp:journal-archive-lag-limit-status>
  </bp:forest>
</bp:backup-plan>
« Previous chapter
Next chapter »