您可能希望在初次发布服务时对服务属性进行精细控制。可以通过使用 JavaScript 对象表示法 (JSON) 在文本文件中列出服务参数来实现此操作。然后,调用 ArcGIS REST API 中的 createService 方法并传入从文件读取的 JSON。
对于地图服务,必须在 JSON 中指定地图服务定义 (MSD) 文件。此文件以 ArcGIS Server 能够理解和绘制的格式合成您的 ArcMap 文档 (MXD) 的信息。在继续创建服务之前,必须使用 arcpy.mapping 模块分析地图并创建 MSD。本部分要求计算机具有 ArcGIS 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": []}
以下代码显示了发布服务时如何在 Python 脚本中引用此 JSON 文件的内容。
# 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 = 6443 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:]))