Ejemplo n.º 1
0
 def get_overlay_actions(self, **kwargs):
     if 'file_path' in kwargs:
         id = kwargs.get('id', None)
         file_path = kwargs.get('file_path', None)
         if id == None:
             ext = mm_util.get_file_extension_no_period(file_path)
             api_name = mm_util.get_file_name_no_extension(file_path)
             mtype = mm_util.get_meta_type_by_suffix(ext)
             id = self.get_apex_entity_id_by_name(
                 object_type=mtype['xmlName'], name=api_name)
         query_string = "Select Id, Line, Iteration, ExpirationDate, IsDumpingHeap from ApexExecutionOverlayAction Where ExecutableEntityId = '{0}'".format(
             id)
         payload = {'q': query_string}
         r = requests.get(self.get_tooling_url() + "/query/",
                          params=payload,
                          headers=self.get_rest_headers(),
                          verify=False)
         return mm_util.parse_rest_response(r.text)
     else:
         query_string = "Select Id, ScopeId, ExecutableEntityId, Line, Iteration, ExpirationDate, IsDumpingHeap from ApexExecutionOverlayAction limit 5000"
         payload = {'q': query_string}
         r = requests.get(self.get_tooling_url() + "/query/",
                          params=payload,
                          headers=self.get_rest_headers(),
                          verify=False)
         return mm_util.parse_rest_response(r.text)
Ejemplo n.º 2
0
    def check_for_conflicts(self, files):
        local_store = self.get_local_store()
        retrieve_result = self.project.get_retrieve_result({"files": files})
        properties = retrieve_result.fileProperties
        for f in files:
            ext = mm_util.get_file_extension_no_period(f)
            apex_type = mm_util.get_meta_type_by_suffix(ext)
            apex_entity_api_name = mm_util.get_file_name_no_extension(f)
            body_field = "Body"
            if apex_type["xmlName"] == "ApexPage" or apex_type["xmlName"] == "ApexComponent":
                body_field = "Markup"
            api_name_plus_extension = apex_entity_api_name + "." + ext

            server_property = None
            for p in properties:
                if p["fullName"] == apex_entity_api_name:
                    server_property = p
            if api_name_plus_extension in local_store and server_property != None:
                local_store_entry = local_store[api_name_plus_extension]
                local_last_modified_date = local_store_entry["lastModifiedDate"]
                server_last_modified_date = server_property["lastModifiedDate"]
                last_modified_name = server_property["lastModifiedByName"]
                qr = self.project.sfdc_client.query(
                    "Select LastModifiedById, LastModifiedDate, LastModifiedBy.Name, {0} From {1} Where Name = '{2}'".format(
                        body_field, apex_type["xmlName"], apex_entity_api_name
                    )
                )
                body = qr["records"][0][body_field]
                body = body.encode("utf-8")
                if (
                    str(local_last_modified_date) != str(server_last_modified_date)
                    or local_store_entry["mmState"] == "dirty"
                ):
                    if local_store_entry["mmState"] != "dirty":
                        local_store_entry["mmState"] = "dirty"
                    msg = mm_util.generate_request_for_action_response(
                        "The local version of your file and the server copy are out of sync.\n\n{0} was last modified by {1} on {2}.".format(
                            apex_entity_api_name, last_modified_name, server_last_modified_date
                        ),
                        "compile",
                        ["Diff With Server", "Operation Canceled"],
                        tmp_file_path=mm_util.put_tmp_file_on_disk(
                            apex_entity_api_name, body, apex_type.get("suffix", "")
                        ),
                    )
                    self.mark_dirty(api_name_plus_extension)
                    return True, msg
        return False, None
Ejemplo n.º 3
0
 def get_apex_checkpoints(self, **kwargs):        
     if 'file_path' in kwargs:
         id = kwargs.get('id', None)
         file_path = kwargs.get('file_path', None)
         if id == None:
             ext = mm_util.get_file_extension_no_period(file_path)
             api_name = mm_util.get_file_name_no_extension(file_path)
             mtype = mm_util.get_meta_type_by_suffix(ext)
             id = self.get_apex_entity_id_by_name(object_type=mtype['xmlName'], name=api_name)
         query_string = "Select Id, Line, Iteration, ExpirationDate, IsDumpingHeap from ApexExecutionOverlayAction Where ExecutableEntityId = '{0}'".format(id)
         payload = { 'q' : query_string }
         r = requests.get(self.get_tooling_url()+"/query/", params=payload, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
         return mm_util.parse_rest_response(r.text)
     else:
         query_string = "Select Id, ScopeId, ExecutableEntityId, Line, Iteration, ExpirationDate, IsDumpingHeap from ApexExecutionOverlayAction limit 5000"
         payload = { 'q' : query_string }
         r = requests.get(self.get_tooling_url()+"/query/", params=payload, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
         return mm_util.parse_rest_response(r.text)
Ejemplo n.º 4
0
 def delete_apex_checkpoint(self, **kwargs):
     if 'overlay_id' in kwargs:
         r = requests.delete(self.get_tooling_url()+"/sobjects/ApexExecutionOverlayAction/{0}".format(kwargs['overlay_id']), headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
         r.raise_for_status()
         return mm_util.generate_success_response('OK')
     else:
         id = kwargs.get('id', None)
         file_path = kwargs.get('file_path', None)
         line_number = kwargs.get('line_number', None)
         if id == None:
             ext = mm_util.get_file_extension_no_period(file_path)
             api_name = mm_util.get_file_name_no_extension(file_path)
             mtype = mm_util.get_meta_type_by_suffix(ext)
             id = self.get_apex_entity_id_by_name(object_type=mtype['xmlName'], name=api_name)
         
         query_string = "Select Id from ApexExecutionOverlayAction Where ExecutableEntityId = '{0}' AND Line = {1}".format(id, line_number)
         r = requests.get(self.get_tooling_url()+"/query/", params={'q':query_string}, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
         r.raise_for_status()
         query_result = mm_util.parse_rest_response(r.text)
         overlay_id = query_result['records'][0]['Id']
         r = requests.delete(self.get_tooling_url()+"/sobjects/ApexExecutionOverlayAction/{0}".format(overlay_id), headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
         r.raise_for_status()
         return mm_util.generate_success_response('OK')
Ejemplo n.º 5
0
    def remove_overlay_action(self, **kwargs):
        if 'overlay_id' in kwargs:
            r = requests.delete(
                self.get_tooling_url() +
                "/sobjects/ApexExecutionOverlayAction/{0}".format(
                    kwargs['overlay_id']),
                headers=self.get_rest_headers(),
                verify=False)
            r.raise_for_status()
            return mm_util.generate_success_response('OK')
        else:
            id = kwargs.get('id', None)
            file_path = kwargs.get('file_path', None)
            line_number = kwargs.get('line_number', None)
            if id == None:
                ext = mm_util.get_file_extension_no_period(file_path)
                api_name = mm_util.get_file_name_no_extension(file_path)
                mtype = mm_util.get_meta_type_by_suffix(ext)
                id = self.get_apex_entity_id_by_name(
                    object_type=mtype['xmlName'], name=api_name)

            query_string = "Select Id from ApexExecutionOverlayAction Where ExecutableEntityId = '{0}' AND Line = {1}".format(
                id, line_number)
            r = requests.get(self.get_tooling_url() + "/query/",
                             params={'q': query_string},
                             headers=self.get_rest_headers(),
                             verify=False)
            r.raise_for_status()
            query_result = mm_util.parse_rest_response(r.text)
            overlay_id = query_result['records'][0]['Id']
            r = requests.delete(
                self.get_tooling_url() +
                "/sobjects/ApexExecutionOverlayAction/{0}".format(overlay_id),
                headers=self.get_rest_headers(),
                verify=False)
            r.raise_for_status()
            return mm_util.generate_success_response('OK')
Ejemplo n.º 6
0
    def compile_with_tooling_api(self, files, container_id):
        for file_path in files:
            payload = {}
            file_name = file_path.split('.')[0]
            file_name = mm_util.get_file_name_no_extension(file_path)
            metadata_def = mm_util.get_meta_type_by_suffix(file_path.split('.')[-1])
            metadata_type = metadata_def['xmlName']
            if metadata_type == 'ApexPage':
                tooling_type = 'ApexPageMember'
            elif metadata_type == 'ApexComponent':
                tooling_type = 'ApexComponentMember'
            elif metadata_type == 'ApexClass':
                tooling_type = 'ApexClassMember'
            elif metadata_type == 'ApexTrigger':
                tooling_type = 'ApexTriggerMember'

            #create/submit "member"
            payload['MetadataContainerId']  = container_id
            payload['ContentEntityId']      = self.get_apex_entity_id_by_name(object_type=metadata_type, name=file_name)
            payload['Body']                 = open(file_path, 'r').read()
            #payload['LastSyncDate']         = TODO
            payload = json.dumps(payload)
            config.logger.debug(payload)
            r = requests.post(self.get_tooling_url()+"/sobjects/"+tooling_type, data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False)
            response = mm_util.parse_rest_response(r.text)
            
            #if it's a dup (probably bc we failed to delete before, let's delete and retry)
            if type(response) is list and 'errorCode' in response[0]:
                if response[0]['errorCode'] == 'DUPLICATE_VALUE':
                    dup_id = response[0]['message'].split(':')[-1]
                    dup_id = dup_id.strip()
                    query_string = "Select Id from "+tooling_type+" Where Id = '"+dup_id+"'"
                    r = requests.get(self.get_tooling_url()+"/query/", params={'q':query_string}, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
                    r.raise_for_status()
                    query_result = mm_util.parse_rest_response(r.text)
                    
                    r = requests.delete(self.get_tooling_url()+"/sobjects/{0}/{1}".format(tooling_type, query_result['records'][0]['Id']), headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
                    r.raise_for_status()

                    #retry member request
                    r = requests.post(self.get_tooling_url()+"/sobjects/"+tooling_type, data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False)
                    response = mm_util.parse_rest_response(r.text)
                    member_id = response['id']
                elif response[0]['errorCode'] == 'INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY' or response[0]['errorCode'] == 'MALFORMED_ID':
                    raise MetadataContainerException('Invalid metadata container')
                else:
                    return mm_util.generate_error_response(response[0]['errorCode'])
            else:
                member_id = response['id']

        #ok, now we're ready to submit an async request
        payload = {}
        payload['MetadataContainerId'] = container_id
        payload['IsCheckOnly'] = False
        payload['IsRunTests'] = False
        payload = json.dumps(payload)
        config.logger.debug(payload)
        r = requests.post(self.get_tooling_url()+"/sobjects/ContainerAsyncRequest", data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False)
        response = mm_util.parse_rest_response(r.text)

        finished = False
        while finished == False:
            time.sleep(1)
            query_string = "Select Id, MetadataContainerId, MetadataContainerMemberId, State, IsCheckOnly, CompilerErrors, ErrorMsg FROM ContainerAsyncRequest WHERE Id='"+response["id"]+"'"
            r = requests.get(self.get_tooling_url()+"/query/", params={'q':query_string}, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
            r.raise_for_status()
            query_result = mm_util.parse_rest_response(r.text)
            if query_result["done"] == True and query_result["size"] == 1 and 'records' in query_result:
                if query_result['records'][0]["State"] != 'Queued':
                    response = query_result['records'][0]
                    finished = True

        #clean up the apex member
        if 'id' in response:
            #delete member
            r = requests.delete(self.get_tooling_url()+"/sobjects/{0}/{1}".format(tooling_type, member_id), headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False)
            r.raise_for_status()

        return response