Иногда при первоначальной публикации сервиса может потребоваться детальный контроль за свойствами этого сервиса. Это можно обеспечить, перечислив параметры сервиса в текстовом файле в формате JavaScript Object Notation (JSON). Затем нужно вызвать метод createService из ArcGIS REST API и передать в JSON, считанный из файла.
Для картографического сервиса в данных JSON нужно указать файл определения картографического сервиса (MSD). В файле содержатся сводные данные из документа ArcMap (MXD) в формате, поддерживаемом ArcGIS for Server. Перед продолжением создания сервиса с помощью модуля arcpy.mapping нужно проанализировать карту и создать MSD-файл. Для этого требуется, чтобы у компьютера была лицензия ArcGIS for Desktop. Для других типов сервисов использование arcpy.mapping или создание MSD-файла не требуется.
Ниже приводится пример файла JSON. Подробные примеры создания файла JSON для сервисов разных типов см. в справке по ArcGIS REST API.
{ "serviceName": "Beirut", "type": "MapServer", "description": "Service showing Beirut parcels and streets.", "capabilities": "Map,Query,Data", "clusterName": "default", "minInstancesPerNode": 1, "maxInstancesPerNode": 3, "instancesPerContainer": 1, "maxWaitTime": 60, "maxStartupTime": 300, "maxIdleTime": 1800, "maxUsageTime": 600, "loadBalancing": "ROUND_ROBIN", "isolationLevel": "HIGH", "configuredState": "STARTED", "recycleInterval": 24, "recycleStartTime": "00:00", "keepAliveInterval": 1800, "private": false, "isDefault": false, "properties": { "maxBufferCount": "100", "maxImageHeight": "2048", "maxRecordCount": "1000", "filePath": "c:\\data\\Beirut\\Beirut_Parcels.msd", "maxImageWidth": "2048", "enableDynamicLayers": "false", "cacheOnDemand": "false", "dynamicDataWorkspaces": "", "useLocalCacheDir": "true", "outputDir": "c:\\arcgisserver\\directories\\arcgisoutput", "virtualOutputDir": "/rest/directories/arcgisoutput", "supportedImageReturnTypes": "URL", "isCached": "false", "ignoreCache": "false", "clientCachingAllowed": "true", "cacheDir": "" }, "extensions": [], "datasets": []}
В коде ниже показано, как можно обращаться к содержимому файла JSON в скрипте Python при публикации сервиса.
# Demonstrates how to publish a service from a JSON definition file
# An MSD file is required, which is made from the MXD in this script
# For Http calls
import httplib, urllib, json, arcpy, os
# 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 publishes a service using an MXD and JSON definiton."
print
# Ask for admin/publisher user name and password
username = raw_input("Enter user name: ")
password = getpass.getpass("Enter password: ")
# Ask for other necessary information
serverName = raw_input("Enter Server name: ")
serverPort = 6080
mxdPath = raw_input("Enter the path to the MXD: ")
msdPath = raw_input("Enter the desired path for the MSD: ")
jsonPath = raw_input("Enter the path to the JSON file: ")
# Analyze MXD and create MSD file
if not os.path.isfile(mxdPath):
return
if mxdPath.endswith('.mxd'):
mapErrors = analyzeMap(mxdPath)
if len(mapErrors) > 0:
print "Fix map errors before converting to mxd"
return
mxd = arcpy.mapping.MapDocument(mxdPath)
convertMap(mxd, msdPath);
del mxd
else:
print "Invalid file type submitted"
return
# Get a token
token = getToken(username, password, serverName, serverPort)
if token == "":
print "Could not generate a token with the username and password provided."
return
# Read the JSON file for the service
serviceJSON = open(jsonPath).read()
# Construct URL to create a service
# If publishing to a folder, invoke createService on the folder URL
createServiceURL = "/arcgis/admin/services/createService"
# This request needs the token, the JSON defining the service properties,
# and the response format
params = urllib.urlencode({'token': token, 'service':serviceJSON, '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", createServiceURL, params, headers)
# Read response
response = httpConn.getresponse()
if (response.status != 200):
httpConn.close()
print "Error while creating 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 analyze a map document
def analyzeMap(mapPath):
mxd = arcpy.mapping.MapDocument(mapPath)
analysis = arcpy.mapping.AnalyzeForMSD(mxd)
vars = analysis['errors']
for ((message, code), layerlist) in vars.iteritems():
print "Errors: "
print message, " (CODE %i)" % code
print " applies to the following layers:",
for layer in layerlist:
print layer.name,
print
del mxd
return analysis['errors']
# A function to convert a map document to a map service definition (MSD)
def convertMap(mxd, msd):
arcpy.mapping.ConvertToMSD(mxd, msd, "USE_ACTIVE_VIEW", "NORMAL", "NORMAL")
del mxd, msd
# 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:]))