Skip To Content

Пример: Публикация сервиса с подробными параметрами

Иногда при первоначальной публикации сервиса может потребоваться детальный контроль за свойствами этого сервиса. Это можно обеспечить, перечислив параметры сервиса в текстовом файле в формате JavaScript Object Notation (JSON). Затем нужно вызвать метод createService из ArcGIS REST API и передать в JSON, считанный из файла.

Для картографического сервиса в данных JSON нужно указать файл определения картографического сервиса (MSD). В файле содержатся сводные данные из документа ArcMap (MXD) в формате, поддерживаемом ArcGIS for Server. Перед продолжением создания сервиса с помощью модуля 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": []}

В коде ниже показано, как можно обращаться к содержимому файла 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:]))