ArcGIS Engine 10.2 如何发布服务
http://blog.csdn.net/arcgis_all/article/details/17376397
1 ArcGIS Engine 10.2 如何发布服务
ArcGIS Engine的代码不能直接将MXD地图文档作为数据源进行发布,如果要发布的话,需要用ArcMap将MXD转成MSD,然后使用转换成功的MSD文档进行发布,代码如下:
public void Publish(string host,string username,string password, string service, string msdDocument, string outputDir)
{
//IAGSServerConnectionFactory3 pConnectionFactory = new AGSServerConnectionFactoryClass();
////admin connection file works fine, tested in ArcCatalog on the same server
//IAGSServerConnection4 server = pConnectionFactory.OpenFromFile(@"e:\admin-connection.ags", 0) as IAGSServerConnection4;
// IAGSServerConnectionAdmin pAGSServerConnectionAdmin = server as IAGSServerConnectionAdmin;
IPropertySet propertySet = new PropertySetClass();
propertySet.SetProperty("url", host);
propertySet.SetProperty("ConnectionMode", esriAGSConnectionMode.esriAGSConnectionModeAdmin);
propertySet.SetProperty("ServerType", esriAGSServerType.esriAGSServerTypeDiscovery);
propertySet.SetProperty("user", username);
propertySet.SetProperty("password", password);
propertySet.SetProperty("ALLOWINSECURETOKENURL", true); //设置为false会弹出一个警告对话框
IAGSServerConnectionName3 pConnectName = new AGSServerConnectionNameClass() as IAGSServerConnectionName3;//10.1新增接口
pConnectName.ConnectionProperties = propertySet;
IAGSServerConnectionAdmin pAGSAdmin = ((IName)pConnectName).Open() as IAGSServerConnectionAdmin;
IAGSServerConnectionAdmin pAGSServerConnectionAdmin = pAGSAdmin as IAGSServerConnectionAdmin;
IServerObjectAdmin pServerObjectAdmin = pAGSServerConnectionAdmin.ServerObjectAdmin;
IServerObjectConfiguration5 pConfiguration = (IServerObjectConfiguration5)pServerObjectAdmin.CreateConfiguration();
//Set the general configuration settings
pConfiguration.Name = service;
pConfiguration.TypeName = "MapServer";
pConfiguration.TargetCluster = "default";
pConfiguration.StartupType = esriStartupType.esriSTAutomatic;
pConfiguration.IsolationLevel = esriServerIsolationLevel.esriServerIsolationHigh;
pConfiguration.IsPooled = true;
pConfiguration.Description = "Modsim Map Output";
// pConfiguration.LoadBalancing = esriLoadBalancing.esriLoadBalancingNone;//没有集群的话可以不用设置
pConfiguration.MinInstances = 1;
pConfiguration.MaxInstances = 15;
pConfiguration.WaitTimeout = 60;
pConfiguration.UsageTimeout = 600;
pConfiguration.IdleTimeout = 1800;
//Set the configuration properties of the MapServer
IPropertySet pProps = pConfiguration.Properties;
pProps.SetProperty("FilePath", msdDocument);
pProps.SetProperty("OutputDir", outputDir);
pProps.SetProperty("MaxImageHeight", "2048");
pProps.SetProperty("MaxRecordCount", "1000");
pProps.SetProperty("MaxBufferCount", "100");
pProps.SetProperty("MaxImageWidth", "2048");
pConfiguration.Properties = pProps;
//MIME+URL (virtual directory)
IEnumServerDirectory dirs = pServerObjectAdmin.GetServerDirectories();
dirs.Reset();
IServerDirectory serverDir = dirs.Next();
while (serverDir != null)
{
if (((IServerDirectory2)serverDir).Type == esriServerDirectoryType.esriSDTypeOutput)
{
pProps.SetProperty("OutputDir", serverDir.Path);
pProps.SetProperty("VirtualOutputDir", serverDir.URL);
break;
// gp.AddMessage("[DEBUG] Outputpath: " + serverDir.Path + " || Virtual: " + serverDir.URL);
}
serverDir = dirs.Next();
}
//Set the info segment properties
IPropertySet info = pConfiguration.Info;
info.SetProperty("WebEnabled", "true");
info.SetProperty("WebCapabilities", "Map,Query,Data");
pConfiguration.Info = info;
//Set the recycle properties of the MapServer object
IPropertySet recycle = pConfiguration.RecycleProperties;
recycle.SetProperty("StartTime", "1:00 AM");
recycle.SetProperty("Interval", "86400");
pConfiguration.RecycleProperties = recycle;
//Add the configuration to the server
pServerObjectAdmin.AddConfiguration(pConfiguration);
pServerObjectAdmin.StartConfiguration(service, "MapServer");
}
2 使用ArcGIS Engie中的GP发布地图文档
ArcGIS 10.1 在发布服务的时候其实是按照下面的步骤来的,如果认真观察过也不难得出:
l 将MXD文档转成sddraft文件;
l 将sddraft文件转成sd文件;
l 将sd文件上传到ArcGIS for Server中
既然这个过程已经知道了,那么就可以通过Python按照这个流程来自动化的完成服务的发布:
import arcpy
# define local variables
wrkspc = 'C:/Project/'
mapDoc = arcpy.mapping.MapDocument(wrkspc + 'counties.mxd')
con = r'GIS Servers\arcgis on MyServer_6080 (admin).ags'
service = 'Counties'
sddraft = wrkspc + service + '.sddraft'
sd = wrkspc + service + '.sd'
# create service definition draft
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER', con, True, None)
# analyze the service definition draft
analysis = arcpy.mapping.AnalyzeForSD(sddraft)
# stage and upload the service if the sddraft analysis did not contain errors
if analysis['errors'] == {}:
# Execute StageService
arcpy.StageService_server(sddraft, sd)
# Execute UploadServiceDefinition
arcpy.UploadServiceDefinition_server(sd, con)
else:
# if the sddraft analysis contained errors, display them
print analysis['errors']
可以将上面的脚本创建为一个tbx文件,然后在ArcGIS Engine中通过GP来实现服务的发布.
其实Esri在官网上发布了一个tbx里面就包含了对server服务管理的功能(有兴趣的可以下载,文档所在的目录下也包含了):
3 使用Admin API 发布文档
ArcGIS for Server 10.1 增加了Admin API,那么,所谓的Admin API 其实就是一一http请求的方法,这些方法包含了对Server的管理,下面为Admin API 的代码:
namespace ServerAPIAdmin.ArcGIS.Rest
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using ESRI.ArcGIS.SOESupport;
///<summary>
/// tipi di servizio arcgis server (mappa la tabella servizio tipo)
///</summary>
public enum ServiceType
{
MapServer,
GeocodeServer,
SearchServer,
IndexingLauncher,
IndexGenerator,
GeometryServer,
GeoDataServer,
GPServer,
GlobeServer,
ImageServer
}
///<summary>
/// Load Balancing
///</summary>
public enum LoadBalancing
{
ROUND_ROBIN,
FAIL_OVER
}
///<summary>
/// isolation level
///</summary>
public enum IsolationLevel
{
LOW,
HIGH
}
///<summary>
/// administrative API Rest
///</summary>
public class AGSAdmin
{
private string username;
private string password;
private string urlRestAdmin;
private string urlRestServer;
///<summary>
/// Initializes a new instance of the <see cref="AGSAdmin"/> class.
///</summary>
///<param name="serverName">server name</param>
///<param name="port">port of server</param>
///<param name="username">username administrator</param>
///<param name="password">password administrator</param>
public AGSAdmin(string serverName, int port, string username, string password)
{
this.username = username;
this.password = password;
string url = string.Format("http://{0}:{1}/arcgis", serverName, port.ToString());
this.urlRestAdmin = url + "/admin";
this.urlRestServer = url + "/server";
}
///<summary>
/// Prevents a default instance of the <see cref="AGSAdmin"/> class from being created.
///</summary>
private AGSAdmin()
{
}
///<summary>
/// Create arcgis server folder
///</summary>
///<param name="folderName">Folder name</param>
///<param name="description">Description of the folder</param>
///<returns>True if successfully created</returns>
public bool CreateServerFolder(string folderName, string description)
{
try
{
string token = this.GenerateAGSToken();
string folderUrl = this.urlRestAdmin + "/services/" + folderName + "?f=json&token=" + token;
string resultExistsFolder = this.GetResult(folderUrl);
if (!this.HasError(resultExistsFolder))
{
return true; // exists
}
else
{
string createFolderUrl = this.urlRestAdmin + "/services/createFolder";
string postContent = string.Format("folderName={0}&description={1}&f=json&token={2}", folderName, description, token);
string result = this.GetResult(createFolderUrl, postContent);
return this.HasSuccess(result);
}
}
catch
{
return false;
}
}
///<summary>
/// Get physical Path and virtual Path from directory ags
///</summary>
///<param name="directory">directory ags</param>
///<param name="physicalPath">physical Path</param>
///<param name="virtualPath">virtual Path</param>
///<returns>True if successfully return path</returns>
public bool GetServerDirectory(string directory, out string physicalPath, out string virtualPath)
{
physicalPath = null;
virtualPath = null;
try
{
string token = this.GenerateAGSToken();
string directoryUrl = this.urlRestAdmin + "/system/directories/" + directory + "?f=json&token=" + token;
string result = this.GetResult(directoryUrl);
JsonObject jsonObject = new JsonObject(result);
if (!jsonObject.Exists("physicalPath") || !jsonObject.TryGetString("physicalPath", out physicalPath))
{
throw new Exception();
}
jsonObject = new JsonObject(result);
if (!jsonObject.Exists("virtualPath") || !jsonObject.TryGetString("virtualPath", out virtualPath))
{
throw new Exception();
}
return true;
}
catch
{
return false;
}
}
///<summary>
/// Delete Service
///</summary>
///<param name="serviceName">Service Name</param>
///<param name="serviceType">Server Type</param>
///<returns>True if successfully deleted</returns>
public bool DeleteService(string serviceName, ServiceType serviceType)
{
try
{
string token = this.GenerateAGSToken();
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/delete";
string result = this.GetResult(serviceUrl, "f=json&token=" + token);
return this.HasSuccess(result);
}
catch
{
return false;
}
}
///<summary>
/// Start Service
///</summary>
///<param name="serviceName">Service Name</param>
///<param name="serviceType">Server Type</param>
///<returns>True if successfully started</returns>
public bool StartService(string serviceName, ServiceType serviceType)
{
try
{
string token = this.GenerateAGSToken();
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/start";
string result = this.GetResult(serviceUrl, "f=json&token=" + token);
return this.HasSuccess(result);
}
catch
{
return false;
}
}
///<summary>
/// Stop Service
///</summary>
///<param name="serviceName">Service Name</param>
///<param name="serviceType">Server Type</param>
///<returns>True if successfully stopped</returns>
public bool StopService(string serviceName, ServiceType serviceType)
{
try
{
string token = this.GenerateAGSToken();
string serviceUrl = this.urlRestAdmin + "/services/" + serviceName + "." + Enum.GetName(typeof(ServiceType), serviceType) + "/stop";
string result = this.GetResult(serviceUrl, "f=json&token=" + token);
return this.HasSuccess(result);
}
catch
{
return false;
}
}
///<summary>
/// list of services
///</summary>
public void ListServices()
{
this.ListServices(null);
}
///<summary>
/// list of services in folder
///</summary>
///<param name="folder">name of folder</param>
public void ListServices(string folder)
{
try
{
string token = this.GenerateAGSToken();
string serviceUrl = this.urlRestAdmin + "/services/" + folder;
string postcontent = "f=json&token=" + token;
string result = this.GetResult(serviceUrl, postcontent);
JsonObject jsonObject = new JsonObject(result);
object[] folders = null;
if (jsonObject.Exists("folders") && jsonObject.TryGetArray("folders", out folders))
{
foreach (string subfolder in folders)
{
this.ListServices(subfolder);
}
}
object[] services = null;
if (jsonObject.Exists("services") && jsonObject.TryGetArray("services", out services))
{
IEnumerable<JsonObject> jsonObjectService = services.Cast<JsonObject>();
jsonObjectService.ToList().ForEach(jo =>
{
string serviceName;
jo.TryGetString("serviceName", out serviceName);
string folderName;
jo.TryGetString("folderName", out folderName);
Console.WriteLine(folderName + "/" + serviceName);
});
}
}
catch
{
throw;
}
}
///<summary>
/// create service type MapServer
///</summary>
///<returns>>True if successfully created</returns>
public bool CreateService(String msdPath)
{
try
{
string token = this.GenerateAGSToken();
string serviceUrl = this.urlRestAdmin + "/services/createService";
JsonObject jsonObject = new JsonObject();
jsonObject.AddString("serviceName", "Test");
jsonObject.AddString("type", Enum.GetName(typeof(ServiceType), ServiceType.MapServer));
jsonObject.AddString("description", "This is an example");
jsonObject.AddString("capabilities", "Map,Query,Data");
jsonObject.AddString("clusterName", "default");
jsonObject.AddLong("minInstancesPerNode", 1);
jsonObject.AddLong("maxInstancesPerNode", 2);
jsonObject.AddLong("maxWaitTime", 60);
jsonObject.AddLong("maxStartupTime", 300);
jsonObject.AddLong("maxIdleTime", 1800);
jsonObject.AddLong("maxUsageTime", 600);
jsonObject.AddLong("recycleInterval", 24);
jsonObject.AddString("loadBalancing", Enum.GetName(typeof(LoadBalancing), LoadBalancing.ROUND_ROBIN));
jsonObject.AddString("isolationLevel", Enum.GetName(typeof(IsolationLevel), IsolationLevel.HIGH));
JsonObject jsonObjectProperties = new JsonObject();
// see for a list complete http://resources.arcgis.com/en/help/server-admin-api/serviceTypes.html
jsonObjectProperties.AddLong("maxBufferCount", 100); // optional 100
jsonObjectProperties.AddString("virtualCacheDir", this.urlRestServer + "/arcgiscache"); // optional
jsonObjectProperties.AddLong("maxImageHeight", 2048); // optional 2048
jsonObjectProperties.AddLong("maxRecordCount", 1000); // optional 500
// Other service types do not require you to use arcpy.mapping or create an MSD.
jsonObjectProperties.AddString("filePath", msdPath); // required
jsonObjectProperties.AddLong("maxImageWidth", 2048); // optional 2048
jsonObjectProperties.AddBoolean("cacheOnDemand", false); // optional false
jsonObjectProperties.AddString("virtualOutputDir", this.urlRestServer + "/arcgisoutput");
jsonObjectProperties.AddString("outputDir", @"C:\arcgisserver\directories\arcgisoutput"); // required
jsonObjectProperties.AddString("supportedImageReturnTypes", "MIME+URL"); // optional MIME+URL
jsonObjectProperties.AddBoolean("isCached", false); // optional false
jsonObjectProperties.AddBoolean("ignoreCache", false); // optional false
jsonObjectProperties.AddBoolean("clientCachingAllowed", false); // optional true
jsonObjectProperties.AddString("cacheDir", @"C:\arcgisserver\directories\arcgiscache"); // optional
jsonObject.AddJsonObject("properties", jsonObjectProperties);
string result = this.GetResult(serviceUrl, "service=" + HttpUtility.UrlEncode(jsonObject.ToJson()) + "&f=json&token=" + token);
return this.HasSuccess(result);
}
catch
{
return false;
}
}
///<summary>
/// check is status is equal success
///</summary>
///<param name="result">result of request</param>
///<returns>True if status is equal success</returns>
private bool HasSuccess(string result)
{
JsonObject jsonObject = new JsonObject(result);
string status = null;
if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status))
{
return false;
}
return status == "success";
}
///<summary>
/// check is status is equal error
///</summary>
///<param name="result">result of request</param>
///<returns>True if status is equal error</returns>
private bool HasError(string result)
{
JsonObject jsonObject = new JsonObject(result);
string status = null;
if (!jsonObject.Exists("status") || !jsonObject.TryGetString("status", out status))
{
return false;
}
return status == "error";
}
///<summary>
/// Get request rest
///</summary>
///<param name="url">url of request</param>
///<returns>return response</returns>
private string GetResult(string url)
{
try
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
return reader.ReadToEnd();
}
}
}
catch
{
throw;
}
}
///<summary>
/// Post request rest
///</summary>
///<param name="url">url of request</param>
///<param name="postContent">content of post</param>
///<returns>return response</returns>
private string GetResult(string url, string postContent)
{
try
{
WebRequest request = WebRequest.Create(url);
byte[] content = Encoding.UTF8.GetBytes(postContent);
request.ContentLength = content.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = WebRequestMethods.Http.Post;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(content, 0, content.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
return reader.ReadToEnd();
}
}
}
}
catch
{
throw;
}
}
///<summary>
/// Generate a token
///</summary>
///<returns>A token that has default expiration time</returns>
private string GenerateAGSToken()
{
try
{
string urlGenerateToken = string.Format("{0}/generateToken", this.urlRestAdmin);
string credential = string.Format("username={0}&password={1}&client=requestip&expiration=&f=json", this.username, this.password);
string result = this.GetResult(urlGenerateToken, credential);
JsonObject jsonObject = new JsonObject(result);
string token = null;
if (!jsonObject.Exists("token") || !jsonObject.TryGetString("token", out token))
{
throw new Exception("Token not found!");
}
return token;
}
catch
{
return string.Empty;
}
}
}
}