fixed SPRNET-1204: added Server Component support

This commit is contained in:
eeichinger
2009-05-13 16:16:05 +00:00
parent ab9683d9c9
commit e4ecb38507
17 changed files with 1109 additions and 430 deletions

View File

@@ -20,9 +20,11 @@
#region Imports
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using NUnit.Framework;
@@ -45,102 +47,182 @@ namespace Spring.Objects.Factory.Config
<configSections>
<section name='foo' type='System.Configuration.NameValueSectionHandler, System'/>
</configSections>
<foo>
<add key='rilo' value='kiley'/>
<add key='jenny' value='lewis'/>
</foo>
<foo>
<add key='rilo' value='kiley'/>
<add key='jenny' value='lewis'/>
</foo>
</configuration>";
#if !NET_0 && !NET_1_1
/// <summary>
/// Unfortunately ConfigurationManager doesn't accept uri's.
/// </summary>
[Test]
public void ConfigurationManagerCannotReadFromUrl()
{
try
{
ConfigurationManager.OpenExeConfiguration("http://localhost/something.config");
Assert.Fail();
}
catch (ConfigurationErrorsException cfgex)
{
Assert.IsInstanceOfType(typeof (ArgumentException), cfgex.InnerException);
}
}
#endif
[Test]
public void ReadSunnyDay()
{
new StreamHelperDecorator(new StreamHelperCallback(_ReadSunnyDay)).Run();
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
NameValueCollection props = ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo");
Assert.IsNotNull(props,
"Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count,
"Wrong number of properties read in.");
Assert.AreEqual("kiley",
props["rilo"],
"Wrong value for second property");
Assert.AreEqual("lewis",
props["jenny"],
"Wrong value for second property");
}
string machineConfig = RuntimeEnvironment.SystemConfigurationFile;
}
private void _ReadSunnyDay(out Stream stream)
#if !NET_1_0 && !NET_1_1
[Test]
public void GetSectionLocalSectionHandler()
{
stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml));
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo");
Assert.IsNotNull(props, "Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count, "Wrong number of properties read in.");
Assert.AreEqual("kiley", props["rilo"], "Wrong value for second property");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for second property");
string xml = @"<?xml version='1.0' encoding='UTF-8' ?>
<configuration>
<configSections>
<section name='connectionStrings' type='System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' requirePermission='false' />
</configSections>
<connectionStrings>
<add name='Sales'
providerName='System.Data.SqlClient'
connectionString= 'server=myserver;database=Products;uid=user name;pwd=secure password' />
</connectionStrings>
</configuration>
";
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
ConnectionStringsSection css = ConfigurationReader.GetSection<ConnectionStringsSection>(new InputStreamResource(stream, ""), "connectionStrings");
Assert.IsNotNull(css, "Failed to read in any properties at all (props is null).");
Assert.IsNotNull(css.ConnectionStrings["Sales"]);
Assert.AreEqual("System.Data.SqlClient", css.ConnectionStrings["Sales"].ProviderName);
Assert.AreEqual("server=myserver;database=Products;uid=user name;pwd=secure password", css.ConnectionStrings["Sales"].ConnectionString);
}
}
[Test]
public void GetSectionMachineInheritedSectionHandler()
{
string xml = @"<?xml version='1.0' encoding='UTF-8' ?>
<configuration>
<connectionStrings>
<add name='Sales'
providerName='System.Data.SqlClient'
connectionString= 'server=myserver;database=Products;uid=user name;pwd=secure password' />
</connectionStrings>
</configuration>
";
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
ConnectionStringsSection css = ConfigurationReader.GetSection<ConnectionStringsSection>(new InputStreamResource(stream, ""), "connectionStrings");
Assert.IsNotNull(css, "Failed to read in any properties at all (props is null).");
Assert.IsNotNull(css.ConnectionStrings["Sales"]);
Assert.AreEqual("System.Data.SqlClient", css.ConnectionStrings["Sales"].ProviderName);
Assert.AreEqual("server=myserver;database=Products;uid=user name;pwd=secure password", css.ConnectionStrings["Sales"].ConnectionString);
}
}
#endif
[Test]
public void GetSectionSunnyDay()
{
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
NameValueCollection props = ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo");
Assert.IsNotNull(props,
"Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count,
"Wrong number of properties read in.");
Assert.AreEqual("kiley",
props["rilo"],
"Wrong value for second property");
Assert.AreEqual("lewis",
props["jenny"],
"Wrong value for second property");
}
}
[Test]
public void ReadWithOverrideOfPreviouslyExistingValues()
{
new StreamHelperDecorator(new StreamHelperCallback(_ReadWithOverrideOfPreviouslyExistingValues)).Run();
}
private void _ReadWithOverrideOfPreviouslyExistingValues(out Stream stream)
{
stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml));
NameValueCollection defaults = new NameValueCollection();
defaults.Add("jenny", "agutter");
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", defaults);
Assert.IsTrue(ReferenceEquals(defaults, props), "Must have got same collection as was passed in.");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for overridden property (was not overridden");
using(Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
NameValueCollection defaults = new NameValueCollection();
defaults.Add("jenny", "agutter");
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", defaults);
Assert.IsTrue(ReferenceEquals(defaults, props), "Must have got same collection as was passed in.");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for overridden property (was not overridden");
}
}
[Test]
public void ReadWithOverrideOfPreviouslyExistingValuesButWithOverrideSwitchedOff()
{
new StreamHelperDecorator(new StreamHelperCallback(_ReadWithOverrideOfPreviouslyExistingValuesButWithOverrideSwitchedOff)).Run();
}
private void _ReadWithOverrideOfPreviouslyExistingValuesButWithOverrideSwitchedOff(out Stream stream)
{
stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml));
NameValueCollection defaults = new NameValueCollection();
defaults.Add("jenny", "agutter");
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", defaults, false);
Assert.IsTrue(ReferenceEquals(defaults, props), "Must have got same collection as was passed in.");
Assert.AreEqual("agutter,lewis", props["jenny"], "Wrong value for overridden property (was not overridden");
using(Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
NameValueCollection defaults = new NameValueCollection();
defaults.Add("jenny", "agutter");
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", defaults, false);
Assert.IsTrue(ReferenceEquals(defaults, props), "Must have got same collection as was passed in.");
Assert.AreEqual("agutter,lewis", props["jenny"], "Wrong value for overridden property (was not overridden");
}
}
[Test]
public void ReadWithNullExistingValuesPassedIn()
{
new StreamHelperDecorator(new StreamHelperCallback(_ReadWithNullExistingValuesPassedIn)).Run();
}
private void _ReadWithNullExistingValuesPassedIn(out Stream stream)
{
stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml));
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", null);
Assert.IsNotNull(props, "Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count, "Wrong number of properties read in.");
Assert.AreEqual("kiley", props["rilo"], "Wrong value for second property");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for second property");
using(Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", null);
Assert.IsNotNull(props, "Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count, "Wrong number of properties read in.");
Assert.AreEqual("kiley", props["rilo"], "Wrong value for second property");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for second property");
}
}
[Test]
public void ReadWithNoConfigSectionSectionDefaultsToNameValueSectionHandler()
{
new StreamHelperDecorator(new StreamHelperCallback(_ReadWithNoConfigSectionSectionDefaultsToNameValueSectionHandler)).Run();
}
private void _ReadWithNoConfigSectionSectionDefaultsToNameValueSectionHandler(out Stream stream)
{
const string NoConfigSectionXml = @"<?xml version='1.0' encoding='UTF-8' ?>
<configuration>
<foo>
<add key='rilo' value='kiley'/>
<add key='jenny' value='lewis'/>
</foo>
<foo>
<add key='rilo' value='kiley'/>
<add key='jenny' value='lewis'/>
</foo>
</configuration>";
stream = new MemoryStream(Encoding.UTF8.GetBytes(NoConfigSectionXml));
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", null);
Assert.IsNotNull(props, "Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count, "Wrong number of properties read in.");
Assert.AreEqual("kiley", props["rilo"], "Wrong value for second property");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for second property");
using(Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(NoConfigSectionXml)))
{
NameValueCollection props
= ConfigurationReader.Read(new InputStreamResource(stream, ""), "foo", null);
Assert.IsNotNull(props, "Failed to read in any properties at all (props is null).");
Assert.AreEqual(2, props.Count, "Wrong number of properties read in.");
Assert.AreEqual("kiley", props["rilo"], "Wrong value for second property");
Assert.AreEqual("lewis", props["jenny"], "Wrong value for second property");
}
}
[Test]
@@ -148,16 +230,13 @@ namespace Spring.Objects.Factory.Config
[ExpectedException(typeof(ConfigurationException), "Cannot read properties; config section 'ELNOMBRE' not found.")]
#else
[ExpectedException(typeof(ConfigurationErrorsException), "Cannot read properties; config section 'ELNOMBRE' not found.")]
#endif
#endif
public void TryReadFromNonExistantConfigSection()
{
new StreamHelperDecorator(new StreamHelperCallback(_TryReadFromNonExistantConfigSection)).Run();
}
private void _TryReadFromNonExistantConfigSection(out Stream stream)
{
stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml));
ConfigurationReader.Read(new InputStreamResource(stream, ""), "ELNOMBRE", null);
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(SunnyDayXml)))
{
ConfigurationReader.Read(new InputStreamResource(stream, ""), "ELNOMBRE", null);
}
}
}
}

View File

@@ -14,7 +14,13 @@ namespace Spring
/// Supports obtaining embedded resources from assembly.
/// </summary>
/// <remarks>
/// <para>
/// The first <c>context</c> argument is always the namespace scope to be used for resolving resource names.
/// </para>
/// <para>
/// Upon first usage, TestResourceLoader registers the "testres://" protocol prefix for loading embedded resources.
/// A testres:// Url must be of the form "testres://./&lt;context-typename&gt;#&lt;ext" - <see cref="GetStream"/>.
/// </para>
/// </remarks>
public class TestResourceLoader
{
@@ -73,6 +79,12 @@ namespace Spring
private TestResourceLoader()
{ }
/// <summary>
/// Returns an Uri of the form "testres://./resourcname" that may be passed into <see cref="WebRequest.Create(string)"/> etc.
/// </summary>
/// <param name="context"></param>
/// <param name="ext"></param>
/// <returns></returns>
public static Uri GetUri(object context, string ext)
{
string resname = context.GetType().AssemblyQualifiedName + "#" + ext;
@@ -131,6 +143,10 @@ namespace Spring
}
}
/// <summary>
/// Returns an embedded assembly resource, who's name is constructed from the given parameters as
/// <c>context.GetType().FullName + ext</c>
/// </summary>
public static Stream GetStream(object context, string ext)
{
Type contextType = (context is Type) ? (Type)context : context.GetType();
@@ -140,6 +156,32 @@ namespace Spring
return stm;
}
/// <summary>
/// Exports a resource obtained via <see cref="GetStream"/> to the specified destination.
/// </summary>
public static FileInfo ExportResource(object context, string ext, FileInfo destination)
{
Stream istm = GetStream(context, ext);
using(istm)
{
FileStream ostm = destination.OpenWrite();
using (ostm)
{
byte[] buffer = new byte[2048];
int bytesRead = istm.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
ostm.Write(buffer, 0, bytesRead);
bytesRead = istm.Read(buffer, 0, buffer.Length);
}
ostm.Flush();
ostm.Close();
}
istm.Close();
}
return destination;
}
/// <summary>
/// returns an "assembly://" uri for the specified manifest resource, scoped by the namespace of the specified type.
/// ("assembly://hint.assemblyname_without_version/hint.Namespace/name")

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
</sectionGroup>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<appSettings>
<add key="key" value="from custom config!"/>
</appSettings>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging"/>
</logging>
</common>
</configuration>

View File

@@ -0,0 +1,45 @@

namespace Spring.EnterpriseServices
{
#if NET_2_0
using System.Configuration;
using System.Configuration.Internal;
using System.IO;
using Common.Logging;
using Common.Logging.Simple;
using NUnit.Framework;
using Spring.Util;
[TestFixture]
public class ExeConfigurationSystemTests
{
[Test]
public void SunnyDay()
{
FileInfo resFile = TestResourceLoader.ExportResource(this, ".config", new FileInfo(Path.GetTempFileName()+".config"));
string exePath = resFile.FullName.Substring(0, resFile.FullName.Length - ".config".Length);
Assert.IsTrue(resFile.Exists);
IInternalConfigSystem prevConfig = null;
try
{
ExeConfigurationSystem ccs = new ExeConfigurationSystem(exePath);
prevConfig = ConfigurationUtils.SetConfigurationSystem(ccs, true);
LogSetting settings = (LogSetting) ConfigurationManager.GetSection("common/logging");
Assert.AreEqual(typeof (TraceLoggerFactoryAdapter), settings.FactoryAdapterType);
Assert.AreEqual("from custom config!", ConfigurationManager.AppSettings["key"]);
Assert.IsNull(ConfigurationManager.GetSection("spring/context"));
}
finally
{
if (prevConfig != null)
{
ConfigurationUtils.SetConfigurationSystem(prevConfig, true);
}
resFile.Delete();
}
}
}
#endif
}

View File

@@ -111,7 +111,7 @@ namespace Spring.EnterpriseServices
try
{
// ServiceComponent will obtain its target from root context
ContextRegistry.RegisterContext(appCtx);
// ContextRegistry.RegisterContext(appCtx);
IComparable testObject;
testObject = (IComparable)Activator.CreateInstance(serviceType);
@@ -126,6 +126,7 @@ namespace Spring.EnterpriseServices
}
}
#if NET_2_0
[Test]
public void CanExportAopProxyToServer()
{
@@ -146,9 +147,9 @@ namespace Spring.EnterpriseServices
finally
{
exporter.UnregisterServicedComponents(assemblyFile);
ContextRegistry.Clear();
}
}
#endif
private Type ExportObject(EnterpriseServicesExporter exporter, FileInfo assemblyFile, IConfigurableApplicationContext appCtx, string objectName)
{

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<!-- library components access their process' app.config -->
<resource uri="ServiceComponentExporterTests.TestServicedComponents.Services.xml" />
</context>
</spring>
</configuration>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging"/>
</logging>
</common>
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object id="countingInterceptor" type="Spring.EnterpriseServices.ServicedComponentExporterTests+CountingMethodInterceptor, Spring.Services.Tests" />
<object name="objectTest" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="ProxyInterfaces">
<list>
<value>System.IComparable</value>
</list>
</property>
<property name="InterceptorNames">
<list>
<idref local="countingInterceptor"/>
</list>
</property>
</object>
</objects>
</spring>
</configuration>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<spring>
<context>
<resource uri="ServiceComponentExporterTests.TestServicedComponents.Services.xml" />
</context>
</spring>

View File

@@ -72,6 +72,14 @@
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, PublicKeyToken=65e474d141e25e07, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\antlr.runtime.dll</HintPath>
</Reference>
<Reference Include="Common.Logging, Version=1.2.0.0, Culture=neutral, PublicKeyToken=af08829b84f0328e">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="DotNetMock, Version=0.7.4.0, Culture=neutral, PublicKeyToken=805ea88df19095f6">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\Net\2.0\DotNetMock.dll</HintPath>
@@ -87,6 +95,7 @@
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Data">
<Name>System.Data</Name>
</Reference>
@@ -103,6 +112,8 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="EnterpriseServices\ExeConfigurationSystemTests.cs" />
<Compile Include="EnterpriseServices\ExportedServicedComponentSample.cs" />
<Compile Include="EnterpriseServices\ServicedComponentExporterTests.cs" />
<Compile Include="Remoting\BaseRemotingTestFixture.cs" />
<Compile Include="Remoting\CaoExporterTests.cs">
@@ -138,6 +149,7 @@
</SubType>
</None>
<None Include="Data\Spring\Web\Services\Service.cs.fyi" />
<EmbeddedResource Include="EnterpriseServices\ExeConfigurationSystemTests.config" />
<None Include="Spring.Services.Tests.build" />
<None Include="Spring.Services.Tests.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -190,9 +202,12 @@
<EmbeddedResource Include="Data\Spring\Remoting\saoSingleton-autowired.xml" />
</ItemGroup>
<ItemGroup>
<Content Include="ServiceComponentExporterTests.TestServicedComponents.exe.spring-context.xml">
<None Include="ServiceComponentExporterTests.TestServicedComponents.dll.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</None>
<None Include="ServiceComponentExporterTests.TestServicedComponents.exe.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="ServiceComponentExporterTests.TestServicedComponents.Services.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>