public IActionResult GetResult(string id)
        {
            using (_tracer.Step("DeploymentService.GetResult"))
            {
                DeployResult pending;
                if (IsLatestPendingDeployment(ref id, out pending))
                {
                    Response.GetTypedHeaders().Location = new Uri(Request.GetDisplayUrl());
                    pending.Status = DeployStatus.Pending;
                    return(Accepted(ArmUtils.AddEnvelopeOnArmRequest(pending, Request)));
                }

                DeployResult result = _deploymentManager.GetResult(id);

                if (result == null)
                {
                    return(NotFound(String.Format(CultureInfo.CurrentCulture,
                                                  Resources.Error_DeploymentNotFound,
                                                  id)));
                }

                if (_deploymentLock.IsHeld)
                {
                    result.Status = DeployStatus.Pending;
                }

                Uri baseUri = kUriHelper.MakeRelative(kUriHelper.GetBaseUri(Request), new Uri(Request.GetDisplayUrl()).AbsolutePath);
                result.Url    = baseUri;
                result.LogUrl = kUriHelper.MakeRelative(baseUri, "log");

                return(Ok(ArmUtils.AddEnvelopeOnArmRequest(result, Request)));
            }
        }
Exemple #2
0
        public HttpResponseMessage GetResult(string id)
        {
            using (_tracer.Step("DeploymentService.GetResult"))
            {
                DeployResult pending;
                if (IsLatestPendingDeployment(ref id, out pending))
                {
                    var response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(pending, Request));
                    if (ArmUtils.IsArmRequest(Request) && Request.Headers.Referrer != null && Request.Headers.Referrer.AbsolutePath.EndsWith(Constants.LatestDeployment, StringComparison.OrdinalIgnoreCase))
                    {
                        response.Headers.Location = Request.Headers.Referrer;
                    }
                    else
                    {
                        response.Headers.Location = Request.RequestUri;
                    }
                    return(response);
                }

                DeployResult result = _deploymentManager.GetResult(id);

                if (result == null)
                {
                    var response = Request.CreateErrorResponse(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture,
                                                                                                      Resources.Error_DeploymentNotFound,
                                                                                                      id));
                    throw new HttpResponseException(response);
                }

                Uri baseUri = UriHelper.MakeRelative(UriHelper.GetBaseUri(Request), Request.RequestUri.AbsolutePath);
                result.Url    = baseUri;
                result.LogUrl = UriHelper.MakeRelative(baseUri, "log");

                if (ArmUtils.IsArmRequest(Request))
                {
                    switch (result.Status)
                    {
                    case DeployStatus.Building:
                    case DeployStatus.Deploying:
                    case DeployStatus.Pending:
                        result.ProvisioningState = "InProgress";
                        HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.OK, ArmUtils.AddEnvelopeOnArmRequest(result, Request));
                        responseMessage.Headers.Location = Request.RequestUri;
                        return(responseMessage);

                    case DeployStatus.Failed:
                        result.ProvisioningState = "Failed";
                        break;

                    case DeployStatus.Success:
                        result.ProvisioningState = "Succeeded";
                        break;

                    default:
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, ArmUtils.AddEnvelopeOnArmRequest(result, Request)));
                    }
                }
                return(Request.CreateResponse(HttpStatusCode.OK, ArmUtils.AddEnvelopeOnArmRequest(result, Request)));
            }
        }
        public HttpResponseMessage GetResult(string id)
        {
            using (_tracer.Step("DeploymentService.GetResult"))
            {
                DeployResult pending;
                if (IsLatestPendingDeployment(ref id, out pending))
                {
                    var response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(pending, Request));
                    response.Headers.Location = Request.RequestUri;
                    return(response);
                }

                DeployResult result = _deploymentManager.GetResult(id);

                if (result == null)
                {
                    var response = Request.CreateErrorResponse(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture,
                                                                                                      Resources.Error_DeploymentNotFound,
                                                                                                      id));
                    throw new HttpResponseException(response);
                }

                Uri baseUri = UriHelper.MakeRelative(UriHelper.GetBaseUri(Request), Request.RequestUri.AbsolutePath);
                result.Url    = baseUri;
                result.LogUrl = UriHelper.MakeRelative(baseUri, "log");

                return(Request.CreateResponse(HttpStatusCode.OK, ArmUtils.AddEnvelopeOnArmRequest(result, Request)));
            }
        }
        private bool IsLatestPendingDeployment(ref string id, out DeployResult pending)
        {
            if (String.Equals(Constants.LatestDeployment, id))
            {
                using (_tracer.Step("DeploymentService.GetLatestDeployment"))
                {
                    var results = _deploymentManager.GetResults();
                    pending = results.Where(r => r.Status != DeployStatus.Success && r.Status != DeployStatus.Failed).FirstOrDefault();
                    if (pending != null)
                    {
                        _tracer.Trace("Deployment {0} is {1}", pending.Id, pending.Status);
                        return(true);
                    }

                    var latest = results.Where(r => r.EndTime != null).OrderBy(r => r.EndTime.Value).LastOrDefault();
                    if (latest != null)
                    {
                        _tracer.Trace("Deployment {0} is {1} at {2}", latest.Id, latest.Status, latest.EndTime.Value.ToString("o"));

                        id = latest.Id;
                    }
                    else
                    {
                        _tracer.Trace("Could not find latest deployment!");
                    }
                }
            }

            pending = null;
            return(false);
        }
Exemple #5
0
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();

            InvokeInDeploymentOperationContext(() =>
            {
                List <DeployResult> deployments = DeploymentChannel.GetDeployments(MaxResults ?? DefaultMaxResults);

                if (CommitId != null)
                {
                    DeployResult deployment = deployments.FirstOrDefault(d => d.Id.Equals(CommitId));
                    if (deployment == null)
                    {
                        throw new Exception(string.Format(Resources.InvalidDeployment, CommitId));
                    }

                    if (Details)
                    {
                        SetDetails(deployment);
                    }

                    deployments.Add(deployment);
                }
                else if (Details)
                {
                    foreach (DeployResult deployResult in deployments)
                    {
                        SetDetails(deployResult);
                    }
                }

                WriteObject(deployments, true);
            });
        }
Exemple #6
0
        private void WriteSuccess()
        {
            DeployResult obj = new DeployResult();

            obj.Success          = true;
            Response.ContentType = "application/json";
            Response.Write(JsonConvert.SerializeObject(obj));
        }
Exemple #7
0
        private void WriteError(string errMsg)
        {
            DeployResult obj = new DeployResult();

            obj.Success          = false;
            obj.Msg              = errMsg;
            Response.ContentType = "application/json";
            Response.Write(JsonConvert.SerializeObject(obj));
        }
Exemple #8
0
        private void WriteSuccess(List <string> data = null)
        {
            DeployResult <List <string> > obj = new DeployResult <List <string> >();

            obj.Success          = true;
            obj.Data             = data ?? new List <string>();
            Response.ContentType = "application/json";
            Response.Write(JsonConvert.SerializeObject(obj));
        }
        protected override async Task <HttpResponseMessage> CreateItemDeleteResponse(FileSystemInfo info, string localFilePath)
        {
            HttpResponseMessage response;

            if (!PrepareBranch(true, out response))
            {
                return(response);
            }

            response = await base.CreateItemDeleteResponse(info, localFilePath);

            // Commit to local branch
            _repository.Commit(String.Format("Committing delete from request {0}", Request.RequestUri), authorName: null);

            try
            {
                // Rebase to get updates from master while checking whether we get a conflict
                _repository.Rebase(MasterBranch);

                // Switch content back to master
                _repository.UpdateRef(VfsUpdateBranch);
            }
            catch (CommandLineException commandLineException)
            {
                Tracer.TraceError(commandLineException);

                // Abort the ongoing rebase operation
                try
                {
                    _repository.RebaseAbort();
                }
                finally
                {
                    _repository.Update();
                }

                // The rebase resulted in a conflict.
                HttpResponseMessage conflictResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict, commandLineException);
                return(conflictResponse);
            }

            // Deploy changes
            DeployResult result = DeployChanges();

            if (result != null && result.Status != DeployStatus.Success)
            {
                HttpResponseMessage deploymentErrorResponse =
                    Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText));
                return(deploymentErrorResponse);
            }

            // Delete succeeded. We add the etag as is has been updated as a result of the delete
            // This allows a client to keep track of the latest etag even for deletes.
            response.Headers.ETag = CreateEtag(_repository.CurrentId);
            return(response);
        }
Exemple #10
0
        private void WriteSuccess <T>(T data)
        {
            DeployResult <T> obj = new DeployResult <T>();

            obj.Success          = true;
            obj.Data             = data;
            Response.StatusCode  = 200;
            Response.ContentType = "application/json";
            Response.Write(JsonConvert.SerializeObject(obj));
        }
Exemple #11
0
        private void WriteError(string errMsg)
        {
            DeployResult <List <string> > obj = new DeployResult <List <string> >();

            obj.Success          = false;
            obj.Msg              = errMsg;
            obj.Data             = new List <string>();
            Response.ContentType = "application/json";
            Response.StatusCode  = 200;
            Response.Write(JsonConvert.SerializeObject(obj));
        }
        public IActionResult CreateDeployment(DeployResult deployResult, string details)
        {
            var    id   = deployResult.Id;
            string path = Path.Combine(_environment.DeploymentsPath, id);
            IDeploymentStatusFile statusFile = _status.Open(id);

            if (statusFile != null)
            {
                return(StatusCode(StatusCodes.Status409Conflict, String.Format("Deployment with id '{0}' exists", id)));
            }

            FileSystemHelpers.EnsureDirectory(path);
            statusFile             = _status.Create(id);
            statusFile.Status      = deployResult.Status;
            statusFile.Message     = deployResult.Message;
            statusFile.Deployer    = deployResult.Deployer;
            statusFile.Author      = deployResult.Author;
            statusFile.AuthorEmail = deployResult.AuthorEmail;
            statusFile.StartTime   = deployResult.StartTime;
            statusFile.EndTime     = deployResult.EndTime;

            // miscellaneous
            statusFile.Complete     = true;
            statusFile.IsReadOnly   = true;
            statusFile.IsTemporary  = false;
            statusFile.ReceivedTime = deployResult.StartTime;
            // keep it simple regardless of success or failure
            statusFile.LastSuccessEndTime = deployResult.EndTime;
            statusFile.Save();

            if (deployResult.Current)
            {
                _status.ActiveDeploymentId = id;
            }

            var     logger = new StructuredTextLogger(Path.Combine(path, DeploymentManager.TextLogFile), _analytics);
            ILogger innerLogger;

            if (deployResult.Status == DeployStatus.Success)
            {
                innerLogger = logger.Log("Deployment successful.");
            }
            else
            {
                innerLogger = logger.Log("Deployment failed.", LogEntryType.Error);
            }

            if (!String.IsNullOrEmpty(details))
            {
                innerLogger.Log(details);
            }

            return(Ok());
        }
Exemple #13
0
        public async Task <IActionResult> Deploy(DeployRequest model)
        {
            try
            {
                var gitHubClient = new GitHubClient(new ProductHeaderValue(client_id));
                gitHubClient.Credentials = new Credentials(HttpContext.Session.GetString("githubtoken"));

                IReadOnlyList <RepositoryContent> contents = await gitHubClient.Repository.Content.GetAllContentsByRef(model.Username, model.Repo, model.ContractPath, model.Branch);

                String temp = Path.GetTempPath();

                foreach (RepositoryContent content in contents.Where(c => c.Name.EndsWith(".sol")))
                {
                    using (var client = new HttpClient())
                    {
                        var stream = await client.GetStreamAsync(content.DownloadUrl);

                        using (var fileStream = System.IO.File.Create(temp + content.Name))
                            using (var reader = new StreamReader(stream))
                            {
                                stream.CopyTo(fileStream);
                                fileStream.Flush();
                            }
                    }

                    //String hash = CheckHash(temp + content.Name);
                }

                var solcLib  = SolcLib.Create("");
                var compiled = solcLib.Compile(temp + model.Contract + ".sol", outputSelection);

                var output = compiled.Contracts[temp + model.Contract + ".sol"][model.Contract];

                DeployResult result = new DeployResult()
                {
                    JSON = output.AbiJsonString,
                    ABI  = "",
                    Bin  = BitConverter.ToString(output.Evm.Bytecode.ObjectBytes).Replace("-", String.Empty)
                };

                var account = new Wallet(model.Password, null).GetAccount(Convert.ToInt32(model.KeyFile));
                var web3    = new Nethereum.Web3.Web3(account, model.Node);

                result.TxID = await web3.Eth.DeployContract.SendRequestAsync(result.Bin, model.KeyFile, new Nethereum.Hex.HexTypes.HexBigInteger(model.Gas));

                return(View(result));
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
                throw ex;
            }
        }
Exemple #14
0
        private static async Task AssertSuccessfulDeployment(ApplicationManager appManager, int timeoutSecs = 30)
        {
            DeployResult deployment = null;

            for (int i = 0; i < timeoutSecs; ++i)
            {
                deployment = await appManager.DeploymentManager.GetResultAsync("latest");

                if (deployment.Status == DeployStatus.Success || deployment.Status == DeployStatus.Failed)
                {
                    break;
                }

                await Task.Delay(1000);
            }

            Assert.Equal(DeployStatus.Success, deployment.Status);
        }
Exemple #15
0
        public DeployResult GetResult(string id)
        {
            using (_tracer.Step("DeploymentService.GetResult"))
            {
                DeployResult result = _deploymentManager.GetResult(id);

                if (result == null)
                {
                    var response = Request.CreateErrorResponse(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture,
                                                                                                      Resources.Error_DeploymentNotFound,
                                                                                                      id));
                    throw new HttpResponseException(response);
                }

                result.Url    = Request.RequestUri;
                result.LogUrl = UriHelper.MakeRelative(Request.RequestUri, "log");

                return(result);
            }
        }
Exemple #16
0
 /// <summary>
 /// 处理请求
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Task ProcessRequest(IOwinContext context)
 {
     Context  = context;
     Response = context.Response;
     Request  = context.Request;
     return(Task.Factory.StartNew(() =>
     {
         try
         {
             ProcessRequest();
         }
         catch (Exception ex)
         {
             DeployResult obj = new DeployResult {
                 Success = false, Msg = ex.Message
             };
             Response.ContentType = "application/json";
             Response.Write(JsonConvert.SerializeObject(obj));
         }
     }));
 }
        // private ILog _log;

        public IndexModule()
        {
            Get["/"] = _ =>
            {
                var response = (Response)"Listening...";
                response.ContentType = "text/plain";
                return(response);
            };

            Post["/", true] = async(x, ct) =>
            {
                DeployResult result = await DoDeploy(x, ct);

                var response = (Response)result.Content;
                if (!result.Succeeded)
                {
                    response.StatusCode = HttpStatusCode.InternalServerError;
                }

                response.ContentType = "text/plain";
                return(response);
            };
        }
Exemple #18
0
        private void DoGitRedeploy(ApplicationManager appManager, string commitId, string verificationContent)
        {
            DeployResult result = null;

            try
            {
                appManager.DeploymentManager.DeployAsync(commitId).Wait();
                var results = appManager.DeploymentManager.GetResultsAsync().Result.ToList();
                result = results.Where(r => r.Id == commitId).FirstOrDefault();
            }
            catch (Exception ex)
            {
                string msg = string.Format("Redeploy operation failed for commit ID:  {0}.  Exception:  {1}", commitId, ex.ToString());
                throw new ApplicationException(msg);
            }

            if (result == null)
            {
                string msg = string.Format("Redeploy operation completed but expected commit Id was not deployed.  Commit ID:  {0}.", commitId);
                throw new ApplicationException(msg);
            }

            StressUtils.VerifySite(appManager.SiteUrl, verificationContent);
        }
        private bool IsLatestPendingDeployment(HttpRequestMessage request, string id, out DeployResult pending, out DeployResult latest)
        {
            latest = null;
            if (string.Equals(Constants.LatestDeployment, id))
            {
                if (ScmHostingConfigurations.GetLatestDeploymentOptimized &&
                    (ArmUtils.IsAzureResourceManagerUserAgent(request) || ArmUtils.IsVSTSDevOpsUserAgent(request)) &&
                    _deploymentLock.IsHeld)
                {
                    pending = DeployResult.PendingResult;
                    return(true);
                }

                using (_tracer.Step("DeploymentService.GetLatestDeployment"))
                {
                    var results = _deploymentManager.GetResults();
                    pending = results.Where(r => r.Status != DeployStatus.Success && r.Status != DeployStatus.Failed).FirstOrDefault();
                    if (pending != null)
                    {
                        _tracer.Trace("Deployment {0} is {1}", pending.Id, pending.Status);
                        return(true);
                    }

                    latest = results.Where(r => r.EndTime != null).OrderBy(r => r.EndTime.Value).LastOrDefault();
                    if (latest != null)
                    {
                        _tracer.Trace("Deployment {0} is {1} at {2}", latest.Id, latest.Status, latest.EndTime.Value.ToString("o"));
                    }
                    else
                    {
                        _tracer.Trace("Could not find latest deployment!");
                    }
                }
            }

            pending = null;
            return(false);
        }
Exemple #20
0
 internal void SetDetails(DeployResult deployResult)
 {
     InvokeInDeploymentOperationContext(() => { deployResult.Logs = DeploymentChannel.GetDeploymentLogs(deployResult.Id); });
 }
        private static DeployResult checkResultsOfDeploy(MetadataApiClientResponse response, string asyncId)
        {
            DeployResult result;
            checkDeployStatusResponse responseCheck;
            string debugLog = "";

            ConsoleHelper.WriteDocLine("Request for a deploy submitted successfully.");
            ConsoleHelper.WriteDocLine("Request ID for the current deploy task: " + asyncId);
            ConsoleHelper.WriteDocLine("Waiting for server to finish processing the request...");

            do
            {
                try{
                    responseCheck = MetadataApiCheckDeployService.checkDeployStatus(response.Metadataclient, asyncId);
                    result        = responseCheck.result;
                    ConsoleHelper.WriteDocLine("Request Status: " + result.status);

                    if (result.stateDetail != null)
                    {
                        ConsoleHelper.WriteDocLine(result.stateDetail);
                    }

                    if (responseCheck.DebuggingInfo != null)
                    {
                        debugLog = responseCheck.DebuggingInfo.debugLog;
                    }

                    if (result.status == DeployStatus.Failed)
                    {
                        if (result.details != null && result.details.componentFailures != null)
                        {
                            for (int i = 0; i < result.details.componentFailures.Length; i++)
                            {
                                DeployMessage message = result.details.componentFailures[i];
                                ConsoleHelper.WriteErrorLine((i + 1) + ": " + message.componentType + " " + message.fullName + " line " + message.lineNumber + " - " + message.problem);
                            }
                        }

                        if (result.details != null && result.details.runTestResult != null)
                        {
                            if (result.details.runTestResult.failures != null)
                            {
                                for (int i = 0; i < result.details.runTestResult.failures.Length; i++)
                                {
                                    RunTestFailure errorTest = result.details.runTestResult.failures[i];
                                    ConsoleHelper.WriteErrorLine((i + 1) + ": " + errorTest.name + " - " + errorTest.methodName + " - " + errorTest.message + " - " + errorTest.stackTrace);
                                }
                            }
                            if (result.details.runTestResult.codeCoverageWarnings != null)
                            {
                                for (int i = 0; i < result.details.runTestResult.codeCoverageWarnings.Length; i++)
                                {
                                    CodeCoverageWarning errorTest = result.details.runTestResult.codeCoverageWarnings[i];
                                    ConsoleHelper.WriteErrorLine((i + 1) + ": " + errorTest.name + " - " + errorTest.message);
                                }
                            }
                        }

                        if (result.status == DeployStatus.Failed)
                        {
                            if (result.errorMessage != null)
                            {
                                ConsoleHelper.WriteErrorLine(result.errorMessage);
                            }
                        }
                    }
                }catch (Exception e) {
                    result = new DeployResult();
                    ConsoleHelper.WriteErrorLine(e.Message);
                }
                Thread.Sleep(2000);

                if (result.status == DeployStatus.Failed)
                {
                    throw new Exception();
                }
            } while (!result.done);



            //.WriteDocLine(debugLog);

            return(result);
        }
        public void RestoresDeploymentForSlot()
        {
            string slot = "staging";
            // Setup
            var site1 = new Site
            {
                Name           = "website1",
                WebSpace       = "webspace1",
                SiteProperties = new SiteProperties
                {
                    Properties = new List <NameValuePair>
                    {
                        new NameValuePair {
                            Name = "repositoryuri", Value = "http"
                        },
                        new NameValuePair {
                            Name = "PublishingUsername", Value = "user1"
                        },
                        new NameValuePair {
                            Name = "PublishingPassword", Value = "password1"
                        }
                    }
                }
            };

            var clientMock = new Mock <IWebsitesClient>();

            clientMock.Setup(c => c.ListWebSpaces())
            .Returns(new[] { new WebSpace {
                                 Name = "webspace1"
                             }, new WebSpace {
                                 Name = "webspace2"
                             } });
            clientMock.Setup(c => c.GetWebsite("website1", slot))
            .Returns(site1);

            SimpleDeploymentServiceManagement deploymentChannel = new SimpleDeploymentServiceManagement();

            var deployments = new List <DeployResult> {
                new DeployResult {
                    Id = "id1", Current = false
                }, new DeployResult {
                    Id = "id2", Current = true
                }
            };

            deploymentChannel.GetDeploymentsThunk = ar => deployments;
            deploymentChannel.DeployThunk         = ar =>
            {
                // Keep track of currently deployed id
                DeployResult newDeployment = deployments.FirstOrDefault(d => d.Id.Equals(ar.Values["commitId"]));
                if (newDeployment != null)
                {
                    // Make all inactive
                    deployments.ForEach(d => d.Complete = false);

                    // Set new to active
                    newDeployment.Complete = true;
                }
            };

            // Test
            RestoreAzureWebsiteDeploymentCommand restoreAzureWebsiteDeploymentCommand =
                new RestoreAzureWebsiteDeploymentCommand(deploymentChannel)
            {
                Name                = "website1",
                CommitId            = "id2",
                ShareChannel        = true,
                WebsitesClient      = clientMock.Object,
                CommandRuntime      = new MockCommandRuntime(),
                CurrentSubscription = new WindowsAzureSubscription {
                    SubscriptionId = base.subscriptionId
                },
                Slot = slot
            };

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();
            Assert.AreEqual(1, ((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.Count);
            var responseDeployments = (IEnumerable <DeployResult>)((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.FirstOrDefault();

            Assert.IsNotNull(responseDeployments);
            Assert.AreEqual(2, responseDeployments.Count());
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id2") && d.Complete));
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id1") && !d.Complete));

            // Change active deployment to id1
            restoreAzureWebsiteDeploymentCommand = new RestoreAzureWebsiteDeploymentCommand(deploymentChannel)
            {
                Name                = "website1",
                CommitId            = "id1",
                ShareChannel        = true,
                WebsitesClient      = clientMock.Object,
                CommandRuntime      = new MockCommandRuntime(),
                CurrentSubscription = new WindowsAzureSubscription {
                    SubscriptionId = base.subscriptionId
                },
                Slot = slot
            };

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();
            Assert.AreEqual(1, ((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.Count);
            responseDeployments = (IEnumerable <DeployResult>)((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.FirstOrDefault();
            Assert.IsNotNull(responseDeployments);
            Assert.AreEqual(2, responseDeployments.Count());
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id1") && d.Complete));
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id2") && !d.Complete));
        }
        private async Task <HttpResponseMessage> PushDeployAsync(ArtifactDeploymentInfo deploymentInfo, bool isAsync, JObject requestObject = null, ArtifactType artifactType = ArtifactType.Zip)
        {
            var content       = Request.Content;
            var isRequestJSON = content.Headers?.ContentType?.MediaType?.Equals("application/json", StringComparison.OrdinalIgnoreCase);

            if (isRequestJSON == true)
            {
                try
                {
                    // Read the request body if it hasn't been read already
                    if (requestObject == null)
                    {
                        requestObject = await Request.Content.ReadAsAsync <JObject>();
                    }
                    deploymentInfo.RemoteURL = ArmUtils.IsArmRequest(Request) ? GetArticfactURLFromARMJSON(requestObject) : GetArtifactURLFromJSON(requestObject);
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }
            }
            // For zip artifacts (zipdeploy, wardeploy, onedeploy with type=zip), copy the request body in a temp zip file.
            // It will be extracted to the appropriate directory by the Fetch handler
            else if (artifactType == ArtifactType.Zip)
            {
                await _deploymentLock.LockHttpOperationAsync(async() =>
                {
                    if (_settings.RunFromLocalZip())
                    {
                        await WriteSitePackageZip(deploymentInfo, _tracer, Request.Content);
                    }
                    else
                    {
                        var zipFileName = Path.ChangeExtension(Path.GetRandomFileName(), "zip");
                        var zipFilePath = Path.Combine(_environment.ZipTempPath, zipFileName);

                        using (_tracer.Step("Saving request content to {0}", zipFilePath))
                        {
                            await content.CopyToAsync(zipFilePath, _tracer);
                        }

                        deploymentInfo.RepositoryUrl = zipFilePath;
                    }
                }, "Preparing zip package");
            }
            // Copy the request body to a temp file.
            // It will be moved to the appropriate directory by the Fetch handler
            else if (deploymentInfo.Deployer == Constants.OneDeploy)
            {
                await _deploymentLock.LockHttpOperationAsync(async() =>
                {
                    var artifactTempPath = Path.Combine(_environment.ZipTempPath, deploymentInfo.TargetFileName);
                    using (_tracer.Step("Saving request content to {0}", artifactTempPath))
                    {
                        await content.CopyToAsync(artifactTempPath, _tracer);
                    }

                    deploymentInfo.RepositoryUrl = artifactTempPath;
                }, "Preparing zip package");
            }

            isAsync = ArmUtils.IsArmRequest(Request) ? true : isAsync;

            var result = await _deploymentManager.FetchDeploy(deploymentInfo, isAsync, Request.GetRequestUri(), "HEAD");

            var response = Request.CreateResponse();

            switch (result)
            {
            case FetchDeploymentRequestResult.RunningAynschronously:
                if (ArmUtils.IsArmRequest(Request))
                {
                    DeployResult deployResult = new DeployResult();
                    response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(deployResult, Request));
                    string statusURL = GetStatusUrl(Request.Headers.Referrer ?? Request.RequestUri);
                    // Should not happen: If we couldn't make the URL, there must have been an error in the request
                    if (string.IsNullOrEmpty(statusURL))
                    {
                        var badResponse = Request.CreateResponse();
                        badResponse.StatusCode = HttpStatusCode.BadRequest;
                        return(badResponse);
                    }
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(statusURL +
                                                        String.Format("/deployments/{0}?api-version=2018-02-01&deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                    response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(ScmHostingConfigurations.ArmRetryAfterSeconds));
                }
                else if (isAsync)
                {
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(Request.GetRequestUri(),
                                                        String.Format("/api/deployments/{0}?deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                    response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(ScmHostingConfigurations.ArmRetryAfterSeconds));
                }
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.ForbiddenScmDisabled:
                // Should never hit this for zip push deploy
                response.StatusCode = HttpStatusCode.Forbidden;
                _tracer.Trace("Scm is not enabled, reject all requests.");
                break;

            case FetchDeploymentRequestResult.ConflictAutoSwapOngoing:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_AutoSwapDeploymentOngoing);
                break;

            case FetchDeploymentRequestResult.Pending:
                // Shouldn't happen here, as we disallow deferral for this use case
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.RanSynchronously:
                response.StatusCode = HttpStatusCode.OK;
                break;

            case FetchDeploymentRequestResult.ConflictDeploymentInProgress:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_DeploymentInProgress);
                break;

            case FetchDeploymentRequestResult.ConflictRunFromRemoteZipConfigured:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_RunFromRemoteZipConfigured);
                break;

            default:
                response.StatusCode = HttpStatusCode.BadRequest;
                break;
            }

            return(response);
        }
        public bool TryParseDeployResult(string id, JObject payload, out DeployResult deployResult)
        {
            deployResult = null;
            if (String.IsNullOrEmpty(id) || payload == null)
            {
                return(false);
            }

            var status = payload.Value <int?>("status");

            if (status == null || (status.Value != 3 && status.Value != 4))
            {
                return(false);
            }

            var message = payload.Value <string>("message");

            if (String.IsNullOrEmpty(message))
            {
                return(false);
            }

            var deployer = payload.Value <string>("deployer");

            if (String.IsNullOrEmpty(deployer))
            {
                return(false);
            }

            var author = payload.Value <string>("author");

            if (String.IsNullOrEmpty(author))
            {
                return(false);
            }

            deployResult = new DeployResult
            {
                Id       = id,
                Status   = (DeployStatus)status.Value,
                Message  = message,
                Deployer = deployer,
                Author   = author
            };

            // optionals
            var now = DateTime.UtcNow;

            deployResult.AuthorEmail = payload.Value <string>("author_email");
            deployResult.StartTime   = payload.Value <DateTime?>("start_time") ?? now;
            deployResult.EndTime     = payload.Value <DateTime?>("end_time") ?? now;

            // only success status can be active
            var active = payload.Value <bool?>("active");

            if (active == null)
            {
                deployResult.Current = deployResult.Status == DeployStatus.Success;
            }
            else
            {
                if (active.Value && deployResult.Status != DeployStatus.Success)
                {
                    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Only successful status can be active!"));
                }

                deployResult.Current = active.Value;
            }

            return(true);
        }
Exemple #25
0
        protected override async Task <IActionResult> CreateFileDeleteResponse(FileInfoBase info)
        {
            IActionResult result;

            if (!PrepareBranch(true, out result))
            {
                return(result);
            }

            result = await base.CreateFileDeleteResponse(info);

            // Get the query parameters
            QueryParameters parameters = new QueryParameters(this.Request);

            // Commit to local branch
            _repository.Commit(parameters.Message, authorName: null, emailAddress: null);

            bool rebasing = false;

            try
            {
                // Only rebase if VFS branch isn't up-to-date already
                if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch))
                {
                    // Rebase to get updates from master while checking whether we get a conflict
                    rebasing = true;
                    _repository.Rebase(MasterBranch);
                }

                // Switch content back to master
                _repository.UpdateRef(VfsUpdateBranch);
            }
            catch (CommandLineException commandLineException)
            {
                Tracer.TraceError(commandLineException);

                // Abort the ongoing rebase operation
                try
                {
                    if (rebasing)
                    {
                        _repository.RebaseAbort();
                    }
                }
                finally
                {
                    _repository.Update();
                }

                // The rebase resulted in a conflict.
                return(StatusCode(StatusCodes.Status409Conflict, commandLineException));
            }

            // Get current commit ID
            string currentId = _repository.CurrentId;

            // Deploy changes unless request indicated to not deploy
            if (!parameters.NoDeploy)
            {
                DeployResult deployResult = await DeployChangesAsync(currentId);

                if (deployResult != null && deployResult.Status != DeployStatus.Success)
                {
                    return(StatusCode(StatusCodes.Status500InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, deployResult.StatusText)));
                }
            }

            // Delete succeeded. We add the etag as is has been updated as a result of the delete
            // This allows a client to keep track of the latest etag even for deletes.
            Response.GetTypedHeaders().ETag = CreateEtag(currentId);
            return(result);
        }
Exemple #26
0
        protected override async Task <IActionResult> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                if (!PrepareBranch(itemExists, out IActionResult errorResponse))
                {
                    return(errorResponse);
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                // Get the query parameters
                QueryParameters parameters = new QueryParameters(this.Request);

                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Body.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        return(StatusCode(StatusCodes.Status409Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
                    }
                }

                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = true;

                // Commit to local branch
                bool commitResult = _repository.Commit(parameters.Message, authorName: null, emailAddress: null);
                if (!commitResult)
                {
                    // TODO this is janky here, we return an actionresult but set the etag on the response directly
                    Response.GetTypedHeaders().ETag = CreateEtag(_repository.CurrentId);
                    return(NoContent());
                }

                bool rebasing = false;
                if (_currentEtag != null)
                {
                    try
                    {
                        // Only rebase if VFS branch isn't up-to-date already
                        if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch))
                        {
                            // Rebase to get updates from master while checking whether we get a conflict
                            rebasing = true;
                            updateBranchIsUpToDate = _repository.Rebase(MasterBranch);
                        }

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        if (rebasing)
                        {
                            // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                            // can see the conflicts and resubmit.
                            _cleanupRebaseConflict = true;

                            // CORE TODO not sure this works; I'm not sure you can set StatusCode for a File result
                            Response.StatusCode = StatusCodes.Status409Conflict;
                            _readStream         = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            // CORE TODO make sure mediatype.tostring works as intended here
                            return(File(_readStream, _conflictMediaType.ToString()));

                            //HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                            //_readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            //conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                            //conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                            //return conflictResponse;
                        }
                        else
                        {
                            return(StatusCode(StatusCodes.Status500InternalServerError,
                                              RS.Format(Resources.VfsScmUpdate_Error, commandLineException.Message)));
                        }
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                IActionResult successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = NoContent();
                    }
                    else
                    {
                        _readStream         = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse = File(_readStream, MediaTypeMap.GetMediaType(info.Extension).ToString());
                    }
                }
                else
                {
                    successFileResponse = StatusCode(StatusCodes.Status201Created);
                }

                // Get current commit ID
                string currentId = _repository.CurrentId;

                // Deploy changes unless request indicated to not deploy
                if (!parameters.NoDeploy)
                {
                    DeployResult result = await DeployChangesAsync(currentId);

                    if (result != null && result.Status != DeployStatus.Success)
                    {
                        return(StatusCode(StatusCodes.Status500InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText)));
                    }
                }

                // Set updated etag for the file
                Response.GetTypedHeaders().ETag = CreateEtag(currentId);
                return(successFileResponse);
            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                return(StatusCode(StatusCodes.Status409Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
            }
        }
Exemple #27
0
        public void RestoreAzureWebsiteDeploymentTest()
        {
            // Setup
            var site1 = new Site
            {
                Name           = "website1",
                WebSpace       = "webspace1",
                SiteProperties = new SiteProperties
                {
                    Properties = new List <NameValuePair>
                    {
                        new NameValuePair {
                            Name = "repositoryuri", Value = "http"
                        },
                        new NameValuePair {
                            Name = "PublishingUsername", Value = "user1"
                        },
                        new NameValuePair {
                            Name = "PublishingPassword", Value = "password1"
                        }
                    }
                }
            };

            var clientMock = new Mock <IWebsitesClient>();

            clientMock.Setup(c => c.ListWebSpaces())
            .Returns(new[] { new WebSpace {
                                 Name = "webspace1"
                             }, new WebSpace {
                                 Name = "webspace2"
                             } });
            clientMock.Setup(c => c.GetWebsite("website1", null))
            .Returns(site1);

            SimpleDeploymentServiceManagement deploymentChannel = new SimpleDeploymentServiceManagement();

            var deployments = new List <DeployResult> {
                new DeployResult {
                    Id = "id1", Current = false
                }, new DeployResult {
                    Id = "id2", Current = true
                }
            };

            deploymentChannel.GetDeploymentsThunk = ar => deployments;
            deploymentChannel.DeployThunk         = ar =>
            {
                // Keep track of currently deployed id
                DeployResult newDeployment = deployments.FirstOrDefault(d => d.Id.Equals(ar.Values["commitId"]));
                if (newDeployment != null)
                {
                    // Make all inactive
                    deployments.ForEach(d => d.Complete = false);

                    // Set new to active
                    newDeployment.Complete = true;
                }
            };

            // Test
            RestoreAzureWebsiteDeploymentCommand restoreAzureWebsiteDeploymentCommand =
                new RestoreAzureWebsiteDeploymentCommand(deploymentChannel)
            {
                Name           = "website1",
                CommitId       = "id2",
                ShareChannel   = true,
                WebsitesClient = clientMock.Object,
                CommandRuntime = new MockCommandRuntime(),
            };

            currentProfile = new AzureSMProfile();
            var subscription = new AzureSubscription {
                Id = new Guid(base.subscriptionId)
            };

            subscription.Properties[AzureSubscription.Property.Default] = "True";
            currentProfile.Subscriptions[new Guid(base.subscriptionId)] = subscription;

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();

            var responseDeployments = System.Management.Automation.LanguagePrimitives.GetEnumerable(((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline).Cast <DeployResult>();

            Assert.NotNull(responseDeployments);
            Assert.Equal(2, responseDeployments.Count());
            Assert.True(responseDeployments.Any(d => d.Id.Equals("id2") && d.Complete));
            Assert.True(responseDeployments.Any(d => d.Id.Equals("id1") && !d.Complete));

            // Change active deployment to id1
            restoreAzureWebsiteDeploymentCommand = new RestoreAzureWebsiteDeploymentCommand(deploymentChannel)
            {
                Name           = "website1",
                CommitId       = "id1",
                ShareChannel   = true,
                WebsitesClient = clientMock.Object,
                CommandRuntime = new MockCommandRuntime(),
            };
            currentProfile = new AzureSMProfile();
            subscription   = new AzureSubscription {
                Id = new Guid(base.subscriptionId)
            };
            subscription.Properties[AzureSubscription.Property.Default] = "True";
            currentProfile.Subscriptions[new Guid(base.subscriptionId)] = subscription;

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();

            responseDeployments = System.Management.Automation.LanguagePrimitives.GetEnumerable(((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline).Cast <DeployResult>();
            Assert.NotNull(responseDeployments);
            Assert.Equal(2, responseDeployments.Count());
            Assert.True(responseDeployments.Any(d => d.Id.Equals("id1") && d.Complete));
            Assert.True(responseDeployments.Any(d => d.Id.Equals("id2") && !d.Complete));
        }
        private async Task <HttpResponseMessage> PushDeployAsync(ZipDeploymentInfo deploymentInfo, bool isAsync)
        {
            var content       = Request.Content;
            var isRequestJSON = content.Headers?.ContentType?.MediaType?.Equals("application/json", StringComparison.OrdinalIgnoreCase);

            if (isRequestJSON == true)
            {
                try
                {
                    var requestObject = await Request.Content.ReadAsAsync <JObject>();

                    deploymentInfo.ZipURL = ArmUtils.IsArmRequest(Request) ? GetZipURLFromARMJSON(requestObject) : GetZipURLFromJSON(requestObject);
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }
            }
            else
            {
                if (_settings.RunFromLocalZip())
                {
                    await WriteSitePackageZip(deploymentInfo, _tracer, Request.Content);
                }
                else
                {
                    var zipFileName = Path.ChangeExtension(Path.GetRandomFileName(), "zip");
                    var zipFilePath = Path.Combine(_environment.ZipTempPath, zipFileName);

                    using (_tracer.Step("Saving request content to {0}", zipFilePath))
                    {
                        await content.CopyToAsync(zipFilePath, _tracer);
                    }

                    deploymentInfo.RepositoryUrl = zipFilePath;
                }
            }

            isAsync = ArmUtils.IsArmRequest(Request) ? true : isAsync;

            var result = await _deploymentManager.FetchDeploy(deploymentInfo, isAsync, UriHelper.GetRequestUri(Request), "HEAD");

            var response = Request.CreateResponse();

            switch (result)
            {
            case FetchDeploymentRequestResult.RunningAynschronously:
                if (ArmUtils.IsArmRequest(Request))
                {
                    DeployResult deployResult = new DeployResult();
                    response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(deployResult, Request));
                    string statusURL = GetStatusUrl();
                    // Should not happen: If we couldn't make the URL, there must have been an error in the request
                    if (string.IsNullOrEmpty(statusURL))
                    {
                        var badResponse = Request.CreateResponse();
                        badResponse.StatusCode = HttpStatusCode.BadRequest;
                        return(badResponse);
                    }
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(statusURL +
                                                        String.Format("/deployments/{0}?api-version=2018-02-01&deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                }
                else if (isAsync)
                {
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(UriHelper.GetRequestUri(Request),
                                                        String.Format("/api/deployments/{0}?deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                }
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.ForbiddenScmDisabled:
                // Should never hit this for zip push deploy
                response.StatusCode = HttpStatusCode.Forbidden;
                _tracer.Trace("Scm is not enabled, reject all requests.");
                break;

            case FetchDeploymentRequestResult.ConflictAutoSwapOngoing:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_AutoSwapDeploymentOngoing);
                break;

            case FetchDeploymentRequestResult.Pending:
                // Shouldn't happen here, as we disallow deferral for this use case
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.RanSynchronously:
                response.StatusCode = HttpStatusCode.OK;
                break;

            case FetchDeploymentRequestResult.ConflictDeploymentInProgress:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_DeploymentInProgress);
                break;

            case FetchDeploymentRequestResult.ConflictRunFromRemoteZipConfigured:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_RunFromRemoteZipConfigured);
                break;

            default:
                response.StatusCode = HttpStatusCode.BadRequest;
                break;
            }

            return(response);
        }
 internal void SetDetails(DeployResult deployResult)
 {
     InvokeInDeploymentOperationContext(() => { deployResult.Logs = DeploymentChannel.GetDeploymentLogs(deployResult.Id); });
 }
Exemple #30
0
        public void RestoreAzureWebsiteDeploymentTest()
        {
            // Setup
            SimpleWebsitesManagement channel = new SimpleWebsitesManagement();

            channel.GetWebSpacesThunk = ar => new WebSpaces(new List <WebSpace> {
                new WebSpace {
                    Name = "webspace1"
                }, new WebSpace {
                    Name = "webspace2"
                }
            });
            channel.GetSitesThunk = ar =>
            {
                if (ar.Values["webspaceName"].Equals("webspace1"))
                {
                    return(new Sites(new List <Site> {
                        new Site {
                            Name = "website1", WebSpace = "webspace1", SiteProperties = new SiteProperties
                            {
                                Properties = new List <NameValuePair>
                                {
                                    new NameValuePair {
                                        Name = "repositoryuri", Value = "http"
                                    },
                                    new NameValuePair {
                                        Name = "PublishingUsername", Value = "user1"
                                    },
                                    new NameValuePair {
                                        Name = "PublishingPassword", Value = "password1"
                                    }
                                }
                            }
                        }
                    }));
                }

                return(new Sites(new List <Site> {
                    new Site {
                        Name = "website2", WebSpace = "webspace2"
                    }
                }));
            };

            SimpleDeploymentServiceManagement deploymentChannel = new SimpleDeploymentServiceManagement();

            var deployments = new List <DeployResult> {
                new DeployResult {
                    Id = "id1", Current = false
                }, new DeployResult {
                    Id = "id2", Current = true
                }
            };

            deploymentChannel.GetDeploymentsThunk = ar => deployments;
            deploymentChannel.DeployThunk         = ar =>
            {
                // Keep track of currently deployed id
                DeployResult newDeployment = deployments.FirstOrDefault(d => d.Id.Equals(ar.Values["commitId"]));
                if (newDeployment != null)
                {
                    // Make all inactive
                    deployments.ForEach(d => d.Complete = false);

                    // Set new to active
                    newDeployment.Complete = true;
                }
            };

            // Test
            RestoreAzureWebsiteDeploymentCommand restoreAzureWebsiteDeploymentCommand =
                new RestoreAzureWebsiteDeploymentCommand(channel, deploymentChannel)
            {
                Name                = "website1",
                CommitId            = "id2",
                ShareChannel        = true,
                CommandRuntime      = new MockCommandRuntime(),
                CurrentSubscription = new SubscriptionData {
                    SubscriptionId = base.subscriptionId
                }
            };

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();
            Assert.AreEqual(1, ((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.Count);
            var responseDeployments = (IEnumerable <DeployResult>)((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.FirstOrDefault();

            Assert.IsNotNull(responseDeployments);
            Assert.AreEqual(2, responseDeployments.Count());
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id2") && d.Complete));
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id1") && !d.Complete));

            // Change active deployment to id1
            restoreAzureWebsiteDeploymentCommand = new RestoreAzureWebsiteDeploymentCommand(channel, deploymentChannel)
            {
                Name                = "website1",
                CommitId            = "id1",
                ShareChannel        = true,
                CommandRuntime      = new MockCommandRuntime(),
                CurrentSubscription = new SubscriptionData {
                    SubscriptionId = base.subscriptionId
                }
            };

            restoreAzureWebsiteDeploymentCommand.ExecuteCmdlet();
            Assert.AreEqual(1, ((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.Count);
            responseDeployments = (IEnumerable <DeployResult>)((MockCommandRuntime)restoreAzureWebsiteDeploymentCommand.CommandRuntime).OutputPipeline.FirstOrDefault();
            Assert.IsNotNull(responseDeployments);
            Assert.AreEqual(2, responseDeployments.Count());
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id1") && d.Complete));
            Assert.IsTrue(responseDeployments.Any(d => d.Id.Equals("id2") && !d.Complete));
        }
        protected override async Task <HttpResponseMessage> CreateItemPutResponse(FileSystemInfo info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                HttpResponseMessage errorResponse;
                if (!PrepareBranch(itemExists, out errorResponse))
                {
                    return(errorResponse);
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Content.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath),
                            ex);
                        return(conflictResponse);
                    }
                }


                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = false;

                // Commit to local branch
                bool commitResult = _repository.Commit(String.Format("Committing update from request {0}", Request.RequestUri), authorName: null);
                if (!commitResult)
                {
                    HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                    return(noChangeResponse);
                }

                if (_currentEtag != null)
                {
                    try
                    {
                        // Rebase to get updates from master while checking whether we get a conflict
                        updateBranchIsUpToDate = _repository.Rebase(MasterBranch);

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                        // can see the conflicts and resubmit.
                        _cleanupRebaseConflict = true;
                        HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                        _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                        conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                        return(conflictResponse);
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                HttpResponseMessage successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        successFileResponse         = Request.CreateResponse(HttpStatusCode.OK);
                        _readStream                 = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                        successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension);
                    }
                }
                else
                {
                    successFileResponse = Request.CreateResponse(HttpStatusCode.Created);
                }

                // Deploy changes
                DeployResult result = DeployChanges();
                if (result != null && result.Status != DeployStatus.Success)
                {
                    HttpResponseMessage deploymentErrorResponse =
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText));
                    return(deploymentErrorResponse);
                }

                // Set updated etag for the file
                successFileResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                return(successFileResponse);
            }
            catch (Exception e)
            {
                Tracer.TraceError(e);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict,
                                                                                RS.Format(Resources.VfsController_WriteConflict, localFilePath), e);
                return(errorResponse);
            }
        }