Содержимое, полученное из документов Alfresco, отсутствует ‹content›

Я создал пользовательский тип контента, производный от document. Я пытаюсь использовать CMIS для программного запроса моего сервера Alfresco (пробовал с 4.2.b и 4.2.c) для моих документов, используя python cmislib. У меня есть сервер-пирамида, который принимает вызовы REST и отправляет их на мой сервер Alfresco с помощью CMIS.

Я получаю эту ошибку:

2013-04-11 11:19:25,526 | ERROR | Exception when serving /access_manager/search_noauth
Traceback (most recent call last):
  File "/home/hbrown/.virtualenvs/access_manager_master/local/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/channel.py", line 329, in service
    task.service()
[...]
  File "/home/hbrown/workspace/spt/access_manager/access_manager/views/search.py", line 223, in cmis_main
    for result in repo.query(whole_query)
  File "/home/hbrown/.virtualenvs/access_manager_master/local/lib/python2.7/site-packages/cmislib/model.py", line 2467, in getContentStream
    assert(len(contentElements) == 1), 'Expected to find exactly one atom:content element.'
AssertionError: Expected to find exactly one atom:content element.

Я использую getContentStream() для получить содержимое. Основываясь на комментарии к коду, я бы сказал, что это правильный вызов API:

    >>> doc.getName()
    u'sample-b.pdf'
    >>> o = open('tmp.pdf', 'wb')
    >>> result = doc.getContentStream()
    >>> o.write(result.read())
    >>> result.close()
    >>> o.close()
    >>> import os.path
    >>> os.path.getsize('tmp.pdf')
    117248

Код Python в cmislib явно ожидает, что документ будет иметь XML, который включает элемент с именем content, а мой — нет.

Код вызова выглядит так:

from cmislib import CmisClient

SERVER = "localhost"
url = "http://{0}:8080/alfresco/cmisatom".format(SERVER)
client = CmisClient(url, 'admin', 'alfresco')
repo = client.defaultRepository
results = repo.query("select * from wg:bulletin")
print results[0].getContentStream().read()

XML, над которым работают в getContentStream, выглядит следующим образом:

<atom:entry>
    <atom:author>
        <atom:name/>
    </atom:author>
    <atom:id>http://chemistry.apache.org/aWQtMQ==</atom:id>
    <atom:published>2013-04-12T03:22:38Z</atom:published>
    <atom:title>Query Result id-1</atom:title>
    <app:edited>2013-04-12T03:22:38Z</app:edited>
    <atom:updated>2013-04-12T03:22:38Z</atom:updated>
    <cmisra:object xmlns:ns3="http://docs.oasis-open.org/ns/cmis/messaging/200908/">
        <cmis:properties>
            <cmis:propertyInteger displayName="Content Stream Length" localName="contentStreamLength" propertyDefinitionId="cmis:contentStreamLength" queryName="b.cmis:contentStreamLength">
                <cmis:value>249</cmis:value>
            </cmis:propertyInteger>
            <cmis:propertyId displayName="Object Type Id" localName="objectTypeId" propertyDefinitionId="cmis:objectTypeId" queryName="b.cmis:objectTypeId">
                <cmis:value>D:wg:bulletin</cmis:value>
            </cmis:propertyId>
            <cmis:propertyString displayName="Version Series Checked Out By" localName="versionSeriesCheckedOutBy" propertyDefinitionId="cmis:versionSeriesCheckedOutBy" queryName="b.cmis:versionSeriesCheckedOutBy"/>
            <cmis:propertyId displayName="Version Series Checked Out Id" localName="versionSeriesCheckedOutId" propertyDefinitionId="cmis:versionSeriesCheckedOutId" queryName="b.cmis:versionSeriesCheckedOutId"/>
            <cmis:propertyId displayName="Version series id" localName="versionSeriesId" propertyDefinitionId="cmis:versionSeriesId" queryName="b.cmis:versionSeriesId">
                <cmis:value>workspace://SpacesStore/1cd2053d-1fc4-4e85-b780-ba80284f0841</cmis:value>
            </cmis:propertyId>
            <cmis:propertyString displayName="wg:account" localName="account" propertyDefinitionId="wg:account" queryName="b.wg:account"/>
            <cmis:propertyString displayName="Version Label" localName="versionLabel" propertyDefinitionId="cmis:versionLabel" queryName="b.cmis:versionLabel">
                <cmis:value>1.0</cmis:value>
            </cmis:propertyString>
            <cmis:propertyBoolean displayName="Is Latest Version" localName="isLatestVersion" propertyDefinitionId="cmis:isLatestVersion" queryName="b.cmis:isLatestVersion">
                <cmis:value>true</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyBoolean displayName="Is Version Series Checked Out" localName="isVersionSeriesCheckedOut" propertyDefinitionId="cmis:isVersionSeriesCheckedOut" queryName="b.cmis:isVersionSeriesCheckedOut">
                <cmis:value>false</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyString displayName="Last Modified By" localName="lastModifiedBy" propertyDefinitionId="cmis:lastModifiedBy" queryName="b.cmis:lastModifiedBy">
                <cmis:value>admin</cmis:value>
            </cmis:propertyString>
            <cmis:propertyString displayName="Created by" localName="createdBy" propertyDefinitionId="cmis:createdBy" queryName="b.cmis:createdBy">
                <cmis:value>admin</cmis:value>
            </cmis:propertyString>
            <cmis:propertyDateTime displayName="wg:displayUntil" localName="displayUntil" propertyDefinitionId="wg:displayUntil" queryName="b.wg:displayUntil"/>
            <cmis:propertyId displayName="Alfresco Node Ref" localName="nodeRef" propertyDefinitionId="alfcmis:nodeRef" queryName="b.alfcmis:nodeRef">
                <cmis:value>workspace://SpacesStore/1cd2053d-1fc4-4e85-b780-ba80284f0841</cmis:value>
            </cmis:propertyId>
            <cmis:propertyString displayName="wg:email" localName="email" propertyDefinitionId="wg:email" queryName="b.wg:email"/>
            <cmis:propertyBoolean displayName="wg:isActive" localName="isActive" propertyDefinitionId="wg:isActive" queryName="b.wg:isActive">
                <cmis:value>false</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyString displayName="wg:username" localName="username" propertyDefinitionId="wg:username" queryName="b.wg:username"/>
            <cmis:propertyBoolean displayName="Is Latest Major Version" localName="isLatestMajorVersion" propertyDefinitionId="cmis:isLatestMajorVersion" queryName="b.cmis:isLatestMajorVersion">
                <cmis:value>true</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyId displayName="Content Stream Id" localName="contentStreamId" propertyDefinitionId="cmis:contentStreamId" queryName="b.cmis:contentStreamId">
                <cmis:value>store://2013/4/10/15/29/20b185d0-afae-4a7f-a06e-58eab399bdc9.bin</cmis:value>
            </cmis:propertyId>
            <cmis:propertyString displayName="Name" localName="name" propertyDefinitionId="cmis:name" queryName="b.cmis:name">
                <cmis:value>.pythonrc</cmis:value>
            </cmis:propertyString>
            <cmis:propertyString displayName="Content Stream MIME Type" localName="contentStreamMimeType" propertyDefinitionId="cmis:contentStreamMimeType" queryName="b.cmis:contentStreamMimeType">
                <cmis:value>text/plain</cmis:value>
            </cmis:propertyString>
            <cmis:propertyDateTime displayName="Creation Date" localName="creationDate" propertyDefinitionId="cmis:creationDate" queryName="b.cmis:creationDate">
                <cmis:value>2013-04-10T15:29:18.146-04:00</cmis:value>
            </cmis:propertyDateTime>
            <cmis:propertyString displayName="Change token" localName="changeToken" propertyDefinitionId="cmis:changeToken" queryName="b.cmis:changeToken"/>
            <cmis:propertyString displayName="wg:state" localName="state" propertyDefinitionId="wg:state" queryName="b.wg:state"/>
            <cmis:propertyDateTime displayName="wg:displayFrom" localName="displayFrom" propertyDefinitionId="wg:displayFrom" queryName="b.wg:displayFrom"/>
            <cmis:propertyString displayName="Checkin Comment" localName="checkinComment" propertyDefinitionId="cmis:checkinComment" queryName="b.cmis:checkinComment"/>
            <cmis:propertyString displayName="wg:application" localName="application" propertyDefinitionId="wg:application" queryName="b.wg:application"/>
            <cmis:propertyId displayName="Object Id" localName="objectId" propertyDefinitionId="cmis:objectId" queryName="b.cmis:objectId">
                <cmis:value>workspace://SpacesStore/1cd2053d-1fc4-4e85-b780-ba80284f0841;1.0</cmis:value>
            </cmis:propertyId>
            <cmis:propertyBoolean displayName="Is Immutable" localName="isImmutable" propertyDefinitionId="cmis:isImmutable" queryName="b.cmis:isImmutable">
                <cmis:value>false</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyBoolean displayName="Is Major Version" localName="isMajorVersion" propertyDefinitionId="cmis:isMajorVersion" queryName="b.cmis:isMajorVersion">
                <cmis:value>true</cmis:value>
            </cmis:propertyBoolean>
            <cmis:propertyString displayName="wg:institution" localName="institution" propertyDefinitionId="wg:institution" queryName="b.wg:institution"/>
            <cmis:propertyId displayName="Base Type Id" localName="baseTypeId" propertyDefinitionId="cmis:baseTypeId" queryName="b.cmis:baseTypeId">
                <cmis:value>cmis:document</cmis:value>
            </cmis:propertyId>
            <cmis:propertyString displayName="Content Stream Filename" localName="contentStreamFileName" propertyDefinitionId="cmis:contentStreamFileName" queryName="b.cmis:contentStreamFileName">
                <cmis:value>.pythonrc</cmis:value>
            </cmis:propertyString>
            <cmis:propertyDateTime displayName="Last Modified Date" localName="lastModificationDate" propertyDefinitionId="cmis:lastModificationDate" queryName="b.cmis:lastModificationDate">
                <cmis:value>2013-04-10T15:29:23.384-04:00</cmis:value>
            </cmis:propertyDateTime>
        </cmis:properties>
    </cmisra:object>
</atom:entry>

Здесь явно нет элемента XML с именем content для извлечения кода Python.

Является ли это неправильной настройкой моего пользовательского документа с содержимым или это изменение в CMIS, которое cmislib не отслеживает, или я вызываю неправильную функцию API для получения содержимого или что-то еще?


Позже: минимальное изменение, чтобы исправить это, состоит в том, чтобы делать вызовы либо reload, либо getAllowableActions.

Это был исходный код:

def cmis_main(props, settings):
    """
    Create a CMIS query based on props and execute against Alfresco
    """
    def cmis_query(props, mapping):
        """
        Create CMIS query of AND-separated OR-clauses
        """
        # Code that formats a query string from dictionaries...

    cmis_mapping = {
        # Dictionary config for call to cmis_query
        # Nothing to see here. Move on.
        "app_sids": {
            "where_fmt": IN_WHERE_FMT,
            "key": "{0}:application".format(CMIS_NAMESPACE),
            "fn": set_format,
        },
    }

    cmis_url, cmis_user, cmis_password = cmis_args(settings)
    cmisclient = CmisClient(cmis_url, cmis_user, cmis_password)
    repo = cmisclient.getDefaultRepository()
    whole_query = cmis_query(props, cmis_mapping)
    logger.debug(whole_query)

    return [
        {
            'name': result.name,
            'content': result.getContentStream().read(),
            'content_mime_type': result.properties["cmis:contentStreamMimeType"],
        }
        for result in repo.query(whole_query)
    ]

И он был сломан. Поэтому я изменил код на это:

    results = list(repo.query(whole_query))
    for result in results:
        print(result.getAllowableActions())
        # or: result.reload()

    return [
        {
            'name': result.name,
            'content': result.getContentStream().read(),
            'content_mime_type': result.properties["cmis:contentStreamMimeType"],
        }
        for result in results
    ]

И это сработало. Я изменил это на это:

    results = list(repo.query(whole_query))
    for result in results:
        pass

    return [
        {
            'name': result.name,
            'content': result.getContentStream().read(),
            'content_mime_type': result.properties["cmis:contentStreamMimeType"],
        }
        for result in results
    ]

И он сломался. Таким образом, кажется, что XML не полностью загружен в объект CMISLIB.


person hughdbrown    schedule 11.04.2013    source источник
comment
У вас есть XML-контент, который в настоящее время возвращается в руки? А также код, который вы используете для извлечения документа, а затем содержимого?   -  person Will Abson    schedule 12.04.2013
comment
@Will Abson: я предоставил гораздо более подробный код и выходные данные, чтобы помочь в анализе / спелеологии.   -  person hughdbrown    schedule 12.04.2013
comment
Это очень странно. Я не могу воссоздать это на своем компьютере, используя Alfresco 4.2.c, cmislib 0.5.1 и объекты, используя мою собственную модель контента. Можете ли вы поделиться своей моделью контента или хотя бы рассказать мне о wg:bulletin? Например, наследуется ли он от cm:content напрямую? Используете ли вы какие-либо аспекты? Кроме того, что возвращает results[0].getAllowableActions()['canGetContentStream']?   -  person Jeff Potts    schedule 13.04.2013


Ответы (1)


Попробуйте выполнить results[0].reload() перед вызовом getContentStream(). Это не обязательно, но может привести к перезагрузке объекта с элементом содержимого.

person Jeff Potts    schedule 12.04.2013
comment
Исправление: мне пришлось перезагружать каждый результат, а не только первый. Пробовал repo.reload(), resultset.reload(), resultset[0].reload (когда был хотя бы один результат). Только вызов reload для каждого результата спас меня от ошибок. Соответственно, я разместил этот запрос на включение в github: /тянуть/1 - person hughdbrown; 23.07.2013