Esempio n. 1
0
    def check_retrieve_status(self, async_process_id):
        """
        After async process is done, post a checkRetrieveStatus to 
        obtain the zipFile(base64)

        @async_process_id: retrieve request asyncProcessId
        """
        server_url = globals()[self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }
        soap_body = soap_bodies.check_retrieve_status_body.format(
            session_id=globals()[self.username]["session_id"],
            async_process_id=async_process_id)

        response = requests.post(server_url, soap_body, verify=False, 
            headers=headers)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(content, "message")
            return result

        result["zipFile"] = getUniqueElementValueFromXmlString(content, "zipFile")

        return result
Esempio n. 2
0
    def retrieve_all(self):
        """
        1. Issue a retrieve request to start the asynchronous retrieval and asyncProcessId is returned
        2. Thread sleep for a while and then issue a checkStatus request to check whether the async 
           process job is completed.
        3. After the job is completed, issue a checkRetrieveStatus request to obtain the zipFile(base64) 
           in the retrieve result.
        4. Use Python Lib base64 to convert the base64 string to zip file.
        5. Use Python Lib zipFile to unzip the zip file to path
        """
        # Firstly Login
        self.login(False)

        # 1. Issue a retrieve request to start the asynchronous retrieval
        server_url = globals()[self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }

        # Populate the soap_body with actual session id
        soap_body = soap_bodies.retrieve_all_task_body.format(
            session_id=globals()[self.username]["session_id"])

        response = requests.post(server_url, soap_body, verify=False, 
            headers=headers)

        # Check whether session_id is expired
        if "INVALID_SESSION_ID" in response.text:
            self.login(True)
            return self.retrieve_all()

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(content, "message")
            self.result = result
            return

        # Get async process id
        async_process_id = getUniqueElementValueFromXmlString(content, "id")
        print ("asyncProcessId: " + async_process_id)

        # 2. issue a check status loop request to assure the async
        # process is done
        result = self.check_status(async_process_id)

        # If check status request failed, this will not be done
        print (result)
        if result["done"] == "Failed":
            self.result = result
            return

        # 3 Obtain zipFile(base64)
        print ("Downloading zipFile in this retrieve result...")
        result = self.check_retrieve_status(async_process_id)
        self.result = result
Esempio n. 3
0
    def check_status(self, async_process_id):
        """
        Ensure the retrieve request is done and then we can continue other work

        @async_process_id: retrieve request asyncProcessId
        """
        # Thread sleep for 10 seconds
        print("Retrieve is in progress, please wait for 30 seconds.")
        time.sleep(30)

        # Check the status of retrieve job
        server_url = globals()[
            self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }
        soap_body = soap_bodies.check_status_body.format(
            session_id=globals()[self.username]["session_id"],
            async_process_id=async_process_id)

        response = requests.post(server_url,
                                 soap_body,
                                 verify=False,
                                 headers=headers)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(
                content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(
                content, "message")
            result["done"] = "Failed"
            return result

        # Get the retrieve status
        done = getUniqueElementValueFromXmlString(content, "done")

        # If retrieve is not done, sleep 10s and check again
        if done == "false":
            return self.check_status(async_process_id)

        # If retrieve is done
        result["done"] = True
        result["state"] = getUniqueElementValueFromXmlString(content, "state")

        return result
Esempio n. 4
0
    def execute_anonymous(self, apex_string):
        """
        Generate a new view to display executed reusult of Apex Snippet

        :apex_string: Apex Snippet
        """
        # Firstly Login
        self.login(False)

        server_url = globals()[self.username]['instance_url'] + "/services/Soap/s/27.0"
        # https://gist.github.com/richardvanhook/1245068
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }

        # If we don't quote <, >, & in body, we will get below exception
        # Element type "String" must be followed by either attribute specifications, ">" or "/>"
        # http://wiki.python.org/moin/EscapingXml
        apex_string = quoteattr(apex_string).replace('"', '')
        soap_body = soap_bodies.execute_anonymous_body.format(
            session_id=globals()[self.username]["session_id"], 
            apex_string = apex_string)

        response = requests.post(server_url, soap_body, verify=False, 
            headers=headers)

        # Check whether session_id is expired
        if "INVALID_SESSION_ID" in response.text:
            self.login(True)
            return self.execute_anonymous(apex_string)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(content, "message")
            self.result = result
            return result
        
        # If execute anonymous succeed, just display message with a new view
        result["debugLog"] = unescape(getUniqueElementValueFromXmlString(content, "debugLog"))
        result["column"] = getUniqueElementValueFromXmlString(content, "column")
        result["compileProblem"] = unescape(getUniqueElementValueFromXmlString(content, "compileProblem"))
        result["compiled"] = getUniqueElementValueFromXmlString(content, "compiled")
        result["line"] = getUniqueElementValueFromXmlString(content, "line")
        result["success"] = getUniqueElementValueFromXmlString(content, "success")
        pprint.pprint (result)

        # Self.result is used to keep thread result
        self.result = result

        # This result is used for invoker
        return result
Esempio n. 5
0
def soap_login(settings, timeout=120):
    login_soap_request_body = soap_bodies.login_body.format(
        username=settings["username"],
        password=settings["password"] + settings["security_token"])

    login_soap_request_headers = {
        'content-type': 'text/xml',
        'charset': 'UTF-8',
        'SOAPAction': 'login'
    }

    response = requests.post(settings["soap_login_url"],
                             login_soap_request_body,
                             verify=False,
                             headers=login_soap_request_headers,
                             timeout=timeout)

    result = {}
    if response.status_code != 200:
        except_code = getUniqueElementValueFromXmlString(
            response.content, 'sf:exceptionCode')
        except_msg = getUniqueElementValueFromXmlString(
            response.content, 'sf:exceptionMessage')
        result["errorCode"] = except_code
        result["message"] = except_msg
        result["status_code"] = response.status_code
        return result

    session_id = getUniqueElementValueFromXmlString(response.content,
                                                    'sessionId')
    server_url = getUniqueElementValueFromXmlString(response.content,
                                                    'serverUrl')
    sf_instance = server_url[:server_url.find('/services')]
    user_id = getUniqueElementValueFromXmlString(response.content, 'userId')

    print("session_id", session_id)
    result = {
        "session_id": session_id,
        "server_url": server_url,
        "instance_url": sf_instance,
        "user_id": user_id,
        "status_code": response.status_code
    }
    return result
Esempio n. 6
0
    def check_status(self, async_process_id):
        """
        Ensure the retrieve request is done and then we can continue other work

        @async_process_id: retrieve request asyncProcessId
        """
        # Thread sleep for 10 seconds
        print ("Retrieve is in progress, please wait for 30 seconds.")
        time.sleep(30)

        # Check the status of retrieve job
        server_url = globals()[self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }
        soap_body = soap_bodies.check_status_body.format(
            session_id=globals()[self.username]["session_id"],
            async_process_id=async_process_id)

        response = requests.post(server_url, soap_body, verify=False, 
            headers=headers)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(content, "message")
            result["done"] = "Failed"
            return result

        # Get the retrieve status
        done = getUniqueElementValueFromXmlString(content, "done")

        # If retrieve is not done, sleep 10s and check again
        if done == "false":
            return self.check_status(async_process_id)

        # If retrieve is done
        result["done"] = True
        result["state"] = getUniqueElementValueFromXmlString(content, "state")

        return result
Esempio n. 7
0
def create_batch(job_id, sobject, sobject_soql):
    url = globals()["instance_url"] +\
        "/services/async/27.0/job/{job_id}/batch".format(job_id = job_id)

    headers = {
        "X-SFDC-Session": access_token,
        "Content-Type": "text/csv; charset=UTF-8"
    }
    
    response = requests.post(url, sobject_soql, verify = False, headers = headers)
    batch_id = getUniqueElementValueFromXmlString(response.content, "id")

    return batch_id
Esempio n. 8
0
def get_batch_result_id(sobject, job_id, batch_id):
    url = globals()["instance_url"] +\
        "/services/async/27.0/job/{job_id}/batch/{batch_id}/result".format(job_id = job_id,
            batch_id = batch_id)

    headers = {
        "X-SFDC-Session": access_token
    }

    response = requests.get(url, data = None, verify = False, headers = headers)
    result_id = getUniqueElementValueFromXmlString(response.content, "result")

    return result_id
Esempio n. 9
0
def soap_login(settings, timeout=120):
    login_soap_request_body = soap_bodies.login_body.format(
        username=settings["username"], password=settings["password"] + settings["security_token"]
    )

    login_soap_request_headers = {"content-type": "text/xml", "charset": "UTF-8", "SOAPAction": "login"}

    response = requests.post(
        settings["soap_login_url"],
        login_soap_request_body,
        verify=False,
        headers=login_soap_request_headers,
        timeout=timeout,
    )

    result = {}
    if response.status_code != 200:
        except_code = getUniqueElementValueFromXmlString(response.content, "sf:exceptionCode")
        except_msg = getUniqueElementValueFromXmlString(response.content, "sf:exceptionMessage")
        result["errorCode"] = except_code
        result["message"] = except_msg
        result["status_code"] = response.status_code
        return result

    session_id = getUniqueElementValueFromXmlString(response.content, "sessionId")
    server_url = getUniqueElementValueFromXmlString(response.content, "serverUrl")
    sf_instance = server_url[: server_url.find("/services")]
    user_id = getUniqueElementValueFromXmlString(response.content, "userId")

    print("session_id", session_id)
    result = {
        "session_id": session_id,
        "server_url": server_url,
        "instance_url": sf_instance,
        "user_id": user_id,
        "status_code": response.status_code,
    }
    return result
Esempio n. 10
0
def check_batch_status(job_id, batch_id, sobject):
    url = globals()["instance_url"] +\
        "/services/async/27.0/job/{job_id}/batch/{batch_id}".format(job_id = job_id,
            batch_id = batch_id)

    headers = {
        "X-SFDC-Session": access_token
    }

    response = requests.get(url, data = None, verify = False, headers = headers)
    batch_status = getUniqueElementValueFromXmlString(response.content, "state")

    if batch_status == "Failed":
        error_message = getUniqueElementValueFromXmlString(response.content, "stateMessage")
        print(batch_id + " failed, because " + error_message)
        return False

    while batch_status != "Completed":
        print(sobject + " is not completed, please continue waiting...")
        time.sleep(15)
        check_batch_status(job_id, batch_id, sobject)

    return True
Esempio n. 11
0
def login(username, password, securityToken, sandbox=False):
    if sandbox:
        soapUrl = "https://test.salesforce.com/services/Soap/u/23.0"
    else:
        soapUrl = "https://login.salesforce.com/services/Soap/u/23.0"

    loginSoapRequestBody = """<?xml version="1.0" encoding="utf-8" ?> 
        <env:Envelope 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
            <env:Body>
                <n1:login xmlns:n1="urn:partner.soap.sforce.com">
                    <n1:username>%s</n1:username>
                    <n1:password>%s%s</n1:password>
                </n1:login>
            </env:Body>
        </env:Envelope>""" % (username, password, securityToken)

    loginSoapRequestHeaders = {
        "content-type":"text/xml",
        "charset":"UTF-8",
        "SOAPAction":"login"
    }
    response = requests.post(soapUrl, loginSoapRequestBody, headers=loginSoapRequestHeaders)

    if response.status_code != 200:
        exception_code = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionCode')
        exception_message = getUniqueElementValueFromXmlString(response.content, 'sf:exceptionMessage')
        raise SalesforceAuthenticationFailedException('%s: %s' % (exception_code, exception_message)) 

    sessionId = getUniqueElementValueFromXmlString(response.content, 'sessionId')
    serverUrl = getUniqueElementValueFromXmlString(response.content, 'serverUrl')
    sfInstance = serverUrl.replace('http://', '').replace('https://', '').split('/')[0].replace('-api', '')

    return (sessionId, sfInstance)
Esempio n. 12
0
    def check_retrieve_status(self, async_process_id):
        """
        After async process is done, post a checkRetrieveStatus to 
        obtain the zipFile(base64)

        @async_process_id: retrieve request asyncProcessId
        """
        server_url = globals()[
            self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }
        soap_body = soap_bodies.check_retrieve_status_body.format(
            session_id=globals()[self.username]["session_id"],
            async_process_id=async_process_id)

        response = requests.post(server_url,
                                 soap_body,
                                 verify=False,
                                 headers=headers)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(
                content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(
                content, "message")
            return result

        result["zipFile"] = getUniqueElementValueFromXmlString(
            content, "zipFile")

        return result
Esempio n. 13
0
def check_job_status(job_id):
    url = globals()["instance_url"] + "/services/async/27.0/job/" + job_id

    headers = {
        "X-SFDC-Session": access_token
    }

    response = requests.get(url, data = None, verify = False, headers = headers)
    job_status = getUniqueElementValueFromXmlString(response.content, "state")

    while job_status != "Completed":
        print(job_id + " is not completed, please continue waiting...")
        time.sleep(15)
        check_job_status(job_id)

    return True
Esempio n. 14
0
def create_job(sobject, operation):
    url = globals()["instance_url"] + "/services/async/27.0/job"
    body = soap_bodies.create_job.format(operation=operation, sobject=sobject)
    headers = {
        "X-SFDC-Session": globals()["access_token"],
        "Content-Type": "application/xml; charset=UTF-8",
        "Accept": "text/plain"
    }

    response = requests.post(url, body, verify = False, headers = headers)
    job_id = getUniqueElementValueFromXmlString(response.content, "id")

    if job_id == None:
        print(sobject + " is not valid sobject, please check.")

    return job_id
Esempio n. 15
0
    def retrieve_all(self):
        """
        1. Issue a retrieve request to start the asynchronous retrieval and asyncProcessId is returned
        2. Thread sleep for a while and then issue a checkStatus request to check whether the async 
           process job is completed.
        3. After the job is completed, issue a checkRetrieveStatus request to obtain the zipFile(base64) 
           in the retrieve result.
        4. Use Python Lib base64 to convert the base64 string to zip file.
        5. Use Python Lib zipFile to unzip the zip file to path
        """
        # Firstly Login
        self.login(False)

        # 1. Issue a retrieve request to start the asynchronous retrieval
        server_url = globals()[
            self.username]['instance_url'] + "/services/Soap/m/28.0"
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }

        # Populate the soap_body with actual session id
        soap_body = soap_bodies.retrieve_sobjects_workflow_task_body.format(
            session_id=globals()[self.username]["session_id"])

        response = requests.post(server_url,
                                 soap_body,
                                 verify=False,
                                 headers=headers)

        # Check whether session_id is expired
        if "INVALID_SESSION_ID" in response.text:
            self.login(True)
            return self.retrieve_all()

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(
                content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(
                content, "message")
            self.result = result
            return

        # Get async process id
        async_process_id = getUniqueElementValueFromXmlString(content, "id")
        print("asyncProcessId: " + async_process_id)

        # 2. issue a check status loop request to assure the async
        # process is done
        result = self.check_status(async_process_id)

        # If check status request failed, this will not be done
        print(result)
        if result["done"] == "Failed":
            self.result = result
            return

        # 3 Obtain zipFile(base64)
        print("Downloading zipFile in this retrieve result...")
        result = self.check_retrieve_status(async_process_id)
        self.result = result
Esempio n. 16
0
    def execute_anonymous(self, apex_string):
        """
        Generate a new view to display executed reusult of Apex Snippet

        :apex_string: Apex Snippet
        """
        # Firstly Login
        self.login(False)

        server_url = globals()[
            self.username]['instance_url'] + "/services/Soap/s/28.0"
        # https://gist.github.com/richardvanhook/1245068
        headers = {
            "Content-Type": "text/xml;charset=UTF-8",
            "SOAPAction": '""'
        }

        # If we don't quote <, >, & in body, we will get below exception
        # Element type "String" must be followed by either attribute specifications, ">" or "/>"
        # http://wiki.python.org/moin/EscapingXml
        apex_string = quoteattr(apex_string).replace('"', '')
        soap_body = soap_bodies.execute_anonymous_body.format(
            session_id=globals()[self.username]["session_id"],
            apex_string=apex_string)

        response = requests.post(server_url,
                                 soap_body,
                                 verify=False,
                                 headers=headers)

        # Check whether session_id is expired
        if "INVALID_SESSION_ID" in response.text:
            self.login(True)
            return self.execute_anonymous(apex_string)

        # If status_code is > 399, which means it has error
        content = response.content
        result = {"status_code": response.status_code}
        if response.status_code > 399:
            result["errorCode"] = getUniqueElementValueFromXmlString(
                content, "errorCode")
            result["message"] = getUniqueElementValueFromXmlString(
                content, "message")
            self.result = result
            return result

        # If execute anonymous succeed, just display message with a new view
        result["debugLog"] = unescape(
            getUniqueElementValueFromXmlString(content, "debugLog"))
        result["column"] = getUniqueElementValueFromXmlString(
            content, "column")
        result["compileProblem"] = unescape(
            getUniqueElementValueFromXmlString(content, "compileProblem"))
        result["compiled"] = getUniqueElementValueFromXmlString(
            content, "compiled")
        result["line"] = getUniqueElementValueFromXmlString(content, "line")
        result["success"] = getUniqueElementValueFromXmlString(
            content, "success")
        pprint.pprint(result)

        # Self.result is used to keep thread result
        self.result = result

        # This result is used for invoker
        return result