private Yield UpdateHelper(string id, string rev, IPlay aDoc, Result<IPlay> aResult) { //Check if a play with this id exists. Result<IPlay> validPlayResult = new Result<IPlay>(); yield return thePlayDataMapper.Retrieve(aDoc.Id, validPlayResult); if (validPlayResult.Value == null) { aResult.Throw(new ArgumentException()); yield break; } //Check if the current user has the update rights. if (!HasAuthorization(validPlayResult.Value)) { aResult.Throw(new UnauthorizedAccessException()); yield break; } //Check if the source in the play exist and are not null. Coroutine.Invoke(CheckSource, aDoc, new Result()); //Update and return the updated play. Result<IPlay> playResult = new Result<IPlay>(); yield return thePlayDataMapper.Update(id, rev, aDoc, playResult); aResult.Return(playResult.Value); }
/// <summary> /// <para>Deletes a single configuration value from a given section in the /// CouchDB server configuration.</para> /// <para>(This method is asynchronous.)</para> /// </summary> /// <param name="section">The configuration section.</param> /// <param name="keyName">The name of the configuration key.</param> /// <param name="result"></param> /// <returns></returns> public Result DeleteConfigValue( string section, string keyName, Result result) { if (String.IsNullOrEmpty(section)) throw new ArgumentException("section cannot be null nor empty"); if (String.IsNullOrEmpty(keyName)) throw new ArgumentException("keyName cannot be null nor empty"); if (result == null) throw new ArgumentNullException("result"); BasePlug .At(Constants._CONFIG, XUri.EncodeFragment(section), XUri.EncodeFragment(keyName)) .Delete(DreamMessage.Ok(), new Result<DreamMessage>()) .WhenDone( a => { if (a.Status == DreamStatus.Ok) result.Return(); // remove " and "\n else result.Throw(new CouchException(a)); }, result.Throw ); return result; }
private Yield CheckSource(IPlay aPlay, Result aResult) { //can't be null, it must have a source if (aPlay.SourceId == null) { aResult.Throw(new ArgumentException()); yield break; } // if this source exists Result<bool> validSourceResult = new Result<bool>(); yield return Context.Current.Instance.SourceController.Exists(aPlay.SourceId, validSourceResult); if (!validSourceResult.Value) { aResult.Throw(new ArgumentException()); yield break; } aResult.Return(); }
public Result<bool> Logoff(Result<bool> aResult) { if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At("_session").Delete(new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Ok) aResult.Return(true); else aResult.Throw(new CouchException(a)); }, aResult.Throw ); return aResult; }
private Yield CreateHelper(IPlay aDoc, Result<IPlay> aResult) { //Check if user is set as we need to know the creator. if (Context.Current.User == null) { aResult.Throw(new UnauthorizedAccessException()); yield break; } //Check that the sources aren't null and does exists yield return Coroutine.Invoke(CheckSource, aDoc, new Result()); //Insert a the score and return Result<IPlay> resultCreate = new Result<IPlay>(); yield return thePlayDataMapper.Create(aDoc, resultCreate); aResult.Return(resultCreate.Value); }
/* ========================================================================= * Asynchronous methods * =======================================================================*/ /// <summary> /// <para>Adds an attachment to a document. The document revision must be /// specified when using this method.</para> /// <para>(This method is asynchronous.)</para> /// </summary> /// <param name="id">ID of the CouchDB document.</param> /// <param name="rev">Revision of the CouchDB document.</param> /// <param name="attachment">Stream of the attachment. Will be closed once /// the request is sent.</param> /// <param name="attachmentLength">Length of the attachment stream.</param> /// <param name="fileName">Filename of the attachment.</param> /// <param name="contentType">Content type of the document.</param> /// <param name="result"></param> /// <returns></returns> public Result<JObject> AddAttachment( string id, string rev, Stream attachment, long attachmentLength, string fileName, MimeType contentType, Result<JObject> result) { if (String.IsNullOrEmpty(id)) throw new ArgumentNullException("id"); if (String.IsNullOrEmpty(rev)) throw new ArgumentNullException("rev"); if (attachment == null) throw new ArgumentNullException("attachment"); if (attachmentLength < 0) throw new ArgumentOutOfRangeException("attachmentLength"); if (String.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName"); if (contentType == null) throw new ArgumentNullException("contentType"); if (result == null) throw new ArgumentNullException("result"); BasePlug .AtPath(XUri.EncodeFragment(id)) .At(XUri.EncodeFragment(fileName)) .With(Constants.REV, rev) .Put(DreamMessage.Ok(contentType, attachmentLength, attachment), new Result<DreamMessage>()) .WhenDone( a => { if (a.Status == DreamStatus.Created) result.Return(JObject.Parse(a.ToText())); else result.Throw(new CouchException(a)); }, result.Throw ); return result; }
public Result<User> GetUser(string username, Result<User> aResult) { theServiceUri.At("users", username) .Get(new Result<DreamMessage>()) .WhenDone(delegate(Result<DreamMessage> answer) { if (!answer.Value.IsSuccessful) { if (answer.Value.Status == DreamStatus.NotFound) aResult.Return((User)null); aResult.Throw(answer.Exception); } else { aResult.Return(new User(JObject.Parse(answer.Value.ToText()))); } } ); return aResult; }
/* ========================================================================= * Asynchronous methods * =======================================================================*/ /// <summary> /// <para>Restarts the CouchDB instance. You must be authenticated as a user /// with administration privileges for this to work.</para> /// <para>(This method is asynchronous.)</para> /// </summary> /// <param name="result"></param> /// <returns></returns> public Result RestartServer(Result result) { if (result == null) throw new ArgumentNullException("result"); BasePlug .At(Constants._RESTART) .Post(DreamMessage.Ok(MimeType.JSON, String.Empty), new Result<DreamMessage>()) .WhenDone( a => { if (a.Status == DreamStatus.Ok) result.Return(); else result.Throw(new CouchException(a)); }, result.Throw ); return result; }
public Result<bool> BulkFascimile(string sourceId, Stream file, Result<bool> aResult) { theServiceUri .At("sources",sourceId,"fascimiles") .Post(DreamMessage.Ok(new MimeType("application/zip"), file.Length, file),new Result<DreamMessage>()) .WhenDone(delegate(Result<DreamMessage> answer) { if (!answer.Value.IsSuccessful) { if (answer.Value.Status == DreamStatus.BadRequest) aResult.Return(false); else aResult.Throw(answer.Exception); } else { aResult.Return(true); } } ); return aResult; }
public Result<bool> IsLogged(Result<bool> aResult) { if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At("_session").Get(new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Ok) { JObject user = JObject.Parse(a.ToText()); aResult.Return(user["info"]["authenticated"] != null); } else { aResult.Throw(new CouchException(a)); } }, aResult.Throw ); return aResult; }
/// <summary> /// Creates a database /// </summary> /// <param name="aDatabaseName">Name of new database</param> /// <param name="aResult"></param> /// <returns></returns> public Result<JObject> CreateDatabase(string aDatabaseName, Result<JObject> aResult) { if (String.IsNullOrEmpty(aDatabaseName)) throw new ArgumentException("DatabaseName cannot be null nor empty"); if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At(XUri.EncodeFragment(aDatabaseName)).Put(DreamMessage.Ok(), new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Created) { aResult.Return(JObject.Parse(a.ToText())); } else { aResult.Throw(new CouchException(a)); } }, aResult.Throw ); return aResult; }
/// <summary> /// <para>Deletes the specified database.</para> /// <para>(This method is asynchronous.)</para> /// </summary> /// <param name="databaseName">Name of the database to delete.</param> /// <param name="result"></param> /// <returns></returns> public Result<JObject> DeleteDatabase( string databaseName, Result<JObject> result) { if (String.IsNullOrEmpty(databaseName)) throw new ArgumentException("databaseName cannot be null nor empty"); if (result == null) throw new ArgumentNullException("result"); BasePlug .At(XUri.EncodeFragment(databaseName)) .Delete(new Result<DreamMessage>()) .WhenDone( a => { if (a.Status == DreamStatus.Ok) result.Return(JObject.Parse(a.ToText())); else result.Throw(new CouchException(a)); }, result.Throw ); return result; }
private Yield LoadContactsHelper(Result<ViewResult<string,string, Contact>> aResult) { Result<bool> exists = new Result<bool>(); yield return theDatabase.DocumentExists("_design/contactview", exists); if(exists.HasException){ aResult.Throw(exists.Exception); yield break; } if (!exists.Value) { CouchDesignDocument view = new CouchDesignDocument("contactview"); view.Views.Add("all", new CouchView( @"function(doc){ if(doc.type && doc.type == 'contact'){ emit(doc.lastName, doc.firstName) } }")); Result<CouchDesignDocument> creationResult = new Result<CouchDesignDocument>(); yield return theDatabase.CreateDocument(view, creationResult); if(creationResult.HasException) { aResult.Throw(creationResult.Exception); yield break; } } var viewRes = new Result<ViewResult<string, string, Contact>>(); yield return theDatabase.GetView("contactview", "all",viewRes); if(viewRes.HasException) { aResult.Throw(viewRes.Exception); yield break; } aResult.Return(viewRes.Value); }
private Yield DeleteHelper(string id, string rev, Result<bool> aResult) { //Check if a source with this id exists. Result<ISource> validSourceResult = new Result<ISource>(); yield return theSourceDataMapper.Retrieve(id, validSourceResult); if (validSourceResult.Value == null) { aResult.Throw(new ArgumentException(String.Format("Source not found for id '{0}'", id))); yield break; } yield return theSourceDataMapper.Delete(id, rev ?? validSourceResult.Value.Rev, aResult); }
private Result<IssueData[]> ProcessIssueBatch(ElasticThreadPool pool, string projectId, string filterId, int pageNumber, int issuesInBatch, Tuplet<bool> canceled, Result<IssueData[]> result) { pool.QueueWorkItem(HandlerUtil.WithEnv(delegate { // TODO (steveb): use result.IsCanceled instead of shared tuple once cancellation is supported on the result object // check if request has been canceled if(!canceled.Item1) { IssueData[] issuesForBatch; if(!string.IsNullOrEmpty(filterId)) { issuesForBatch = _service.mc_filter_get_issues(_username, _password, projectId, filterId, pageNumber.ToString(), issuesInBatch.ToString()); } else { issuesForBatch = _service.mc_project_get_issues(_username, _password, projectId, pageNumber.ToString(), issuesInBatch.ToString()); } result.Return(issuesForBatch); } else { // TODO (steveb): throw a more specific exception result.Throw(new Exception("unspecified error")); } },TaskEnv.Clone())); return result; }
private Result Write(Action<string> activity, Stream stream, byte[] buffer, int offset, int count, Result result) { // asynchronously execute read operation Result<IAsyncResult> inner = new Result<IAsyncResult>(TimeSpan.MaxValue); inner.WhenDone(delegate(Result<IAsyncResult> _unused) { try { activity(string.Format("pre {0}!EndWrite", stream.GetType().FullName)); stream.EndWrite(inner.Value); activity("post EndWrite"); result.Return(); } catch(Exception e) { activity("throw Write 1"); result.Throw(e); } }); try { activity(string.Format("pre {0}!BeginWrite", stream.GetType().FullName)); stream.BeginWrite(buffer, offset, count, inner.Return, stream); activity("post BeginWrite"); } catch(Exception e) { activity("throw Write 2"); result.Throw(e); } // return yield handle return result; }
private Yield UpdateHelper(string id, string rev, ISource aDoc, Result<ISource> aResult) { //Check if a source with this id exists. Result<ISource> validSourceResult = new Result<ISource>(); yield return theSourceDataMapper.Retrieve(id, validSourceResult); if (validSourceResult.Value == null) { aResult.Throw(new ArgumentException(String.Format("Source not found for id '{0}'",id))); yield break; } //Update and return the updated source. Result<ISource> sourceResult = new Result<ISource>(); yield return theSourceDataMapper.Update(id, rev ?? validSourceResult.Value.Rev , aDoc, sourceResult); aResult.Return(sourceResult.Value); }
public Result<JObject> TriggerReplication(ReplicationOptions aReplicationOptions, Result<JObject> aResult) { if (aReplicationOptions == null) throw new ArgumentNullException("aReplicationOptions"); if (aResult == null) throw new ArgumentNullException("aResult"); Plug p = BasePlug.At(Constants.REPLICATE); string json = aReplicationOptions.ToString(); p.Post(DreamMessage.Ok(MimeType.JSON, json), new Result<DreamMessage>()).WhenDone( a => { if((a.Status == DreamStatus.Accepted)|| (a.Status == DreamStatus.Ok)) { aResult.Return(JObject.Parse(a.ToText())); } else { aResult.Throw(new CouchException(a)); } }, aResult.Throw ); return aResult; }
private Yield UpdateHelper(string id, string rev, IScore aDoc, Result<IScore> aResult) { //Check if a score with this id exists. Result<IScore> validScoreResult = new Result<IScore>(); yield return theScoreDataMapper.Retrieve(aDoc.Id, validScoreResult); if (validScoreResult.Value == null) { aResult.Throw(new ArgumentException()); yield break; } //Check if the sources in the score exists and are not null. Coroutine.Invoke(CheckSources, aDoc, new Result()); //Update and return the updated score. Result<IScore> scoreResult = new Result<IScore>(); yield return theScoreDataMapper.Update(id, rev, aDoc, scoreResult); aResult.Return(scoreResult.Value); }
private Yield GetPlaysFromSourceHelper(int offset, int max, string aSourceId, Result<SearchResult<IPlay>> aResult) { //Check if the play exists Result<bool> resultExists = new Result<bool>(); yield return Context.Current.Instance.SourceController.Exists(aSourceId, resultExists); if (resultExists.Value) { //Get the plays that have this source id as textual or musical source. Result<SearchResult<IPlay>> resultSearch = new Result<SearchResult<IPlay>>(); yield return thePlayDataMapper.GetPlaysFromSource(offset, max, aSourceId, resultSearch); aResult.Return(resultSearch.Value); } else aResult.Throw(new DreamNotFoundException("Source not found")); }
public Result<Dictionary<string, Dictionary<string, string>>> GetConfig(Result<Dictionary<string, Dictionary<string, string>>> aResult) { if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At(Constants.CONFIG).Get(DreamMessage.Ok(), new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Ok) aResult.Return(JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(a.ToText())); else aResult.Throw(new CouchException(a)); }, aResult.Throw ); return aResult; }
/// <summary> /// Perform Cookie base authentication with given username and password /// Resulting cookie will be automatically used for all subsequent requests /// </summary> /// <param name="aUserName">User Name</param> /// <param name="aPassword">Password</param> /// <param name="aResult"></param> /// <returns>true if authentication succeed</returns> public Result<bool> Logon(string aUserName, string aPassword, Result<bool> aResult) { if (String.IsNullOrEmpty(aUserName)) throw new ArgumentException("aUserName cannot be null nor empty"); if (String.IsNullOrEmpty(aPassword)) throw new ArgumentException("aPassword cannot be null nor empty"); if (aResult == null) throw new ArgumentNullException("aResult"); string content = String.Format("name={0}&password={1}", aUserName, aPassword); BasePlug.At("_session").Post(DreamMessage.Ok(MimeType.FORM_URLENCODED,content), new Result<DreamMessage>()).WhenDone( a => { switch(a.Status) { case DreamStatus.Ok: BasePlug.CookieJar.Update(a.Cookies, new XUri(BasePlug.Uri.SchemeHostPort)); BasePlug = BasePlug.WithHeader("X-CouchDB-WWW-Authenticate", "Cookie"); aResult.Return(true); break; default: aResult.Throw(new CouchException(a)); break; } }, aResult.Throw ); return aResult; }
private Result<DreamMessage> SubmitRequestAsync(string verb, XUri uri, IPrincipal user, DreamMessage request, Result<DreamMessage> response, Action completion) { if(string.IsNullOrEmpty(verb)) { if(completion != null) { completion(); } throw new ArgumentNullException("verb"); } if(uri == null) { if(completion != null) { completion(); } throw new ArgumentNullException("uri"); } if(request == null) { if(completion != null) { completion(); } throw new ArgumentNullException("request"); } if(response == null) { if(completion != null) { completion(); } throw new ArgumentNullException("response"); } // ensure environment is still running if(!IsRunning) { response.Return(DreamMessage.InternalError("host not running")); if(completion != null) { completion(); } return response; } try { Interlocked.Increment(ref _requestCounter); // check if we were not able to begin processing the request DreamMessage failed = BeginRequest(completion, uri, request); if(failed != null) { response.Return(failed); EndRequest(completion, uri, request); return response; } // check if 'verb' is overwritten by a processing parameter verb = verb.ToUpperInvariant(); string requestedVerb = (uri.GetParam(DreamInParam.VERB, null) ?? request.Headers.MethodOverride ?? verb).ToUpperInvariant(); if( verb.EqualsInvariant(Verb.POST) || ( verb.EqualsInvariant(Verb.GET) && ( requestedVerb.EqualsInvariant(Verb.OPTIONS) || requestedVerb.EqualsInvariant(Verb.HEAD) ) ) ) { verb = requestedVerb; } // check if an origin was specified request.Headers.DreamOrigin = uri.GetParam(DreamInParam.ORIGIN, request.Headers.DreamOrigin); // check if a public uri is supplied XUri publicUri = XUri.TryParse(uri.GetParam(DreamInParam.URI, null) ?? request.Headers.DreamPublicUri); XUri transport = XUri.TryParse(request.Headers.DreamTransport) ?? uri.WithoutCredentialsPathQueryFragment(); if(publicUri == null) { // check if request is local if(transport.Scheme.EqualsInvariantIgnoreCase("local")) { // local:// uris with no public-uri specifier default to the configured public-uri publicUri = _publicUri; } else { // check if the request was forwarded through Apache mod_proxy string proxyOverride = uri.GetParam(DreamInParam.HOST, null); if(string.IsNullOrEmpty(proxyOverride)) { proxyOverride = request.Headers.ForwardedHost; } string serverPath = string.Join("/", transport.Segments); if(proxyOverride != null) { // request used an override, append path of public-uri serverPath = string.Join("/", _publicUri.Segments); } // set the uri scheme based-on the incoming scheme and the override header string scheme = transport.Scheme; if("On".EqualsInvariantIgnoreCase(request.Headers.FrontEndHttps ?? "")) { scheme = Scheme.HTTPS; } scheme = uri.GetParam(DreamInParam.SCHEME, scheme); // set the host port string hostPort = proxyOverride ?? request.Headers.Host ?? uri.HostPort; publicUri = new XUri(string.Format("{0}://{1}", scheme, hostPort)).AtPath(serverPath); } request.Headers.DreamPublicUri = publicUri.ToString(); } // set host header request.Headers.Host = publicUri.HostPort; // convert incoming uri to local:// XUri localFeatureUri = uri.ChangePrefix(uri.WithoutPathQueryFragment(), _localMachineUri); // check if path begins with public uri path if((transport.Segments.Length > 0) && localFeatureUri.PathStartsWith(transport.Segments)) { localFeatureUri = localFeatureUri.WithoutFirstSegments(transport.Segments.Length); } // check if the path is the application root and whether we have special behavior for that if(localFeatureUri.Path.IfNullOrEmpty("/") == "/") { if(!string.IsNullOrEmpty(_rootRedirect)) { localFeatureUri = localFeatureUri.AtAbsolutePath(_rootRedirect); } else if(IsDebugEnv) { localFeatureUri = localFeatureUri.AtAbsolutePath("/host/services"); } } // find the requested feature List<DreamFeature> features; lock(_features) { features = _features.Find(localFeatureUri); } DreamFeature feature = null; if(features != null) { // TODO (steveb): match the incoming mime-type to the feature's acceptable mime-types (mime-type overloading) // match the request verb to the feature verb foreach(DreamFeature entry in features) { if((entry.Verb == "*") || entry.Verb.EqualsInvariant(verb)) { feature = entry; break; } } // check if this is an OPTIONS request and there is no defined feature for it if(verb.EqualsInvariant(Verb.OPTIONS) && ((feature == null) || feature.Verb.EqualsInvariant("*"))) { // list all allowed methods List<string> methods = new List<string>(); foreach(DreamFeature entry in features) { if(!methods.Contains(entry.Verb)) { methods.Add(entry.Verb); } } methods.Sort(StringComparer.Ordinal.Compare); DreamMessage result = DreamMessage.Ok(); result.Headers.Allow = string.Join(", ", methods.ToArray()); response.Return(result); // decrease counter for external requests EndRequest(completion, uri, request); return response; } } // check if a feature was found if(feature == null) { DreamMessage result; // check if any feature was found if((features == null) || (features.Count == 0)) { string msg = verb + " URI: " + uri.ToString(false) + " LOCAL: " + localFeatureUri.ToString(false) + " PUBLIC: " + publicUri + " TRANSPORT: " + transport; _log.WarnMethodCall("ProcessRequest: feature not found", msg); result = DreamMessage.NotFound("resource not found"); } else { string msg = verb + " " + uri.ToString(false); _log.WarnMethodCall("ProcessRequest: method not allowed", msg); List<string> methods = new List<string>(); foreach(DreamFeature entry in features) { if(!methods.Contains(entry.Verb)) { methods.Add(entry.Verb); } } methods.Sort(StringComparer.Ordinal.Compare); result = DreamMessage.MethodNotAllowed(methods.ToArray(), "allowed methods are " + string.Join(", ", methods.ToArray())); } response.Return(result); // decrease counter for external requests EndRequest(completion, uri, request); return response; } // add uri to aliases list if(_memorizeAliases) { lock(_aliases) { _aliases[transport] = transport; _aliases[publicUri] = publicUri; } } // create context DreamContext context = new DreamContext(this, verb, localFeatureUri, feature, publicUri, _publicUri, request, CultureInfo.InvariantCulture, GetRequestLifetimeScopeFactory(feature.Service)); // attach request id to the context context.SetState(DreamHeaders.DREAM_REQUEST_ID, request.Headers.DreamRequestId); // add user to context context.User = user; // build linked-list of feature calls var chain = new Result<DreamMessage>(TimeSpan.MaxValue, TaskEnv.Current).WhenDone(result => { // extract message DreamMessage message; if(result.HasValue) { message = result.Value; } else if(result.Exception is DreamAbortException) { message = ((DreamAbortException)result.Exception).Response; } else if(result.Exception is DreamCachedResponseException) { message = ((DreamCachedResponseException)result.Exception).Response; } else { _log.ErrorExceptionFormat(response.Exception, "Failed Feature '{0}' Chain [{1}:{2}]: {3}", feature.MainStage.Name, verb, localFeatureUri.Path, response.Exception.Message ); message = DreamMessage.InternalError(result.Exception); } // decrease counter for external requests EndRequest(completion, uri, request); // need to manually dispose of the context, since we're already attaching and detaching it by hand to TaskEnvs throughout the chain if(response.IsCanceled) { _log.DebugFormat("response for '{0}' has already returned", context.Uri.Path); response.ConfirmCancel(); ((ITaskLifespan)context).Dispose(); } else { ((ITaskLifespan)context).Dispose(); response.Return(message); } }); for(int i = feature.Stages.Length - 1; i >= 0; --i) { var link = new DreamFeatureChain(feature.Stages[i], i == feature.MainStageIndex, context, chain, (i > 0) ? feature.Stages[i - 1].Name : "first"); chain = new Result<DreamMessage>(TimeSpan.MaxValue, TaskEnv.Current).WhenDone(link.Handler); } // kick-off new task AsyncUtil.Fork( () => chain.Return(request), TaskEnv.New(TimerFactory), new Result(TimeSpan.MaxValue, response.Env).WhenDone(res => { if(!res.HasException) { return; } _log.ErrorExceptionFormat(res.Exception, "handler for {0}:{1} failed", context.Verb, context.Uri.ToString(false)); ((ITaskLifespan)context).Dispose(); // forward exception to recipient response.Throw(res.Exception); // decrease counter for external requests EndRequest(completion, uri, request); }) ); } catch(Exception e) { response.Throw(e); EndRequest(completion, uri, request); } return response; }
public Result<Dictionary<string, string>> GetConfigSection(string aSection, Result<Dictionary<string, string>> aResult) { if (aSection == null) throw new ArgumentNullException("aSection"); if (aResult == null) throw new ArgumentNullException("aResult"); if (String.IsNullOrEmpty(aSection)) throw new ArgumentException("Section cannot be empty"); BasePlug.At(Constants.CONFIG,XUri.EncodeFragment(aSection)).Get(DreamMessage.Ok(), new Result<DreamMessage>()).WhenDone( a => { switch(a.Status) { case DreamStatus.Ok: aResult.Return(JsonConvert.DeserializeObject<Dictionary<string, string>>(a.ToText())); break; case DreamStatus.NotFound: aResult.Return(new Dictionary<string, string>()); break; default: aResult.Throw(new CouchException(a)); break; } }, aResult.Throw ); return aResult; }
public Result<string> GetConfigValue(string aSection, string aKeyName, Result<string> aResult) { if (String.IsNullOrEmpty(aSection)) throw new ArgumentException("aSection cannot be null nor empty"); if (String.IsNullOrEmpty(aKeyName)) throw new ArgumentException("aKeyName cannot be null nor empty"); if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At(Constants.CONFIG,XUri.EncodeFragment(aSection),XUri.EncodeFragment(aKeyName)).Get(DreamMessage.Ok(), new Result<DreamMessage>()).WhenDone( a => { string value = a.ToText(); switch(a.Status) { case DreamStatus.Ok: aResult.Return(value.Substring(1, value.Length - 3));// remove " and "\n break; case DreamStatus.NotFound: aResult.Return((string)null); break; default: aResult.Throw(new CouchException(a)); break; } }, aResult.Throw ); return aResult; }
private void ReturnUserError(Exception exception, Result<DreamMessage> response) { var dreamException = exception as DreamResponseException; if(dreamException != null) { response.Throw(new DreamAbortException(dreamException.Response)); } else if(exception is UserException) { response.Throw(new DreamBadRequestException(exception.Message)); } else { response.Throw(exception); } }
//--- Methods --- /// <summary> /// Invoke the stage method. /// </summary> /// <param name="context"><see cref="DreamContext"/> for invocation.</param> /// <param name="request"><see cref="DreamMessage"/> for invocation.</param> /// <param name="response"><see cref="Result{DreamMessage}"/> for invocations.</param> public void Invoke(DreamContext context, DreamMessage request, Result<DreamMessage> response) { if(_handler != null) { Coroutine.Invoke(_handler, context, request, response); } else { try { // build parameter list var arguments = new object[_plan.Count]; for(int i = 0; i < _plan.Count; ++i) { try { arguments[i] = _plan[i].Invoke(context, request, response); } catch(DreamException e) { throw e; } catch(Exception e) { throw new FeatureArgumentParseException(_plan[i].ArgumentName, e); } } // invoke method if(_method.ReturnType == typeof(Yield)) { // invoke method as coroutine new Coroutine(_method, response).Invoke(() => (Yield)_method.InvokeWithRethrow(_service, arguments)); } else if(_method.ReturnType == typeof(XDoc)) { // invoke method to get XDoc response (always an Ok) var doc = _method.InvokeWithRethrow(_service, arguments) as XDoc; response.Return(DreamMessage.Ok(doc)); } else { response.Return((DreamMessage)_method.InvokeWithRethrow(_service, arguments)); } } catch(Exception e) { response.Throw(e); } } }
/// <summary> /// Retrieve list of available databases on the server /// </summary> /// <param name="aResult"></param> /// <returns></returns> public Result<IEnumerable<string>> GetAllDatabases(Result<IEnumerable<string>> aResult) { if (aResult == null) throw new ArgumentNullException("aResult"); BasePlug.At("_all_dbs").Get(new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Ok) { var d = JArray.Parse(a.ToText()); aResult.Return(d.Values<string>()); } else { aResult.Throw(new CouchException(a)); } }, aResult.Throw ); return aResult; }
private Yield Memorize_Helper(long max, Result result) { // NOTE (steveb): this method is used to load an external stream into memory; this alleviates the problem of streams not being closed for simple operations if(max < 0) { max = long.MaxValue - 1; } // check if we already know that the stream will not fit long length = ContentLength; if(length > max) { // mark stream as closed _stream.Close(); _stream = null; _streamOpen = false; // throw size exceeded exception result.Throw(new InternalBufferOverflowException("message body exceeded max size")); yield break; } if(length < 0) { length = long.MaxValue; } // NOTE: the content-length and body length may differ (e.g. HEAD verb) // copy contents asynchronously var buffer = new MemoryStream(); Result<long> res; // TODO (steveb): use WithCleanup() to dispose of resources in case of failure yield return res = _stream.CopyToStream(buffer, Math.Min(length, max + 1), new Result<long>(TimeSpan.MaxValue)).Catch(); // mark stream as closed _stream.Close(); _stream = null; _streamOpen = false; // confirm successful outcome for asynchronous operation res.Confirm(); if(buffer.Length > max) { result.Throw(new InternalBufferOverflowException("message body exceeded max size")); yield break; } buffer.Position = 0; _stream = buffer; result.Return(); }
public Result SetConfigValue(string aSection, string aKeyName, string aValue, Result aResult) { if (String.IsNullOrEmpty(aSection)) throw new ArgumentException("aSection cannot be null nor empty"); if (String.IsNullOrEmpty(aKeyName)) throw new ArgumentException("aKeyName cannot be null nor empty"); if (aResult == null) throw new ArgumentNullException("aResult"); if (aValue == null) return DeleteConfigValue(aSection, aKeyName, aResult); BasePlug.At(Constants.CONFIG, XUri.EncodeFragment(aSection), XUri.EncodeFragment(aKeyName)).Put(DreamMessage.Ok(MimeType.TEXT, "\"" + aValue + "\""), new Result<DreamMessage>()).WhenDone( a => { if (a.Status == DreamStatus.Ok) aResult.Return(); else aResult.Throw(new CouchException(a)); }, aResult.Throw ); return aResult; }