ISConfig.cs
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // using System; using System.IO; using ESRI.ArcGIS; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Server; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.DataSourcesGDB; using ESRI.ArcGIS.DataSourcesRaster; namespace ISConfig { /// <summary> /// 1. Description: /// This sample demonstrate how to create an image service and set configurations based on data source types (raster dataset, mosaic dataset, compiled image service definition, raster layer); it also have additional features to start,stop,delete image service programmatically. /// The user running this utility needs to be in the agsadmin group on ArcGIS Server; and needs access to data source. /// The application can be run locally on AGSServer machine (localhost), or remotely. If source data is iscdef, image server must be already registered on ArcGIS Server. /// 2. Case sensitivity: /// (1) switches are case sensitive. /// (2) when publish a service, the service name is case sensitive /// e.g. If it's published to a folder, e.g. Temporary/Test1. "Temporary" must match the case. /// 3. Usage: /// Run from command line environment. Usage. <>: required parameter; |: pick one. /// isconfig -o publish -h <host> -d <datapath> -n <configName> /// isconfig -o <delete|start|stop|pause> -h <host> -n <configName> /// isconfig -o <list> -h <host> /// Example 1: isconfig -o publish -h localhost -d \\myserver\data\test.gdb\mdtest -n mdtest /// Example 2: isconfig -o stop -h myservername -n mdtest /// Example 3: isconfig -o list -h myservername /// </summary> class ISConfig { #region static variables private static string sourcePath = ""; //data source path: a raster dataset, an iscdef, a mosaic dataset private static string host = ""; //host machine; use "localhost" for local ags server private static string configName = ""; //image service configuration name private static IGISServerConnection2 gisServerConnection = null; private static IRasterDataset rasterDataset = null; #endregion [STAThread] public static void Main(string[] args) { try { //validation if (!ValidateParams(args)) return; //license if (!InitLicense()) return; //retrieve parameters Retrieve_Params(args); string operation = args[1]; switch (operation.ToLower()) { case "publish": CreateISConfig(); break; case "delete": DeleteService(); break; case "start": StartService(); break; case "stop": StopService(); break; case "pause": PauseService(); break; case "list": ListServices(); break; } } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } #region management operations /// <summary> /// create image service configuration /// </summary> private static void CreateISConfig() { try { if (!ConnectAGS(host)) return; esriImageServiceSourceType sourceType = GetSourceType(sourcePath); //connect to ArcGIS Server and create configuration IGISServerConnection gisServerConnection = new GISServerConnectionClass(); gisServerConnection.Connect(host); IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; IServerObjectConfiguration soConfig = (IServerObjectConfiguration)soAdmin.CreateConfiguration(); //set general service parameters soConfig.Name = configName; soConfig.TypeName = "ImageServer"; soConfig.StartupType = esriStartupType.esriSTAutomatic; soConfig.IsPooled = true; soConfig.IsolationLevel = esriServerIsolationLevel.esriServerIsolationHigh; soConfig.MinInstances = 1; soConfig.MaxInstances = 2; IPropertySet propertySet_Recycle = soConfig.RecycleProperties; propertySet_Recycle.SetProperty("Start", "00:00"); propertySet_Recycle.SetProperty("Interval", "86400"); IPropertySet propertySet = soConfig.Properties; if (sourceType == esriImageServiceSourceType.esriImageServiceSourceTypeCatalog)//(sourceDataPath.ToLower().EndsWith(".iscdef")) propertySet.SetProperty("ServiceDefinition", sourcePath); else propertySet.SetProperty("Path", sourcePath); propertySet.SetProperty("SupportedImageReturnTypes", "URL"); //virtual directory IEnumServerDirectory dirs = soAdmin.GetServerDirectories(); dirs.Reset(); IServerDirectory serverDir = dirs.Next(); while (serverDir != null) { if (((IServerDirectory2)serverDir).Type == esriServerDirectoryType.esriSDTypeOutput) { propertySet.SetProperty("OutputDir", serverDir.Path); propertySet.SetProperty("VirtualOutputDir", serverDir.URL); break; } serverDir = dirs.Next(); } //properties for a mosaic dataset; if (sourceType == esriImageServiceSourceType.esriImageServiceSourceTypeMosaicDataset) { IFunctionRasterDataset functionRasterDataset = (IFunctionRasterDataset)rasterDataset; IPropertySet propDefaults = functionRasterDataset.Properties; propertySet.SetProperty("MaxImageHeight", propDefaults.GetProperty("MaxImageHeight"));//4100 propertySet.SetProperty("MaxImageWidth", propDefaults.GetProperty("MaxImageWidth"));//15000 propertySet.SetProperty("AllowedCompressions", propDefaults.GetProperty("AllowedCompressions"));//"None,JPEG,LZ77" propertySet.SetProperty("DefaultResamplingMethod", propDefaults.GetProperty("DefaultResamplingMethod"));//0 propertySet.SetProperty("DefaultCompressionQuality", propDefaults.GetProperty("DefaultCompressionQuality"));//75 propertySet.SetProperty("MaxRecordCount", propDefaults.GetProperty("MaxRecordCount"));//500 propertySet.SetProperty("MaxMosaicImageCount", propDefaults.GetProperty("MaxMosaicImageCount"));//20 propertySet.SetProperty("MaxDownloadImageCount", propDefaults.GetProperty("MaxDownloadImageCount"));//20 propertySet.SetProperty("AllowedFields", propDefaults.GetProperty("AllowedFields"));//"Name,MinPS,MaxPS,LowPS,HighPS,CenterX,CenterY" propertySet.SetProperty("AllowedMosaicMethods", propDefaults.GetProperty("AllowedMosaicMethods"));//"Center,NorthWest,LockRaster,ByAttribute,Nadir,Viewpoint,Seamline" propertySet.SetProperty("AllowedItemMetadata", propDefaults.GetProperty("AllowedItemMetadata"));//"Full" //propertySet.SetProperty("DownloadDir", ""); //put the download dir here //propertySet.SetProperty("VirutalDownloadDir", ""); //put the virtual download dir here } else if (sourceType != esriImageServiceSourceType.esriImageServiceSourceTypeCatalog) //not iscdef { propertySet.SetProperty("MaxImageHeight", 4100); propertySet.SetProperty("MaxImageWidth", 15000); propertySet.SetProperty("AllowedCompressions", "None,JPEG,LZ77"); propertySet.SetProperty("DefaultResamplingMethod", 0); propertySet.SetProperty("DefaultCompressionQuality", 75); } //enable web capabilities IServerObjectConfiguration2 soConfig2 = (IServerObjectConfiguration2)soConfig; soConfig2.Info.SetProperty("WebEnabled", "true"); if (sourceType == esriImageServiceSourceType.esriImageServiceSourceTypeMosaicDataset) soConfig2.Info.SetProperty("WebCapabilities", "Image,Catalog,Metadata,Download,Pixels"); else soConfig2.Info.SetProperty("WebCapabilities", "Image,Metadata"); //enable wcs, assume data has spatial reference soConfig2.set_ExtensionEnabled("WCSServer", true); IPropertySet propertySetWCS = soConfig2.get_ExtensionInfo("WCSServer"); propertySetWCS.SetProperty("WebEnabled", "true"); //enable wms soConfig2.set_ExtensionEnabled("WMSServer", true); IPropertySet propertySetWMS = soConfig2.get_ExtensionInfo("WMSServer"); propertySetWMS.SetProperty("WebEnabled", "true"); //add configuration and start soAdmin.AddConfiguration(soConfig); soAdmin.StartConfiguration(configName, "ImageServer"); if (soAdmin.GetConfigurationStatus(configName, "ImageServer").Status == esriConfigurationStatus.esriCSStarted) Console.WriteLine("{0} on {1} has been configured and started.", configName, host); else Console.WriteLine("{0} on {1} was configured but can not be started, please investigate.", configName, host); } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } /// <summary> /// delete a service /// </summary> private static void DeleteService() { try { if (!ConnectAGS(host)) return; IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; if (!ValidateConfigName(soAdmin, ref configName, host)) return; soAdmin.DeleteConfiguration(configName, "ImageServer"); Console.WriteLine("{0} on {1} was deleted successfully.", configName, host); } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } /// <summary> /// start a service /// </summary> private static void StartService() { try { if (!ConnectAGS(host)) return; IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; if (!ValidateConfigName(soAdmin, ref configName, host)) return; soAdmin.StartConfiguration(configName, "ImageServer"); if (soAdmin.GetConfigurationStatus(configName, "ImageServer").Status == esriConfigurationStatus.esriCSStarted) Console.WriteLine("{0} on {1} was started successfully.", configName, host); else Console.WriteLine("{0} on {1} couldn't be started, please investigate.", configName, host); } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } /// <summary> /// stop a service /// </summary> private static void StopService() { try { if (!ConnectAGS(host)) return; IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; if (!ValidateConfigName(soAdmin, ref configName, host)) return; soAdmin.StopConfiguration(configName, "ImageServer"); if (soAdmin.GetConfigurationStatus(configName, "ImageServer").Status == esriConfigurationStatus.esriCSStopped) Console.WriteLine("{0} on {1} was stopped successfully.", configName, host); else Console.WriteLine("{0} on {1} couldn't be stopped, please investigate.", configName, host); } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } /// <summary> /// pause a service /// </summary> private static void PauseService() { try { if (!ConnectAGS(host)) return; IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; if (!ValidateConfigName(soAdmin, ref configName, host)) return; if ((soAdmin.GetConfigurationStatus(configName, "ImageServer").Status == esriConfigurationStatus.esriCSStopped)) { Console.WriteLine("{0} on {1} is currently stopped --- not paused.", configName, host); return; } soAdmin.PauseConfiguration(configName, "ImageServer"); if (soAdmin.GetConfigurationStatus(configName, "ImageServer").Status == esriConfigurationStatus.esriCSPaused) Console.WriteLine("{0} on {1} was paused successfully.", configName, host); else Console.WriteLine("{0} on {1} couldn't be paused, please investigate.", configName, host); } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } /// <summary> /// List services /// </summary> private static void ListServices() { try { if (!ConnectAGS(host)) return; IServerObjectAdmin soAdmin = gisServerConnection.ServerObjectAdmin; IEnumServerObjectConfiguration enumConfigs = soAdmin.GetConfigurations(); enumConfigs.Reset(); IServerObjectConfiguration soConfig = enumConfigs.Next(); Console.WriteLine("ArcGIS Server {0} has the following image services:", host); while (soConfig != null) { if (soConfig.TypeName == "ImageServer") Console.WriteLine("{0}", soConfig.Name); soConfig = enumConfigs.Next(); } } catch (Exception exc) { Console.WriteLine("Error: {0}", exc.Message); } } #endregion #region validation etc. /// <summary> /// connect to ags server /// </summary> /// <param name="host">host</param> /// <returns>true if connected</returns> private static bool ConnectAGS(string host) { try { gisServerConnection = new GISServerConnectionClass(); gisServerConnection.Connect(host); return true; } catch (Exception exc) { Console.WriteLine("Error: Couldn't connect to AGSServer: {0}. Message: {1}", host, exc.Message); return false; } } /// <summary> /// Validate ConfigName /// </summary> /// <returns>Convert the config name to the correct case and returns true; if not exist in any cases, returns false </returns> private static bool ValidateConfigName(IServerObjectAdmin soAdmin, ref string configName, string host) { IEnumServerObjectConfiguration enumConfigs = soAdmin.GetConfigurations(); enumConfigs.Reset(); IServerObjectConfiguration soConfig = enumConfigs.Next(); while (soConfig != null) { if (soConfig.Name.ToUpper() == configName.ToUpper()) { configName = soConfig.Name; return true; } soConfig = enumConfigs.Next(); } Console.WriteLine("Configuration {0} on {1} can not be found.", configName, host); return false; } /// <summary> /// Validate input parameters /// </summary> /// <param name="args">args</param> /// <returns>validation result</returns> private static bool ValidateParams(string[] args) { //at least two params if (args.Length < 2) // at least -o action { ShowUsage(); return false; } // must start with -o string[] operations = new string[] { "publish", "delete", "start", "stop", "pause", "list" }; if ((!args[0].StartsWith("-o")) || (!strInArray(args[1].ToLower(), operations))) { Console.WriteLine("Incorrect operation"); ShowUsage(); return false; } // for stop/start/pause/list, must contains "-n" and argument length is 4 if ((args[1].ToLower() == "stop") || (args[1].ToLower() == "start") || (args[1].ToLower() == "pause") || (args[1].ToLower() == "delete")) { if (!strInArray("-h", args)) { Console.WriteLine("Missing host server -h"); return false; } if (!strInArray("-n", args)) { Console.WriteLine("Missing service name switch -n"); return false; } if (args.Length > 6) { Console.WriteLine("Too many arguments"); return false; } } // for publish, must contains "-d" "-n" and argument length is 6 if (args[1].ToLower() == "publish") { if (!strInArray("-d", args)) { Console.WriteLine("Missing data source switch -d"); return false; } if (!strInArray("-n", args)) { Console.WriteLine("Missing service name switch -n"); return false; } if (args.Length > 8) { Console.WriteLine("Too many arguments"); return false; } } // validate each parameter: host, sourcepath, configname string[] parameters = new string[] { "-h", "-d", "-n" }; for (int i = 2; i < args.Length; i++) { switch (args[i]) { case "-h": if (i == args.Length - 1) { Console.WriteLine("Missing host parameter, switch -h"); return false; } else if (strInArray(args[i + 1], parameters)) { Console.WriteLine("Missing host parameter, switch -h"); return false; } ++i; break; case "-d": if (i == args.Length - 1) { Console.WriteLine("Missing data source parameter, switch -d"); return false; } else if (strInArray(args[i + 1], parameters)) { Console.WriteLine("Missing data source parameter, switch -d"); return false; } ++i; break; case "-n": if (i == args.Length - 1) { Console.WriteLine("Missing service name parameter, switch -n"); return false; } else if (strInArray(args[i + 1], parameters)) { Console.WriteLine("Missing service name parameter, switch -n"); return false; } ++i; break; default: Console.WriteLine("Incorrect parameter switch: {0} is not a recognized.", args[i]); return false; } } return true; } /// <summary> /// string in array /// </summary> /// <param name="name"></param> /// <param name="nameArray"></param> /// <returns></returns> private static bool strInArray(string name, string[] nameArray) { for (int i = 0; i < nameArray.Length; i++) { if (nameArray[i] == name) return true; } return false; } /// <summary> /// initialize license /// </summary> /// <returns>status</returns> private static bool InitLicense() { RuntimeManager.Bind(ProductCode.Desktop); IAoInitialize aoInit = new AoInitializeClass(); string license = System.Environment.GetEnvironmentVariable("ARCLICENSE"); esriLicenseStatus status = aoInit.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcView); if (status != esriLicenseStatus.esriLicenseCheckedOut) { Console.WriteLine("License initialization error"); return false; } else return true; } #endregion #region helper methods /// <summary> /// Retrieve parameters /// </summary> /// <param name="args">args</param> private static void Retrieve_Params(string[] args) { for (int i = 2; i < args.Length; i++) { switch (args[i]) { case "-h": host = args[++i]; break; case "-d": sourcePath = args[++i]; break; case "-n": configName = args[++i]; break; } } } /// <summary> /// Get Source Type /// </summary> /// <param name="sourcePath">path of the data source</param> /// <returns>data source type</returns> private static esriImageServiceSourceType GetSourceType(string sourcePath) { if (sourcePath.ToLower().EndsWith(".iscdef")) return esriImageServiceSourceType.esriImageServiceSourceTypeCatalog; else if (sourcePath.ToLower().EndsWith(".lyr")) return esriImageServiceSourceType.esriImageServiceSourceTypeLayer; else { FileInfo fileInfo = new FileInfo(sourcePath); OpenRasterDataset(fileInfo.DirectoryName, fileInfo.Name); if (rasterDataset is IMosaicDataset) return esriImageServiceSourceType.esriImageServiceSourceTypeMosaicDataset; else return esriImageServiceSourceType.esriImageServiceSourceTypeDataset; } } /// <summary> /// Open Raster Dataset /// </summary> /// <param name="path">path of the dataset</param> /// <param name="rasterDSName">name of the dataset</param> private static void OpenRasterDataset(String path, String rasterDSName) { //this is why the utility user needs access to data source. image service configurations varies among data sources. IWorkspaceFactory workspaceFactory = null; IWorkspace workspace = null; IRasterWorkspaceEx rasterWorkspaceEx = null; Type factoryType = null; try { switch (path.Substring(path.Length - 4, 4).ToLower()) // a path can never be shorter than 4 characters, isn't it? c:\a { case ".mdb": factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory"); workspaceFactory = Activator.CreateInstance(factoryType) as IWorkspaceFactory; workspace = workspaceFactory.OpenFromFile(path, 1); rasterWorkspaceEx = (IRasterWorkspaceEx)workspace; rasterDataset = rasterWorkspaceEx.OpenRasterDataset(rasterDSName); break; case ".gdb": factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory"); workspaceFactory = Activator.CreateInstance(factoryType) as IWorkspaceFactory; workspace = workspaceFactory.OpenFromFile(path, 1); rasterWorkspaceEx = (IRasterWorkspaceEx)workspace; rasterDataset = rasterWorkspaceEx.OpenRasterDataset(rasterDSName); break; case ".sde": factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory"); workspaceFactory = Activator.CreateInstance(factoryType) as IWorkspaceFactory; workspace = workspaceFactory.OpenFromFile(path, 1); rasterWorkspaceEx = (IRasterWorkspaceEx)workspace; rasterDataset = rasterWorkspaceEx.OpenRasterDataset(rasterDSName); break; default: factoryType = Type.GetTypeFromProgID("esriDataSourcesRaster.RasterWorkspaceFactory"); workspaceFactory = Activator.CreateInstance(factoryType) as IWorkspaceFactory; workspace = workspaceFactory.OpenFromFile(path, 1); IRasterWorkspace rasterWorkspace = (IRasterWorkspace)workspace; rasterDataset = rasterWorkspace.OpenRasterDataset(rasterDSName); break; } } catch (Exception) { throw new ArgumentException("Failed to open source data"); } } /// <summary> /// Show usage /// </summary> private static void ShowUsage() { Console.WriteLine(); Console.WriteLine("ArcObject Sample: command line image service configuration utility."); Console.WriteLine(); Console.WriteLine("Usage. <>: required parameter; |: pick one."); Console.WriteLine("isconfig -o publish -h <host> -d <datapath> -n <configName>"); Console.WriteLine("isconfig -o <delete|start|stop|pause> -h <host> -n <configName>"); Console.WriteLine("isconfig -o <list> -h <host>"); } #endregion } }