def get_metadata_container_id(self): query_string = "Select Id from MetadataContainer Where Name = 'MavensMate-" + self.user_id + "'" #print self.get_tooling_url()+"/query/" 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) try: return query_result['records'][0]['Id'] except: payload = {} payload['Name'] = "MavensMate-" + self.user_id payload = json.dumps(payload) r = requests.post(self.get_tooling_url() + "/sobjects/MetadataContainer", data=payload, headers=self.get_rest_headers('POST'), verify=False) create_response = mm_util.parse_rest_response(r.text) if create_response["success"] == True: return create_response["id"] else: return "error"
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)
def get_symbol_table(self, ids=[]): id_string = "','".join(ids) id_string = "'"+id_string+"'" query_string = "Select ContentEntityId, SymbolTable From ApexClassMember Where ContentEntityId IN (" + id_string + ")" 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)
def delete_apex_checkpoints(self): query_string = 'Select Id FROM ApexExecutionOverlayAction' r = requests.get(self.get_tooling_url()+"/query/", params={'q':query_string}, proxies=urllib.getproxies(), headers=self.get_rest_headers(), verify=False) r.raise_for_status() qr = mm_util.parse_rest_response(r.text) for r in qr['records']: self.delete_tooling_entity("ApexExecutionOverlayAction", r["Id"])
def get_symbol_tables_by_class_id(self, ids=[]): id_string = "','".join(ids) id_string = "'"+id_string+"'" query_string = "Select NamespacePrefix, SymbolTable, Name From ApexClass Where Id IN (" + id_string + ")" 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)
def run_async_apex_tests(self, payload): payload = json.dumps(payload) r = requests.post(self.get_tooling_url() + "/sobjects/ApexTestQueueItem", data=payload, headers=self.get_rest_headers('POST'), verify=False) return mm_util.parse_rest_response(r.text)
def get_trace_flags(self, **kwargs): query_string = "Select Id, ScopeId, TracedEntityId, ExpirationDate from TraceFlag 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)
def delete_apex_checkpoint_results(self): query_string = 'Select Id From ApexExecutionOverlayResult Where UserId = \''+self.user_id+'\' order by CreatedDate' 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() qr = mm_util.parse_rest_response(r.text) for record in qr['records']: self.delete_tooling_entity("ApexExecutionOverlayResult", record["Id"]) return mm_util.generate_success_response("Done")
def delete_trace_flags(self): query_string = 'Select Id From TraceFlag' 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() qr = mm_util.parse_rest_response(r.text) for record in qr['records']: self.delete_tooling_entity("TraceFlag", record["Id"]) return mm_util.generate_success_response("Done")
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)
def create_trace_flag(self, payload): if 'ScopeId' not in payload: payload['ScopeId'] = self.user_id payload = json.dumps(payload) r = requests.post(self.get_tooling_url() + "/sobjects/TraceFlag", data=payload, headers=self.get_rest_headers('POST'), verify=False) return mm_util.parse_rest_response(r.text)
def get_apex_checkpoint_results(self, user_id=None, limit=20): if user_id == None: user_id = self.user_id #dont query heapdump, soqlresult, or apexresult here - JF query_string = 'Select Id, CreatedDate, ActionScript, ActionScriptType, ExpirationDate, IsDumpingHeap, Iteration, Line, UserId From ApexExecutionOverlayResult order by CreatedDate desc limit '+str(limit) 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() qr = mm_util.parse_rest_response(r.text) for record in qr['records']: heap_query = 'SELECT HeapDump, ApexResult, SOQLResult, ActionScript FROM ApexExecutionOverlayResult WHERE Id = \''+record['Id']+'\'' rr = requests.get(self.get_tooling_url()+"/query/", params={'q':heap_query}, headers=self.get_rest_headers(), proxies=urllib.getproxies(), verify=False) rr.raise_for_status() qrr = mm_util.parse_rest_response(rr.text) record["HeapDump"] = qrr['records'][0]['HeapDump'] record["ApexResult"] = qrr['records'][0]['ApexResult'] record["SOQLResult"] = qrr['records'][0]['SOQLResult'] record["ActionScript"] = qrr['records'][0]['ActionScript'] return qr
def get_metadata_container_id(self): query_string = "Select Id from MetadataContainer Where Name = 'MavensMate-"+self.user_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) #print query_result try: return query_result['records'][0]['Id'] except: payload = {} payload['Name'] = "MavensMate-"+self.user_id payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/MetadataContainer", data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False) create_response = mm_util.parse_rest_response(r.text) if create_response["success"] == True: return create_response["id"] else: return "error"
def get_symbol_table(self, ids=[]): id_string = "','".join(ids) id_string = "'" + id_string + "'" query_string = "Select ContentEntityId, SymbolTable From ApexClassMember Where ContentEntityId IN (" + id_string + ")" 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)
def delete_mavensmate_metadatacontainers_for_this_user(self): query_string = "Select Id from MetadataContainer Where Name = 'MavensMate-"+self.user_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() qr = mm_util.parse_rest_response(r.text) responses = [] for r in qr['records']: resp = self.delete_tooling_entity("MetadataContainer", r["Id"]) responses.append(resp.status_code) return responses
def run_async_apex_tests(self, payload): classes = payload["classes"] responses = [] for c in classes: payload = { "ApexClassId" : self.get_apex_entity_id_by_name(object_type="ApexClass", name=c) } payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/ApexTestQueueItem", data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False) res = mm_util.parse_rest_response(r.text) if res["success"] == True: parentJobId = None qr = self.query("Select ParentJobId FROM ApexTestQueueItem WHERE Id='{0}'".format(res["id"])) if qr["done"] == True and qr["totalSize"] == 1 and 'records' in qr: parentJobId = qr['records'][0]["ParentJobId"] finished = False while finished == False: time.sleep(1) query_string = "SELECT ApexClassId, Status, ExtendedStatus FROM ApexTestQueueItem WHERE ParentJobId = '{0}'".format(parentJobId) query_result = self.query(query_string) if query_result["done"] == True and query_result["totalSize"] == 1 and 'records' in query_result: done_statuses = ['Aborted', 'Completed', 'Failed'] if query_result['records'][0]["Status"] in done_statuses: #now check for method results qr = self.query("SELECT Outcome, ApexClass.Name, MethodName, Message, StackTrace, ApexLogId FROM ApexTestResult WHERE AsyncApexJobId ='{0}'".format(parentJobId)) parent_response = query_result['records'][0] parent_response["detailed_results"] = [] for r in qr["records"]: parent_response["detailed_results"].append(r) if "ApexLogId" in r and r["ApexLogId"] != None: if os.path.isdir(os.path.join(config.connection.workspace,config.connection.project.project_name,"debug","test_logs")) == False: os.makedirs(os.path.join(config.connection.workspace,config.connection.project.project_name,"debug","test_logs")) ts = time.time() if not config.is_windows: st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') else: st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H %M %S') file_name = st+"."+r["ApexLogId"]+".json" file_path = os.path.join(config.connection.workspace,config.connection.project.project_name,"debug","test_logs", file_name) debug_log_body = self.download_log(r["ApexLogId"]) src = open(file_path, "w") src.write(debug_log_body) src.close() #file_name = mm_util.get_random_string(12) + ".json" #log_location = mm_util.put_file_in_tmp_directory(file_name, debug_log_body) #r["log_location"] = log_location responses.append(parent_response) finished = True else: responses.append({"class":c,"success":False}) return json.dumps(responses)
def delete_debug_logs(self, scope="user"): if scope != "user": query_string = "Select Id From ApexLog" else: query_string = "Select Id From ApexLog WHERE LogUserId = '{0}'".format(self.user_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() qr = mm_util.parse_rest_response(r.text) for record in qr['records']: self.delete_tooling_entity("ApexLog", record["Id"]) return mm_util.generate_success_response("Done")
def create_overlay_action(self, payload): if 'ScopeId' not in payload: payload['ScopeId'] = self.user_id if 'API_Name' in payload: payload['ExecutableEntityId'] = self.get_apex_entity_id_by_name(object_type=payload['Object_Type'], name=payload['API_Name']) payload.pop('Object_Type', None) payload.pop('API_Name', None) payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/ApexExecutionOverlayAction", data=payload, headers=self.get_rest_headers('POST'), verify=False) return mm_util.parse_rest_response(r.text)
def get_debug_logs(self, download_body=False, limit=20, scope="user"): if scope == "user": query_string = "Select Id,Application,Location,LogLength,LogUserId,Operation,Request,StartTime,Status From ApexLog WHERE LogUserId = '{0}' Order By StartTime desc limit {1}".format(self.user_id, limit) else: query_string = "Select Id,Application,Location,LogLength,LogUserId,Operation,Request,StartTime,Status From ApexLog Order By StartTime desc limit {1}".format(self.user_id, limit) 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() qr = mm_util.parse_rest_response(r.text) for record in qr['records']: if download_body: record['Body'] = self.download_log(record['Id']) return qr
def create_overlay_action(self, payload): if 'ScopeId' not in payload: payload['ScopeId'] = self.user_id if 'API_Name' in payload: payload['ExecutableEntityId'] = self.get_apex_entity_id_by_name( object_type=payload['Object_Type'], name=payload['API_Name']) payload.pop('Object_Type', None) payload.pop('API_Name', None) payload = json.dumps(payload) r = requests.post(self.get_tooling_url() + "/sobjects/ApexExecutionOverlayAction", data=payload, headers=self.get_rest_headers('POST'), verify=False) return mm_util.parse_rest_response(r.text)
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')
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')
def get_trace_flags(self, **kwargs): query_string = "Select Id, ScopeId, TracedEntityId, ExpirationDate from TraceFlag 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)
def run_async_apex_tests(self, payload): payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/ApexTestQueueItem", data=payload, headers=self.get_rest_headers('POST'), verify=False) return mm_util.parse_rest_response(r.text)
def get_trace_flags(self, delete=False): query_string = 'Select Id,ApexCode,ApexProfiling,Callout,Database,System,Validation,Visualforce,Workflow,ExpirationDate,TracedEntityId,ScopeId FROM TraceFlag order by CreatedDate desc' 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() return mm_util.parse_rest_response(r.text)
def create_trace_flag(self, payload): if 'ScopeId' not in payload: payload['ScopeId'] = self.user_id payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/TraceFlag", data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False) return mm_util.parse_rest_response(r.text)
def sign_in(creds): r = requests.get('https://mavensmate.appspot.com/github', params={'username':creds['username'], 'password':creds['password']}, proxies=urllib.getproxies(), verify=False) r.raise_for_status() return mm_util.parse_rest_response(r.text)
def compile_with_tooling_api(self, file_path, container_id): file_name = file_path.split('.')[0] file_suffix = file_path.split('.')[-1] file_name = file_name.split('/')[-1] metadata_def = mm_util.get_meta_type_by_suffix( file_path.split('.')[-1]) metadata_type = metadata_def['xmlName'] payload = {} 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['Metadata'] = { # "label": "foo", # "apiVersion": 27 # } 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'), 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(), 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(), 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'), verify=False) response = mm_util.parse_rest_response(r.text) member_id = response['id'] 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'), 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(), 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(), verify=False) r.raise_for_status() return response
def new_metadatacontainer_for_this_user(self): payload = {} payload['Name'] = "MavensMate-"+self.user_id payload = json.dumps(payload) r = requests.post(self.get_tooling_url()+"/sobjects/MetadataContainer", data=payload, headers=self.get_rest_headers('POST'), proxies=urllib.getproxies(), verify=False) return mm_util.parse_rest_response(r.text)
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