Create service with network capabilities

1124
5
Jump to solution
12-10-2013 03:39 AM
TobiasLitherland1
New Contributor II
Hi,

I need to create a Python script that automatically publishes services with network capabilities. To do this, I use the function arcpy.mapping.CreateMapSDDraft to create a draft from an MXD. The mxd contains network layers, and the service needs to be capable of network analysis, so I need to activate the Network Analysis capability before publishing the service.

What I can't fathom is how to add network capabilities to the service. I see all the examples of how to add KmlServer and WMSServer and Feature Access and what not, but I can't understand which variables need to be set to what for the network capabilitiy, and I can't find any documentation for it.

I also tried checking the differences between the XML code in sddraft files for two different ArcMap-created drafts (one with network, one without), but I was none the wiser. There was just too much code.

Please help, if you can!

Tobias
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
DennisJarrard
Esri Contributor
Hey Tobias,

Even though the samples don't use the Network Analysis Service capability, the exact same concept applies. You basically just change the soe value to 'NAServer'. The code essentially parses the XML in the draft and sets the "enabled" value for the Network Analysis SOE from "false" to "true".

The following code allowed me to publish a completely functional NA service from an MXD that I have. I used the sample from the Sample 3 in the Help documentation from the CreateMapSDDraft help to build this.

import arcpy, os import xml.dom.minidom as DOM  print "Establishing environment" workspace = r"C:\temp\enableNA" mxd = arcpy.mapping.MapDocument(os.path.join(workspace,"enablenatest.mxd")) svrconnection = os.path.join(workspace, "svrconnection.ags") outsddraft = os.path.join(workspace,"service.sddraft") draftfinal = os.path.join(workspace,"draftfinal.sddraft") outsd = os.path.join(workspace,"naservice.sd")  print "Creating initial draft" arcpy.mapping.CreateMapSDDraft(mxd, outsddraft, "PythonNaTest","ARCGIS_SERVER",svrconnection) soe = 'NAServer'  print "Enabling Network Analysis in the draft" # Read the sddraft xml. doc = DOM.parse(outsddraft) # Find all elements named TypeName. This is where the server object extension (SOE) names are defined. typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames:     # Get the TypeName whose properties we want to modify.     if typeName.firstChild.data == soe:         extension = typeName.parentNode         for extElement in extension.childNodes:             # Enabled SOE.             if extElement.tagName == 'Enabled':                 extElement.firstChild.data = 'true'                                          # Output to a new sddraft. f = open(draftfinal, 'w')      doc.writexml( f )      f.close()  print "Staging Service" arcpy.StageService_server(draftfinal, outsd)  print "Publishing to Server" arcpy.UploadServiceDefinition_server(outsd,svrconnection,"PythonNATest")

View solution in original post

5 Replies
DennisJarrard
Esri Contributor
Hey Tobias,

Even though the samples don't use the Network Analysis Service capability, the exact same concept applies. You basically just change the soe value to 'NAServer'. The code essentially parses the XML in the draft and sets the "enabled" value for the Network Analysis SOE from "false" to "true".

The following code allowed me to publish a completely functional NA service from an MXD that I have. I used the sample from the Sample 3 in the Help documentation from the CreateMapSDDraft help to build this.

import arcpy, os import xml.dom.minidom as DOM  print "Establishing environment" workspace = r"C:\temp\enableNA" mxd = arcpy.mapping.MapDocument(os.path.join(workspace,"enablenatest.mxd")) svrconnection = os.path.join(workspace, "svrconnection.ags") outsddraft = os.path.join(workspace,"service.sddraft") draftfinal = os.path.join(workspace,"draftfinal.sddraft") outsd = os.path.join(workspace,"naservice.sd")  print "Creating initial draft" arcpy.mapping.CreateMapSDDraft(mxd, outsddraft, "PythonNaTest","ARCGIS_SERVER",svrconnection) soe = 'NAServer'  print "Enabling Network Analysis in the draft" # Read the sddraft xml. doc = DOM.parse(outsddraft) # Find all elements named TypeName. This is where the server object extension (SOE) names are defined. typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames:     # Get the TypeName whose properties we want to modify.     if typeName.firstChild.data == soe:         extension = typeName.parentNode         for extElement in extension.childNodes:             # Enabled SOE.             if extElement.tagName == 'Enabled':                 extElement.firstChild.data = 'true'                                          # Output to a new sddraft. f = open(draftfinal, 'w')      doc.writexml( f )      f.close()  print "Staging Service" arcpy.StageService_server(draftfinal, outsd)  print "Publishing to Server" arcpy.UploadServiceDefinition_server(outsd,svrconnection,"PythonNATest")
SanghongYoo1
New Contributor II

I am trying to accomplish same thing like OP but I am getting an error after analyzing the modified sddraft file. I checked the modified sddraft and it is updated to "true". I can publish the mxd file using ArcMap with NA on. The error message is:

----ERRORS---
The Network Analyst extension needed for layer "Route" is not enabled (CODE 146)
applies to: Route

Dennis Jarrard, any help any help would be appreciated.

# https://enterprise.arcgis.com/en/server/10.4/administer/windows/example-publish-a-map-service-from-a-map-document-mxd-.htm
# https://community.esri.com/thread/179472
# http://desktop.arcgis.com/en/arcmap/10.4/analyze/arcpy-mapping/createmapsddraft.htm
# https://community.esri.com/thread/85441


# A connection to ArcGIS Server must be established in the
#  Catalog window of ArcMap before running this script
import arcpy
import os
import urllib, urllib2
import httplib
import json
import sys
import xml.dom.minidom as DOM

# A function to generate a token given username, password and the adminURL.
def getToken():
    # Token URL is typically http://server[:port]/arcgis/admin/generateToken
    tokenURL = "/arcgis/admin/generateToken"

    params = urllib.urlencode({
        'username': portalAdminName,
        'password': portalAdminPassword,
        '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()

    # Extract the token from it
    token = json.loads(data)

    return token.get('token')


if len(sys.argv[1:]) != 9:
    print len(sys.argv[1:])
    print ("Parameters are missing or too many, check your parameters.")
    sys.exit(2)
else:
     mxd = sys.argv[1]
     severadmurl = sys.argv[2]
     portalAdminName = sys.argv[3]
     portalAdminPassword = sys.argv[4]
     serverName = sys.argv[5]
     con = sys.argv[6]
     severfolder = sys.argv[7]
     maxRecordCount = sys.argv[8]
     schemaLockingEnabled = sys.argv[9]
     serverPort = 6080

# Define local variables
wrkspc = os.path.dirname(mxd)
arcpy.env.workspace = wrkspc
arcpy.env.overwriteOutput = True

# Generate Token
token = getToken()


print " \nProcessing {}".format(os.path.basename(mxd))
mapDoc = arcpy.mapping.MapDocument(mxd)

# Provide other service details
service = os.path.basename(mxd).split(".")[0] # service name
sddraft = wrkspc + "\\" + service + '.sddraft'
draftfinal = wrkspc + "\\" + service + 'draft.sddraft'
sd = wrkspc + "\\" + service + '.sd'
summary = mapDoc.description
tags = mapDoc.tags

# Create service definition draft
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER', con, True, severfolder, summary, tags)

naserver = 'NAServer'
print "Enabling Network Analysis in the draft"
doc = DOM.parse(sddraft)
# Find all elements named TypeName. This is where the server object extension (SOE) names are defined.
typeNames = doc.getElementsByTagName('TypeName')
for typeName in typeNames:
    # Get the TypeName whose properties we want to modify.
    if typeName.firstChild.data == naserver:
        extension = typeName.parentNode
        for extElement in extension.childNodes:
            # Enabled SOE.
            if extElement.tagName == 'Enabled':
                extElement.firstChild.data = 'true'

# Output to a new sddraft.
f = open(draftfinal, 'w')
doc.writexml(f)
f.close()

# Analyze the service definition draft
analysis = arcpy.mapping.AnalyzeForSD(draftfinal)

# Print errors, warnings, and messages returned from the analysis
print "The following information was returned during analysis of the MXD:"
for key in ('messages', 'warnings', 'errors'):
  print '----' + key.upper() + '---'
  vars = analysis[key]
  for ((message, code), layerlist) in vars.iteritems():
    print '    ', message, ' (CODE %i)' % code
    print '       applies to:',
    for layer in layerlist:
        print layer.name,
    print
print " "

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
TobiasLitherland1
New Contributor II
Thank you, djarrard! That solved it.

I figured it was the exact same code as for the other capabilities, but i was not able to find the name of the soe for Network Analysis. Ideally the documentation for CreateMapSDDraft could state all the different soe-tags so that it is possible to know where to start when attempting to enable a specific capability.
0 Kudos
DennisJarrard
Esri Contributor
All of the standard capability definitions are actually automatically added to sddraft, they just aren't all enabled by default. The easiest way to find the one you're looking for is to search for the <TypeName> tag. Just for everyone's information, this is how each service type is referenced in the sddraft files.

MapServer
WCSServer
WMSServer
FeatureServer
SchematicsServer
MobileServer
NAServer
KmlServer
WFSServer
BAServer

Cheers!
0 Kudos
TobiasLitherland1
New Contributor II
Thank you, that's perfect! 😃
0 Kudos