/// <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); }
/// <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); }
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)); }
/// <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; }
/// <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(); }
/// <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; }
/// <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; }
/// <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; }
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(); }
/// <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; }
/// <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); }
/// <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; }