def get_folder(self, object_id: str) -> Folder: """Retrieve folder with given objectId""" soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=object_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) except CmisRuntimeException as exc: if "objectNotFound" in exc.message: error_string = f"Folder met objectId '{object_id}' bestaat niet in het CMIS connection" raise FolderDoesNotExistError(error_string) else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return Folder(extracted_data)
def move_object(self, target_folder: "Folder") -> "CMISContentObject": """Move a document to the specified folder""" source_folder = self.get_parent_folders()[0] soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, object_id=self.objectId, target_folder_id=target_folder.objectId, source_folder_id=source_folder.objectId, cmis_action="moveObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "ObjectService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml(xml_response, "moveObject")[ 0 ] return type(self)(extracted_data)
def get_latest_version(self): """Get the latest version or the PWC""" # This always selects the latest version, and if there is a pwc, # Alfresco returns both the pwc and the latest major version, while Corsa only returns the pwc. query = CMISQuery("SELECT * FROM drc:document WHERE drc:document__uuid = '%s'") soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, statement=query(self.uuid), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.client.request( "DiscoveryService", soap_envelope=soap_envelope.toxml() ) # Corsa raises an error for queries that return no results except CmisRuntimeException as exc: if "objectNotFound" in exc.message: error_string = f"Object met objectId '{self.objectId}' bestaat niet in het CMIS connection" raise DocumentDoesNotExistError(error_string) else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml(xml_response, "query") return extract_latest_version(type(self), extracted_data)
def checkout(self) -> "Document": """Checkout a private working copy of the document""" soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, cmis_action="checkOut", object_id=str(self.objectId), ) logger.debug(soap_envelope.toprettyxml()) # FIXME temporary solution due to alfresco raising a 500 AFTER locking the document try: soap_response = self.client.request( "VersioningService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "checkOut" )[0] pwc_id = extracted_data["properties"]["objectId"]["value"] except CmisRuntimeException: pwc_document = self.get_latest_version() pwc_id = pwc_document.objectId return self.get_document(pwc_id)
def get_content_object( self, object_id: str, object_type: type ) -> "CMISContentObject": """Get a content object with specified objectId :param object_id: string, objectId of the content object :param object_type: type, type of the object to return :return: CMISContentObject """ soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, object_id=object_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "ObjectService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml(xml_response, "getObject")[ 0 ] return object_type(extracted_data)
def _update_properties(self, properties: dict) -> dict: """ Update properties and return the properties of the updated object. :param properties: dict, new properties to update :return: dict, properties of the updated object """ soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, properties=properties, cmis_action="updateProperties", object_id=self.objectId, ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "ObjectService", soap_envelope=soap_envelope.toxml(), ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "updateProperties" )[0] return extracted_data
def get_content_object(self, drc_uuid: Union[str, UUID], object_type: str) -> CMISContentObject: """Get the gebruiksrechten/oio with specified uuid :param drc_uuid: string or UUID, the value of drc:oio__uuid or drc:gebruiksrechten__uuid :param object_type: string, either "gebruiksrechten" or "oio" :return: Either a Gebruiksrechten or ObjectInformatieObject """ assert object_type in [ "gebruiksrechten", "oio", ], "'object_type' can be only 'gebruiksrechten' or 'oio'" query = CMISQuery("SELECT * FROM drc:%s WHERE drc:%s__uuid = '%s'") soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, statement=query(object_type, object_type, str(drc_uuid)), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) error_string = ( f"{object_type.capitalize()} {object_type} met identificatie drc:{object_type}__uuid {drc_uuid} " f"bestaat niet in het CMIS connection") does_not_exist = DocumentDoesNotExistError(error_string) try: soap_response = self.request("DiscoveryService", soap_envelope=soap_envelope.toxml()) # Corsa raises an error if the query retrieves 0 results except CmisRuntimeException as exc: if "objectNotFound" in exc.message: raise does_not_exist else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "query") if len(extracted_data) == 0: raise does_not_exist if object_type == "oio": return ObjectInformatieObject(extracted_data[0]) elif object_type == "gebruiksrechten": return Gebruiksrechten(extracted_data[0])
def create_folder(self, name: str, parent_id: str, data: dict = None) -> Folder: """Create a new folder inside a parent :param name: string, name of the new folder to create :param parent_id: string, cmis:objectId of the parent folder :param data: dict, contains the properties of the folder to create. The names of the properties are already converted to cmis names (e.g. drc:zaaktype__url) :return: Folder, the created folder """ object_type_id = CmisId("cmis:folder") properties = { "cmis:objectTypeId": { "value": object_type_id, "type": "propertyId" }, "cmis:name": { "value": name, "type": "propertyString" }, } if data is not None: properties.update(data) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=parent_id, properties=properties, cmis_action="createFolder", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createFolder")[0] # Creating a folder only returns the objectId folder_id = extracted_data["properties"]["objectId"]["value"] return self.get_folder(folder_id)
def get_document(self, drc_uuid: str, filters: Optional[dict] = None) -> Document: """Retrieve a document in the main repository with given uuid (drc:document__uuid) If the document series is checked out, it returns the private working copy :param drc_uuid: string, value of the cmis property drc:document__uuid :param filters: dict, filters to find the document :return: Document, latest document version """ error_string = f"Document met drc:document__uuid {drc_uuid} bestaat niet in het CMIS connection" does_not_exist = DocumentDoesNotExistError(error_string) if drc_uuid is None: raise does_not_exist # This always selects the latest version, and if there is a pwc, # Alfresco returns both the pwc and the latest major version, while Corsa only returns the pwc. query = CMISQuery( "SELECT * FROM drc:document WHERE drc:document__uuid = '%s' %s") filter_string = build_query_filters(filters, filter_string="AND ", strip_end=True) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, statement=query(drc_uuid, filter_string), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.request("DiscoveryService", soap_envelope=soap_envelope.toxml()) # Corsa raises an error if the query retrieves 0 results except CmisRuntimeException as exc: if "objectNotFound" in exc.message: raise does_not_exist else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "query") return extract_latest_version(self.document_type, extracted_data)
def get_child_folder( self, name: str, child_type: dict = None ) -> Optional["Folder"]: """Get a folder in the current folder that has a specific name :param name: str, the cmis:name of the folder to retrieve :param child_type: dict, With keys "value" and "type". The value contains the object type ID of the children folders to retrieve. """ if child_type is not None: object_type_id = child_type["value"] # Alfresco case: the object type ID has an extra prefix (F:drc:zaakfolder, instead of drc:zaakfolder) # The prefix needs to be removed for the query if len(object_type_id.split(":")) > 2: object_type_id = ":".join(object_type_id.split(":")[1:]) else: object_type_id = "cmis:folder" query = CMISQuery( f"SELECT * FROM {object_type_id} WHERE cmis:parentId = '%s' AND cmis:name = '%s'" ) soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, statement=query(str(self.objectId), name), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.client.request( "DiscoveryService", soap_envelope=soap_envelope.toxml() ) # Corsa raises an error if the query retrieves 0 results except CmisRuntimeException as exc: if "objectNotFound" in exc.message: return None else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml(xml_response, "query") if len(extracted_data) == 0: return None return type(self)(extracted_data[0])
def get_all_versions(self) -> List["Document"]: object_id = self.objectId.split(";")[0] soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, cmis_action="getAllVersions", object_id=object_id, ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "VersioningService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getAllVersions" ) return [Document(data) for data in extracted_data]
def check_document_exists(self, identification: Union[str, UUID], bronorganisatie: str) -> None: """Check if a document with the same (identificatie, bronorganisatie) already exists in the repository :param identification: string, document ``identificatie`` :param bronorganisatie: string, document ``bronorganisatie`` """ cmis_identificatie = mapper("identificatie", type="document") cmis_bronorganisatie = mapper("bronorganisatie", type="document") query = CMISQuery( f"SELECT * FROM drc:document WHERE {cmis_identificatie} = '%s' AND {cmis_bronorganisatie} = '%s'" ) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, statement=query(str(identification), bronorganisatie), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.request("DiscoveryService", soap_envelope=soap_envelope.toxml()) except CmisRuntimeException as exc: # Corsa raises an error if the query gives no results, while Alfresco a 200 if "objectNotFound" in exc.message: return else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "query") if len(extracted_data) > 0: raise DocumentExistsError( "Een document met dezelfde identificatie en bronorganisatie al bestaat." )
def checkin(self, checkin_comment: str, major: bool = True) -> "Document": soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, cmis_action="checkIn", object_id=str(self.objectId), major=str(major).lower(), checkin_comment=checkin_comment, ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "VersioningService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml(xml_response, "checkIn")[0] doc_id = extracted_data["properties"]["objectId"]["value"] return self.get_document(doc_id)
def get_parent_folders(self) -> List["Folder"]: """Get all the parent folders of an object""" soap_envelope = make_soap_envelope( auth=(self.client.user, self.client.password), repository_id=self.client.main_repo_id, object_id=self.objectId, cmis_action="getObjectParents", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.client.request( "NavigationService", soap_envelope=soap_envelope.toxml() ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObjectParents" ) return [Folder(data) for data in extracted_data]
def query(self, return_type_name: str, lhs: List[str] = None, rhs: List[str] = None) -> List[CMISBaseObject]: """Perform an SQL query in the DMS :param return_type_name: string, either Folder, Document, Oio or Gebruiksrechten :param lhs: list of strings, with the LHS of the SQL query :param rhs: list of strings, with the RHS of the SQL query :return: type, either Folder, Document, Oio or Gebruiksrechten """ return_type = self.get_return_type(return_type_name) processed_rhs = rhs # Any query that filters based on URL fields needs to be converted to use the short URL version if settings.CMIS_URL_MAPPING_ENABLED and lhs is not None and rhs is not None: processed_rhs = [] # Join all the queries and find which fields are used to filter joined_lhs = " ".join(lhs) column_names = re.findall(r"([a-z]+?:.+?__[a-z]+)", joined_lhs) for index, item_rhs in enumerate(rhs): column_name = column_names[index] property_name = reverse_mapper(column_name, type=return_type_name.lower()) if (property_name is not None and get_type( return_type.type_class, property_name) == QueriableUrl and item_rhs != ""): processed_rhs.append(shrink_url(item_rhs)) else: processed_rhs.append(item_rhs) table = return_type.table where = (" WHERE " + " AND ".join(lhs)) if lhs else "" query = CMISQuery("SELECT * FROM %s%s" % (table, where)) statement = query(*processed_rhs) if processed_rhs else query() soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, statement=statement, cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.request("DiscoveryService", soap_envelope=soap_envelope.toxml()) # Corsa raises an error if the query retrieves 0 results except CmisRuntimeException as exc: if "objectNotFound" in exc.message: return [] else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "query") return [return_type(cmis_object) for cmis_object in extracted_data]
def copy_document(self, document: Document, destination_folder: Folder) -> Document: """Copy document to a folder :param document: Document, the document to copy :param destination_folder: Folder, the folder in which to place the copied document :return: the copied document """ # copy the properties from the source document drc_properties = {} drc_url_properties = {} for property_name, property_details in document.properties.items(): if ("cmis:" not in property_name and property_details["value"] is not None) or property_name == "cmis:objectTypeId": drc_property_name = reverse_mapper(property_name, type="document") # Urls are handled separately, because they are already in the 'short' form if (get_type(EnkelvoudigInformatieObject, drc_property_name) == QueriableUrl): drc_url_properties[property_name] = { "value": property_details["value"], "type": "propertyString", } else: drc_properties[drc_property_name] = property_details[ "value"] cmis_properties = Document.build_properties(drc_properties, new=False) cmis_properties.update( **{ "cmis:objectTypeId": { "value": document.objectTypeId, "type": "propertyId", }, mapper("titel", type="document"): { "value": f"{document.titel} - copy", "type": "propertyString", }, "drc:kopie_van": { "value": document.uuid, "type": "propertyString", }, # Keep tack of where this is copied from. "drc:document__uuid": { "value": str(uuid.uuid4()), "type": "propertyString", }, **drc_url_properties, }) # Update the cmis:name to make it more unique file_name = f"{document.titel}-{get_random_string()}" cmis_properties["cmis:name"] = { "value": file_name, "type": "propertyString" } # Create copy document content_id = str(uuid.uuid4()) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=cmis_properties, cmis_action="createDocument", content_id=content_id, content_filename=drc_properties.get("bestandsnaam"), ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), attachments=[(content_id, document.get_content_stream())], ) # Creating the document only returns its ID xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] copy_document_id = extracted_data["properties"]["objectId"]["value"] return document.get_document(copy_document_id)
def copy_gebruiksrechten(self, source_object: Gebruiksrechten, destination_folder: Folder) -> Gebruiksrechten: """Copy a gebruiksrechten to a folder :param source_object: Gebruiksrechten, the gebruiksrechten to copy :param destination_folder: Folder, the folder in which to place the copied gebruiksrechten :return: the copied object """ # copy the properties from the source document drc_properties = {} drc_url_properties = {} for property_name, property_details in source_object.properties.items( ): if ("cmis:" not in property_name and property_details["value"] is not None) or property_name == "cmis:objectTypeId": drc_property_name = reverse_mapper(property_name, type="gebruiksrechten") # Urls are handled separately, because they are already in the 'short' form if get_type(GebruiksRechtDoc, drc_property_name) == QueriableUrl: drc_url_properties[property_name] = { "value": property_details["value"], "type": "propertyString", } else: drc_properties[drc_property_name] = property_details[ "value"] cmis_properties = Gebruiksrechten.build_properties(drc_properties) cmis_properties.update( **{ "cmis:objectTypeId": { "value": source_object.objectTypeId, "type": "propertyId", }, mapper("kopie_van", type="gebruiksrechten"): { "value": source_object.objectId, "type": "propertyString", # Keep tack of where this is copied from. }, "cmis:name": { "value": get_random_string(), "type": "propertyString" }, "drc:gebruiksrechten__uuid": { "value": str(uuid.uuid4()), "type": "propertyString", }, **drc_url_properties, }) # Create copy gebruiksrechten soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=cmis_properties, cmis_action="createDocument", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), ) # Creating the document only returns its ID xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] copy_gebruiksrechten_id = extracted_data["properties"]["objectId"][ "value"] # Request all the properties of the newly created object soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=copy_gebruiksrechten_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return Gebruiksrechten(extracted_data)
def create_document( self, identification: str, bronorganisatie: str, data: dict, content: BytesIO = None, check_if_already_exists: bool = True, ) -> Document: """Create a custom Document (with the EnkelvoudigInformatieObject properties) :param identification: string, the document ``identificatie`` :param bronorganisatie: string, The identifier of the organisation. :param data: dict, the properties of the document :param content: BytesIO, the content of the document :param check_if_already_exists: Bool, whether to check if the document with given identificatie/bronorganisatie already exists in the DMS. :return: Document, the document created """ if check_if_already_exists and identification and bronorganisatie: self.check_document_exists(identification, bronorganisatie) data.setdefault("versie", "1") data.setdefault( "object_type_id", f"{self.get_object_type_id_prefix('document')}drc:document", ) data["bronorganisatie"] = bronorganisatie data["identificatie"] = identification content_id = str(uuid.uuid4()) if content is None: content = BytesIO() # Create Document in default folder other_folder = self.get_or_create_other_folder() properties = Document.build_properties(data, new=True) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=other_folder.objectId, properties=properties, cmis_action="createDocument", content_id=content_id, content_filename=data.get("bestandsnaam"), ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), attachments=[(content_id, content)], ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) # Creating the document only returns its ID extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] new_document_id = extracted_data["properties"]["objectId"]["value"] # Request all the properties of the newly created document soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=new_document_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return Document(extracted_data)
def create_content_object( self, data: dict, object_type: str, destination_folder: Folder = None) -> CMISContentObject: """Create a Gebruiksrechten or a ObjectInformatieObject :param data: dict, properties of the object to create :param object_type: string, either "gebruiksrechten" or "oio" :param destination_folder: Folder, the folder in which to place the object :return: Either a Gebruiksrechten or ObjectInformatieObject """ assert object_type in [ "gebruiksrechten", "oio", ], "'object_type' can be only 'gebruiksrechten' or 'oio'" if object_type == "oio": return_type = ObjectInformatieObject data_class = Oio elif object_type == "gebruiksrechten": return_type = Gebruiksrechten data_class = GebruiksRechtDoc if destination_folder is None: other_folder = self.get_or_create_other_folder() destination_folder = self.get_or_create_folder( "Related data", other_folder) properties = return_type.build_properties(data) properties.setdefault( "cmis:objectTypeId", { "value": f"{self.get_object_type_id_prefix(object_type)}drc:{object_type}", "type": "propertyId", }, ) properties.setdefault("cmis:name", { "value": get_random_string(), "type": "propertyString" }) properties.setdefault( mapper("uuid", type=object_type), { "value": str(uuid.uuid4()), "type": get_cmis_type(data_class, "uuid") }, ) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=properties, cmis_action="createDocument", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] new_object_id = extracted_data["properties"]["objectId"]["value"] # Request all the properties of the newly created object soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=new_object_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return return_type(extracted_data)