zoukankan      html  css  js  c++  java
  • How To: Write a BizTalk Application Configuration Wizard

    We have a BizTalk Application to be deployed on some environment, however, the deploy team is not familiar with BizTalk Administrator Console. And sometimes they make things worse even with a detailed deployment guideline. Then we decide to write a wizard.
    To Begin with the wizard, it's better list all we have to set up for the BizTalk application:
    1. Three web services
    2. Three custom BizTalk adapters
    3. A 32 bit host instance for SQL and FTP adapter
    4. A SQL Server database
    Then we can go with the main application import process:
    1. Import the .msi application and install it on the server
    2. Import the individual binding file for the application
    3. Update the port configuration for the application
    4. Start the application
    If we have incremental update, we have to redo the import process(That's depends on the update).
    Below will the code we use for all the function listed:
    Step One: Create Web Service
    For this function, we packaged the complied web services, we ask the path of the web services folder, then the wizard set up a pool with BizTalk Isolate account, and binding the three web services with the app pool we created.
    Code herein:

    View Code
    public class IIS7Management
    {
    public static void CreateAppPool(string AppPoolName, string User, string password)
    {
    ServerManager mgr = new ServerManager();

    var app = mgr.ApplicationPools.First(s => s.Name == AppPoolName);
    if (app == null)
    {
    // Add a new application pool called PoolName
    ApplicationPool myAppPool = mgr.ApplicationPools.Add(AppPoolName);

    // Set the runtime version of ASP.NET to 4.0
    myAppPool.ManagedRuntimeVersion = "v4.0";

    // Use the Classic Pipeline mode
    myAppPool.ManagedPipelineMode = ManagedPipelineMode.Classic;

    // Configure my new app pool to start automatically.
    myAppPool.AutoStart = true;

    // What action should IIS take when my app pool exceeds
    // the CPU limit specified by the Limit property
    myAppPool.Cpu.Action = ProcessorAction.NoAction;

    // Use the SpecificUser account
    myAppPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
    myAppPool.ProcessModel.UserName = User;
    myAppPool.ProcessModel.Password = password;

    // Shut down after being idle for 5 minutes.
    myAppPool.ProcessModel.IdleTimeout = TimeSpan.FromMinutes(5);

    // Max. number of IIS worker processes (W3WP.EXE)
    myAppPool.ProcessModel.MaxProcesses = 1;

    // Commit the changes
    mgr.CommitChanges();
    }
    }

    public static void CreateApplication(string AppPoolName, string AppName, string physicalPath)
    {
    try
    {
    ServerManager mgr = new ServerManager();
    Application myapp = mgr.Sites["Default Web Site"].Applications.Add("/" + AppName, physicalPath);
    myapp.ApplicationPoolName = AppPoolName;
    mgr.CommitChanges();
    }
    catch(Exception ex)
    {
    throw ex;
    }
    }
    }

    Step Two: Install Adapters:
    From here we have to install the Adapters and Add these adapters into BizTalk.
    We use a process to install the adapters and wait until it finished then we add this into BizTalk.

    Code here

    View Code
    public static void CreateAdapter(string Name, string AdapterCLSID, string comment)
    {
    try
    {
    PutOptions options = new PutOptions();
    options.Type = PutType.UpdateOrCreate;

    //create a ManagementClass object and spawn a ManagementObject instance
    ManagementClass objAdapterClass = new ManagementClass("root\\MicrosoftBizTalkServer", "MSBTS_AdapterSetting", null);
    ManagementObject objAdapter = objAdapterClass.CreateInstance();

    //set the properties for the Managementobject
    objAdapter.SetPropertyValue("Name", Name);
    objAdapter.SetPropertyValue("MgmtCLSID", AdapterCLSID);
    objAdapter.SetPropertyValue("Comment", comment);

    objAdapter.Put(options);
    }
    catch (Exception excep)
    {
    throw excep;
    }

    }

    Step Three: Create Host Instance and update the adapters.

    We use the assembly in Microsoft.BizTalk.ExplorerOM to create host and host instance.

    Code here:

    View Code
    public static void CreateHost(string HostName, int HostType, string NTGroupName, bool IsHost32BitOnly, bool HostTracking)
    {
    try
    {
    PutOptions options = new PutOptions();
    options.Type = PutType.CreateOnly;

    //create a ManagementClass object and spawn a ManagementObject instance
    ManagementClass objHostSettingClass = new ManagementClass("root\\MicrosoftBizTalkServer", "MSBTS_HostSetting", null);
    ManagementObject objHostSetting = objHostSettingClass.CreateInstance();

    ManagementObject objHostSetting1 = new ManagementObject();
    objHostSetting1.Scope = new ManagementScope("root\\MicrosoftBizTalkServer");

    //define lookup query
    string strQuery = "MSBTS_HostSetting.Name='BizTalkServerApplication'";
    objHostSetting1.Path = new ManagementPath(strQuery);

    //set the properties for the Managementobject
    objHostSetting["Name"] = HostName;
    objHostSetting["HostType"] = HostType;
    if (NTGroupName == "")
    {
    //redefine properties value
    objHostSetting["NTGroupName"] = objHostSetting1["NTGroupName"];
    }
    else
    {
    objHostSetting["NTGroupName"] = NTGroupName;
    }

    objHostSetting["AuthTrusted"] = objHostSetting1["AuthTrusted"];

    objHostSetting["IsHost32BitOnly"] = IsHost32BitOnly;
    objHostSetting["HostTracking"] = HostTracking;

    //create the Managementobject
    objHostSetting.Put(options);
    }
    catch (Exception excep)
    {
    System.Console.WriteLine("CreateHost - " + HostName + " - failed: " + excep.Message);
    }
    }

    public static void CreateHostInstance(string HostName, string username, string password)
    {
    try
    {
    PutOptions options = new PutOptions();
    options.Type = PutType.CreateOnly;

    //create a ManagementClass object and spawn a ManagementObject instance
    ManagementClass objHostClass = new ManagementClass("root\\MicrosoftBizTalkServer", "MSBTS_ServerHost", null);
    ManagementObject objHost = objHostClass.CreateInstance();

    //set the properties for the Managementobject
    objHost["HostName"] = HostName;
    objHost["ServerName"] = System.Environment.MachineName;
    objHost.InvokeMethod("Map", null);

    ManagementClass objHostClass2 = new ManagementClass("root\\MicrosoftBizTalkServer", "MSBTS_HostInstance", null);
    ManagementObject objHostInstance = objHostClass2.CreateInstance();
    objHostInstance["Name"] = "Microsoft BizTalk Server " + System.Environment.MachineName + "" + RuntimeGlobal.BiztalkServerName;

    object[] args = new object[2];
    args[0] = username;
    args[1] = password;

    objHostInstance.InvokeMethod("Install", args);

    }
    catch (Exception excep)
    {
    System.Console.WriteLine("CreateHost - " + HostName + " - failed: " + excep.Message);
    }

    }

    After this, we have to update the host name of the adapter handles:

    View Code
    public static void UpdateHandler(string AdapterName, string HostName, string HostNameToSwitchTo)
    {
    try
    {
    PutOptions options = new PutOptions();
    options.Type = PutType.UpdateOnly;

    //Look for the target WMI Class MSBTS_ReceiveHandler instance
    string strWQL = "SELECT * FROM MSBTS_ReceiveHandler WHERE AdapterName =\"" + AdapterName + "\" AND HostName = \"" + HostName + "\"";
    ManagementObjectSearcher searcherHandler = new ManagementObjectSearcher(new ManagementScope("root\\MicrosoftBizTalkServer"), new WqlObjectQuery(strWQL), null);

    if (searcherHandler.Get().Count > 0)
    foreach (ManagementObject objReceiveHandler in searcherHandler.Get())
    {
    //update host association
    objReceiveHandler["HostNameToSwitchTo"] = HostNameToSwitchTo;
    //update the ManagementObject
    objReceiveHandler.Put(options);
    }

    strWQL = "SELECT * FROM MSBTS_SendHandler2 WHERE AdapterName =\"" + AdapterName + "\" AND HostName = \"" + HostName + "\"";
    searcherHandler = new ManagementObjectSearcher(new ManagementScope("root\\MicrosoftBizTalkServer"), new WqlObjectQuery(strWQL), null);

    if (searcherHandler.Get().Count > 0)
    foreach (ManagementObject objSendHandler in searcherHandler.Get())
    {
    //update host association
    objSendHandler["HostNameToSwitchTo"] = HostNameToSwitchTo;
    //update the ManagementObject
    objSendHandler.Put(options);
    }

    }
    catch (Exception excep)
    {
    System.Console.WriteLine("UpdateReceiveHandler - " + AdapterName + "" + HostName + " - failed: " + excep.Message);
    }
    }


    Last Step: Create the SQL Server DB:

    Code Here:

    View Code
    private void CreateSQLDataBase(string connString, string cmdString)
    {
    SqlConnection myConn = new SqlConnection(connString);

    SqlCommand myCommand ;
    try
    {
    myConn.Open();
    foreach (string command in SplitSqlCommands(cmdString))
    {
    if (command != "")
    {
    myCommand = new SqlCommand(command, myConn);
    myCommand.ExecuteNonQuery();
    }
    }
    MessageBox.Show("DataBase is Created Successfully", "Success");
    }
    catch (System.Exception ex)
    {
    MessageBox.Show(ex.ToString(), "Error");
    }
    finally
    {
    if (myConn.State == ConnectionState.Open)
    {
    myConn.Close();
    }
    }

    }

    private IEnumerable<string> SplitSqlCommands(string commandText)
    {
    IEnumerable<string> commands = commandText.Split(new string[] { "\r\nGO\r\n", "\r\nGo\r\n", "\r\ngo\r\n", "\r\ngO\r\n" },
    StringSplitOptions.None);
    return commands;
    }



    Now, all the prepare works are done. We are ready to import the Biztalk Application.

    To import the msi and install it on the server:

    Code Here:

    View Code
                BTSManagement.StopApplication(APPName);
    Process p = new Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.Verb = "runas";
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.CreateNoWindow = true;
    p.Start();
    string targetPath = System.Environment.GetEnvironmentVariable("BTSINSTALLPATH").ToString();
    p.StandardInput.WriteLine(targetPath.Substring(0, 2));
    p.StandardInput.WriteLine("cd " + targetPath);

    p.StandardInput.WriteLine("BTSTask ImportApp /Package:\"" + MSIPath + "\" /Environment:Default /ApplicationName:" + APPName + "/Overwrite");

    p.StandardInput.WriteLine("exit");

    string strRst = p.StandardOutput.ReadToEnd();
    System.IO.File.WriteAllText(@"C:\BTSImportlog.txt", strRst);
    // if end
    p.Close();

    Process p1 = new Process();
    p1.StartInfo.FileName = "msiexec.exe";
    p1.StartInfo.Verb = "runas";
    p1.StartInfo.Arguments = "/i \"" + MSIPath + "\" /qr";
    p1.StartInfo.CreateNoWindow = false;
    p1.Start();
    p1.WaitForExit();

    BTSManagement.StartApplication("NNA");
    MessageBox.Show("MSI Import finished, Log File at " + @"C:\BTSImportlog.txt", "Information");

    Then import the binding:

    Code Here:

    View Code
                BTSManagement.StopApplication(AppName);
    Process p = new Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.Verb = "runas";
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.CreateNoWindow = true;
    p.Start();
    string targetPath = System.Environment.GetEnvironmentVariable("BTSINSTALLPATH").ToString();
    p.StandardInput.WriteLine(targetPath.Substring(0, 2));
    p.StandardInput.WriteLine("cd " + targetPath);

    p.StandardInput.WriteLine("BTSTask ImportBindings /ApplicationName:" + AppName +" /Source:\"" + bindingPath + "\"");
    p.StandardInput.WriteLine("exit");

    string strRst = p.StandardOutput.ReadToEnd();
    System.IO.File.WriteAllText(@"C:\BTSImportlog.txt", strRst);
    // if end
    p.Close();
    BTSManagement.StartApplication(AppName);
    MessageBox.Show("Binding Import finished, Log File at " + @"C:\BTSImportlog.txt", "Information");

    Then update the ports configuration:

    View Code
    public static void UpdateReceiveLocation(string ReceivePort, string ReceiveLocationName, string Address)
    {
    BtsCatalogExplorer catalog = new BtsCatalogExplorer();
    catalog.ConnectionString = RuntimeGlobal.ConnectString;
    try
    {
    ReceiveLocation loc = catalog.ReceivePorts[ReceivePort].ReceiveLocations[ReceiveLocationName];
    loc.Address = Address;

    // persist changes to BizTalk configuration database
    catalog.SaveChanges();
    }
    catch (Exception e)
    {
    catalog.DiscardChanges();
    throw e;
    }
    }

    public static void UpdateSendPort(string SendPort, string Address)
    {
    BtsCatalogExplorer catalog = new BtsCatalogExplorer();
    catalog.ConnectionString = RuntimeGlobal.ConnectString;
    try
    {
    SendPort myStaticOnewaySendPort = catalog.SendPorts[SendPort];
    myStaticOnewaySendPort.PrimaryTransport.Address = Address;

    // persist changes to BizTalk configuration database
    catalog.SaveChanges();
    }
    catch (Exception e)
    {
    catalog.DiscardChanges();
    throw e;
    }
    }


    To start/Stop the BizTalk Application:

    View Code
    public static void StartApplication(string AppName)
    {
    BtsCatalogExplorer catalog = new BtsCatalogExplorer();
    catalog.ConnectionString = RuntimeGlobal.ConnectString;

    Application app = catalog.Applications[AppName];
    if (app != null)
    {
    app.Stop(ApplicationStopOption.StopAll);
    }
    app.Start(ApplicationStartOption.StartAll);
    }

    public static void StopApplication(string AppName)
    {
    BtsCatalogExplorer catalog = new BtsCatalogExplorer();
    catalog.ConnectionString = RuntimeGlobal.ConnectString;

    Application app = catalog.Applications[AppName];
    if (app != null)
    {
    app.Stop(ApplicationStopOption.StopAll);
    }
    }


    The RuntimeGlobal is here:

    View Code
    public class RuntimeGlobal
    {
    ///<summary>
    /// Query information from BizTalk MgmtDB
    ///</summary>
    ///<param name="strCmd">string strCmd = string.Format("SELECT a.uidGUID, b.OutboundEngineCLSID FROM bts_sendport a,adm_Adapter b WHERE a.nvcName = '{0}' and b.Name = '{1}'", "DynamicSendToDMS", "WCF-Custom");</param>
    ///<returns></returns>
    public static string[] GetBizTalkConfigValue(string strCmd)
    {
    string[] result = null;
    SqlCommand command = new SqlCommand(strCmd, GetConnection())
    {
    CommandType = CommandType.Text,
    CommandTimeout = 60
    };
    SqlDataReader sdr = command.ExecuteReader();
    while (sdr.Read())
    {
    result = new string[sdr.FieldCount];
    for (int i = 0; i < sdr.FieldCount; i++)
    result[i] = sdr[i].ToString();
    break;
    }
    return result;
    }

    private static string m_BtsDBServer;
    private static string m_BtsDBName;

    private static string BiztalkMgmtDbname
    {
    get
    {
    if (m_BtsDBName == null)
    {
    m_BtsDBName = GetBiztalkRegistryKeyValue("MgmtDBName");
    }
    return string.Format(CultureInfo.InvariantCulture, m_BtsDBName, new object[0]);
    }
    }

    public static string BiztalkServerName
    {
    get
    {
    if (m_BtsDBServer == null)
    {
    m_BtsDBServer = GetBiztalkRegistryKeyValue("MgmtDBServer");
    }
    return string.Format(CultureInfo.InvariantCulture, m_BtsDBServer, new object[0]);
    }
    }

    private static string GetBiztalkRegistryKeyValue(string keyName)
    {
    return (string)Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\BizTalk Server\3.0\Administration").GetValue(keyName);
    }

    private static SqlConnection GetConnection()
    {
    SqlConnection connection = new SqlConnection
    {
    ConnectionString = string.Format(CultureInfo.InvariantCulture,
    "Server={0};integrated security=SSPI",
    new object[] { BiztalkServerName })
    };
    connection.Open();
    connection.ChangeDatabase(BiztalkMgmtDbname);
    return connection;
    }

    public static string ConnectString
    {
    get
    {
    return string.Format(CultureInfo.InvariantCulture,
    "Server={0};integrated security=SSPI;Initial Catalog={1}",
    BiztalkServerName,
    BiztalkMgmtDbname);
    }

    }
    }


    Ok, now all the work is done. We add some UI for all the action needed.

    The deployment team then use this to deploythe BizTalk application and everything goes well.

    I think many of the BizTalk guys will meet this so I write it here, and hope it's helpful.

  • 相关阅读:
    动画效果(二)
    动画效果(一)
    高级事件(二)
    高级事件(一)
    事件对象(二)
    事件对象(一)
    使用jquery ajax代替iframe
    SQL语句汇总(终篇)—— 表联接与联接查询
    SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
    SQL语句汇总(二)——数据修改、数据查询
  • 原文地址:https://www.cnblogs.com/JasonLiao/p/2265026.html
Copyright © 2011-2022 走看看