2

dotcmis と alfresco をアプリケーションに統合しようとしています。単体テストを作成するときに、次の問題に直面します。

次に、ドキュメントを見つけようとします: - 初めて (myfolder が以前に存在しなかった場合)、検索は 0 の結果を返します - 次回、myfolder が以前に存在し、テスト セットアップによって削除された場合、例外が発生します:

Apache Chemistry OpenCMIS - runtime error
HTTP Status 500 - <!--exception-->runtime<!--/exception--><p><!--message-->Node does     not exist: missing://missing/missing(null)<!--/message--></p><hr noshade='noshade'/><!--    stacktrace--><pre>
org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException: Node does not exist: missing://missing/missing(null)
at org.alfresco.opencmis.AlfrescoCmisExceptionInterceptor.invoke(AlfrescoCmisExceptionInterceptor.java:80)
at ...

Alfresco に行くと、ドキュメントが存在します。フォルダーとドキュメントはまだクエリに対して責任を負っていないようですが、なぜですか? テスト環境のinitをコメントにすると、ドキュメントが見つかります

多分私は何か間違ったことをしますが、何ですか?

これが私のコードです:

[TestMethod()]
[DeploymentItem(@"Files\SearchTest_1", @"Files\SearchTest_1")]
public void SearchTest_2()
{
    string myfoldername = "myfolder";

    // Session creation
    var p = new Dictionary<String, String>();
    p[SessionParameter.User] = _userName;
    p[SessionParameter.Password] = _userPassword;
    p[SessionParameter.BindingType] = BindingType.AtomPub;
    p[SessionParameter.AtomPubUrl] = _serverUrl;

    var session = DotCMIS.Client.Impl.SessionFactory.NewInstance().GetRepositories(p)[0].CreateSession();
    session.DefaultContext.CacheEnabled = false;
    var operationContext = session.CreateOperationContext();
    operationContext.IncludeAcls = true;

    // Delete and create back folder and document
    // /*
    DotCMIS.Client.IFolder rootFolder = this._testSession.GetRootFolder(operationContext);
    DotCMIS.Client.IFolder myFolder = null;
    Dictionary<String, Object> properties = null;

    // Le dossier de destination des tests existe-t-il ?
    var myFolderExists = rootFolder.GetChildren(operationContext).Any(child => child.Name.Equals(myfoldername));
    if (myFolderExists)
    {
        myFolder = (DotCMIS.Client.IFolder)session.GetObjectByPath(String.Format(@"/{0}", myfoldername), operationContext);
        myFolder.DeleteTree(true, DotCMIS.Enums.UnfileObject.Delete, true);
    }

    properties = new Dictionary<String, Object>();
    properties[PropertyIds.Name] = myfoldername;
    properties[PropertyIds.ObjectTypeId] = "cmis:folder";
    myFolder = rootFolder.CreateFolder(properties);
    rootFolder.Refresh();

    myFolder = (DotCMIS.Client.IFolder)session.GetObjectByPath(String.Format(@"/{0}", myfoldername), operationContext);

    FileInfo sourceFile = new FileInfo(@"Files\SearchTest_1\SearchTest_1.pdf");
    properties = new Dictionary<String, Object>();

    properties[PropertyIds.ObjectTypeId] = "cmis:document";
    properties[PropertyIds.Name] = sourceFile.Name;

    using (var fileStream = sourceFile.OpenRead())
    {
        var contentStream = new DotCMIS.Data.Impl.ContentStream();
        contentStream.MimeType = "application/pdf";
        contentStream.Stream = fileStream;
        contentStream.Length = fileStream.Length;
        //this._testSession.CreateDocument(properties, this._testSession.CreateObjectId(myFolder.Id), contentStream, null);
        DotCMIS.Client.IDocument createdDocument = myFolder.CreateDocument(properties, contentStream, null);
    }

    // */

    // Recherche
    string query = @"SELECT * FROM cmis:document WHERE cmis:name = 'SearchTest_1.pdf'";
    var results = this._testSession.Query(query, false, operationContext).ToArray();
    Assert.AreEqual(1, results.Length);
}
4

2 に答える 2

3

インデックス作成に Alfresco 4.0 と Solr を使用していますか? Solr インデックスは最終的に一貫性があります。つまり、更新が検索結果に表示されるまでに時間がかかる場合があります (既定の構成では最大 15 秒)。

更新をすぐに表示する必要がある場合は、インデックス作成サブシステムとして Lucene に切り替えることができます。

于 2012-07-04T11:15:01.950 に答える
0

solr の「結果整合性」の側面は、本番環境の問題ではないと思います。それはテスト中かもしれませんが、本番環境でより良いシステムを使用し、デバッグでいくつかの問題を抱えているほうが、その逆よりも好きです。

デバッグで私の問題を解決するために、最初に Thread.Sleep(20) を配置しました...そしてそれは機能しましたが..デバッグ中はかなり時間がかかります。

うまくいくと思われる私の2番目の解決策は、URLアドレス:8080/solr/admin/cores?action=REPORT(私のコードでは_solrStateUrl)を使用してsolrのインデックス作成状態を確認することです。問題は、デフォルトで SSL でしかアクセスできないことです。そのため、afresco サーバーから「browser.p12」というファイルを取得して、プロジェクトに配置する必要があります。

だから私は2つのメソッドを作りました: - 進行中のトランザクションを見つけるためにxml応答を解析しているCheckIndexingState - CheckIndexingStateでループしているWaitForIndexingDone

このコードはあまり安全ではないかもしれませんが、テスト用です...

ここにあります。これが誰かを助けることを願っています...

private bool CheckIndexingState()
{
    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(delegate(object sender2, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; });
    System.Net.HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create(_solrStateUrl);
    request.ClientCertificates.Add(new X509Certificate2(@"ssl/browser.p12", "alfresco"));
    var sb = new System.Text.StringBuilder();
    byte[] buffer = new byte[256];
    int nbRead = -1;
    using (var stream = request.GetResponse().GetResponseStream())
    {
        while (nbRead != 0)
        {
            nbRead = stream.Read(buffer, 0, 256);
            sb.Append(System.Text.Encoding.UTF8.GetString(buffer, 0, nbRead));
        }
    }

    String state = sb.ToString();

    try
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(sb.ToString());

        var node = doc.SelectSingleNode(@"/response/lst[@name='report']/lst[@name='alfresco']/long[@name='Count of transactions in the index but not the DB']");
        int count = Int32.Parse(node.InnerText);
        if (count > 0)
            return false;

        node = doc.SelectSingleNode(@"/response/lst[@name='report']/lst[@name='alfresco']/long[@name='Count of acl transactions in the index but not the DB']");
        count = Int32.Parse(node.InnerText);
        if (count > 0)
            return false;

        node = doc.SelectSingleNode(@"/response/lst[@name='report']/lst[@name='alfresco']/long[@name='Count of missing transactions from the Index']");
        count = Int32.Parse(node.InnerText);
        if (count > 0)
            return false;

        node = doc.SelectSingleNode(@"/response/lst[@name='report']/lst[@name='alfresco']/long[@name='Count of missing acl transactions from the Index']");
        count = Int32.Parse(node.InnerText);
        if (count > 0)
            return false;
    }
    catch (Exception)
    {
        throw;
    }

    return true;

}
于 2012-07-05T09:18:30.890 に答える