スクリプト言語と ArcGIS REST API
ArcGIS REST API は、HTTP を使用して REST ベースの Web サービスを呼び出し、応答を解析することができるスクリプト言語で機能します。これらの言語には、Python、Java、JavaScript、PowerShell、C#、Ruby、Scala、Perl、その他があります。
ArcGIS Server ヘルプの REST 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 REST 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 を使用してジオメトリ サービスを開始します。このスクリプトは常に保護されたログインを試行します(ユーザ名とパスワードを暗号化します)。HTTPS が ArcGIS Server 用に設定されていない場合は、保護されたログインの試行が失敗し、デフォルトでスクリプトは保護されていないログインを試行します。保護されていないログインを試行したくない場合は、保護されたログインを必要とする -e オプションを使用します。
このスクリプトは、すべての Perl ディストリビューションに通常付属している LWP および HTTP ライブラリを使用します。このスクリプトは、スクリプトを実行するシステムに Esri ソフトウェアをインストールしておく必要はありません。
ユーザ独自で使用するためにこのスクリプトを変更する場合は、Utilities フォルダにジオメトリ サービスがあること、他のフォルダを使用するにはスクリプトで使用する 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 for Server Administrator API
// - Dispatch (http://dispatch.databinder.net)
// - LiftJSON
// ...demonstrates how to START or STOP the Geometry Service in an 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)
}
}
}