/// <summary> /// Creates a <see cref="IValueCalculator"/> for the specified <see cref="WebMethodParameterMappingDefinition"/>. /// </summary> /// <param name="mappingDefinition"> /// The mapping definition. /// </param> /// <returns> /// The <see cref="IValueCalculator"/>. /// </returns> public IValueCalculator CreateValueCalculator(WebMethodParameterMappingDefinition mappingDefinition) { if (mappingDefinition == null) throw new ArgumentNullException("mappingDefinition"); var type = TypeResolver.FindType(mappingDefinition.TypeName); if (type.IsArray) return CreateArrayValueCalculator(type, mappingDefinition); if (IsSimpleType(type)) return CreateSimpleValueCalculator(type, mappingDefinition); return CreateComplexValueCalculator(type, mappingDefinition); }
public void CreateSimpleValueCalculatorTest() { // Arrange. const string FieldName = "TestField"; const string TypeName = "TestType"; var typeResolver = new Mock<ITypeResolver>(); typeResolver.Setup(x => x.FindType(TypeName)).Returns(typeof(string)); var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose); var mappingDefinition = new WebMethodParameterMappingDefinition { Name = FieldName, TypeName = TypeName }; var factory = new WebMethodParameterCalculatorFactory { TypeResolver = typeResolver.Object, TypeConverter = typeConverter }; // Act. var valueCalculator = factory.CreateValueCalculator(mappingDefinition); // Assert. Assert.IsTrue(valueCalculator is SimpleValueCalculator); }
public void CreateDynamicLengthArrayValueCalculatorTest() { // Arrange. const string FieldName = "TestField"; const string TypeName = "TestType"; const string ElementTypeName = "TestElementType"; var typeResolver = new Mock<ITypeResolver>(); typeResolver.Setup(x => x.FindType(TypeName)).Returns(typeof(Employee[])); typeResolver.Setup(x => x.FindType(ElementTypeName)).Returns(typeof(Employee)); var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose); var elementMappingDefinition = new WebMethodParameterMappingDefinition { Name = Constants.ArrayItemGenericFieldName, TypeName = ElementTypeName }; var mappingDefinition = new WebMethodParameterMappingDefinition { Name = FieldName, TypeName = TypeName, Subfields = { elementMappingDefinition } }; var factory = new WebMethodParameterCalculatorFactory { TypeResolver = typeResolver.Object, TypeConverter = typeConverter }; // Act. var valueCalculator = factory.CreateValueCalculator(mappingDefinition); // Assert. Assert.IsTrue(valueCalculator is ArrayValueCalculator); }
private IValueCalculator CreateComplexValueCalculator(Type valueType, WebMethodParameterMappingDefinition mappingDefinition) { return new ComplexValueCalculator(valueType, mappingDefinition.Subfields.Select(m => CreatePropertySetter(valueType, m))); }
private IValueCalculator CreateArrayValueCalculator(Type valueType, WebMethodParameterMappingDefinition mappingDefinition) { var elementType = valueType.GetElementType(); if (mappingDefinition.ArrayItemCount.HasValue) { var elementSetters = new List<IPropertySetter>(); var mappingDictionary = mappingDefinition.Subfields.ToDictionary(m => m.Name); for (var i = 0; i < mappingDefinition.ArrayItemCount.Value; ++i) { var elementName = string.Format(CultureInfo.InvariantCulture, Constants.ArrayItemFieldNamePattern, i); if (mappingDictionary.ContainsKey(elementName)) elementSetters.Add(new ArrayElementSetter(i, CreateValueCalculator(mappingDictionary[elementName]))); } return new FixedLengthArrayValueCalculator(elementType, mappingDefinition.ArrayItemCount.Value, elementSetters); } IValueCalculator elementCalculator = null; var elementMappingDefinition = mappingDefinition.Subfields.FirstOrDefault(m => m.Name == Constants.ArrayItemGenericFieldName); if (elementMappingDefinition != null) { elementCalculator = CreateValueCalculator(elementMappingDefinition); } return new ArrayValueCalculator(elementType, mappingDefinition.ValueExpression, elementCalculator, TypeConverter); }
private IValueCalculator CreateSimpleValueCalculator(Type valueType, WebMethodParameterMappingDefinition mappingDefinition) { return new SimpleValueCalculator(mappingDefinition.ValueExpression, valueType, TypeConverter); }
/// <summary> /// Creates a property setter for the specified <see cref="WebMethodParameterMappingDefinition"/>. /// </summary> /// <param name="targetType"> /// The target type. /// </param> /// <param name="mappingDefinition"> /// The mapping definition. /// </param> /// <returns> /// The <see cref="IPropertySetter"/>. /// </returns> public IPropertySetter CreatePropertySetter(Type targetType, WebMethodParameterMappingDefinition mappingDefinition) { if (targetType == null) throw new ArgumentNullException("targetType"); if (mappingDefinition == null) throw new ArgumentNullException("mappingDefinition"); var propertyInfo = targetType.GetProperty(mappingDefinition.Name, BindingFlags.Instance | BindingFlags.Public); if (propertyInfo != null) { return new PropertySetter(propertyInfo, CreateValueCalculator(mappingDefinition)); } var fieldInfo = targetType.GetField(mappingDefinition.Name, BindingFlags.Instance | BindingFlags.Public); if (fieldInfo != null) { return new FieldSetter(fieldInfo, CreateValueCalculator(mappingDefinition)); } throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "Could not find the field or property \"{0}\" in type \"{1}\".", mappingDefinition.Name, targetType.AssemblyQualifiedName), "mappingDefinition"); }
public void ExecuteTest() { // Arrange. const int ServiceDescriptionId = 123; const string ServiceName = "TestService"; const string Username = "******"; const string ProcessDisplayName = "Test Process"; const string RequestXml = "Test Request"; const string ResponseXml = "Test Response"; var serviceGuid = new Guid("{298F9413-AB7F-4DCC-A3E0-9B5E5640FC68}"); var headerValueMappingDefinition = new WebMethodParameterMappingDefinition(); var headerDefinition = new WebMethodHeaderMappingDefinition { ValueMapping = headerValueMappingDefinition }; var parameterDefinition = new WebMethodParameterMappingDefinition(); var callDefinition = new WebMethodCallDefinition { ServiceDescriptionId = ServiceDescriptionId, Name = ServiceName, Guid = serviceGuid, ProcessDisplayName = ProcessDisplayName }; callDefinition.HeaderMappings.Add(headerDefinition); callDefinition.ParameterMappings.Add(parameterDefinition); var editableRoot = Mock.Create<IEditableRoot>(Behavior.Loose); var callContext = Mock.Create<IDataContext>(Behavior.Loose); var callContextFactory = Mock.Create<IEditableRootDataContextFactory>(Behavior.Loose); Mock.Arrange(() => callContextFactory.CreateDataContext(editableRoot)).Returns(callContext); var soapHeaderAttributes = new SoapHeaderAttributes { HeaderName = "Test Header", HeaderNamespace = "Test Namespace", Actor = "Test Actor", MustUnderstand = true, Relay = true }; var headerAttributesCalculator = Mock.Create<ISoapHeaderAttributesCalculator>(Behavior.Loose); Mock.Arrange(() => headerAttributesCalculator.GetHeaderAttributes(callContext)).Returns(soapHeaderAttributes); var headerValue = new object(); var headerSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => headerSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Header = headerValue); var parameterValue = new object(); var parameterSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => parameterSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Parameter = parameterValue); var mappingFactory = Mock.Create<IWebMethodParameterCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), headerValueMappingDefinition)).Returns(headerSetter); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), parameterDefinition)).Returns(parameterSetter); var headerMappingFactory = Mock.Create<ISoapHeaderAttributesCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => headerMappingFactory.CreateCalculator(typeof(InputMessage), headerDefinition)).Returns(headerAttributesCalculator); WebMethodCallData callData = null; var methodProxy = Mock.Create<IWebMethodProxy>(); Mock.Arrange(() => methodProxy.RequestType).Returns(typeof(InputMessage)); Mock.Arrange(() => methodProxy.Invoke(Arg.IsAny<WebMethodCallData>())).DoInstead<WebMethodCallData>( data => { callData = data; if (IntegrationServiceCallScope.Current != null) { IntegrationServiceCallScope.Current.Request = RequestXml; IntegrationServiceCallScope.Current.Response = ResponseXml; } }); var utils = Mock.Create<IUtils>(Behavior.Loose); Mock.Arrange(() => utils.CurrentUserName).Returns(Username); var events = new List<IntegrationEvent>(); var eventLogger = Mock.Create<IIntegrationEventLogger>(Behavior.Loose); Mock.Arrange(() => eventLogger.Log(Arg.IsAny<IntegrationEvent>())).DoInstead<IntegrationEvent>(events.Add); var serviceCaller = new WebMethodServiceCaller { ParameterCalculatorFactory = mappingFactory, HeaderAttributesCalculatorFactory = headerMappingFactory, MethodProxy = methodProxy, EditableRootDataContextFactory = callContextFactory, Utils = utils, IntegrationEventLogger = eventLogger }; serviceCaller.Initialize(callDefinition); // Act. serviceCaller.Execute(editableRoot); // Assert. Assert.IsNotNull(callData); var request = callData.Message as InputMessage; Assert.IsNotNull(request); Assert.AreSame(headerValue, request.Header); Assert.AreSame(parameterValue, request.Parameter); Assert.AreEqual(1, callData.Options.HeaderAttributes.Count); Assert.IsTrue(callData.Options.HeaderAttributes.Contains(soapHeaderAttributes)); Mock.Assert(() => methodProxy.Invoke(Arg.IsAny<WebMethodCallData>()), Occurs.Once()); Assert.AreEqual(1, events.Count); Assert.IsTrue(events[0].IsSuccessful); Assert.AreEqual(ProcessDisplayName, events[0].Process); Assert.AreEqual(ServiceName, events[0].Service); Assert.AreEqual(Username, events[0].Username); Assert.AreEqual(RequestXml, events[0].Request); Assert.AreEqual(ResponseXml, events[0].Response); // Exceptions. TestsHelper.VerifyThrow<ArgumentNullException>(() => serviceCaller.Execute(null)); }
public void EnqueueServiceCall_InsertsScheduledCall() { const int ServiceDescriptionId = 123; const string ServiceName = "TestService"; const string SerializedRequest = "TestData"; const string SerializedOptions = "TestOptions"; var serviceGuid = new Guid("{298F9413-AB7F-4DCC-A3E0-9B5E5640FC68}"); const string ProcessName = "TestProcess"; const int ItemId = 456; var headerValueMappingDefinition = new WebMethodParameterMappingDefinition(); var headerDefinition = new WebMethodHeaderMappingDefinition { ValueMapping = headerValueMappingDefinition }; var parameterDefinition = new WebMethodParameterMappingDefinition(); var callDefinition = new WebMethodCallDefinition { ServiceDescriptionId = ServiceDescriptionId, Name = ServiceName, Guid = serviceGuid }; callDefinition.HeaderMappings.Add(headerDefinition); callDefinition.ParameterMappings.Add(parameterDefinition); var editableRoot = Mock.Create<IEditableRoot>(Behavior.Loose); Mock.Arrange(() => editableRoot.Id).Returns(ItemId); Mock.Arrange(() => editableRoot.ProcessName).Returns(ProcessName); var callContext = Mock.Create<IDataContext>(Behavior.Loose); var callContextFactory = Mock.Create<IEditableRootDataContextFactory>(Behavior.Loose); Mock.Arrange(() => callContextFactory.CreateDataContext(editableRoot)).Returns(callContext); var soapHeaderAttributes = new SoapHeaderAttributes { HeaderName = "Test Header", HeaderNamespace = "Test Namespace", Actor = "Test Actor", MustUnderstand = true, Relay = true }; var headerAttributesCalculator = Mock.Create<ISoapHeaderAttributesCalculator>(Behavior.Loose); Mock.Arrange(() => headerAttributesCalculator.GetHeaderAttributes(callContext)).Returns(soapHeaderAttributes); var headerValue = new object(); var headerSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => headerSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Header = headerValue); var parameterValue = new object(); var parameterSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => parameterSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Parameter = parameterValue); var mappingFactory = Mock.Create<IWebMethodParameterCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), headerValueMappingDefinition)).Returns(headerSetter); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), parameterDefinition)).Returns(parameterSetter); var headerMappingFactory = Mock.Create<ISoapHeaderAttributesCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => headerMappingFactory.CreateCalculator(typeof(InputMessage), headerDefinition)).Returns(headerAttributesCalculator); var methodProxy = Mock.Create<IWebMethodProxy>(Behavior.Loose); Mock.Arrange(() => methodProxy.RequestType).Returns(typeof(InputMessage)); Mock.Arrange(() => methodProxy.ContractType).Returns(typeof(ITestService)); Mock.Arrange(() => methodProxy.Method).Returns(typeof(ITestService).GetMethod("TestMethod")); var requestSerializer = Mock.Create<IWebMethodRequestSerializer>(Behavior.Loose); Mock.Arrange(() => requestSerializer.SerializeRequest(Arg.IsAny<object>())).Returns(SerializedRequest); Mock.Arrange(() => requestSerializer.SerializeOptions(Arg.IsAny<WebMethodCallOptions>())).Returns(SerializedOptions); WebMethodScheduledCall scheduledCall = null; var callScheduler = Mock.Create<IServiceCallScheduler>(Behavior.Loose); Mock.Arrange(() => callScheduler.InsertScheduledCall(Arg.IsAny<ServiceScheduledCall>())) .DoInstead<ServiceScheduledCall>(sc => scheduledCall = (WebMethodScheduledCall)sc); var utils = Mock.Create<IUtils>(Behavior.Loose); var eventLogger = Mock.Create<IIntegrationEventLogger>(Behavior.Loose); var serviceCaller = new WebMethodServiceCaller { ParameterCalculatorFactory = mappingFactory, HeaderAttributesCalculatorFactory = headerMappingFactory, MethodProxy = methodProxy, EditableRootDataContextFactory = callContextFactory, RequestSerializer = requestSerializer, CallScheduler = callScheduler, Utils = utils, IntegrationEventLogger = eventLogger }; serviceCaller.Initialize(callDefinition); // Act. serviceCaller.EnqueueServiceCall(editableRoot); // Assert. Mock.Assert(() => callScheduler.InsertScheduledCall(Arg.IsAny<ServiceScheduledCall>()), Occurs.Once()); Assert.IsNotNull(scheduledCall); Assert.AreEqual(serviceGuid, scheduledCall.IntegrationServiceGuid); Assert.AreEqual(ProcessName, scheduledCall.ProcessName); Assert.AreEqual(ItemId, scheduledCall.ItemId); Assert.AreEqual(0, scheduledCall.CallCount); Assert.AreEqual(ServiceCallStatus.Scheduled, scheduledCall.Status); Assert.AreEqual(ServiceDescriptionId, scheduledCall.ServiceDescriptionId); Assert.AreEqual(typeof(ITestService).AssemblyQualifiedName, scheduledCall.ContractTypeName); Assert.AreEqual("TestMethod", scheduledCall.MethodName); Assert.AreEqual(SerializedRequest, scheduledCall.Data); Assert.AreEqual(SerializedOptions, scheduledCall.Options); }
public void WhenExecutionFails_ServiceCallExceptionIsThrown() { // Arrange. const int ServiceDescriptionId = 123; const string ServiceName = "TestService"; const string SerializedRequest = "TestData"; const string SerializedOptions = "TestOptions"; var serviceGuid = new Guid("{298F9413-AB7F-4DCC-A3E0-9B5E5640FC68}"); const string ProcessName = "TestProcess"; const int ItemId = 456; var headerValueMappingDefinition = new WebMethodParameterMappingDefinition(); var headerDefinition = new WebMethodHeaderMappingDefinition { ValueMapping = headerValueMappingDefinition }; var parameterDefinition = new WebMethodParameterMappingDefinition(); var callDefinition = new WebMethodCallDefinition { ServiceDescriptionId = ServiceDescriptionId, Name = ServiceName, Guid = serviceGuid }; callDefinition.HeaderMappings.Add(headerDefinition); callDefinition.ParameterMappings.Add(parameterDefinition); var editableRoot = Mock.Create<IEditableRoot>(Behavior.Loose); Mock.Arrange(() => editableRoot.Id).Returns(ItemId); Mock.Arrange(() => editableRoot.ProcessName).Returns(ProcessName); var callContext = Mock.Create<IDataContext>(Behavior.Loose); var callContextFactory = Mock.Create<IEditableRootDataContextFactory>(Behavior.Loose); Mock.Arrange(() => callContextFactory.CreateDataContext(editableRoot)).Returns(callContext); var soapHeaderAttributes = new SoapHeaderAttributes { HeaderName = "Test Header", HeaderNamespace = "Test Namespace", Actor = "Test Actor", MustUnderstand = true, Relay = true }; var headerAttributesCalculator = Mock.Create<ISoapHeaderAttributesCalculator>(Behavior.Loose); Mock.Arrange(() => headerAttributesCalculator.GetHeaderAttributes(callContext)).Returns(soapHeaderAttributes); var headerValue = new object(); var headerSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => headerSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Header = headerValue); var parameterValue = new object(); var parameterSetter = Mock.Create<IPropertySetter>(Behavior.Loose); Mock.Arrange(() => parameterSetter.Update(callContext, Arg.IsAny<InputMessage>())) .DoInstead<IDataContext, InputMessage>((dc, target) => target.Parameter = parameterValue); var mappingFactory = Mock.Create<IWebMethodParameterCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), headerValueMappingDefinition)).Returns(headerSetter); Mock.Arrange(() => mappingFactory.CreatePropertySetter(typeof(InputMessage), parameterDefinition)).Returns(parameterSetter); var headerMappingFactory = Mock.Create<ISoapHeaderAttributesCalculatorFactory>(Behavior.Loose); Mock.Arrange(() => headerMappingFactory.CreateCalculator(typeof(InputMessage), headerDefinition)).Returns(headerAttributesCalculator); var methodProxy = Mock.Create<IWebMethodProxy>(Behavior.Loose); Mock.Arrange(() => methodProxy.RequestType).Returns(typeof(InputMessage)); Mock.Arrange(() => methodProxy.Invoke(Arg.IsAny<WebMethodCallData>())).Throws(new CommunicationException()); Mock.Arrange(() => methodProxy.ContractType).Returns(typeof(ITestService)); Mock.Arrange(() => methodProxy.Method).Returns(typeof(ITestService).GetMethod("TestMethod")); var requestSerializer = Mock.Create<IWebMethodRequestSerializer>(Behavior.Loose); Mock.Arrange(() => requestSerializer.SerializeRequest(Arg.IsAny<object>())).Returns(SerializedRequest); Mock.Arrange(() => requestSerializer.SerializeOptions(Arg.IsAny<WebMethodCallOptions>())).Returns(SerializedOptions); var callScheduler = Mock.Create<IServiceCallScheduler>(Behavior.Loose); var utils = Mock.Create<IUtils>(Behavior.Loose); var eventLogger = Mock.Create<IIntegrationEventLogger>(Behavior.Loose); var serviceCaller = new WebMethodServiceCaller { ParameterCalculatorFactory = mappingFactory, HeaderAttributesCalculatorFactory = headerMappingFactory, MethodProxy = methodProxy, EditableRootDataContextFactory = callContextFactory, RequestSerializer = requestSerializer, CallScheduler = callScheduler, Utils = utils, IntegrationEventLogger = eventLogger }; serviceCaller.Initialize(callDefinition); // Act / Assert. TestsHelper.VerifyThrow<ServiceCallException>(() => serviceCaller.Execute(editableRoot)); }