脚本语言和 ArcGIS Server Administrator API

ArcGIS Server Administrator API 可使用任何能够通过 HTTP 调用 RESTful Web 服务和解析响应的脚本语言。包括 Python、Java、JavaScript、PowerShell、C#、Ruby、Scala、Perl 以及其他语言。

本帮助系统中的 Administrator API 示例使用的是 Python 语言。但下方示例将演示如何使用各种语言编写等效的脚本。每个脚本都可启动随 ArcGIS Server 一起安装的几何服务。

Python

此脚本使用 Python 语言启动几何服务。

启动服务需要具有管理权限,因此运行此脚本时必须提供一个具有管理员权限的用户名和密码。

# Demonstrates how to start a service by starting the geometry service
# This service is included with every ArcGIS Server and is stopped by default

# For Http calls
import httplib, urllib, json

# For system tools
import sys

# For reading passwords without echoing
import getpass


# Defines the entry point into the script
def main(argv=None):
    # Print some info
    print
    print "This tool is a sample script that starts the Geometry service on a Server."
    print
    
    # Ask for admin/publisher user name and password
    username = raw_input("Enter user name: ")
    password = getpass.getpass("Enter password: ")

    # Ask for server name
    serverName = raw_input("Enter server name: ")
    serverPort = 6080
    
    # Get a token
    token = getToken(username, password, serverName, serverPort)
    if token == "":
        print "Could not generate a token with the username and password provided."
        return
    
    # Construct URL to start a service - as an example the Geometry service
    serviceStartURL = "/arcgis/admin/services/utilities/Geometry.GeometryServer/start"
    
    # This request only needs the token and the response formatting parameter 
    params = urllib.urlencode({'token': token, 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters    
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", serviceStartURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while attempting to start the service."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):          
            print "Error returned by operation. " + data
        else:
            print "Operation completed successfully!"
        
        return


# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):
    # Token URL is typically http://server[:port]/arcgis/admin/generateToken
    tokenURL = "/arcgis/admin/generateToken"
    
    # URL-encode the token parameters
    params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", tokenURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while fetching tokens from admin URL. Please check the URL and try again."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):            
            return
        
        # Extract the token from it
        token = json.loads(data)        
        return token["token"]            
        

# A function that checks that the input JSON object 
#  is not an error object.  
def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print "Error: JSON object returns an error. " + str(obj)
        return False
    else:
        return True
    
        
# Script start
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

Windows PowerShell

此脚本使用 Windows PowerShell 语言启动几何服务。旨在演示如何通过 ArcGIS Server Administrator API 编写其他 PowerShell 脚本。

# Demonstrates how to start a service by starting the geometry service.# This service is included with every ArcGIS Server 

and is stopped by default.

# To run this script, you must set the the appropriate security settings.
#  For more information about Powershell security, visit the following URL: 
#  http://www.windowsecurity.com/articles/PowerShell-Security.html


# provides serialization and deserialization functionality for JSON object
Add-Type -AssemblyName System.Web.Extensions


# Defines the entry point into the script
function main(){
  # Print some info
  echo "This is a sample script that starts the ArcGIS Server geometry service."
  
  # Ask for admin/publisher user name
  $username = read-host "Enter user name"
  $securePassword = read-host -AsSecureString "Enter password"
  
  # Ask for Admin/publisher password
  # Use Marshal Class to decode the secure string. Reference:
  #  http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx
  $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($securePassword)
  $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
  [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
  
  # Ask for servername
  $serverName = read-host "Enter server name"
  $serverPort = 6080
  
  # Get a token
  $token = token $username $password $serverName $serverPort
  if(!$token){
    write-warning "Could not generate a token with the username and password provided"
    
    return
  }
  
  # construct URL to start a service - as an example the Geometry service
  $url = "http://${serverName}:${serverPort}/arcgis/admin/services/Utilities/Geometry.GeometryServer/start"
  $parameters = "token=${token}&f=json"
  
  # Construct a HTTP request
  $http_request = New-Object -ComObject Msxml2.XMLHTTP
  $http_request.open('POST', $url, $false)
  $http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  
  # Connect to URL and post parameters
  try{
    $http_request.send($parameters)
  }
  catch{
    write-warning 'There were exceptions when sending the request'
    
    return
  }
  
  # Read response
  if($http_request.status -eq 200){
    # Check that data returned is not an error object
    if(assertJsonSuccess $http_request.responseText){
      echo "Operation completed successfully!"
    }
    else{
      write-warning "Error returned by operation."
      write-warning $http_request
    }
  }
  else{
    write-warning "Error while attempting to start the service."
  }
}


# A function to generate a token given username, password and the adminURL.
function token([string]$username, [string]$password, [string]$serverName, [int]$serverPort){
  # Token URL is typically http://server[:port]/arcgis/admin/generateToken
  $url = "http://${serverName}:${serverPort}/arcgis/admin/generateToken"
  $parameters = "username=${username}&password=${password}&client=requestip&f=json"
  
  # Construct a HTTP request
  $http_request = New-Object -ComObject Msxml2.XMLHTTP
  $http_request.open('POST', $url, $false)
  $http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  
  # Connect to URL and post parameters
  $token = ''
  try{
    $http_request.send($parameters)
  }
  catch{
    write-warning 'There were exceptions when sending the request'
    
    return $token
  }
  
  # Read response
  if($http_request.status -eq 200){
    # Check that data returned is not an error object
    if(assertJsonSuccess $http_request.responseText){
      # Extract the token from it
      $jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
      $jsonObj = $jsonSerializer.DeserializeObject($http_request.responseText)
      
      $token = $jsonObj['token']
    }
  }
  else{
    write-warning "Error encountered when retrieving an administrative token. Please check your credentials and try again."
  }
  
  $token
}


# A function that checks that the input JSON object 
#  is not an error object.  
function assertJsonSuccess([string]$data){
  $jsonSerializer = New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer
  $jsonObj = $jsonSerializer.DeserializeObject($data)
  
  if($jsonObj['status'] -eq 'error'){
    write-warning "JSON object returns an error. Data => ${data}"
    $FALSE
  }
  else{
    $TRUE
  }
}


# Script start
main

Perl

此示例脚本使用 Perl 启动几何服务。脚本始终尝试安全登录(加密用户名和密码)。如果 ArcGIS Server 未配置 HTTPS,则安全登录尝试失败,默认情况下,脚本将尝试非安全登录。如果不希望尝试非安全登录,则使用 -e 选项要求安全登录。

此脚本使用所有 Perl 分布通常随附的 LWP 和 HTTP 库。此脚本无需在其运行系统上安装任何 Esri 软件。

如果要更改此脚本以供您自己使用,请注意修改位于“工具”文件夹中的几何服务和脚本中使用的 URL 以配合其他文件夹名称。

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common qw(GET POST);

my $ua = LWP::UserAgent->new;
$ua->timeout(300); 	#services start within 5 minutes or timeout

my ($user, $password, $serverName, $port, $requireEncryption) = getUserInput();
my $baseUrl ="http://$serverName:$port/arcgis";

my $token = getToken($baseUrl, $user, $password, $requireEncryption);
startService($baseUrl, $token, "Geometry", "GeometryServer");


sub getToken {
	# Attempt to login securely.  
	# If it fails and encryption required, tell user.
	# If it fails and encryption not required, try insecure login.
	
	my ($baseUrl, $user, $password, $requireEncryption) = @_;
	my $secureUrl = $baseUrl;
	$secureUrl =~ s/http/https/;
	$secureUrl =~ s/:6080/:6443/;

	my $token = makeTokenRequest($secureUrl, $user, $password);
	return $token if (defined $token);

	if ($requireEncryption) {
		print "Unable to login. Either the server doesn't support https, or the server name,\nusername, or password might be incorrect.\n\n";
		exit(1);
	}

	$token = makeTokenRequest($baseUrl, $user, $password);
	return $token if (defined $token);
	
	print "Unable to get token.  The server name, username, or password might be incorrect.\n";
	exit(1);
}


sub makeTokenRequest {
	my ($url, $user, $password) = @_;
	my $response = makeHttpPost("$url/admin/generateToken", {username=>$user, password=>$password, client=>"requestip", expiration=>30, f=>'json'});
	if ($response =~/\{\"token\"\:\"(.*)\",/) {
		return $1;
	} else {
		return undef;
	}
}

sub startService {
	my($baseUrl, $token, $serviceName, $serviceType) = @_;

	my $response = makeHttpPost("$baseUrl/admin/services/Utilities/$serviceName.$serviceType/start", {f=>'json', token=>$token});
	if ($response eq "") {
		print "ERROR: Unable to start the service.  Unable to make http connection to server.\n";
	} elsif ($response =~/success/) {
		print "Service $serviceName.$serviceType successfully started.\n";
	} elsif ($response =~ /"code":404/) {
		print "Service $serviceName.$serviceType was not found. Please check for typos.\n";
	}
}




sub makeHttpPost {

        my $url         = $_[0];
        my %parameter   = %{$_[1]};

        my $req = HTTP::Request->new(POST => $url);
        $req->content_type('application/x-www-form-urlencoded');
        my $requestParameters = "";
        foreach my $key ( keys %parameter) {
                $requestParameters .= "$key=$parameter{$key}&"
        }

        $req->content($requestParameters);
        my $res = $ua->request($req);
        if ($res->is_success) {
                return $res->content;
        } else {
	        return "";
	}
}

sub getUserInput {

	my ($user, $password, $serverName, $port, $requireEncryption);
	$serverName = "localhost";
	$port = "6080";
	$requireEncryption = 0;

	if ($#ARGV < 0) {
		print "This tool is a sample script that starts the Geometry service on a Server.\n\n";
		print "\t-u\tArcGIS Server publisher or admin user. Required\n";
		print "\t-p\tPassword for the user. Required.\n";
		print "\t-s\tServer machine. Optional, default is localhost.\n";
		print "\t-t\tPort.  Optional, default is 6080.\n";
		print "\t-e\tRequire secure login.\n";
		print "\n\n\tExample: startGeometryService -u admin -p password.\n";
		print "\tExample: startGeometryService -u admin -p password -s gis1.\n";
		print "\tExample: startGeometryService -u admin -p password -e.\n";
		print "\tExample: startGeometryService -u admin -p password -s gis1 -t 80.\n\n";
		print "Warning: This script always tries to login securely through https (encrypted).\n";
		print "If that fails, it tries an insecure login since ArcGIS Server may not be\n";
		print "configured for https.  Use the -e option to avoid ever using an insecure login.\n\n\n";
		exit();
	} else {
		for my $i (0 .. $#ARGV) {
			$user = $ARGV[$i+1] if ($ARGV[$i] eq "-u");
			$password = $ARGV[$i+1] if ($ARGV[$i] eq "-p");
			$serverName = $ARGV[$i+1] if ($ARGV[$i] eq "-s");
			$port = $ARGV[$i+1] if ($ARGV[$i] eq "-t");
			$requireEncryption = 1 if ($ARGV[$i] eq "-e");
		}
	}

	if (! defined $user || ! defined $password) {
		print "A user was not provided using the correct syntax.\n" if (! defined $user);
		print "A password was not provided using the correct syntax.\n" if (! defined $password);
		exit(1);
	}

	return ($user, $password, $serverName, $port, $requireEncryption);
}

Scala

以下示例用 Scala 语言编写。可以停止或启动几何服务。

// Sample usage of the ArcGIS 10.1 for Server Administrator API
// - Dispatch (http://dispatch.databinder.net)
// - LiftJSON
// ...demonstrates how to START or STOP the Geometry Service in a 10.1 ArcGIS Server Site

import dispatch._
import dispatch.liftjson._
import Http._
import dispatch.liftjson.Js._
import net.liftweb.json.JsonAST._

object StartStopGeometryService {

	def main(args: Array[String]){

                
		try{
		    print("Enter Command (START or STOP): ")       
            val command = Console.readLine()
            print("Enter host name: ") 
            val host = Console.readLine() 
            print("Enter port:") 
		    val port = Console.readLine()
		    print("Enter username: ") 
		    val username = Console.readLine()
		    print("Enter password (WARNING! Password will show up as clear text): ") 
		    val password = Console.readLine()
		    
		   // if (!command.equalsIgnoreCase("start") || !command.equalsIgnoreCase("stop")){
		   //   println("Usage: StartGeometryService <START | STOP> <hostname> <port> <username> <password>")
		   //   sys.exit()
		   // }
		      

		    // Http Request
            val http = new Http

		
		    // Request a TOKEN...
		    val u = url("http://" + host + ":" + port + "/arcgis/admin/generateToken") << Map("f" -> "pjson","username" -> username.toString, "password" -> password.toString,"client" -> "requestip" , "expiration" -> "1000")
		    val token = http(u ># {json => (json \\ "token").values})


		    // Use the token to make a call to the Geometry Service to START or STOP (STOP, in this case)
		    val geomStartURL = url("http://" + host + ":" + port + 			"/arcgis/admin/services/Utilities/Geometry.GeometryServer/" + command) << Map("f" -> "pjson", "token" -> token.toString)
		    val response = http(geomStartURL ># {json => json})
	
		    println(response)

		}catch{
             case e: Exception => println(e.getMessage)
        }
		
	}

}
9/15/2013