2012-07-04 3 views
2

내 응용 프로그램에 dotcmis와 alfresco를 통합하려고합니다. 내 단위 테스트를 만들 때 , 나는이 문제에 직면 를 - 난 다시 MyFolder에 만들고dotcmis/alfresco/delete => 검색 => 검색 지연

가 나는 문서를 찾아보십시오 그것으로 문서를 넣어 - 내가 어떤 이 경우 "MyFolder에"를 삭제하여 내 테스트 환경을 설정 : - 처음 (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 ... 

I을 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); 
} 
+0

어떤 Alfresco 버전을 사용하고 있습니까? 그리고 기존의 웹 스크립트 기반 CMIS 엔드 포인트 또는 새로운 OpenCMIS 기반의 CMIS 엔드 포인트를 사용하고 있습니까? – Gagravarr

답변

3

인덱싱을 위해 SOLR와 프레스코 4.0을 사용하고 있습니까 : 여기

내 코드? 결국 Solr 색인은 일관성이 있습니다. 즉, 검색 결과에 업데이트가 표시 될 때까지 (기본 구성에서 최대 15 초) 소요될 수 있습니다.

즉시 업데이트가 필요하면 색인 생성 하위 시스템으로 Lucene으로 전환 할 수 있습니다.

+0

네 말이 맞아. Alfresco 4.0을 기본 구성으로 사용합니다. Thread.Sleep (15000)을 넣으면 결과가 나타납니다! – boblemar

0

solr의 "궁극적으로 일관성있는"측면이 제작 과정에서의 문제라고 생각하지 않습니다. 테스트 할 때가 있지만 프로덕션 환경에서 더 나은 시스템을 갖고 다른 방법보다 디버그에 문제가있는 것을 선호합니다.

디버그 내 문제를 해결하기 위해 먼저 Thread.Sleep (20)을 넣고 작동했지만 디버깅하는 동안 꽤 오래 걸립니다.

두 번째 해결 방법은 URL 주소 : 8080/solr/admin/cores? action = REPORT (내 코드에서 _solrStateUrl)을 사용하여 solr의 색인 상태를 확인하는 것입니다. 기본적으로 SSL을 통해서만 액세스 할 수 있습니다. afresco 서버에서 "browser.p12"파일을 가져 와서 프로젝트에 넣어야합니다.

그래서 나는이 방법을 만든 : - CheckIndexingState 진행 에 거래를 찾기 위해 XML 응답을 구문 분석 - 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; 

}