2012-10-11 13 views
5

RavenDB genera InvalidOperationException quando IsOperationAllowedOnDocument viene chiamato utilizzando la modalità incorporata.RavenDB IsOperationAllowedOnDocument non supportato in modalità incorporata

Vedo nell'implementazione IsOperationAllowedOnDocument una clausola che verifica le chiamate in modalità incorporata.

namespace Raven.Client.Authorization 
{ 
    public static class AuthorizationClientExtensions 
    { 
     public static OperationAllowedResult[] IsOperationAllowedOnDocument(this ISyncAdvancedSessionOperation session, string userId, string operation, params string[] documentIds) 
     { 
      var serverClient = session.DatabaseCommands as ServerClient; 
      if (serverClient == null) 
       throw new InvalidOperationException("Cannot get whatever operation is allowed on document in embedded mode."); 

Esiste una soluzione alternativa per non utilizzare la modalità incorporata?

Grazie per il vostro tempo.

risposta

4

ho incontrato la stessa situazione durante la scrittura di alcuni test di unità. La soluzione fornita da James ha funzionato; tuttavia, risultava avere un percorso di codice per il test dell'unità e un altro percorso per il codice di produzione, che ha vanificato lo scopo del test dell'unità. Siamo stati in grado di creare un secondo archivio documenti e collegarlo al primo archivio documenti che ci ha permesso di accedere ai metodi di estensione dell'autorizzazione con successo. Mentre questa soluzione probabilmente non andrebbe bene per il codice di produzione (perché la creazione di archivi di documenti è costosa) funziona bene per i test di unità. Ecco un esempio di codice:

using (var documentStore = new EmbeddableDocumentStore 
     { RunInMemory = true, 
      UseEmbeddedHttpServer = true, 
      Configuration = {Port = EmbeddedModePort} }) 
{ 
    documentStore.Initialize(); 
    var url = documentStore.Configuration.ServerUrl; 

    using (var docStoreHttp = new DocumentStore {Url = url}) 
    { 
     docStoreHttp.Initialize(); 

     using (var session = docStoreHttp.OpenSession()) 
     { 
      // now you can run code like: 
      // session.GetAuthorizationFor(), 
      // session.SetAuthorizationFor(), 
      // session.Advanced.IsOperationAllowedOnDocument(), 
      // etc... 
     } 
    } 
} 

Ci sono un paio di altri elementi che dovrebbero essere menzionato:

  1. Il primo negozio documento deve essere eseguito con l'UseEmbeddedHttpServer impostato su true in modo che la seconda si può accedervi
  2. Ho creato una costante per la porta in modo da essere utilizzata in modo coerente e garantire l'uso di una porta non riservata.
3

Ho riscontrato anche questo. Guardando la fonte, non c'è modo di fare quell'operazione come scritto. Non so se c'è una ragione intrinseca per cui quando ho potuto facilmente replicare la funzionalità nella mia app facendo una richiesta HTTP direttamente per le stesse informazioni:

HttpClient http = new HttpClient(); 
http.BaseAddress = new Uri("http://localhost:8080"); 
var url = new StringBuilder("/authorization/IsAllowed/") 
    .Append(Uri.EscapeUriString(userid)) 
    .Append("?operation=") 
    .Append(Uri.EscapeUriString(operation) 
    .Append("&id=").Append(Uri.EscapeUriString(entityid)); 
http.GetStringAsync(url.ToString()).ContinueWith((response) => 
{ 
    var results = _session.Advanced.DocumentStore.Conventions.CreateSerializer() 
     .Deserialize<OperationAllowedResult[]>(
      new RavenJTokenReader(RavenJToken.Parse(response.Result))); 
}).Wait();