A class that represents a contract used to create a new Stump.
예제 #1
0
        /// <summary>
        ///     Creates a Stump contract from a Stump data entity.
        /// </summary>
        /// <param name="serverId">The unique identifier for the server.</param>
        /// <param name="entity">The <see cref="StumpEntity"/> used to create the contract.</param>
        /// <param name="dataAccess">The data access provider used by the instance.</param>
        /// <returns>
        ///     A <see cref="StumpContract"/> created from the specified <paramref name="entity"/>.
        /// </returns>
        public static StumpContract CreateContractFromEntity(string serverId, StumpEntity entity, IDataAccess dataAccess)
        {
            var contract = new StumpContract
            {
                OriginalRequest  = new RecordedRequest(new HttpRequestEntityReader(serverId, entity.OriginalRequest, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                OriginalResponse = new RecordedResponse(new HttpResponseEntityReader(serverId, entity.OriginalResponse, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                Response         = new RecordedResponse(new HttpResponseEntityReader(serverId, entity.Response, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                Rules            = new RuleContractCollection(),
                StumpCategory    = entity.StumpName,
                StumpId          = entity.StumpId,
                StumpName        = entity.StumpName,
            };

            foreach (var ruleEntity in entity.Rules)
            {
                var rule = new RuleContract
                {
                    RuleName = ruleEntity.RuleName
                };

                foreach (var value in ruleEntity.Settings)
                {
                    var setting = new RuleSetting
                    {
                        Name  = value.Name,
                        Value = value.Value
                    };
                    rule.AppendRuleSetting(setting);
                }

                contract.Rules.Add(rule);
            }

            return(contract);
        }
예제 #2
0
        /// <summary>
        ///     Creates a Stump from a contract.
        /// </summary>
        /// <param name="contract">The <see cref="StumpContract"/> used to create the Stump.</param>
        /// <returns>
        ///     A <see cref="Stump"/> created from the specified <paramref name="contract"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="contract"/> is <c>null</c>.</exception>
        public static Stump CreateStumpFromContract(StumpContract contract)
        {
            contract = contract ?? throw new ArgumentNullException(nameof(contract));

            var stump = new Stump(contract.StumpId);

            foreach (var r in contract.Rules)
            {
                var rule = ContractBindings.CreateRuleFromContract(r);
                stump.AddRule(rule);
            }

            stump.Responses.Add(contract.Response);

            return(stump);
        }
예제 #3
0
        public void StumpNameExists_WithExistantName_ReturnsTrue()
        {
            var contract = new StumpContract()
            {
                OriginalRequest = new RecordedRequest(Substitute.For<IStumpsHttpRequest>(), ContentDecoderHandling.DecodeNotRequired),
                OriginalResponse = new RecordedResponse(Substitute.For<IStumpsHttpResponse>(), ContentDecoderHandling.DecodeNotRequired),
                Response = new RecordedResponse(Substitute.For<IStumpsHttpResponse>(), ContentDecoderHandling.DecodeNotRequired),
                StumpCategory = "ABC",
                StumpId = "abc",
                StumpName = "StumpName"
            };

            var instance = new StumpsServerInstance(Substitute.For<IServerFactory>(), _serverId, _dal);
            instance.CreateStump(contract);
            Assert.IsTrue(instance.StumpNameExists(contract.StumpName));
        }
        public void StumpNameExists_WithExistantName_ReturnsTrue()
        {
            var contract = new StumpContract()
            {
                OriginalRequest  = new RecordedRequest(Substitute.For <IStumpsHttpRequest>(), ContentDecoderHandling.DecodeNotRequired),
                OriginalResponse = new RecordedResponse(Substitute.For <IStumpsHttpResponse>(), ContentDecoderHandling.DecodeNotRequired),
                Response         = new RecordedResponse(Substitute.For <IStumpsHttpResponse>(), ContentDecoderHandling.DecodeNotRequired),
                StumpCategory    = "ABC",
                StumpId          = "abc",
                StumpName        = "StumpName"
            };

            var instance = new StumpsServerInstance(Substitute.For <IServerFactory>(), _serverId, _dal);

            instance.CreateStump(contract);
            Assert.IsTrue(instance.StumpNameExists(contract.StumpName));
        }
예제 #5
0
        /// <summary>
        ///     Creates a Stump contract from a Stump data entity.
        /// </summary>
        /// <param name="serverId">The unique identifier for the server.</param>
        /// <param name="entity">The <see cref="T:Stumps.Server.Data.StumpEntity"/> used to create the contract.</param>
        /// <param name="dataAccess">The data access provider used by the instance.</param>
        /// <returns>
        ///     A <see cref="T:Stumps.Server.StumpContract"/> created from the specified <paramref name="entity"/>.
        /// </returns>
        public static StumpContract CreateContractFromEntity(string serverId, StumpEntity entity, IDataAccess dataAccess)
        {
            var contract = new StumpContract
            {
                OriginalRequest = new RecordedRequest(new HttpRequestEntityReader(serverId, entity.OriginalRequest, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                OriginalResponse = new RecordedResponse(new HttpResponseEntityReader(serverId, entity.OriginalResponse, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                Response = new RecordedResponse(new HttpResponseEntityReader(serverId, entity.Response, dataAccess), ContentDecoderHandling.DecodeNotRequired),
                ResponseDelay = entity.ResponseDelay,
                Rules = new RuleContractCollection(),
                StumpCategory = entity.StumpName,
                StumpId = entity.StumpId,
                StumpName = entity.StumpName,
                TerminateConnection = entity.TerminateConnection
            };

            foreach (var ruleEntity in entity.Rules)
            {
                var rule = new RuleContract
                {
                    RuleName = ruleEntity.RuleName
                };

                foreach (var value in ruleEntity.Settings)
                {
                    var setting = new RuleSetting
                    {
                        Name = value.Name,
                        Value = value.Value
                    };
                    rule.AppendRuleSetting(setting);
                }

                contract.Rules.Add(rule);
            }

            return contract;
        }
예제 #6
0
        /// <summary>
        ///     Loads a stump from a specified <see cref="T:Stumps.Server.StumpContract"/>.
        /// </summary>
        /// <param name="contract">The <see cref="T:Stumps.Server.StumpContract"/> used to create the Stump.</param>
        private void UnwrapAndAddStump(StumpContract contract)
        {
            _lock.EnterWriteLock();

            var stump = ContractBindings.CreateStumpFromContract(contract);

            _stumpList.Add(contract);
            _stumpReference.Add(stump.StumpId, contract);
            _server.AddStump(stump);

            _lock.ExitWriteLock();
        }
예제 #7
0
        /// <summary>
        ///     Creates a new Stump.
        /// </summary>
        /// <param name="contract">The contract used to create the Stump.</param>
        /// <returns>
        ///     An updated <see cref="T:Stumps.Server.StumpContract"/>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="contract"/> is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentException">A stump with the same name already exists.</exception>
        public StumpContract CreateStump(StumpContract contract)
        {
            if (contract == null)
            {
                throw new ArgumentNullException("contract");
            }

            if (string.IsNullOrEmpty(contract.StumpId))
            {
                contract.StumpId = RandomGenerator.GenerateIdentifier();
            }

            if (this.StumpNameExists(contract.StumpName))
            {
                throw new ArgumentException(Resources.StumpNameUsedError);
            }

            var entity = ContractEntityBinding.CreateEntityFromContract(contract);

            _dataAccess.StumpCreate(this.ServerId, entity, contract.OriginalRequest.GetBody(), contract.OriginalResponse.GetBody(), contract.Response.GetBody());

            UnwrapAndAddStump(contract);

            return contract;
        }
예제 #8
0
        /// <summary>
        ///     Detrmines the body match based on the rules in the contract.
        /// </summary>
        /// <param name="contract">The contract.</param>
        /// <returns>A member of the <see cref="T:Stumps.Web.Models.BodyMatch"/> enumeration.</returns>
        private BodyMatch DetrmineBodyMatch(StumpContract contract)
        {
            var rules = contract.Rules.FindRuleContractByName(typeof(BodyLengthRule).Name);

            if (rules.Count > 0)
            {
                var blr = ContractBindings.CreateRuleFromContract<BodyLengthRule>(rules[0]);

                if (blr.MinimumBodyLength == 0 && blr.MaximumBodyLength == 0)
                {
                    return BodyMatch.IsBlank;
                }

                if (blr.MinimumBodyLength == 1 && blr.MaximumBodyLength == int.MaxValue)
                {
                    return BodyMatch.IsNotBlank;
                }

            }

            if (contract.Rules.FindRuleContractByName(typeof(BodyContentRule).Name).Count > 0)
            {
                return BodyMatch.ContainsText;
            }

            if (contract.Rules.FindRuleContractByName(typeof(BodyMatchRule).Name).Count > 0)
            {
                return BodyMatch.ExactMatch;
            }

            return BodyMatch.IsAnything;
        }
예제 #9
0
        /// <summary>
        ///     Creates a <see cref="T:Stumps.Web.Models.StumpModel"/> from an existing Stump.
        /// </summary>
        /// <param name="stump">The <see cref="T:Stumps.Server.StumpContract"/> used to create the model.</param>
        /// <param name="serverId">The unique identifier for the proxy the Stump belongs to.</param>
        /// <param name="stumpId">The unique identifier of the Stump.</param>
        /// <returns>
        ///     A new <see cref="T:Stumps.Web.Models.StumpModel"/> object.
        /// </returns>
        private StumpModel CreateStumpModel(StumpContract stump, string serverId, string stumpId)
        {
            var bodyMatch = DetrmineBodyMatch(stump);

            var model = new StumpModel
            {
                Name = stump.StumpName,
                Origin = StumpOrigin.ExistingStump,
                RecordId = -1,
                RequestBody =
                    stump.OriginalRequest.BodyType == HttpBodyClassification.Text ? stump.OriginalRequest.GetBodyAsString() : string.Empty,
                RequestBodyIsImage = stump.OriginalRequest.BodyType == HttpBodyClassification.Image,
                RequestBodyIsText = stump.OriginalRequest.BodyType == HttpBodyClassification.Text,
                RequestBodyLength = stump.OriginalRequest.BodyLength,
                RequestBodyMatch = bodyMatch,
                RequestBodyMatchValues =
                    stump.Rules.FindRuleContractByName(typeof(BodyContentRule).Name).Count > 0 ?
                        ContractBindings.CreateRuleFromContract<BodyContentRule>(stump.Rules.FindRuleContractByName(typeof(BodyContentRule).Name)[0]).GetTextEvaluators() :
                        new string[0],
                RequestBodyUrl = "/api/proxy/" + serverId + "/stumps/" + stumpId + "/request",
                RequestHeaderMatch = CreateHeadersFromRules(stump),
                RequestHttpMethod = stump.OriginalRequest.HttpMethod,
                RequestHttpMethodMatch = stump.Rules.FindRuleContractByName(typeof(HttpMethodRule).Name).Count > 0,
                RequestUrl = stump.OriginalRequest.RawUrl,
                RequestUrlMatch = stump.Rules.FindRuleContractByName(typeof(UrlRule).Name).Count > 0,
                ResponseBody =
                    stump.Response.BodyType == HttpBodyClassification.Text
                        ? stump.Response.GetBodyAsString()
                        : string.Empty,
                ResponseBodyIsImage = stump.Response.BodyType == HttpBodyClassification.Image,
                ResponseBodyIsText = stump.Response.BodyType == HttpBodyClassification.Text,
                ResponseBodyLength = stump.Response.BodyLength,
                ResponseBodyModification = string.Empty,
                ResponseBodySource = BodySource.Origin,
                ResponseBodyUrl = "/api/proxy/" + serverId + "/stumps/" + stumpId + "/response",
                ResponseHeaders = CreateHeaderModel(stump.Response.Headers),
                ResponseStatusCode = stump.Response.StatusCode,
                ResponseStatusDescription = stump.Response.StatusDescription,
                StumpId = stump.StumpId
            };

            return model;
        }
예제 #10
0
        private HeaderModel[] CreateHeadersFromRules(StumpContract contract)
        {
            var models = new List<HeaderModel>();

            var rules = contract.Rules.FindRuleContractByName(typeof(HeaderRule).Name);

            foreach (var rule in rules)
            {
                var headerRule = ContractBindings.CreateRuleFromContract<HeaderRule>(rule);

                var model = new HeaderModel
                {
                    Name = headerRule.HeaderNameTextMatch,
                    Value = headerRule.HeaderValueTextMatch
                };

                models.Add(model);
            }

            return models.ToArray();
        }
예제 #11
0
        /// <summary>
        ///     Creates a Stump contract from an existing Stump.
        /// </summary>
        /// <param name="model">The <see cref="T:Stumps.Web.Models.StumpModel"/> used to create the contract.</param>
        /// <param name="server">The <see cref="T:Stumps.Server.StumpsServerInstance" /> that contains the Stump.</param>
        /// <returns>A <see cref="T:Stumps.Server.StumpContract" /> created from an existing Stump.</returns>
        private StumpContract CreateContractFromStump(StumpModel model, StumpsServerInstance server)
        {
            var originalContract = server.FindStump(model.StumpId);

            var contract = new StumpContract
            {
                OriginalRequest = new RecordedRequest(originalContract.OriginalRequest, ContentDecoderHandling.DecodeNotRequired),
                OriginalResponse = new RecordedResponse(originalContract.OriginalResponse, ContentDecoderHandling.DecodeNotRequired),
                Response = new RecordedResponse(originalContract.Response, ContentDecoderHandling.DecodeNotRequired),
                StumpId = model.StumpId,
                StumpName = model.Name,
                StumpCategory = "Uncategorized"
            };

            if (model.RequestUrlMatch)
            {
                contract.Rules.Add(new RuleContract(new UrlRule(model.RequestUrl)));
            }

            if (model.RequestHttpMethodMatch)
            {
                contract.Rules.Add(new RuleContract(new HttpMethodRule(model.RequestHttpMethod)));
            }

            foreach (var h in model.RequestHeaderMatch)
            {
                contract.Rules.Add(new RuleContract(new HeaderRule(h.Name, h.Value)));
            }

            switch (model.RequestBodyMatch)
            {
                case BodyMatch.ContainsText:
                    contract.Rules.Add(new RuleContract(new BodyContentRule(model.RequestBodyMatchValues)));
                    break;

                case BodyMatch.ExactMatch:
                    contract.Rules.Add(
                        new RuleContract(new BodyMatchRule(contract.OriginalRequest.BodyLength, contract.OriginalRequest.BodyMd5Hash)));
                    break;

                case BodyMatch.IsBlank:
                    contract.Rules.Add(new RuleContract(new BodyLengthRule(0, 0)));
                    break;

                case BodyMatch.IsNotBlank:
                    contract.Rules.Add(new RuleContract(new BodyLengthRule(1, int.MaxValue)));
                    break;

            }

            switch (model.ResponseBodySource)
            {

                case BodySource.Modified:
                    contract.Response.ClearBody();
                    contract.Response.AppendToBody(Encoding.UTF8.GetBytes(model.ResponseBodyModification));
                    break;

                case BodySource.EmptyBody:
                    contract.Response.ClearBody();
                    break;

                case BodySource.Origin:
                    contract.Response.ClearBody();
                    contract.Response.AppendToBody(originalContract.Response.GetBody());
                    break;

            }

            CopyHeaderModelToDictionary(model.ResponseHeaders, contract.Response.Headers);
            contract.Response.StatusCode = model.ResponseStatusCode;
            contract.Response.StatusDescription = model.ResponseStatusDescription;

            contract.Response.ExamineBody();

            return contract;
        }
예제 #12
0
        /// <summary>
        ///     Creates a Stump data entity from a Stump contract.
        /// </summary>
        /// <param name="contract">The <see cref="StumpContract"/> used to create the entity.</param>
        /// <returns>
        ///     A <see cref="StumpEntity"/> created from the specified <paramref name="contract"/>.
        /// </returns>
        public static StumpEntity CreateEntityFromContract(StumpContract contract)
        {
            var originalRequest = new HttpRequestEntity
            {
                BodyResourceName = string.Empty,
                Headers          = CreateNameValuePairFromHeaders(contract.OriginalRequest.Headers),
                HttpMethod       = contract.OriginalRequest.HttpMethod,
                LocalEndPoint    = contract.OriginalRequest.LocalEndPoint.ToString(),
                ProtocolVersion  = contract.OriginalRequest.ProtocolVersion,
                RawUrl           = contract.OriginalRequest.RawUrl,
                RemoteEndPoint   = contract.OriginalRequest.RemoteEndPoint.ToString()
            };

            var originalResponse = new HttpResponseEntity
            {
                BodyResourceName    = string.Empty,
                Headers             = CreateNameValuePairFromHeaders(contract.OriginalResponse.Headers),
                RedirectAddress     = contract.OriginalResponse.RedirectAddress,
                ResponseDelay       = contract.OriginalResponse.ResponseDelay,
                StatusCode          = contract.OriginalResponse.StatusCode,
                StatusDescription   = contract.OriginalResponse.StatusDescription,
                TerminateConnection = contract.OriginalResponse.TerminateConnection
            };

            var response = new HttpResponseEntity
            {
                BodyResourceName    = string.Empty,
                Headers             = CreateNameValuePairFromHeaders(contract.Response.Headers),
                RedirectAddress     = contract.Response.RedirectAddress,
                ResponseDelay       = contract.Response.ResponseDelay,
                StatusCode          = contract.Response.StatusCode,
                StatusDescription   = contract.Response.StatusDescription,
                TerminateConnection = contract.Response.TerminateConnection
            };

            var entity = new StumpEntity
            {
                OriginalRequest  = originalRequest,
                OriginalResponse = originalResponse,
                Response         = response,
                Rules            = new List <RuleEntity>(),
                StumpCategory    = contract.StumpCategory,
                StumpId          = contract.StumpId,
                StumpName        = contract.StumpName,
            };

            foreach (var rule in contract.Rules)
            {
                var ruleEntity = new RuleEntity
                {
                    RuleName = rule.RuleName,
                    Settings = new List <NameValuePairEntity>()
                };

                var settings = rule.GetRuleSettings();
                foreach (var setting in settings)
                {
                    ruleEntity.Settings.Add(
                        new NameValuePairEntity
                    {
                        Name  = setting.Name,
                        Value = setting.Value
                    });
                }

                entity.Rules.Add(ruleEntity);
            }

            return(entity);
        }
예제 #13
0
        /// <summary>
        ///     Creates a Stump data entity from a Stump contract.
        /// </summary>
        /// <param name="contract">The <see cref="T:Stumps.Server.StumpContract"/> used to create the entity.</param>
        /// <returns>
        ///     A <see cref="T:Stumps.Server.Data.StumpEntity"/> created from the specified <paramref name="contract"/>.
        /// </returns>
        public static StumpEntity CreateEntityFromContract(StumpContract contract)
        {
            var originalRequest = new HttpRequestEntity
            {
                BodyResourceName = string.Empty,
                Headers = CreateNameValuePairFromHeaders(contract.OriginalRequest.Headers),
                HttpMethod = contract.OriginalRequest.HttpMethod,
                LocalEndPoint = contract.OriginalRequest.LocalEndPoint.ToString(),
                ProtocolVersion = contract.OriginalRequest.ProtocolVersion,
                RawUrl = contract.OriginalRequest.RawUrl,
                RemoteEndPoint = contract.OriginalRequest.RemoteEndPoint.ToString()
            };

            var originalResponse = new HttpResponseEntity
            {
                BodyResourceName = string.Empty,
                Headers = CreateNameValuePairFromHeaders(contract.OriginalResponse.Headers),
                RedirectAddress = contract.OriginalResponse.RedirectAddress,
                StatusCode = contract.OriginalResponse.StatusCode,
                StatusDescription = contract.OriginalResponse.StatusDescription
            };

            var response = new HttpResponseEntity
            {
                BodyResourceName = string.Empty,
                Headers = CreateNameValuePairFromHeaders(contract.Response.Headers),
                RedirectAddress = contract.Response.RedirectAddress,
                StatusCode = contract.Response.StatusCode,
                StatusDescription = contract.Response.StatusDescription
            };

            var entity = new StumpEntity
            {
                OriginalRequest = originalRequest,
                OriginalResponse = originalResponse,
                Response = response,
                ResponseDelay = contract.ResponseDelay,
                Rules = new List<RuleEntity>(),
                StumpCategory = contract.StumpCategory,
                StumpId = contract.StumpId,
                StumpName = contract.StumpName,
                TerminateConnection = contract.TerminateConnection
            };

            foreach (var rule in contract.Rules)
            {
                var ruleEntity = new RuleEntity
                {
                    RuleName = rule.RuleName,
                    Settings = new List<NameValuePairEntity>()
                };

                var settings = rule.GetRuleSettings();
                foreach (var setting in settings)
                {
                    ruleEntity.Settings.Add(
                        new NameValuePairEntity
                        {
                            Name = setting.Name,
                            Value = setting.Value
                        });
                }

                entity.Rules.Add(ruleEntity);

            }

            return entity;
        }