[mapguide-commits] r7125 - in trunk/Tools/Maestro: MaestroAPITestRunner MaestroAPITests OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/SchemaOverrides OSGeo.MapGuide.MaestroAPI/Services OSGeo.MapGuide.MaestroAPI.Http OSGeo.MapGuide.MaestroAPI.Local OSGeo.MapGuide.MaestroAPI.Native

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Oct 17 06:29:39 PDT 2012


Author: jng
Date: 2012-10-17 06:29:39 -0700 (Wed, 17 Oct 2012)
New Revision: 7125

Added:
   trunk/Tools/Maestro/MaestroAPITests/ConnectionTestBase.cs
   trunk/Tools/Maestro/MaestroAPITests/LocalConnectionTests.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/LongTransaction.cs
Modified:
   trunk/Tools/Maestro/MaestroAPITestRunner/MaestroAPITestRunner.csproj
   trunk/Tools/Maestro/MaestroAPITests/HttpConnectionTests.cs
   trunk/Tools/Maestro/MaestroAPITests/LocalNativeFeatureTests.cs
   trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj
   trunk/Tools/Maestro/MaestroAPITests/ObjectTests.cs
   trunk/Tools/Maestro/MaestroAPITests/ValidationTests.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Local/LocalConnection.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeConnection.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/SchemaOverrides/ConfigurationDocument.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs
Log:
This submission contains the following changes:
 - #2152: Expose the GetSchemaMapping API to IFeatureService, we'll be using this to construct default WMS configuration documents. A unit test has been added to excercise this API
 - Restructure the connection-based test fixtures. Since most of these tests are the same with the only difference being the IServerConnection implementation we're testing against, these test fixtures now all inherit from a ConnectionTestBase class that defines all of the common tests. Ones that are applicable for a given provider are overridden in the subclass and have the [Test] attribute applied so NUnit will execute them.
 - Expose the GetLongTransactions API to IFeatureService

Modified: trunk/Tools/Maestro/MaestroAPITestRunner/MaestroAPITestRunner.csproj
===================================================================
--- trunk/Tools/Maestro/MaestroAPITestRunner/MaestroAPITestRunner.csproj	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITestRunner/MaestroAPITestRunner.csproj	2012-10-17 13:29:39 UTC (rev 7125)
@@ -83,7 +83,7 @@
       <Name>MaestroAPITests</Name>
     </ProjectReference>
     <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI.Local\OSGeo.MapGuide.MaestroAPI.Local.csproj">
-      <Project>{3DDF6501-0148-474C-8674-7C7DA49C7F02}</Project>
+      <Project>{3ddf6501-0148-474c-8674-7c7da49c7f02}</Project>
       <Name>OSGeo.MapGuide.MaestroAPI.Local</Name>
     </ProjectReference>
     <ProjectReference Include="..\OSGeo.MapGuide.MaestroAPI\OSGeo.MapGuide.MaestroAPI.csproj">

Added: trunk/Tools/Maestro/MaestroAPITests/ConnectionTestBase.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/ConnectionTestBase.cs	                        (rev 0)
+++ trunk/Tools/Maestro/MaestroAPITests/ConnectionTestBase.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -0,0 +1,535 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using System.IO;
+using OSGeo.MapGuide.ObjectModels.Common;
+using OSGeo.MapGuide.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
+using NUnit.Framework;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
+using OSGeo.MapGuide.ObjectModels;
+using OSGeo.MapGuide.ObjectModels.Common;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using OSGeo.MapGuide.MaestroAPI.Schema;
+using OSGeo.MapGuide.MaestroAPI.Commands;
+using OSGeo.MapGuide.MaestroAPI.CoordinateSystem;
+using OSGeo.MapGuide.MaestroAPI.Internal;
+using OSGeo.MapGuide.MaestroAPI.Feature;
+
+namespace MaestroAPITests
+{
+    public abstract class ConnectionTestBase
+    {
+        protected abstract IServerConnection CreateTestConnection();
+
+        protected void TestFeatureSourceCaching(string fsName)
+        {
+            var conn = CreateTestConnection();
+            string fsId = "Library://UnitTests/" + fsName + ".FeatureSource";
+            if (!conn.ResourceService.ResourceExists(fsId))
+            {
+                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
+                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
+                fs.ResourceID = fsId;
+                conn.ResourceService.SaveResourceAs(fs, fsId);
+                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
+                {
+                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
+                }
+                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
+            }
+            var pc = (PlatformConnectionBase)conn;
+            pc.ResetFeatureSourceSchemaCache();
+
+            Assert.AreEqual(0, pc.CachedClassDefinitions);
+            Assert.AreEqual(0, pc.CachedFeatureSources);
+
+            var fsd = conn.FeatureService.DescribeFeatureSource(fsId);
+
+            Assert.AreEqual(1, pc.CachedFeatureSources);
+            Assert.AreEqual(1, pc.CachedClassDefinitions);
+
+            var fsd2 = conn.FeatureService.DescribeFeatureSource(fsId);
+
+            Assert.AreEqual(1, pc.CachedFeatureSources);
+            Assert.AreEqual(1, pc.CachedClassDefinitions);
+            //Each cached instance returned is a clone
+            Assert.False(object.ReferenceEquals(fsd, fsd2));
+        }
+
+        protected void TestClassDefinitionCaching(string fsName)
+        {
+            var conn = ConnectionUtil.CreateTestHttpConnection();
+            string fsId = "Library://UnitTests/" + fsName + ".FeatureSource";
+            if (!conn.ResourceService.ResourceExists(fsId))
+            {
+                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
+                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
+                conn.ResourceService.SaveResourceAs(fs, fsId);
+                fs.ResourceID = fsId;
+                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
+                {
+                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
+                }
+                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
+            }
+            var pc = (PlatformConnectionBase)conn;
+            pc.ResetFeatureSourceSchemaCache();
+
+            Assert.AreEqual(0, pc.CachedClassDefinitions);
+            Assert.AreEqual(0, pc.CachedFeatureSources);
+
+            var cls = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
+
+            Assert.AreEqual(0, pc.CachedFeatureSources);
+            Assert.AreEqual(1, pc.CachedClassDefinitions);
+
+            var cls2 = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
+
+            Assert.AreEqual(0, pc.CachedFeatureSources);
+            Assert.AreEqual(1, pc.CachedClassDefinitions);
+            //Each cached instance returned is a clone
+            Assert.False(object.ReferenceEquals(cls, cls2));
+        }
+
+        protected void CreateTestDataStore(IServerConnection conn, string fsId, ref FeatureSchema schema, ref ClassDefinition cls)
+        {
+            schema = new FeatureSchema("Default", "");
+            cls = new ClassDefinition("Class1", "");
+
+            try
+            {
+                if (conn.ResourceService.ResourceExists(fsId))
+                    conn.ResourceService.DeleteResource(fsId);
+
+                cls.DefaultGeometryPropertyName = "GEOM";
+                cls.AddProperty(new DataPropertyDefinition("KEY", "")
+                {
+                    DataType = DataPropertyType.Int32,
+                    IsAutoGenerated = true,
+                    IsReadOnly = true,
+                    IsNullable = false
+                }, true);
+
+                cls.AddProperty(new DataPropertyDefinition("NAME", "")
+                {
+                    DataType = DataPropertyType.String,
+                    Length = 255,
+                    IsNullable = true,
+                    IsReadOnly = false
+                });
+
+                cls.AddProperty(new GeometricPropertyDefinition("GEOM", "")
+                {
+                    GeometricTypes = FeatureGeometricType.Point,
+                    SpatialContextAssociation = "Default"
+                });
+
+                schema.AddClass(cls);
+
+                ICreateDataStore create = (ICreateDataStore)conn.CreateCommand((int)CommandType.CreateDataStore);
+                CoordinateSystemDefinitionBase coordSys = conn.CoordinateSystemCatalog.FindCoordSys("LL84");
+                create.FeatureSourceId = fsId;
+                create.CoordinateSystemWkt = coordSys.WKT;
+                create.Name = "Default";
+                create.ExtentType = OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextListSpatialContextExtentType.Dynamic;
+                create.FileName = "Test.sdf";
+                create.Provider = "OSGeo.SDF";
+                create.Schema = schema;
+                create.XYTolerance = 0.001;
+                create.ZTolerance = 0.001;
+
+                create.Execute();
+            }
+            catch
+            {
+                schema = null;
+                cls = null;
+                throw;
+            }
+        }
+
+        protected void PopulateTestDataStore(IServerConnection conn, string fsId, ref FeatureSchema schema, ref ClassDefinition cls)
+        {
+            CreateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            IInsertFeatures insert = (IInsertFeatures)conn.CreateCommand((int)CommandType.InsertFeature);
+            insert.ClassName = cls.Name;
+            insert.FeatureSourceId = fsId;
+            var feat = new MutableRecord();
+
+            var reader = new FixedWKTReader();
+
+            //Initialize this record
+            feat.PutValue("GEOM", new GeometryValue(reader.Read("POINT (0 0)")));
+            feat.PutValue("NAME", new StringValue("Test1"));
+
+            //Attach to command.
+            insert.RecordToInsert = feat;
+
+            var res = insert.Execute();
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (0 1)"));
+            feat.SetString("NAME", "Test2");
+
+            res = insert.Execute();
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (1 1)"));
+            feat.SetString("NAME", "Test3");
+
+            res = insert.Execute();
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (1 0)"));
+            feat.SetString("NAME", "Test4");
+
+            res = insert.Execute();
+        }
+
+        public virtual void TestInsertFeatures()
+        {
+            var conn = CreateTestConnection();
+            var fsId = "Library://UnitTests/Data/TestInsertFeatures.FeatureSource";
+            ClassDefinition cls = null;
+            FeatureSchema schema = null;
+            CreateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            IInsertFeatures insert = (IInsertFeatures)conn.CreateCommand((int)CommandType.InsertFeature);
+            insert.ClassName = cls.Name;
+            insert.FeatureSourceId = fsId;
+            var feat = new MutableRecord();
+
+            var reader = new FixedWKTReader();
+
+            //Initialize this record
+            feat.PutValue("GEOM", new GeometryValue(reader.Read("POINT (0 0)")));
+            feat.PutValue("NAME", new StringValue("Test1"));
+
+            Assert.True(feat.PropertyExists("GEOM"));
+            Assert.True(feat.PropertyExists("NAME"));
+
+            //Attach to command.
+            insert.RecordToInsert = feat;
+
+            var res = insert.Execute();
+            Assert.Null(res.Error);
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (0 1)"));
+            feat.SetString("NAME", "Test2");
+
+            res = insert.Execute();
+            Assert.Null(res.Error);
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (1 1)"));
+            feat.SetString("NAME", "Test3");
+
+            res = insert.Execute();
+            Assert.Null(res.Error);
+
+            feat.SetGeometry("GEOM", reader.Read("POINT (1 0)"));
+            feat.SetString("NAME", "Test4");
+
+            res = insert.Execute();
+            Assert.Null(res.Error);
+
+            int count = 0;
+            using (var rdr = conn.FeatureService.QueryFeatureSource(fsId, cls.Name))
+            {
+                while (rdr.ReadNext())
+                {
+                    count++;
+                }
+                rdr.Close();
+            }
+
+            Assert.AreEqual(4, count);
+        }
+
+        public virtual void TestUpdateFeatures()
+        {
+            var conn = CreateTestConnection();
+            var fsId = "Library://UnitTests/Data/TestUpdateFeatures.FeatureSource";
+            ClassDefinition cls = null;
+            FeatureSchema schema = null;
+            PopulateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            IUpdateFeatures update = (IUpdateFeatures)conn.CreateCommand((int)CommandType.UpdateFeatures);
+            update.ClassName = cls.Name;
+            update.FeatureSourceId = fsId;
+            update.Filter = "NAME = 'Test4'";
+
+            update.ValuesToUpdate = new MutableRecord();
+            update.ValuesToUpdate.PutValue("NAME", new StringValue("Test4Modified"));
+
+            Assert.AreEqual(1, update.Execute());
+        }
+
+        public virtual void TestDeleteFeatures()
+        {
+            var conn = CreateTestConnection();
+            var fsId = "Library://UnitTests/Data/TestDeleteFeatures.FeatureSource";
+            ClassDefinition cls = null;
+            FeatureSchema schema = null;
+            PopulateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            IDeleteFeatures delete = (IDeleteFeatures)conn.CreateCommand((int)CommandType.DeleteFeatures);
+            delete.ClassName = cls.Name;
+            delete.FeatureSourceId = fsId;
+            delete.Filter = "NAME = 'Test4'";
+
+            Assert.AreEqual(1, delete.Execute());
+
+            int count = 0;
+            using (var rdr = conn.FeatureService.QueryFeatureSource(fsId, cls.Name))
+            {
+                while (rdr.ReadNext()) { count++; }
+            }
+
+            Assert.AreEqual(3, count);
+        }
+
+        public virtual void TestCreateDataStore()
+        {
+            var conn = CreateTestConnection();
+            var fsId = "Library://UnitTests/Data/TestCreateDataStore.FeatureSource";
+            ClassDefinition cls = null;
+            FeatureSchema schema = null;
+            CreateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            ClassDefinition cls2 = conn.FeatureService.GetClassDefinition(fsId, "Class1");
+            Assert.NotNull(cls2);
+            Assert.False(ClassDefinition.ReferenceEquals(cls, cls2));
+
+            Assert.AreEqual(cls.Name, cls2.Name);
+            Assert.AreEqual(cls.DefaultGeometryPropertyName, cls2.DefaultGeometryPropertyName);
+            Assert.AreEqual(cls.Properties.Count, cls2.Properties.Count);
+            Assert.AreEqual(cls.IdentityProperties.Count, cls2.IdentityProperties.Count);
+            foreach (var prop in cls.Properties)
+            {
+                var prop2 = cls2.FindProperty(prop.Name);
+                Assert.AreEqual(prop.Name, prop2.Name);
+                Assert.AreEqual(prop.Type, prop2.Type);
+            }
+        }
+
+        public virtual void TestApplySchema()
+        {
+            var fsId = "Library://UnitTests/Data/TestMaestroLocalApplySchema.FeatureSource";
+            var conn = CreateTestConnection();
+            if (conn.ResourceService.ResourceExists(fsId))
+                conn.ResourceService.DeleteResource(fsId);
+
+            ClassDefinition cls = null;
+            FeatureSchema schema = null;
+            CreateTestDataStore(conn, fsId, ref schema, ref cls);
+
+            cls.AddProperty(new DataPropertyDefinition("ExtraProp", "")
+            {
+                DataType = DataPropertyType.String,
+                IsNullable = false,
+                Length = 255
+            });
+
+            //Apply changes
+            IApplySchema cmd = (IApplySchema)conn.CreateCommand((int)CommandType.ApplySchema);
+            cmd.Schema = schema;
+            cmd.FeatureSourceId = fsId;
+            cmd.Execute();
+
+            ClassDefinition cls2 = conn.FeatureService.GetClassDefinition(cmd.FeatureSourceId, "Class1");
+            Assert.NotNull(cls2);
+            Assert.False(ClassDefinition.ReferenceEquals(cls, cls2));
+
+            Assert.AreEqual(cls.Name, cls2.Name);
+            Assert.AreEqual(cls.DefaultGeometryPropertyName, cls2.DefaultGeometryPropertyName);
+            Assert.AreEqual(cls.Properties.Count, cls2.Properties.Count);
+            Assert.AreEqual(cls.IdentityProperties.Count, cls2.IdentityProperties.Count);
+            foreach (var prop in cls.Properties)
+            {
+                var prop2 = cls2.FindProperty(prop.Name);
+                Assert.AreEqual(prop.Name, prop2.Name);
+                Assert.AreEqual(prop.Type, prop2.Type);
+            }
+        }
+
+        //[Test]
+        public virtual void TestEncryptedFeatureSourceCredentials()
+        {
+            //Sensitive data redacted, nevertheless you can test and verify this by filling in the
+            //blanks here and uncommenting the above [Test] attribute. If the test passes, credential encryption is working
+            string server = "";
+            string database = "";
+            string actualUser = "";
+            string actualPass = "";
+            string bogusUser = "foo";
+            string bogusPass = "bar";
+
+            var conn = ConnectionUtil.CreateTestHttpConnection();
+            string fsId = "Library://UnitTests/EncryptedCredentials.FeatureSource";
+            var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
+            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
+            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
+            fs.SetConnectionProperty("Service", server);
+            fs.SetConnectionProperty("DataStore", database);
+            fs.ResourceID = fsId;
+            conn.ResourceService.SaveResource(fs);
+
+            using (var ms = CredentialWriter.Write(actualUser, actualPass))
+            {
+                conn.ResourceService.SetResourceData(fsId, "MG_USER_CREDENTIALS", ResourceDataType.String, ms);
+            }
+
+            string result = conn.FeatureService.TestConnection(fsId);
+            Assert.AreEqual("TRUE", result.ToUpper());
+
+            //Test convenience method
+            fsId = "Library://UnitTests/EncryptedCredentials2.FeatureSource";
+            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
+            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
+            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
+            fs.SetConnectionProperty("Service", server);
+            fs.SetConnectionProperty("DataStore", database);
+            fs.ResourceID = fsId;
+            conn.ResourceService.SaveResource(fs);
+            fs.SetEncryptedCredentials(actualUser, actualPass);
+
+            result = conn.FeatureService.TestConnection(fsId);
+            Assert.AreEqual("TRUE", result.ToUpper());
+            Assert.AreEqual(actualUser, fs.GetEncryptedUsername());
+
+            //Do not set encrypted credentials
+            fsId = "Library://UnitTests/EncryptedCredentials3.FeatureSource";
+            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
+            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
+            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
+            fs.SetConnectionProperty("Service", server);
+            fs.SetConnectionProperty("DataStore", database);
+            fs.ResourceID = fsId;
+            conn.ResourceService.SaveResource(fs);
+
+            try
+            {
+                result = conn.FeatureService.TestConnection(fsId);
+                Assert.AreEqual("FALSE", result.ToUpper());
+            }
+            catch //Exception or false I can't remember, as long as the result is not "true"
+            {
+
+            }
+
+            //Encrypt credentials, but use bogus username/password
+            fsId = "Library://UnitTests/EncryptedCredentials4.FeatureSource";
+            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
+            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
+            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
+            fs.SetConnectionProperty("Service", server);
+            fs.SetConnectionProperty("DataStore", database);
+            fs.ResourceID = fsId;
+            conn.ResourceService.SaveResource(fs);
+            fs.SetEncryptedCredentials(bogusUser, bogusPass);
+
+            try
+            {
+                result = conn.FeatureService.TestConnection(fsId);
+                Assert.AreEqual("FALSE", result.ToUpper());
+            }
+            catch
+            {
+                //Exception or false I can't remember, as long as the result is not "true"
+            }
+            Assert.AreEqual(bogusUser, fs.GetEncryptedUsername());
+        }
+
+        public virtual void TestTouch()
+        {
+            var conn = CreateTestConnection();
+            var resSvc = conn.ResourceService;
+            if (!resSvc.ResourceExists("Library://UnitTests/Data/HydrographicPolygons.FeatureSource"))
+                resSvc.SetResourceXmlData("Library://UnitTests/Data/HydrographicPolygons.FeatureSource", File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.fs"));
+
+            resSvc.Touch("Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
+        }
+
+        public virtual void TestAnyStreamInput()
+        {
+            string source = "Library://UnitTests/Data/HydrographicPolygons.FeatureSource";
+            string target = "Library://UnitTests/Data/TestAnyStreamInput.FeatureSource";
+
+            var conn = CreateTestConnection();
+            var resSvc = conn.ResourceService;
+            if (!resSvc.ResourceExists(source))
+                resSvc.SetResourceXmlData(source, File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.fs"));
+
+            resSvc.SetResourceXmlData(target, resSvc.GetResourceXmlData(source));
+
+            string dataName = "UT_HydrographicPolygons.sdf";
+            var resDataList = resSvc.EnumerateResourceData(source);
+            if (resDataList.ResourceData.Count == 1)
+                dataName = resDataList.ResourceData[0].Name;
+            else
+                resSvc.SetResourceData(source, dataName, ResourceDataType.File, File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.sdf"));
+
+            resSvc.SetResourceData(target,
+                                   dataName,
+                                   ResourceDataType.File,
+                                   resSvc.GetResourceData(source, dataName));
+        }
+
+        public abstract IServerConnection CreateFromExistingSession(IServerConnection orig);
+
+        public virtual void TestCreateFromExistingSession()
+        {
+            var conn = CreateTestConnection();
+            var conn2 = CreateFromExistingSession(conn);
+
+            //This connection cannot restart sessions, and cannot be set to restart sessions
+            Assert.False(conn2.AutoRestartSession);
+            Assert.Throws<InvalidOperationException>(() => { conn2.AutoRestartSession = true; });
+
+            //Exercise an API to check the minimum parameters are met
+            try
+            {
+                var result = conn2.ResourceService.GetRepositoryResources();
+            }
+            catch (Exception ex)
+            {
+                Assert.Fail(ex.ToString());
+            }
+        }
+
+        public virtual void TestSchemaMapping()
+        {
+            var conn = ConnectionUtil.CreateTestHttpConnection();
+            var doc1 = conn.FeatureService.GetSchemaMapping("OSGeo.WMS", "FeatureServer=http://wms.jpl.nasa.gov/wms.cgi");
+            Assert.NotNull(doc1);
+            Assert.True(doc1 is WmsConfigurationDocument);
+        }
+    }
+}

Modified: trunk/Tools/Maestro/MaestroAPITests/HttpConnectionTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/HttpConnectionTests.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITests/HttpConnectionTests.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -27,170 +27,65 @@
 using System.IO;
 using OSGeo.MapGuide.ObjectModels.Common;
 using OSGeo.MapGuide.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
 
 namespace MaestroAPITests
 {
     [TestFixture(Ignore = TestControl.IgnoreHttpConnectionTests)]
-    public class HttpConnectionTests
+    public class HttpConnectionTests : ConnectionTestBase
     {
         //[Test]
-        public void TestEncryptedFeatureSourceCredentials()
+        public override void TestEncryptedFeatureSourceCredentials()
         {
-            //Sensitive data redacted, nevertheless you can test and verify this by filling in the
-            //blanks here and uncommenting the above [Test] attribute. If the test passes, credential encryption is working
-            string server       = "";
-            string database     = "";
-            string actualUser   = "";
-            string actualPass   = "";
-            string bogusUser    = "foo";
-            string bogusPass    = "bar";
-
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            string fsId = "Library://UnitTests/EncryptedCredentials.FeatureSource";
-            var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
-            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
-            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
-            fs.SetConnectionProperty("Service", server);
-            fs.SetConnectionProperty("DataStore", database);
-            fs.ResourceID = fsId;
-            conn.ResourceService.SaveResource(fs);
-
-            using (var ms = CredentialWriter.Write(actualUser, actualPass))
-            {
-                conn.ResourceService.SetResourceData(fsId, "MG_USER_CREDENTIALS", ResourceDataType.String, ms);
-            }
-
-            string result = conn.FeatureService.TestConnection(fsId);
-            Assert.AreEqual("TRUE", result.ToUpper());
-
-            //Test convenience method
-            fsId = "Library://UnitTests/EncryptedCredentials2.FeatureSource";
-            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
-            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
-            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
-            fs.SetConnectionProperty("Service", server);
-            fs.SetConnectionProperty("DataStore", database);
-            fs.ResourceID = fsId;
-            conn.ResourceService.SaveResource(fs);
-            fs.SetEncryptedCredentials(actualUser, actualPass);
-
-            result = conn.FeatureService.TestConnection(fsId);
-            Assert.AreEqual("TRUE", result.ToUpper());
-            Assert.AreEqual(actualUser, fs.GetEncryptedUsername());
-
-            //Do not set encrypted credentials
-            fsId = "Library://UnitTests/EncryptedCredentials3.FeatureSource";
-            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
-            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
-            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
-            fs.SetConnectionProperty("Service", server);
-            fs.SetConnectionProperty("DataStore", database);
-            fs.ResourceID = fsId;
-            conn.ResourceService.SaveResource(fs);
-
-            try
-            {
-                result = conn.FeatureService.TestConnection(fsId);
-                Assert.AreEqual("FALSE", result.ToUpper());
-            }
-            catch //Exception or false I can't remember, as long as the result is not "true"
-            {
-
-            }
-
-            //Encrypt credentials, but use bogus username/password
-            fsId = "Library://UnitTests/EncryptedCredentials4.FeatureSource";
-            fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SQLServerSpatial");
-            fs.SetConnectionProperty("Username", "%MG_USERNAME%");
-            fs.SetConnectionProperty("Password", "%MG_PASSWORD%");
-            fs.SetConnectionProperty("Service", server);
-            fs.SetConnectionProperty("DataStore", database);
-            fs.ResourceID = fsId;
-            conn.ResourceService.SaveResource(fs);
-            fs.SetEncryptedCredentials(bogusUser, bogusPass);
-
-            try
-            {
-                result = conn.FeatureService.TestConnection(fsId);
-                Assert.AreEqual("FALSE", result.ToUpper());
-            }
-            catch
-            {
-                //Exception or false I can't remember, as long as the result is not "true"
-            }
-            Assert.AreEqual(bogusUser, fs.GetEncryptedUsername());
+            base.TestEncryptedFeatureSourceCredentials();
         }
 
         [Test]
         public void TestFeatureSourceCaching()
         {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            string fsId = "Library://UnitTests/HttpCaching.FeatureSource";
-            if (!conn.ResourceService.ResourceExists(fsId))
-            {
-                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
-                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
-                fs.ResourceID = fsId;
-                conn.ResourceService.SaveResourceAs(fs, fsId);
-                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
-                {
-                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
-                }
-                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
-            }
-            var pc = (PlatformConnectionBase)conn;
-            pc.ResetFeatureSourceSchemaCache();
-
-            Assert.AreEqual(0, pc.CachedClassDefinitions);
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-
-            var fsd = conn.FeatureService.DescribeFeatureSource(fsId);
-
-            Assert.AreEqual(1, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-
-            var fsd2 = conn.FeatureService.DescribeFeatureSource(fsId);
-
-            Assert.AreEqual(1, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-            //Each cached instance returned is a clone
-            Assert.False(object.ReferenceEquals(fsd, fsd2));
+            base.TestFeatureSourceCaching("HttpCaching");
         }
 
         [Test]
         public void TestClassDefinitionCaching()
         {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            string fsId = "Library://UnitTests/HttpCaching.FeatureSource";
-            if (!conn.ResourceService.ResourceExists(fsId))
-            {
-                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
-                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
-                conn.ResourceService.SaveResourceAs(fs, fsId);
-                fs.ResourceID = fsId;
-                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
-                {
-                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
-                }
-                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
-            }
-            var pc = (PlatformConnectionBase)conn;
-            pc.ResetFeatureSourceSchemaCache();
+            base.TestClassDefinitionCaching("HttpCaching");
+        }
 
-            Assert.AreEqual(0, pc.CachedClassDefinitions);
-            Assert.AreEqual(0, pc.CachedFeatureSources);
+        [Test]
+        public override void TestTouch()
+        {
+            base.TestTouch();
+        }
 
-            var cls = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
+        [Test]
+        public override void TestAnyStreamInput()
+        {
+            base.TestAnyStreamInput();
+        }
+        
+        [Test]
+        public override void TestCreateFromExistingSession()
+        {
+            base.TestCreateFromExistingSession();
+        }
 
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
+        [Test]
+        public override void TestSchemaMapping()
+        {
+            base.TestSchemaMapping();
+        }
 
-            var cls2 = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
+        protected override IServerConnection CreateTestConnection()
+        {
+            return ConnectionUtil.CreateTestHttpConnection();
+        }
 
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-            //Each cached instance returned is a clone
-            Assert.False(object.ReferenceEquals(cls, cls2));
+        public override IServerConnection CreateFromExistingSession(IServerConnection orig)
+        {
+            return ConnectionProviderRegistry.CreateConnection("Maestro.Http",
+                HttpServerConnection.PARAM_URL, orig.GetCustomProperty(HttpServerConnection.PROP_BASE_URL).ToString(),
+                HttpServerConnection.PARAM_SESSION, orig.SessionID);
         }
 
         [Test]
@@ -198,7 +93,7 @@
         {
             //Purpose: Unit test to guard against regression as a result of updating/replacing NTS
 
-            var conn = ConnectionUtil.CreateTestHttpConnection();
+            var conn = CreateTestConnection();
             var srcWkt = "GEOGCS[\"WGS84 Lat/Long's, Degrees, -180 ==> +180\",DATUM[\"D_WGS_1984\",SPHEROID[\"World_Geodetic_System_of_1984\",6378137,298.257222932867]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]]";
             var dstCs = conn.CoordinateSystemCatalog.FindCoordSys("WGS84.PseudoMercator");
             var dstWkt = dstCs.WKT;
@@ -220,24 +115,6 @@
         }
 
         [Test]
-        public void TestConnectionString()
-        {
-            System.Data.Common.DbConnectionStringBuilder builder = new System.Data.Common.DbConnectionStringBuilder();
-            builder["Foo"] = "sdfjkg";
-            builder["Bar"] = "skgjuksdf";
-            builder["Snafu"] = "asjdgjh;sdgj"; //Note the ; in the value
-            builder["Whatever"] = "asjd=gjh;sdgj"; //Note the ; and = in the value
-
-            var values = ConnectionProviderRegistry.ParseConnectionString(builder.ToString());
-            Assert.AreEqual(values.Count, 4);
-
-            Assert.AreEqual(builder["Foo"].ToString(), values["Foo"]);
-            Assert.AreEqual(builder["Bar"].ToString(), values["Bar"]);
-            Assert.AreEqual(builder["Snafu"].ToString(), values["Snafu"]);
-            Assert.AreEqual(builder["Whatever"].ToString(), values["Whatever"]);
-        }
-
-        [Test]
         public void TestCustomProperties()
         {
             var builder = new RequestBuilder(new Uri("http://tempuri.org"), "en");
@@ -271,7 +148,7 @@
                 isvc.SetCustomProperty(HttpServerConnection.PROP_BASE_URL, "http://mylocalhost/mapguide");
                 Assert.Fail("Should've thrown exception");
             }
-            catch { } 
+            catch { }
         }
 
         [Test]
@@ -311,66 +188,5 @@
                 }
             }
         }
-
-        [Test]
-        public void TestTouch()
-        {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            var resSvc = conn.ResourceService;
-            if (!resSvc.ResourceExists("Library://UnitTests/Data/HydrographicPolygons.FeatureSource"))
-                resSvc.SetResourceXmlData("Library://UnitTests/Data/HydrographicPolygons.FeatureSource", File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.fs"));
-
-            resSvc.Touch("Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
-        }
-
-        [Test]
-        public void TestAnyStreamInput()
-        {
-            string source = "Library://UnitTests/Data/HydrographicPolygons.FeatureSource";
-            string target = "Library://UnitTests/Data/TestAnyStreamInput.FeatureSource";
-
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            var resSvc = conn.ResourceService;
-            if (!resSvc.ResourceExists(source))
-                resSvc.SetResourceXmlData(source, File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.fs"));
-
-            resSvc.SetResourceXmlData(target, resSvc.GetResourceXmlData(source));
-
-            string dataName = "UT_HydrographicPolygons.sdf";
-            var resDataList = resSvc.EnumerateResourceData(source);
-            if (resDataList.ResourceData.Count == 1)
-                dataName = resDataList.ResourceData[0].Name;
-            else
-                resSvc.SetResourceData(source, dataName, ResourceDataType.File, File.OpenRead("TestData/MappingService/UT_HydrographicPolygons.sdf"));
-
-            resSvc.SetResourceData(target,
-                                   dataName,
-                                   ResourceDataType.File,
-                                   resSvc.GetResourceData(source, dataName));
-        }
-        
-        [Test]
-        public void TestCreateFromExistingSession()
-        {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            var conn2 = ConnectionProviderRegistry.CreateConnection("Maestro.Http",
-                HttpServerConnection.PARAM_SESSION, conn.SessionID,
-                HttpServerConnection.PARAM_URL, conn.GetCustomProperty(HttpServerConnection.PROP_BASE_URL).ToString(),
-                HttpServerConnection.PARAM_UNTESTED, "true");
-
-            //This connection cannot restart sessions, and cannot be set to restart sessions
-            Assert.False(conn2.AutoRestartSession);
-            Assert.Throws<InvalidOperationException>(() => { conn2.AutoRestartSession = true; });
-
-            //Exercise an API to check the minimum parameters are met
-            try
-            {
-                var result = conn2.ResourceService.GetRepositoryResources();
-            }
-            catch (Exception ex)
-            {
-                Assert.Fail(ex.ToString());
-            }
-        }
     }
 }

Added: trunk/Tools/Maestro/MaestroAPITests/LocalConnectionTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/LocalConnectionTests.cs	                        (rev 0)
+++ trunk/Tools/Maestro/MaestroAPITests/LocalConnectionTests.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -0,0 +1,111 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using OSGeo.MapGuide.MaestroAPI.Schema;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.MaestroAPI.Feature;
+using OSGeo.MapGuide.MaestroAPI.Commands;
+using OSGeo.MapGuide.MaestroAPI.CoordinateSystem;
+using OSGeo.MapGuide.MaestroAPI.Internal;
+using OSGeo.MapGuide.ObjectModels;
+using OSGeo.MapGuide.ObjectModels.Common;
+using System.IO;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
+
+namespace MaestroAPITests
+{
+    [TestFixture(Ignore = TestControl.IgnoreLocalNativeFeatureTests)]
+    public class LocalConnectionTests : ConnectionTestBase
+    {
+        protected override IServerConnection CreateTestConnection()
+        {
+            return ConnectionUtil.CreateTestLocalConnection();
+        }
+
+        [Test]
+        public override void TestTouch()
+        {
+            base.TestTouch();
+        }
+
+        [Test]
+        public override void TestAnyStreamInput()
+        {
+            base.TestAnyStreamInput();
+        }
+
+        [Test]
+        public void TestFeatureSourceCaching()
+        {
+            base.TestFeatureSourceCaching("LocalFeatureSourceCaching");
+        }
+
+        [Test]
+        public void TestClassDefinitionCaching()
+        {
+            base.TestClassDefinitionCaching("LocalClassCaching");
+        }
+
+        [Test]
+        public override void TestApplySchema()
+        {
+            base.TestApplySchema();
+        }
+
+        [Test]
+        public override void TestCreateDataStore()
+        {
+            base.TestCreateDataStore();
+        }
+
+        [Test]
+        public override void TestDeleteFeatures()
+        {
+            base.TestDeleteFeatures();
+        }
+
+        [Test]
+        public override void TestInsertFeatures()
+        {
+            base.TestInsertFeatures();
+        }
+
+        [Test]
+        public override void TestUpdateFeatures()
+        {
+            base.TestUpdateFeatures();
+        }
+
+        [Test]
+        public override void TestSchemaMapping()
+        {
+            base.TestSchemaMapping();
+        }
+
+        public override IServerConnection CreateFromExistingSession(IServerConnection orig)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

Modified: trunk/Tools/Maestro/MaestroAPITests/LocalNativeFeatureTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/LocalNativeFeatureTests.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITests/LocalNativeFeatureTests.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -31,351 +31,36 @@
 using OSGeo.MapGuide.ObjectModels;
 using OSGeo.MapGuide.ObjectModels.Common;
 using System.IO;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
 
 namespace MaestroAPITests
 {
-    public abstract class LocalNativeFeatureTestsBase
+    [TestFixture(Ignore = TestControl.IgnoreLocalNativeFeatureTests)]
+    public class LocalNativeFeatureTests : ConnectionTestBase
     {
-        protected abstract IServerConnection CreateTestConnection();
-
-        protected void TestFeatureSourceCaching(string fsName)
+        protected override IServerConnection CreateTestConnection()
         {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            string fsId = "Library://UnitTests/" + fsName + ".FeatureSource";
-            if (!conn.ResourceService.ResourceExists(fsId))
-            {
-                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
-                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
-                fs.ResourceID = fsId;
-                conn.ResourceService.SaveResourceAs(fs, fsId);
-                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
-                {
-                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
-                }
-                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
-            }
-            var pc = (PlatformConnectionBase)conn;
-            pc.ResetFeatureSourceSchemaCache();
-
-            Assert.AreEqual(0, pc.CachedClassDefinitions);
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-
-            var fsd = conn.FeatureService.DescribeFeatureSource(fsId);
-
-            Assert.AreEqual(1, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-
-            var fsd2 = conn.FeatureService.DescribeFeatureSource(fsId);
-
-            Assert.AreEqual(1, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-            //Each cached instance returned is a clone
-            Assert.False(object.ReferenceEquals(fsd, fsd2));
+            return ConnectionUtil.CreateTestLocalNativeConnection();
         }
 
-        protected void TestClassDefinitionCaching(string fsName)
+        [Test]
+        public override void TestTouch()
         {
-            var conn = ConnectionUtil.CreateTestHttpConnection();
-            string fsId = "Library://UnitTests/" + fsName + ".FeatureSource";
-            if (!conn.ResourceService.ResourceExists(fsId))
-            {
-                var fs = ObjectFactory.CreateFeatureSource(conn, "OSGeo.SDF");
-                fs.SetConnectionProperty("File", "%MG_DATA_FILE_PATH%Sheboygan_Parcels.sdf");
-                conn.ResourceService.SaveResourceAs(fs, fsId);
-                fs.ResourceID = fsId;
-                using (var stream = File.OpenRead("TestData/FeatureService/SDF/Sheboygan_Parcels.sdf"))
-                {
-                    fs.SetResourceData("Sheboygan_Parcels.sdf", ResourceDataType.File, stream);
-                }
-                Assert.True(Convert.ToBoolean(conn.FeatureService.TestConnection(fsId)));
-            }
-            var pc = (PlatformConnectionBase)conn;
-            pc.ResetFeatureSourceSchemaCache();
-
-            Assert.AreEqual(0, pc.CachedClassDefinitions);
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-
-            var cls = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
-
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-
-            var cls2 = conn.FeatureService.GetClassDefinition(fsId, "SHP_Schema:Parcels");
-
-            Assert.AreEqual(0, pc.CachedFeatureSources);
-            Assert.AreEqual(1, pc.CachedClassDefinitions);
-            //Each cached instance returned is a clone
-            Assert.False(object.ReferenceEquals(cls, cls2));
+            base.TestTouch();
         }
 
-        protected void CreateTestDataStore(IServerConnection conn, string fsId, ref FeatureSchema schema, ref ClassDefinition cls)
+        [Test]
+        public override void TestAnyStreamInput()
         {
-            schema = new FeatureSchema("Default", "");
-            cls = new ClassDefinition("Class1", "");
-
-            try
-            {
-                if (conn.ResourceService.ResourceExists(fsId))
-                    conn.ResourceService.DeleteResource(fsId);
-
-                cls.DefaultGeometryPropertyName = "GEOM";
-                cls.AddProperty(new DataPropertyDefinition("KEY", "")
-                {
-                    DataType = DataPropertyType.Int32,
-                    IsAutoGenerated = true,
-                    IsReadOnly = true,
-                    IsNullable = false
-                }, true);
-
-                cls.AddProperty(new DataPropertyDefinition("NAME", "")
-                {
-                    DataType = DataPropertyType.String,
-                    Length = 255,
-                    IsNullable = true,
-                    IsReadOnly = false
-                });
-
-                cls.AddProperty(new GeometricPropertyDefinition("GEOM", "")
-                {
-                    GeometricTypes = FeatureGeometricType.Point,
-                    SpatialContextAssociation = "Default"
-                });
-
-                schema.AddClass(cls);
-
-                ICreateDataStore create = (ICreateDataStore)conn.CreateCommand((int)CommandType.CreateDataStore);
-                CoordinateSystemDefinitionBase coordSys = conn.CoordinateSystemCatalog.FindCoordSys("LL84");
-                create.FeatureSourceId = fsId;
-                create.CoordinateSystemWkt = coordSys.WKT;
-                create.Name = "Default";
-                create.ExtentType = OSGeo.MapGuide.ObjectModels.Common.FdoSpatialContextListSpatialContextExtentType.Dynamic;
-                create.FileName = "Test.sdf";
-                create.Provider = "OSGeo.SDF";
-                create.Schema = schema;
-                create.XYTolerance = 0.001;
-                create.ZTolerance = 0.001;
-
-                create.Execute();
-            }
-            catch
-            {
-                schema = null;
-                cls = null;
-                throw;
-            }
+            base.TestAnyStreamInput();
         }
 
-        protected void PopulateTestDataStore(IServerConnection conn, string fsId, ref FeatureSchema schema, ref ClassDefinition cls)
+        [Test]
+        public override void TestCreateFromExistingSession()
         {
-            CreateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            IInsertFeatures insert = (IInsertFeatures)conn.CreateCommand((int)CommandType.InsertFeature);
-            insert.ClassName = cls.Name;
-            insert.FeatureSourceId = fsId;
-            var feat = new MutableRecord();
-
-            var reader = new FixedWKTReader();
-
-            //Initialize this record
-            feat.PutValue("GEOM", new GeometryValue(reader.Read("POINT (0 0)")));
-            feat.PutValue("NAME", new StringValue("Test1"));
-
-            //Attach to command.
-            insert.RecordToInsert = feat;
-
-            var res = insert.Execute();
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (0 1)"));
-            feat.SetString("NAME", "Test2");
-
-            res = insert.Execute();
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (1 1)"));
-            feat.SetString("NAME", "Test3");
-
-            res = insert.Execute();
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (1 0)"));
-            feat.SetString("NAME", "Test4");
-
-            res = insert.Execute();
+            base.TestCreateFromExistingSession();
         }
 
-        public virtual void TestInsertFeatures()
-        {
-            var conn = CreateTestConnection();
-            var fsId = "Library://UnitTests/Data/TestInsertFeatures.FeatureSource";
-            ClassDefinition cls = null;
-            FeatureSchema schema = null;
-            CreateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            IInsertFeatures insert = (IInsertFeatures)conn.CreateCommand((int)CommandType.InsertFeature);
-            insert.ClassName = cls.Name;
-            insert.FeatureSourceId = fsId;
-            var feat = new MutableRecord();
-
-            var reader = new FixedWKTReader();
-
-            //Initialize this record
-            feat.PutValue("GEOM", new GeometryValue(reader.Read("POINT (0 0)")));
-            feat.PutValue("NAME", new StringValue("Test1"));
-
-            Assert.True(feat.PropertyExists("GEOM"));
-            Assert.True(feat.PropertyExists("NAME"));
-
-            //Attach to command.
-            insert.RecordToInsert = feat;
-
-            var res = insert.Execute();
-            Assert.Null(res.Error);
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (0 1)"));
-            feat.SetString("NAME", "Test2");
-
-            res = insert.Execute();
-            Assert.Null(res.Error);
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (1 1)"));
-            feat.SetString("NAME", "Test3");
-
-            res = insert.Execute();
-            Assert.Null(res.Error);
-
-            feat.SetGeometry("GEOM", reader.Read("POINT (1 0)"));
-            feat.SetString("NAME", "Test4");
-
-            res = insert.Execute();
-            Assert.Null(res.Error);
-
-            int count = 0;
-            using (var rdr = conn.FeatureService.QueryFeatureSource(fsId, cls.Name))
-            {
-                while (rdr.ReadNext())
-                {
-                    count++;
-                }
-                rdr.Close();
-            }
-
-            Assert.AreEqual(4, count);
-        }
-        
-        public virtual void TestUpdateFeatures()
-        {
-            var conn = CreateTestConnection();
-            var fsId = "Library://UnitTests/Data/TestUpdateFeatures.FeatureSource";
-            ClassDefinition cls = null;
-            FeatureSchema schema = null;
-            PopulateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            IUpdateFeatures update = (IUpdateFeatures)conn.CreateCommand((int)CommandType.UpdateFeatures);
-            update.ClassName = cls.Name;
-            update.FeatureSourceId = fsId;
-            update.Filter = "NAME = 'Test4'";
-
-            update.ValuesToUpdate = new MutableRecord();
-            update.ValuesToUpdate.PutValue("NAME", new StringValue("Test4Modified"));
-
-            Assert.AreEqual(1, update.Execute());
-        }
-
-        public virtual void TestDeleteFeatures()
-        {
-            var conn = CreateTestConnection();
-            var fsId = "Library://UnitTests/Data/TestDeleteFeatures.FeatureSource";
-            ClassDefinition cls = null;
-            FeatureSchema schema = null;
-            PopulateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            IDeleteFeatures delete = (IDeleteFeatures)conn.CreateCommand((int)CommandType.DeleteFeatures);
-            delete.ClassName = cls.Name;
-            delete.FeatureSourceId = fsId;
-            delete.Filter = "NAME = 'Test4'";
-
-            Assert.AreEqual(1, delete.Execute());
-
-            int count = 0;
-            using (var rdr = conn.FeatureService.QueryFeatureSource(fsId, cls.Name))
-            {
-                while (rdr.ReadNext()) { count++; }
-            }
-
-            Assert.AreEqual(3, count);
-        }
-
-        public virtual void TestCreateDataStore()
-        {
-            var conn = CreateTestConnection();
-            var fsId = "Library://UnitTests/Data/TestCreateDataStore.FeatureSource";
-            ClassDefinition cls = null;
-            FeatureSchema schema = null;
-            CreateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            ClassDefinition cls2 = conn.FeatureService.GetClassDefinition(fsId, "Class1");
-            Assert.NotNull(cls2);
-            Assert.False(ClassDefinition.ReferenceEquals(cls, cls2));
-
-            Assert.AreEqual(cls.Name, cls2.Name);
-            Assert.AreEqual(cls.DefaultGeometryPropertyName, cls2.DefaultGeometryPropertyName);
-            Assert.AreEqual(cls.Properties.Count, cls2.Properties.Count);
-            Assert.AreEqual(cls.IdentityProperties.Count, cls2.IdentityProperties.Count);
-            foreach (var prop in cls.Properties)
-            {
-                var prop2 = cls2.FindProperty(prop.Name);
-                Assert.AreEqual(prop.Name, prop2.Name);
-                Assert.AreEqual(prop.Type, prop2.Type);
-            }
-        }
-
-        public virtual void TestApplySchema()
-        {
-            var fsId = "Library://UnitTests/Data/TestMaestroLocalApplySchema.FeatureSource";
-            var conn = CreateTestConnection();
-            if (conn.ResourceService.ResourceExists(fsId))
-                conn.ResourceService.DeleteResource(fsId);
-
-            ClassDefinition cls = null;
-            FeatureSchema schema = null;
-            CreateTestDataStore(conn, fsId, ref schema, ref cls);
-
-            cls.AddProperty(new DataPropertyDefinition("ExtraProp", "")
-            {
-                DataType = DataPropertyType.String,
-                IsNullable = false,
-                Length = 255
-            });
-
-            //Apply changes
-            IApplySchema cmd = (IApplySchema)conn.CreateCommand((int)CommandType.ApplySchema);
-            cmd.Schema = schema;
-            cmd.FeatureSourceId = fsId;
-            cmd.Execute();
-
-            ClassDefinition cls2 = conn.FeatureService.GetClassDefinition(cmd.FeatureSourceId, "Class1");
-            Assert.NotNull(cls2);
-            Assert.False(ClassDefinition.ReferenceEquals(cls, cls2));
-
-            Assert.AreEqual(cls.Name, cls2.Name);
-            Assert.AreEqual(cls.DefaultGeometryPropertyName, cls2.DefaultGeometryPropertyName);
-            Assert.AreEqual(cls.Properties.Count, cls2.Properties.Count);
-            Assert.AreEqual(cls.IdentityProperties.Count, cls2.IdentityProperties.Count);
-            foreach (var prop in cls.Properties)
-            {
-                var prop2 = cls2.FindProperty(prop.Name);
-                Assert.AreEqual(prop.Name, prop2.Name);
-                Assert.AreEqual(prop.Type, prop2.Type);
-            }
-        }
-    }
-
-    [TestFixture(Ignore = TestControl.IgnoreLocalNativeFeatureTests)]
-    public class LocalNativeFeatureTests : LocalNativeFeatureTestsBase
-    {
-        protected override IServerConnection CreateTestConnection()
-        {
-            return ConnectionUtil.CreateTestLocalNativeConnection();
-        }
-
         [Test]
         public void TestFeatureSourceCaching()
         {
@@ -417,57 +102,17 @@
         {
             base.TestUpdateFeatures();
         }
-    }
 
-    [TestFixture(Ignore = TestControl.IgnoreLocalFeatureTests)]
-    public class LocalFeatureTests : LocalNativeFeatureTestsBase
-    {
-        protected override IServerConnection CreateTestConnection()
-        {
-            return ConnectionUtil.CreateTestLocalConnection();
-        }
-
         [Test]
-        public void TestFeatureSourceCaching()
+        public override void TestSchemaMapping()
         {
-            base.TestFeatureSourceCaching("LocalFeatureSourceCaching");
+            base.TestSchemaMapping();
         }
 
-        [Test]
-        public void TestClassDefinitionCaching()
+        public override IServerConnection CreateFromExistingSession(IServerConnection orig)
         {
-            base.TestClassDefinitionCaching("LocalClassCaching");
+            return ConnectionProviderRegistry.CreateConnection("Maestro.LocalNative",
+                "SessionId", orig.SessionID);
         }
-
-        [Test]
-        public override void TestApplySchema()
-        {
-            base.TestApplySchema();
-        }
-
-        [Test]
-        public override void TestCreateDataStore()
-        {
-            base.TestCreateDataStore();
-        }
-
-        [Test]
-        public override void TestDeleteFeatures()
-        {
-            base.TestDeleteFeatures();
-        }
-
-        [Test]
-        public override void TestInsertFeatures()
-        {
-            base.TestInsertFeatures();
-        }
-
-        [Test]
-        public override void TestUpdateFeatures()
-        {
-            base.TestUpdateFeatures();
-        }
     }
-
 }

Modified: trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj	2012-10-17 13:29:39 UTC (rev 7125)
@@ -79,11 +79,13 @@
     </Compile>
     <Compile Include="CapabilityTests.cs" />
     <Compile Include="ConfigurationTests.cs" />
+    <Compile Include="ConnectionTestBase.cs" />
     <Compile Include="ExpressionTests.cs" />
     <Compile Include="FeatureReaderTests.cs" />
     <Compile Include="GeoRestTests.cs" />
     <Compile Include="HttpConnectionTests.cs" />
     <Compile Include="HttpSiteTests.cs" />
+    <Compile Include="LocalConnectionTests.cs" />
     <Compile Include="LocalNativeFeatureTests.cs" />
     <Compile Include="LocalNativePerformanceTests.cs" />
     <Compile Include="MiscTests.cs" />

Modified: trunk/Tools/Maestro/MaestroAPITests/ObjectTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/ObjectTests.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITests/ObjectTests.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -36,6 +36,24 @@
     public class ObjectTests
     {
         [Test]
+        public void TestConnectionString()
+        {
+            System.Data.Common.DbConnectionStringBuilder builder = new System.Data.Common.DbConnectionStringBuilder();
+            builder["Foo"] = "sdfjkg";
+            builder["Bar"] = "skgjuksdf";
+            builder["Snafu"] = "asjdgjh;sdgj"; //Note the ; in the value
+            builder["Whatever"] = "asjd=gjh;sdgj"; //Note the ; and = in the value
+
+            var values = ConnectionProviderRegistry.ParseConnectionString(builder.ToString());
+            Assert.AreEqual(values.Count, 4);
+
+            Assert.AreEqual(builder["Foo"].ToString(), values["Foo"]);
+            Assert.AreEqual(builder["Bar"].ToString(), values["Bar"]);
+            Assert.AreEqual(builder["Snafu"].ToString(), values["Snafu"]);
+            Assert.AreEqual(builder["Whatever"].ToString(), values["Whatever"]);
+        }
+
+        [Test]
         public void TestArgParser()
         {
             string[] args = new string[] { "-foo", "-bar:snafu", "-whatever:" };

Modified: trunk/Tools/Maestro/MaestroAPITests/ValidationTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/ValidationTests.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/MaestroAPITests/ValidationTests.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -406,6 +406,17 @@
             {
                 throw new NotImplementedException();
             }
+
+
+            public OSGeo.MapGuide.ObjectModels.Common.ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly)
+            {
+                throw new NotImplementedException();
+            }
+
+            public OSGeo.MapGuide.MaestroAPI.SchemaOverrides.ConfigurationDocument GetSchemaMapping(string provider, string partialConnString)
+            {
+                throw new NotImplementedException();
+            }
         }
         #endregion
 

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2012-10-17 13:29:39 UTC (rev 7125)
@@ -250,6 +250,7 @@
     <Compile Include="NsDoc.cs" />
     <Compile Include="ObjectModels\CommonTypes.cs" />
     <Compile Include="ObjectModels\IFdoSpatialContext.cs" />
+    <Compile Include="ObjectModels\LongTransaction.cs" />
     <Compile Include="ObjectModels\NsDoc.cs" />
     <Compile Include="ObjectModels\SymbolDefFactory.cs" />
     <Compile Include="ObjectModels\WatermarkCollectionUtil.cs" />

Added: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/LongTransaction.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/LongTransaction.cs	                        (rev 0)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/LongTransaction.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace OSGeo.MapGuide.ObjectModels.Common
+{
+    /// <summary>
+    /// Represents a list of long transactions
+    /// </summary>
+    public interface ILongTransactionList
+    {
+        /// <summary>
+        /// Gets the long transactions in this list
+        /// </summary>
+        IEnumerable<ILongTransaction> Transactions { get; }
+    }
+
+    /// <summary>
+    /// Represents a long transaction
+    /// </summary>
+    public interface ILongTransaction
+    {
+        /// <summary>
+        /// Gets the name of the long transaction
+        /// </summary>
+        string Name { get; }
+
+        /// <summary>
+        /// Gets the description of the long transaction
+        /// </summary>
+        string Description { get; }
+
+        /// <summary>
+        /// Gets the owner of the long transaction
+        /// </summary>
+        string Owner { get; }
+
+        /// <summary>
+        /// Gets the creation date of the long transaction
+        /// </summary>
+        string CreationDate { get; }
+
+        /// <summary>
+        /// Gets whether the long transaction is active
+        /// </summary>
+        bool IsActive { get; }
+
+        /// <summary>
+        /// Gets whether the long transaction is frozen
+        /// </summary>
+        bool IsFrozen { get; }
+    }
+
+    partial class FdoLongTransactionList : ILongTransactionList
+    {
+        public IEnumerable<ILongTransaction> Transactions
+        {
+            get 
+            {
+                return this.LongTransaction;            
+            }
+        }
+    }
+
+    partial class FdoLongTransactionListLongTransaction : ILongTransaction
+    {
+
+    }
+}

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -40,6 +40,8 @@
 using OSGeo.MapGuide.ObjectModels.LayerDefinition;
 using OSGeo.MapGuide.MaestroAPI.Exceptions;
 using GeoAPI.Geometries;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
 
 namespace OSGeo.MapGuide.MaestroAPI
 {
@@ -1786,6 +1788,23 @@
         /// <returns></returns>
         public abstract string[] GetClassNames(string resourceId, string schemaName);
 
+        /// <summary>
+        /// Gets the long transactions for the specified feature source
+        /// </summary>
+        /// <param name="resourceId">The feature source id</param>
+        /// <param name="activeOnly">If true, will only return active long transactions</param>
+        /// <returns></returns>
+        public abstract ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly);
+
+        /// <summary>
+        /// Gets the schema mappings for the given FDO provider. These mappings form the basis for a custom configuration document
+        /// for a feature source that supports configuration
+        /// </summary>
+        /// <param name="provider">The FDO provider</param>
+        /// <param name="partialConnString">The connection string</param>
+        /// <returns></returns>
+        public abstract ConfigurationDocument GetSchemaMapping(string provider, string partialConnString);
+
         #endregion
 
         #region Feature/Capability Discovery

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/SchemaOverrides/ConfigurationDocument.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/SchemaOverrides/ConfigurationDocument.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/SchemaOverrides/ConfigurationDocument.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -236,6 +236,11 @@
         {
             XmlDocument doc = new XmlDocument();
             doc.LoadXml(xml);
+            return LoadInternal(doc);
+        }
+
+        private static ConfigurationDocument LoadInternal(XmlDocument doc)
+        {
             var mgr = new XmlNamespaceManager(doc.NameTable);
             mgr.AddNamespace("xs", XmlNamespaces.XS); //NOXLATE
             mgr.AddNamespace("xsi", XmlNamespaces.XSI); //NOXLATE
@@ -279,5 +284,17 @@
 
             return null;
         }
+
+        /// <summary>
+        /// Creates a configuration document from the specified stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <returns>The configuration document</returns>
+        public static ConfigurationDocument Load(System.IO.Stream stream)
+        {
+            XmlDocument doc = new XmlDocument();
+            doc.Load(stream);
+            return LoadInternal(doc);
+        }
     }
 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IFeatureService.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -24,6 +24,9 @@
 using ObjCommon = OSGeo.MapGuide.ObjectModels.Common;
 using OSGeo.MapGuide.MaestroAPI.Schema;
 using OSGeo.MapGuide.MaestroAPI.Feature;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
+using OSGeo.MapGuide.ObjectModels.Common;
 
 namespace OSGeo.MapGuide.MaestroAPI.Services
 {
@@ -280,5 +283,22 @@
         /// </param>
         /// <returns></returns>
         string[] GetClassNames(string resourceId, string schemaName);
+
+        /// <summary>
+        /// Gets the long transactions for the specified feature source
+        /// </summary>
+        /// <param name="resourceId">The feature source id</param>
+        /// <param name="activeOnly">If true, will only return active long transactions</param>
+        /// <returns></returns>
+        ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly);
+
+        /// <summary>
+        /// Gets the schema mappings for the given FDO provider. These mappings form the basis for a custom configuration document
+        /// for a feature source that supports configuration
+        /// </summary>
+        /// <param name="provider">The FDO provider</param>
+        /// <param name="partialConnString">The connection string</param>
+        /// <returns></returns>
+        ConfigurationDocument GetSchemaMapping(string provider, string partialConnString);
     }
 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/HttpServerConnection.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -43,6 +43,8 @@
 using OSGeo.MapGuide.MaestroAPI.Schema;
 using OSGeo.MapGuide.MaestroAPI.Feature;
 using System.Drawing;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
 
 namespace OSGeo.MapGuide.MaestroAPI
 {
@@ -1750,6 +1752,18 @@
 			return o;
         }
 
+        public override ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly)
+        {
+            string req = m_reqBuilder.GetLongTransactions(resourceId, activeOnly);
+            return DeserializeObject<FdoLongTransactionList>(this.OpenRead(req));
+        }
+
+        public override ConfigurationDocument GetSchemaMapping(string provider, string partialConnString)
+        {
+            string req = m_reqBuilder.GetSchemaMapping(provider, partialConnString);
+            return ConfigurationDocument.Load(this.OpenRead(req));
+        }
+
         public override bool MoveFolderWithReferences(string oldpath, string newpath, LengthyOperationCallBack callback, LengthyOperationProgressCallBack progress)
         {
             if (this.SiteVersion >= new Version(2, 2)) //new way

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/RequestBuilder.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -1712,5 +1712,29 @@
 
             return m_hosturi + "?" + EncodeParameters(param);
         }
+
+        internal string GetLongTransactions(string resourceId, bool activeOnly)
+        {
+            NameValueCollection param = new NameValueCollection();
+            param.Add("OPERATION", "GETLONGTRANSACTIONS");
+            param.Add("VERSION", "1.0.0");
+            param.Add("SESSION", m_sessionID);
+            param.Add("RESOURCEID", resourceId);
+            param.Add("ACTIVEONLY", activeOnly ? "1" : "0");
+
+            return m_hosturi + "?" + EncodeParameters(param);
+        }
+
+        internal string GetSchemaMapping(string provider, string partialConnString)
+        {
+            NameValueCollection param = new NameValueCollection();
+            param.Add("OPERATION", "GETSCHEMAMAPPING");
+            param.Add("VERSION", "1.0.0");
+            param.Add("SESSION", m_sessionID);
+            param.Add("PROVIDER", provider);
+            param.Add("CONNECTIONSTRING", partialConnString);
+
+            return m_hosturi + "?" + EncodeParameters(param);
+        }
     }
 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Local/LocalConnection.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Local/LocalConnection.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Local/LocalConnection.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -35,6 +35,8 @@
 using OSGeo.MapGuide.MaestroAPI.Local.Commands;
 using OSGeo.MapGuide.MaestroAPI.Commands;
 using OSGeo.MapGuide.MaestroAPI.Mapping;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
 
 namespace OSGeo.MapGuide.MaestroAPI.Local
 {
@@ -1350,5 +1352,96 @@
 
             return xml;
         }
+
+        public override ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly)
+        {
+            var featSvc = GetFeatureService();
+            var resId = new MgResourceIdentifier(resourceId);
+            var rdr = featSvc.GetLongTransactions(resId, activeOnly);
+            return new LocalLongTransactionList(rdr);
+        }
+
+        public override ConfigurationDocument GetSchemaMapping(string provider, string partialConnString)
+        {
+            var featSvc = GetFeatureService();
+            GetByteReaderMethod fetch = () =>
+            {
+                return featSvc.GetSchemaMapping(provider, partialConnString);
+            };
+            using (var stream = new MgReadOnlyStream(fetch))
+            {
+                return ConfigurationDocument.Load(stream);
+            }
+        }
     }
+
+    class LocalLongTransaction : ILongTransaction
+    {
+        public LocalLongTransaction(MgLongTransactionReader rdr)
+        {
+            this.Name = rdr.Name;
+            this.Description = rdr.Description;
+            this.Owner = rdr.Owner;
+            this.CreationDate = rdr.CreationDate.ToString();
+            this.IsActive = rdr.IsActive();
+            this.IsFrozen = rdr.IsFrozen();
+        }
+
+        public string Name
+        {
+            get;
+            private set;
+        }
+
+        public string Description
+        {
+            get;
+            private set;
+        }
+
+        public string Owner
+        {
+            get;
+            private set;
+        }
+
+        public string CreationDate
+        {
+            get;
+            private set;
+        }
+
+        public bool IsActive
+        {
+            get;
+            private set;
+        }
+
+        public bool IsFrozen
+        {
+            get;
+            private set;
+        }
+    }
+
+    class LocalLongTransactionList : ILongTransactionList
+    {
+        private List<LocalLongTransaction> _transactions;
+
+        public LocalLongTransactionList(MgLongTransactionReader rdr)
+        {
+            _transactions = new List<LocalLongTransaction>();
+            while (rdr.ReadNext())
+            {
+                _transactions.Add(new LocalLongTransaction(rdr));
+            }
+            rdr.Close();
+        }
+
+        public IEnumerable<ILongTransaction> Transactions
+        {
+            get { return _transactions; }
+        }
+    }
+
 }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeConnection.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeConnection.cs	2012-10-17 06:46:38 UTC (rev 7124)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeConnection.cs	2012-10-17 13:29:39 UTC (rev 7125)
@@ -39,6 +39,8 @@
 using OSGeo.MapGuide.MaestroAPI.Feature;
 using System.Drawing;
 using System.Globalization;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using OSGeo.MapGuide.MaestroAPI.SchemaOverrides;
 
 namespace OSGeo.MapGuide.MaestroAPI.Native
 {
@@ -1535,5 +1537,95 @@
                 throw exMgd;
             }
         }
+
+        public override ILongTransactionList GetLongTransactions(string resourceId, bool activeOnly)
+        {
+            var featSvc = (MgFeatureService)this.Connection.CreateService(MgServiceType.FeatureService);
+            var resId = new MgResourceIdentifier(resourceId);
+            var rdr = featSvc.GetLongTransactions(resId, activeOnly);
+            return new LocalLongTransactionList(rdr);
+        }
+
+        public override ConfigurationDocument GetSchemaMapping(string provider, string partialConnString)
+        {
+            var featSvc = (MgFeatureService)this.Connection.CreateService(MgServiceType.FeatureService);
+            GetByteReaderMethod fetch = () =>
+            {
+                return featSvc.GetSchemaMapping(provider, partialConnString);
+            };
+            using (var stream = new MgReadOnlyStream(fetch))
+            {
+                return ConfigurationDocument.Load(stream);
+            }
+        }
     }
+
+    class LocalLongTransaction : ILongTransaction
+    {
+        public LocalLongTransaction(MgLongTransactionReader rdr)
+        {
+            this.Name = rdr.Name;
+            this.Description = rdr.Description;
+            this.Owner = rdr.Owner;
+            this.CreationDate = rdr.CreationDate.ToString();
+            this.IsActive = rdr.IsActive();
+            this.IsFrozen = rdr.IsFrozen();
+        }
+
+        public string Name
+        {
+            get;
+            private set;
+        }
+
+        public string Description
+        {
+            get;
+            private set;
+        }
+
+        public string Owner
+        {
+            get;
+            private set;
+        }
+
+        public string CreationDate
+        {
+            get;
+            private set;
+        }
+
+        public bool IsActive
+        {
+            get;
+            private set;
+        }
+
+        public bool IsFrozen
+        {
+            get;
+            private set;
+        }
+    }
+
+    class LocalLongTransactionList : ILongTransactionList
+    {
+        private List<LocalLongTransaction> _transactions;
+
+        public LocalLongTransactionList(MgLongTransactionReader rdr)
+        {
+            _transactions = new List<LocalLongTransaction>();
+            while (rdr.ReadNext())
+            {
+                _transactions.Add(new LocalLongTransaction(rdr));
+            }
+            rdr.Close();
+        }
+
+        public IEnumerable<ILongTransaction> Transactions
+        {
+            get { return _transactions; }
+        }
+    }
 }



More information about the mapguide-commits mailing list