public override IPromise <Stream> Commit(bool async)
        {
            if (Status != UploadStatus.Pending)
            {
                return(_lastPromise);
            }

            Status       = UploadStatus.Committed;
            _lastPromise = Promises.All(Files
                                        .Where(f => f.UploadPromise != null)
                                        .Select(f => f.UploadPromise)
                                        .ToArray())
                           .Continue(l =>
            {
                var errorResult = l
                                  .Select(s => _conn.AmlContext.FromXml((Stream)s))
                                  .FirstOrDefault(r => r.Exception != null);
                if (errorResult == null)
                {
                    return(UploadAndApply(async));
                }
                else
                {
                    var memStream = new MemoryStream();
                    var xml       = XmlWriter.Create(memStream);
                    errorResult.ToAml(xml);
                    memStream.Position = 0;
                    return(Promises.Resolved((Stream)memStream));
                }
            });
            return(_lastPromise);
        }
        /// <summary>
        /// Adds a file <c>Item</c> query to the request where the path to the file is specified as the
        /// <c>actual_filename</c> property, and possibly the <c>actual_data</c> property.
        /// </summary>
        /// <param name="query">Query to add to the request</param>
        /// <param name="async">Whether to perform this action asynchronously</param>
        public IPromise UploadFileQuery(XmlReader query, bool async)
        {
            var elem  = XElement.Load(query);
            var files = elem.DescendantsAndSelf("Item")
                        .Where(e => e.Attributes("type").Any(a => a.Value == "File") &&
                               e.Elements("actual_filename").Any(p => !string.IsNullOrEmpty(p.Value)) &&
                               e.Attributes("id").Any(p => !string.IsNullOrEmpty(p.Value)) &&
                               e.Attributes("action").Any(p => !string.IsNullOrEmpty(p.Value)));

            return(Promises.All(files.Select(file =>
            {
                var dataElem = file.Element("actual_data");
                IPromise <string> promise;
                if (dataElem == null)
                {
                    promise = UploadFile(file.Attribute("id").Value, file.Element("actual_filename").Value
                                         , null, async);
                }
                else
                {
                    var encoding = dataElem.Attribute("encoding");
                    var data = encoding != null && string.Equals(encoding.Value, "base64", StringComparison.OrdinalIgnoreCase)
            ? Convert.FromBase64String(dataElem.Value)
            : Encoding.UTF8.GetBytes(dataElem.Value);
                    var stream = new MemoryStream(data);

                    promise = UploadFile(file.Attribute("id").Value, file.Element("actual_filename").Value
                                         , stream, async);
                }

                return promise.Convert(xml =>
                {
                    var newElem = XElement.Parse(xml);
                    if (file.Parent != null)
                    {
                        MergeIfMissing(newElem, file);
                        return null;
                    }
                    return newElem;
                });
            }).ToArray())
                   .Done(l =>
            {
                var newElem = l.OfType <XElement>().FirstOrDefault(e => e != null);
                base.AddAml(newElem != null ? newElem.ToString() : elem.ToString());
            }));
        }
        public override IPromise <Stream> Rollback(bool async)
        {
            if (Status == UploadStatus.RolledBack)
            {
                return(_lastPromise);
            }

            Status       = UploadStatus.RolledBack;
            _lastPromise = Promises.All(Files
                                        .Where(f => f.UploadPromise != null)
                                        .Select(f => f.UploadPromise.Continue(s =>
            {
                var result = _conn.AmlContext.FromXml(s);
                if (result.Exception != null)
                {
                    return(Promises.Resolved((Stream) new MemoryStream()));
                }

                return(_conn.Process(new Command("<Item type='File' action='delete' id='@0' />", f.Id), async));
            })).ToArray())
                           .Convert(l => l.OfType <Stream>().FirstOrDefault() ?? new MemoryStream());
            return(_lastPromise);
        }
Example #4
0
        public override IPromise <Stream> Commit(bool async)
        {
            if (Status != UploadStatus.Pending)
            {
                return(_lastPromise);
            }

            Status = UploadStatus.Committed;
            // No transaction has been started
            if (_transactionId == null && !Files.Any(f => f.UploadPromise != null))
            {
                _lastPromise = UploadAndApply(async);
            }
            else
            {
                var transactionId = default(string);
                _lastPromise = BeginTransaction(async)
                               .Continue(t =>
                {
                    transactionId = t;
                    return(Promises.All(Files
                                        .Select(f => f.UploadPromise ?? UploadFile(f, async))
                                        .ToArray()));
                })
                               .Continue(l =>
                {
                    var aml     = this.ToNormalizedAml(_conn.AmlContext.LocalizationContext);
                    var content = new FormContent
                    {
                        {
                            "XMLData",
                            "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:i18n=\"http://www.aras.com/I18N\"><SOAP-ENV:Body><ApplyItem>"
                            + aml
                            + "</ApplyItem></SOAP-ENV:Body></SOAP-ENV:Envelope>"
                        }
                    };

                    var req = new HttpRequest()
                    {
                        Content = content
                    };
                    _conn.SetDefaultHeaders(req.SetHeader);
                    foreach (var ac in _conn.DefaultSettings)
                    {
                        ac.Invoke(req);
                    }
                    Settings?.Invoke(req);
                    req.SetHeader("SOAPAction", "CommitTransaction");
                    req.SetHeader("VAULTID", Vault.Id);
                    req.SetHeader("transactionid", transactionId);

                    var trace = new LogData(4
                                            , "Innovator: Execute vault query"
                                            , LogListener ?? Factory.LogListener
                                            , Parameters)
                    {
                        { "aras_url", _conn.MapClientUrl("../../Server") },
                        { "database", _conn.Database },
                        { "query", aml },
                        { "soap_action", "CommitTransaction" },
                        { "url", Vault.Url },
                        { "user_id", _conn.UserId },
                        { "vault_id", Vault.Id },
                        { "version", _conn.Version }
                    };
                    return(Vault.HttpClient.PostPromise(new Uri(Vault.Url), async, req, trace).Always(trace.Dispose));
                })
                               .Convert(r => r.AsStream);
            }
            return(_lastPromise);
        }