Beispiel #1
0
        /// <summary>
        /// Attach a callback that performs new asyncronous work when the original promise fails
        /// </summary>
        public static IPromise <T> FailOver <T>(this IPromise <T> promise, Func <IPromise <T> > callback)
        {
            var result = new Promise <T>();

            result.CancelTarget(
                promise
                .Progress((p, m) => result.Notify(p / 50, m))
                .Done(t => result.Resolve(t))
                .Fail(exT =>
            {
                try
                {
                    result.CancelTarget(
                        callback()
                        .Progress((p, m) => result.Notify(50 + p / 50, m))
                        .Done(s => result.Resolve(s))
                        .Fail(exS => result.Reject(exS)));
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            }));
            return(result);
        }
        /// <summary>
        /// Get a single item from the database using the specified query asynchronously.  If the result is not a single item, an exception will be thrown
        /// </summary>
        /// <param name="conn">Server connection</param>
        /// <param name="request">Query/command which should return a single item</param>
        /// <param name="async">Whether to perform this request asynchronously</param>
        /// <returns>A promise to return a single readonly item</returns>
        public static IPromise <IReadOnlyItem> ItemByQuery(this IConnection conn, Command request, bool async)
        {
            var result = new Promise <IReadOnlyItem>();

            result.CancelTarget(conn.ProcessAsync(request, async)
                                .Progress((p, m) => result.Notify(p, m))
                                .Done(r =>
            {
                if (string.IsNullOrEmpty(conn.UserId))
                {
                    result.Reject(new LoggedOutException());
                }
                else
                {
                    var res = conn.AmlContext.FromXml(r, request, conn);
                    var ex  = res.Exception;
                    if (ex == null)
                    {
                        try
                        {
                            result.Resolve(res.AssertItem());
                        }
                        catch (Exception exc)
                        {
                            result.Reject(exc);
                        }
                    }
                    else
                    {
                        result.Reject(ex);
                    }
                }
            }).Fail(ex => result.Reject(ex)));
            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Convert a promise by modifying the done/fail logic in addition to transforming the type.
        /// </summary>
        public static IPromise <S> Convert <T, S>(this IPromise <T> promise, Action <T, Promise <S> > doneCallback, Action <Exception, Promise <S> > failCallback)
        {
            var result = new Promise <S>();

            result.CancelTarget(
                promise
                .Progress((p, m) => result.Notify(p, m))
                .Done(d =>
            {
                doneCallback.Invoke(d, result);
            }).Fail(ex => failCallback.Invoke(ex, result)));
            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Convert a promise using a simple transformation to go from one type to another
        /// </summary>
        public static IPromise <S> Convert <T, S>(this IPromise <T> promise, Func <T, S> callback)
        {
            var result = new Promise <S>();

            result.CancelTarget(
                promise
                .Progress((p, m) => result.Notify(p, m))
                .Done(d =>
            {
                try
                {
                    result.Resolve(callback.Invoke(d));
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            }).Fail(ex => result.Reject(ex)));
            return(result);
        }
        private static IPromise <IReadOnlyResult> ApplyAsyncInt(this IAsyncConnection conn, Command query, CancellationToken ct, params object[] parameters)
        {
            var result = new Promise <IReadOnlyResult>();

            query.WithAml(query.Aml, parameters);

            ct.Register(() => result.Cancel());

            result.CancelTarget(
                conn.Process(query, true)
                .Progress((p, m) => result.Notify(p, m))
                .Done(r =>
            {
                try
                {
                    if (query.Action == CommandAction.ApplySQL)
                    {
                        var res = ElementFactory.Utc.FromXml(r, query, conn);
                        result.Resolve(res);
                    }
                    else
                    {
                        var res = conn.AmlContext.FromXml(r, query, conn);
                        result.Resolve(res);
                    }
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            }).Fail(ex =>
            {
                result.Reject(ex);
            }));
            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// Asynchronously gets an HTTP connection to an innovator instance (or proxy) at the given URL
        /// </summary>
        /// <param name="preferences">Object containing preferences for the connection</param>
        /// <param name="async">Whether or not to return the connection asynchronously.  This is important
        /// as an HTTP request must be issued to determine the type of connection to create</param>
        /// <returns>A promise to return a connection object</returns>
        public static IPromise <IRemoteConnection> GetConnection(ConnectionPreferences preferences, bool async)
        {
            preferences = preferences ?? new ConnectionPreferences();
            var url = preferences.Url;

            url = (url ?? "").TrimEnd('/');
            if (url.EndsWith("Server/InnovatorServer.aspx", StringComparison.OrdinalIgnoreCase))
            {
                url = url.Substring(0, url.Length - 21);
            }
            if (!url.EndsWith("/server", StringComparison.OrdinalIgnoreCase))
            {
                url += "/Server";
            }
            var configUrl = url + "/mapping.xml";

            var masterService = preferences.HttpService ?? DefaultService.Invoke();
            var arasSerice    = preferences.HttpService ?? DefaultService.Invoke();
            Func <ServerMapping, IRemoteConnection> connFactory = m =>
            {
                var uri = (m.Url ?? "").TrimEnd('/');
                if (!uri.EndsWith("/server", StringComparison.OrdinalIgnoreCase))
                {
                    url += "/Server";
                }
                switch (m.Type)
                {
                case ServerType.Proxy:
                    throw new NotSupportedException();

                default:
                    return(ArasConn(arasSerice, uri, preferences));
                }
            };

            var result = new Promise <IRemoteConnection>();
            var req    = new HttpRequest();

            req.UserAgent = preferences.Headers.UserAgent;
            req.SetHeader("Accept", "text/xml");
            foreach (var header in preferences.Headers.NonUserAgentHeaders())
            {
                req.SetHeader(header.Key, header.Value);
            }

            var trace = new LogData(4, "Innovator: Try to download mapping file", Factory.LogListener)
            {
                { "url", configUrl },
            };

            result.CancelTarget(masterService.GetPromise(new Uri(configUrl), async, trace, req)
                                .Progress((p, m) => result.Notify(p, m))
                                .Done(r =>
            {
                var data = r.AsString();
                if (string.IsNullOrEmpty(data))
                {
                    result.Resolve(ArasConn(arasSerice, url, preferences));
                }
                else
                {
                    try
                    {
                        var servers = ServerMapping.FromXml(data).ToArray();
                        if (servers.Length < 1)
                        {
                            result.Resolve(ArasConn(arasSerice, url, preferences));
                        }
                        else if (servers.Length == 1)
                        {
                            result.Resolve(connFactory(servers.Single()));
                        }
                        else
                        {
                            foreach (var server in servers)
                            {
                                server.Factory = connFactory;
                            }
                            result.Resolve(new MappedConnection(servers, preferences.AuthCallback));
                        }
                    }
                    catch (XmlException)
                    {
                        result.Resolve(ArasConn(arasSerice, url, preferences));
                    }
                }
            }).Fail(ex =>
            {
                result.Resolve(ArasConn(arasSerice, url, preferences));
            })).Always(trace.Dispose);


            if (preferences.Credentials != null)
            {
                IRemoteConnection conn = null;
                return(result
                       .Continue(c =>
                {
                    conn = c;
                    return c.Login(preferences.Credentials, async);
                })
                       .Convert(u => conn));
            }

            return(result);
        }