No JSON object could be decoded - StartStopServices.py

5687
12
10-11-2016 03:31 AM
DilsonKitoko
New Contributor III

I'm trying to run a python scrtipt to stop services, but I'm getting the following error message : "No JSON object could be decoded" . My server uses https protocol thru port 6443. I'm using the file "StartStopServices.py" available at following path: https://github.com/WestonSF/ArcGISAdminToolkit/commit/a183df77441956e515105b2b166b11eb4e525873

#-------------------------------------------------------------
# Name:       Start or Stop Services
# Purpose:    Starts or stops GIS services. Can start/stop all GIS services for an ArcGIS server site or just the ones
#             that are specified.
# Author:     Shaun Weston (shaun_weston@eagle.co.nz)
# Date Created:    07/10/2014
# Last Updated:    06/11/2014
# Copyright:   (c) Eagle Technology
# ArcGIS Version:   10.1+
# Python Version:   2.7
#--------------------------------

# Import modules
import os
import sys
import logging
import smtplib
import arcpy
import httplib
import json
import urllib
import urllib2
import urlparse


# Enable data to be overwritten
arcpy.env.overwriteOutput = True

# Set global variables
enableLogging = "false" # Use logger.info("Example..."), logger.warning("Example..."), logger.error("Example...")
logFile = "" # os.path.join(os.path.dirname(__file__), "Example.log")
sendErrorEmail = "false"
emailTo = ""
emailUser = ""
emailPassword = ""
emailSubject = ""
emailMessage = ""
output = None

# Start of main function
def mainFunction(agsServerSite,username,password,startStop,allServices,userServices): # Get parameters from ArcGIS Desktop tool by seperating by comma e.g. (var1 is 1st parameter,var2 is 2nd parameter,var3 is 3rd parameter)  
    try:
        # Logging
        if (enableLogging == "true"):
            # Setup logging
            logger, logMessage = setLogging(logFile)
            # Log start of process
            logger.info("Process started.")
            
        # --------------------------------------- Start of code --------------------------------------- #


        # Get the server site details
        protocol, serverName, serverPort, context = splitSiteURL(agsServerSite)



        # If any of the variables are blank
        if (serverName == None or serverPort == None or protocol == None or context == None):
            return -1


        # Add on slash to context if necessary
        if not context.endswith('/'):
            context += '/'


        # Add on admin to context if necessary   
        if not context.endswith('admin/'):
            context += 'admin/'
            
        # Get token
        token = getToken(username, password, serverName, serverPort)


        # If token received
        if (token != -1):
            services = []    
            folder = ''



            # If task is for all services
            if (allServices == "true"):                
                # Query the root level for services            
                url = "http://{}:{}/arcgis/admin/services{}?f=pjson&token={}".format(serverName, serverPort, folder, token)   


                # Make the request 
                try:
                    serviceList = json.loads(urllib2.urlopen(url).read())
                except urllib2.URLError, error:
                    arcpy.AddError(error)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error(error)                    
                    sys.exit()


                # Add the services at the root level
                for single in serviceList["services"]:
                    services.append(single['serviceName'] + '.' + single['type'])
                    
                # Build up list of folders and remove the System and Utilities folder
                folderList = serviceList["folders"]
                folderList.remove("Utilities")             
                folderList.remove("System")


                # If there is any folders
                if len(folderList) > 0:
                    # For each folder in the list
                    for folder in folderList:
                        # Query the folder for map services
                        URL = "http://{}:{}/arcgis/admin/services/{}?f=pjson&token={}".format(serverName, serverPort, folder, token)    
                        fList = json.loads(urllib2.urlopen(URL).read())
                        
                        for single in fList["services"]:
                            # Add the services found to the list
                            services.append(folder + "/" + single['serviceName'] + '.' + single['type'])
            # Just for the user defined list of services
            else:
                services = userServices.split(",")
                
            # For each of the services
            for service in services:
                # Start or stop the map service
                op_service_url = "http://{}:{}/arcgis/admin/services/{}/{}?token={}&f=json".format(serverName, serverPort, service, startStop, token)
                status = urllib2.urlopen(op_service_url, ' ').read()


                # If successfully started/stopped                    
                if 'success' in status:
                    arcpy.AddMessage(startStop + " successfully performed on " + service)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error(startStop + " successfully performed on " + service)
                # If there is an error
                else: 
                    arcpy.AddError("Failed to perform operation. Returned message from the server:")
                    arcpy.AddError(status)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error("Failed to perform operation. Returned message from the server:")
                        logger.error(status)

        
        # --------------------------------------- End of code --------------------------------------- #  
            
        # If called from gp tool return the arcpy parameter   
        if __name__ == '__main__':
            # Return the output if there is any
            if output:
                arcpy.SetParameterAsText(1, output)
        # Otherwise return the result          
        else:
            # Return the output if there is any
            if output:
                return output      
        # Logging
        if (enableLogging == "true"):
            # Log end of process
            logger.info("Process ended.")
            # Remove file handler and close log file            
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        pass
    # If arcpy error
    except arcpy.ExecuteError:           
        # Build and show the error message
        errorMessage = arcpy.GetMessages(2)   
        arcpy.AddError(errorMessage)           
        # Logging
        if (enableLogging == "true"):
            # Log error          
            logger.error(errorMessage)                 
            # Remove file handler and close log file
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        if (sendErrorEmail == "true"):
            # Send email
            sendEmail(errorMessage)
    # If python error
    except Exception as e:
        errorMessage = ""
        # Build and show the error message
        for i in range(len(e.args)):
            if (i == 0):
                errorMessage = unicode(e.args[i]).encode('utf-8')
            else:
                errorMessage = errorMessage + " " + unicode(e.args[i]).encode('utf-8')
        arcpy.AddError(errorMessage)              
        # Logging
        if (enableLogging == "true"):
            # Log error            
            logger.error(errorMessage)               
            # Remove file handler and close log file
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        if (sendErrorEmail == "true"):
            # Send email
            sendEmail(errorMessage)            
# End of main function


# Start of get token function
def getToken(username, password, serverName, serverPort):
    
    query_dict = {'username':   username,
                  'password':   password,
                  'expiration': "60",
                  'client':     'requestip'}
    
    query_string = urllib.urlencode(query_dict)
    url = "http://{}:{}/arcgis/admin/generateToken?f=json".format(serverName, serverPort)
   
    try:
        token = json.loads(urllib2.urlopen(url, query_string).read())
        if "token" not in token or token == None:
            arcpy.AddError("Failed to get token, return message from server:")
            arcpy.AddError(token['messages'])            
            # Logging
            if (enableLogging == "true"):   
                logger.error("Failed to get token, return message from server:")
                logger.error(token['messages'])                
            sys.exit()
        else:
            # Return the token to the function which called for it
            return token['token']
    
    except urllib2.URLError, error:
        arcpy.AddError("Could not connect to machine {} on port {}".format(serverName, serverPort))
        arcpy.AddError(error)
        # Logging
        if (enableLogging == "true"):   
            logger.error("Could not connect to machine {} on port {}".format(serverName, serverPort))
            logger.error(error)         
        sys.exit()
# End of get token function


# Start of HTTP POST request to the server function
def postToServer(serverName, serverPort, protocol, url, params):
    # If on standard port
        if (serverPort == -1 and protocol == 'http'):
            serverPort = 80
            
    # If on secure port
        if (serverPort == -1 and protocol == 'https'):
            serverPort = 6443
            
        if (protocol == 'http'):
            httpConn = httplib.HTTPConnection(serverName, int(serverPort))




        if (protocol == 'https'):
            httpConn = httplib.HTTPSConnection(serverName, int(serverPort))




        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain",'referer':'backuputility','referrer':'backuputility'}



    # URL encode the resource URL
        url = urllib.quote(url.encode('utf-8'))




    # Build the connection to add the roles to the server
        httpConn.request("POST", url, params, headers)




        response = httpConn.getresponse()
        data = response.read()




        httpConn.close()





        # Return response
        return (response, data)
# End of HTTP POST request to the server function 
        
            
# Start of split URL function 
def splitSiteURL(siteURL):
    try:
        serverName = ''
        serverPort = -1
        protocol = 'http'
        context = '/arcgis'
        # Split up the URL provided
        urllist = urlparse.urlsplit(siteURL)
        # Put the URL list into a dictionary
        d = urllist._asdict()




        # Get the server name and port
        serverNameAndPort = d['netloc'].split(":")




        # User did not enter the port number, so we return -1
        if (len(serverNameAndPort) == 1):
            serverName = serverNameAndPort[0]
        else:
            if (len(serverNameAndPort) == 2):
                serverName = serverNameAndPort[0]
                serverPort = serverNameAndPort[1]




        # Get protocol
        if (d['scheme'] is not ''):
            protocol = d['scheme']




        # Get path
        if (d['path'] is not '/' and d['path'] is not ''):
            context = d['path']




        # Return variables
        return protocol, serverName, serverPort, context  
    except:
        arcpy.AddError("The ArcGIS Server site URL should be in the format http(s)://<host>:<port>/arcgis")
        # Logging
        if (enableLogging == "true"):      
            logger.error("The ArcGIS Server site URL should be in the format http(s)://<host>:<port>/arcgis")
            sys.exit()
        return None, None, None, None
# End of split URL function


# Start of status check JSON object function


def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        if ('messages' in obj):
            errMsgs = obj['messages']
            for errMsg in errMsgs:


                arcpy.AddError(errMsg)



                # Logging
                        
                if (enableLogging == "true"):


                    logger.error(errMsg)
                    
            sys.exit()
            
        return False
        
    else:
            
        return True
                 
# End of status check JSON object function



# Start of set logging function
def setLogging(logFile):
    # Create a logger
    logger = logging.getLogger(os.path.basename(__file__))
    logger.setLevel(logging.DEBUG)
    # Setup log message handler
    logMessage = logging.FileHandler(logFile)
    # Setup the log formatting
    logFormat = logging.Formatter("%(asctime)s: %(levelname)s - %(message)s", "%d/%m/%Y - %H:%M:%S")
    # Add formatter to log message handler
    logMessage.setFormatter(logFormat)
    # Add log message handler to logger
    logger.addHandler(logMessage)


    return logger, logMessage               
# End of set logging function


# Start of send email function
def sendEmail(message):
    # Send an email
    arcpy.AddMessage("Sending email...")
    # Server and port information
    smtpServer = smtplib.SMTP("smtp.gmail.com",587) 
    smtpServer.ehlo()
    smtpServer.starttls() 
    smtpServer.ehlo
    # Login with sender email address and password
    smtpServer.login(emailUser, emailPassword)
    # Email content
    header = 'To:' + emailTo + '\n' + 'From: ' + emailUser + '\n' + 'Subject:' + emailSubject + '\n'
    body = header + '\n' + emailMessage + '\n' + '\n' + message
    # Send the email and close the connection
    smtpServer.sendmail(emailUser, emailTo, body)    
# End of send email function


# This test allows the script to be used from the operating
# system command prompt (stand-alone), in a Python IDE, 
# as a geoprocessing script tool, or as a module imported in
# another script
if __name__ == '__main__':
    # Arguments are optional - If running from ArcGIS Desktop tool, parameters will be loaded into *argv
    argv = tuple(arcpy.GetParameterAsText(i)
        for i in range(arcpy.GetArgumentCount()))
    mainFunction(*argv)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍


   

Tags (1)
0 Kudos
12 Replies
JonathanQuinn
Esri Notable Contributor

It looks like the script gets information about the input Server on line 54:

  protocol, serverName, serverPort, context = splitSiteURL(agsServerSite)

But then it's hardcoding the http protocol when retrieving the token on line 215:

url = "http://{}:{}/arcgis/admin/generateToken?f=json".format(serverName, serverPort)

.  If the server site entered is using https and 6443, then that is going to be a problem.  The script should really take the protocol as well instead of hardcoding http.

DilsonKitoko
New Contributor III

Hi Jonathan,

From the line 242 to 294 there is addition to the script to allow secured servers. Do you have any suggestion to overcome this hardcoding issue?

I will try to change this line.

Thank you!

DK

0 Kudos
JonathanQuinn
Esri Notable Contributor

It doesn't seem like you're using that function to submit any requests.  I'd try to replace any hardcoded protocols, (seems like it's http throughout), with the protocol derived from the splitSiteURL function:

Ex.

url = "{}://{}:{}/arcgis/admin/generateToken?f=json".format(protocol,serverName, serverPort)
0 Kudos
DilsonKitoko
New Contributor III

Hi Jonathan,

After applying your suggested modifications, it's works. Thank you very much, find below the code that is working for me:

#-------------------------------------------------------------
# Name:       Start or Stop Services
# Purpose:    Starts or stops GIS services. Can start/stop all GIS services for an ArcGIS server site or just the ones
#             that are specified.
# Author:     Shaun Weston (shaun_weston@eagle.co.nz)
# Date Created:    07/10/2014
# Last Updated:    06/11/2014
# Copyright:   (c) Eagle Technology
# ArcGIS Version:   10.1+
# Python Version:   2.7
#--------------------------------

# Import modules
import os
import sys
import logging
import smtplib
import arcpy
import httplib
import json
import urllib
import urllib2
import urlparse
import socket

# Enable data to be overwritten
arcpy.env.overwriteOutput = True

# Set global variables
enableLogging = "false" # Use logger.info("Example..."), logger.warning("Example..."), logger.error("Example...")
logFile = "" # os.path.join(os.path.dirname(__file__), "Example.log")
sendErrorEmail = "false"
emailTo = ""
emailUser = ""
emailPassword = ""
emailSubject = ""
emailMessage = ""
output = None
protocol = "https"
# Start of main function
def mainFunction(agsServerSite,username,password,startStop,allServices,userServices): # Get parameters from ArcGIS Desktop tool by seperating by comma e.g. (var1 is 1st parameter,var2 is 2nd parameter,var3 is 3rd parameter)  
    try:
        # Logging
        if (enableLogging == "true"):
            # Setup logging
            logger, logMessage = setLogging(logFile)
            # Log start of process
            logger.info("Process started.")
            
        # --------------------------------------- Start of code --------------------------------------- #

        # Get the server site details
        protocol, serverName, serverPort, context = splitSiteURL(agsServerSite)

        # If any of the variables are blank
        if (serverName == None or serverPort == None or protocol == None or context == None):
            return -1

        # Add on slash to context if necessary
        if not context.endswith('/'):
            context += '/'

        # Add on admin to context if necessary   
        if not context.endswith('admin/'):
            context += 'admin/'
            
        # Get token
        token = getToken(username, password, serverName, serverPort)

        # If token received
        if (token != -1):
            services = []    
            folder = ''

            # If task is for all services
            if (allServices == "true"):                
                # Query the root level for services            
                url = "{}://{}:{}/arcgis/admin/services{}?f=pjson&token={}".format(protocol,serverName, serverPort, folder, token)    

                # Make the request 
                try:
                    serviceList = json.loads(urllib2.urlopen(url).read())
                except urllib2.URLError, error:
                    arcpy.AddError(error)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error(error)                    
                    sys.exit()

                # Add the services at the root level
                for single in serviceList["services"]:
                    services.append(single['serviceName'] + '.' + single['type'])
                    
                # Build up list of folders and remove the System and Utilities folder
                folderList = serviceList["folders"]
                folderList.remove("Utilities")             
                folderList.remove("System")

                # If there is any folders
                if len(folderList) > 0:
                    # For each folder in the list
                    for folder in folderList:
                        # Query the folder for map services
                        URL = "{}://{}:{}/arcgis/admin/services/{}?f=pjson&token={}".format(protocol,serverName, serverPort, folder, token)    
                        fList = json.loads(urllib2.urlopen(URL).read())
                        
                        for single in fList["services"]:
                            # Add the services found to the list
                            services.append(folder + "/" + single['serviceName'] + '.' + single['type'])
            # Just for the user defined list of services
            else:
                services = userServices.split(",")
                
            # For each of the services
            for service in services:
                # Start or stop the map service
                op_service_url = "{}://{}:{}/arcgis/admin/services/{}/{}?token={}&f=json".format(protocol,serverName, serverPort, service, startStop, token)
                status = urllib2.urlopen(op_service_url, ' ').read()

                # If successfully started/stopped                    
                if 'success' in status:
                    arcpy.AddMessage(startStop + " successfully performed on " + service)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error(startStop + " successfully performed on " + service)
                # If there is an error
                else: 
                    arcpy.AddError("Failed to perform operation. Returned message from the server:")
                    arcpy.AddError(status)
                    # Logging
                    if (enableLogging == "true"):
                        logger.error("Failed to perform operation. Returned message from the server:")
                        logger.error(status) 

        
        # --------------------------------------- End of code --------------------------------------- #  
            
        # If called from gp tool return the arcpy parameter   
        if __name__ == '__main__':
            # Return the output if there is any
            if output:
                arcpy.SetParameterAsText(1, output)
        # Otherwise return the result          
        else:
            # Return the output if there is any
            if output:
                return output      
        # Logging
        if (enableLogging == "true"):
            # Log end of process
            logger.info("Process ended.")
            # Remove file handler and close log file            
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        pass
    # If arcpy error
    except arcpy.ExecuteError:           
        # Build and show the error message
        errorMessage = arcpy.GetMessages(2)   
        arcpy.AddError(errorMessage)           
        # Logging
        if (enableLogging == "true"):
            # Log error          
            logger.error(errorMessage)                 
            # Remove file handler and close log file
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        if (sendErrorEmail == "true"):
            # Send email
            sendEmail(errorMessage)
    # If python error
    except Exception as e:
        errorMessage = ""
        # Build and show the error message
        for i in range(len(e.args)):
            if (i == 0):
                errorMessage = unicode(e.args[i]).encode('utf-8')
            else:
                errorMessage = errorMessage + " " + unicode(e.args[i]).encode('utf-8')
        arcpy.AddError(errorMessage)              
        # Logging
        if (enableLogging == "true"):
            # Log error            
            logger.error(errorMessage)               
            # Remove file handler and close log file
            logging.FileHandler.close(logMessage)
            logger.removeHandler(logMessage)
        if (sendErrorEmail == "true"):
            # Send email
            sendEmail(errorMessage)            
# End of main function


# Start of get token function
def getToken(username, password, serverName, serverPort):
    
    query_dict = {'username':   username,
                  'password':   password,
                  'expiration': "60",
                  'client':     'requestip'}
    
    query_string = urllib.urlencode(query_dict)
    url = "{}://{}:{}/arcgis/admin/generateToken?f=json".format(protocol,serverName, serverPort)
   
    try:
        token = json.loads(urllib2.urlopen(url, query_string).read())
        if "token" not in token or token == None:
            arcpy.AddError("Failed to get token, return message from server:")
            arcpy.AddError(token['messages'])            
            # Logging
            if (enableLogging == "true"):   
                logger.error("Failed to get token, return message from server:")
                logger.error(token['messages'])                
            sys.exit()
        else:
            # Return the token to the function which called for it
            return token['token']
    
    except urllib2.URLError, error:
        arcpy.AddError("Could not connect to machine {} on port {}".format(protocol,serverName, serverPort))
        arcpy.AddError(error)
        # Logging
        if (enableLogging == "true"):   
            logger.error("Could not connect to machine {} on port {}".format(protocol,serverName, serverPort))
            logger.error(error)         
        sys.exit()
# End of get token function

# Start of HTTP POST request to the server function
def postToServer(serverName, serverPort, protocol, url, params):
    # If on standard port
        if (serverPort == -1 and protocol == 'http'):
            serverPort = 80
            
    # If on secure port
        if (serverPort == -1 and protocol == 'https'):
            serverPort = 6443
            
        if (protocol == 'http'):
            httpConn = httplib.HTTPConnection(serverName, int(serverPort))

        if (protocol == 'https'):
            httpConn = httplib.HTTPSConnection(serverName, int(serverPort))

        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain",'referer':'backuputility','referrer':'backuputility'}

    # URL encode the resource URL
        url = urllib.quote(url.encode('utf-8'))

    # Build the connection to add the roles to the server
        httpConn.request("POST", url, params, headers)

        response = httpConn.getresponse()
        data = response.read()

        httpConn.close()


        # Return response
        return (response, data)
# End of HTTP POST request to the server function 
        
            
# Start of split URL function 
def splitSiteURL(siteURL):
    try:
        serverName = ''
        serverPort = -1
        protocol = 'http'
        context = '/arcgis'
        # Split up the URL provided
        urllist = urlparse.urlsplit(siteURL)
        # Put the URL list into a dictionary
        d = urllist._asdict()

        # Get the server name and port
        serverNameAndPort = d['netloc'].split(":")

        # User did not enter the port number, so we return -1
        if (len(serverNameAndPort) == 1):
            serverName = serverNameAndPort[0]
        else:
            if (len(serverNameAndPort) == 2):
                serverName = serverNameAndPort[0]
                serverPort = serverNameAndPort[1]

        # Get protocol
        if (d['scheme'] is not ''):
            protocol = d['scheme']

        # Get path
        if (d['path'] is not '/' and d['path'] is not ''):
            context = d['path']

        # Return variables
        return protocol, serverName, serverPort, context  
    except:
        arcpy.AddError("The ArcGIS Server site URL should be in the format http(s)://<host>:<port>/arcgis")
        # Logging
        if (enableLogging == "true"):      
            logger.error("The ArcGIS Server site URL should be in the format http(s)://<host>:<port>/arcgis")
            sys.exit()
        return None, None, None, None
# End of split URL function


# Start of status check JSON object function

def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        if ('messages' in obj):
            errMsgs = obj['messages']
            for errMsg in errMsgs:

                arcpy.AddError(errMsg)

                # Logging
                        
                if (enableLogging == "true"):

                    logger.error(errMsg)
                    
            sys.exit()
            
        return False
        
    else:
            
        return True
                 
# End of status check JSON object function

# Start of set logging function
def setLogging(logFile):
    # Create a logger
    logger = logging.getLogger(os.path.basename(__file__))
    logger.setLevel(logging.DEBUG)
    # Setup log message handler
    logMessage = logging.FileHandler(logFile)
    # Setup the log formatting
    logFormat = logging.Formatter("%(asctime)s: %(levelname)s - %(message)s", "%d/%m/%Y - %H:%M:%S")
    # Add formatter to log message handler
    logMessage.setFormatter(logFormat)
    # Add log message handler to logger
    logger.addHandler(logMessage) 

    return logger, logMessage               
# End of set logging function


# Start of send email function
def sendEmail(message):
    # Send an email
    arcpy.AddMessage("Sending email...")
    # Server and port information
    smtpServer = smtplib.SMTP("smtp.gmail.com",587) 
    smtpServer.ehlo()
    smtpServer.starttls() 
    smtpServer.ehlo
    # Login with sender email address and password
    smtpServer.login(emailUser, emailPassword)
    # Email content
    header = 'To:' + emailTo + '\n' + 'From: ' + emailUser + '\n' + 'Subject:' + emailSubject + '\n'
    body = header + '\n' + emailMessage + '\n' + '\n' + message
    # Send the email and close the connection
    smtpServer.sendmail(emailUser, emailTo, body)    
# End of send email function


# This test allows the script to be used from the operating
# system command prompt (stand-alone), in a Python IDE, 
# as a geoprocessing script tool, or as a module imported in
# another script
if __name__ == '__main__':
    # Arguments are optional - If running from ArcGIS Desktop tool, parameters will be loaded into *argv
    argv = tuple(arcpy.GetParameterAsText(i)
        for i in range(arcpy.GetArgumentCount()))
    mainFunction(*argv)
    
0 Kudos
CraigPrisland2
New Contributor III

Hi all,

I'm running into a similar issue where I have the following script which stops a particular service.  When run I get the same error message: "No JSON object could be decoded".  Any assistance would be appreciated.

Thanks,

# Required imports
import urllib
import urllib2
import json
import contextlib
## context manager to clean up resources when exiting a 'with' block

def main():  ## Entry point into the script
    # Local variables
    ## Authentication
    adminUser = r"xxxxx"
    adminPass = r"xxxxxx"
    ## ArcGIS Server Machine
    server = "cc.xx.xxxx.xx.us"
    port = "6443"
    ## Services ("FolderName/ServiceName.ServiceType")
    svc = "xxxxx/xxxxxx.MapServer"

    try:
        # Get ArcGIS Server token
        expiration = 60  ## Token timeout in minutes; default is 60 minutes.
        token = getToken(adminUser, adminPass, server, port, expiration)

        # Perform action on service
        action = "stop"  ## "start" or "stop"
        jsonOuput = serviceStartStop(server, port, svc, action, token)
        ## Validate JSON object result
        if jsonOuput['status'] == "success":
            print "{} {} successful".format(action.title(), str(svc))
        else:
            print "Failed to {} {}".format(action, str(svc))
            raise Exception(jsonOuput)

    except Exception, err:
        print err


# Function to generate a token from ArcGIS Server; returns token.
## http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000000m5000000.htm
def getToken(adminUser, adminPass, server, port, expiration):
    # Build URL
    url = "https://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)

    # Encode the query string
    query_dict = {
        'username': adminUser,
        'password': adminPass,
        'expiration': str(expiration),
        'client': 'requestip'
    }
    query_string = urllib.urlencode(query_dict)

    try:
        # Request the token
        with contextlib.closing(urllib2.urlopen(url, query_string)) as jsonResponse:
            getTokenResult = json.loads(jsonResponse.read())
            ## Validate result
            if "token" not in getTokenResult or getTokenResult == None:
                raise Exception("Failed to get token: {}".format(getTokenResult['messages']))
            else:
                return getTokenResult['token']

    except urllib2.URLError, e:
        raise Exception("Could not connect to machine {} on port {}\n{}".format(server, port, e))

# Function to start or stop a service on ArcGIS Server; returns JSON response.
## http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000001s6000000.htm
def serviceStartStop(server, port, svc, action, token):
    # Build URL
    url = "https://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)
    requestURL = url + "/services/{}/{}".format(svc, action)

    # Encode the query string
    query_dict = {
        "token": token,
        "f": "json"
    }
    query_string = urllib.urlencode(query_dict)

    # Send the server request and return the JSON response
    with contextlib.closing(urllib.urlopen(requestURL, query_string)) as jsonResponse:
        return json.loads(jsonResponse.read())


if __name__ == '__main__':
    main()
0 Kudos
JonathanQuinn
Esri Notable Contributor

What line is it failing on?  Right before you convert the string to JSON, print the variable that stores the string to make sure it's JSON.  This could happen on either line 56 or 82.

0 Kudos
CraigPrisland2
New Contributor III

It appears that it is failing around line 56 already.

0 Kudos
JonathanQuinn
Esri Notable Contributor

So add print(jsonResponse.read()) after line 55 so you can see what the variable stores, and determine why it's not JSON, (or at least the string representation of JSON).

0 Kudos
CraigPrisland2
New Contributor III

Jonathan,

Thanks for the feedback.  I added this to my script and it outputted a token and expiration but am still getting the error JSON error.

0 Kudos