Author Topic: How can I read agent and application configuration in WDE/IWS?  (Read 9578 times)

Offline Gabi

  • Jr. Member
  • **
  • Posts: 64
  • Karma: 0
Re: How can I read agent and application configuration in WDE/IWS?
« Reply #15 on: April 21, 2016, 01:35:56 PM »
[quote author=cavagnaro link=topic=9465.msg42992#msg42992 date=1460401003]
;D Congrats! just a suggestion, try to test always with another app which is not the one on PRD, on CME you just clone the Application you are using on PRD and use that for your tests. Easier to debug ;)

Can you please share your solution code here for reference?
Thanks and good luck!
[/quote]

Sorry, I don't understand. Are you suggesting that I clone the Config Server? Anyway, none of this is in production, I'm just running tests on a demo server while I develop my extension.

Here's the working code. It's a class that keeps a local cache of the application configuration options, and also provides an interface for making requests to the Configuration Server (retrieveConfigXml), which I am using to handle requests from an external application.

I'm not reading the agent configuration yet, that part is left for future work.

[code]
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using Genesyslab.Platform.ApplicationBlocks.Commons.Broker;
using Genesyslab.Platform.Commons.Collections;
using Genesyslab.Platform.Commons.Connection;
using Genesyslab.Platform.Commons.Protocols;
using Genesyslab.Platform.Configuration.Protocols;
using Genesyslab.Platform.Configuration.Protocols.ConfServer;
using Genesyslab.Platform.Configuration.Protocols.ConfServer.Events;
using Genesyslab.Platform.Configuration.Protocols.ConfServer.Requests.Objects;
using Genesyslab.Platform.ApplicationBlocks.Commons.Protocols;
using Genesyslab.Platform.Configuration.Protocols.Types;
using System.Xml.Linq;
using System.Collections;
using Genesyslab.Platform.Commons.Logging;
using Genesyslab.Desktop.Infrastructure.DependencyInjection;
using System.Threading;
using Genesyslab.Desktop.Infrastructure.Configuration;
using Genesyslab.Desktop.Modules.Core.SDK.Configurations;
using Genesyslab.Platform.ApplicationBlocks.ConfigurationObjectModel.Queries;
using Genesyslab.Platform.ApplicationBlocks.ConfigurationObjectModel;
using Genesyslab.Desktop.Modules.Core.Model.Agents;

namespace Genesyslab.Desktop.Modules.ExtensionUtils85.Utils
{
    public class ConfigurationServiceClient : LoggingObject
    {
        protected string appName;

        protected XmlDocument doc = null;

        protected IDictionary<string, IDictionary<string, string>> config;

        private bool objectsRead = false;
       
protected ILogger log;

        protected ConfServerProtocol cfgProtocol;
       
        protected static ConfigurationServiceClient instance;

        public ConfigurationServiceClient(IObjectContainer container)
        {
            this.log = container.Resolve<ILogger>().CreateChildLogger("ConfigurationServiceClient");
            this.appName = container.Resolve<IConfigurationService>().ApplicationName;
            this.cfgProtocol = container.Resolve<IConfigurationService>().ConfigServerProtocol;
        }

        /// <summary>
        /// Initializes the service and stores the configuration options.
        /// </summary>
        /// <param name="container">WDE's object container.</param>
        public static void initialize(IObjectContainer container)
        {
            if (instance == null)
            {
                instance = new ConfigurationServiceClient(container);

                instance.ReadObjects();
            }
        }

        protected IMessage prepareRequestReadObjectsMessage(ICfgQuery query) {
            if (query is CfgXPathBasedQuery)
                return RequestReadObjects2.Create((int)(((CfgXPathBasedQuery) query).ObjectType),((CfgXPathBasedQuery) query).XPath);
            int objType = (int)CfgObjectType.CFGNoObject;
            if (query is ICfgFilterBasedQuery) {
                KeyValueCollection objectFilter = prepareReadObjectsFilter((ICfgFilterBasedQuery) query);
                objType = (int)((ICfgFilterBasedQuery) query).QueryObjectType;
                return RequestReadObjects.Create(objType, objectFilter);
            } else {
                throw new ArgumentException("Unsupported query type.");
            }
        }

protected KeyValueCollection prepareReadObjectsFilter(ICfgFilterBasedQuery query) {
KeyValueCollection objectFilter = new KeyValueCollection();
if (query != null) {
Hashtable filter = query.Filter;
foreach (string key in filter.Keys) {
Object value = filter[key];
if (value is Int64)
{
value = Convert.ToInt32(value);
}
try
{
objectFilter.Add(key, (int)value);
}
catch (Exception)
{
objectFilter.Add(key, value);
}
}
}
return objectFilter;
}

public static ConfigurationServiceClient getInstance()
{
return instance;
}



protected void OnEventError(IMessage theMessage)
{
EventError eventError = theMessage as EventError;
if (eventError == null)
{
log.Error("EventError: null.");
return;
}

log.Error("EventError: " + eventError + "\n");
}

protected void OnEventObjectsSent(IMessage theMessage)
{
EventObjectsSent objectsSent = theMessage as EventObjectsSent;
if (objectsSent == null)
{
log.Debug("EventObjectsSent: null");
return;
}

log.Debug("EventObjectsSent: "
+ objectsSent + "\n");
}

protected void OnEventObjectsRead(IMessage theMessage)
{
log.Debug("Application configuration read.");
EventObjectsRead objects =
(EventObjectsRead)theMessage;
String xml = extractXML(objects);

doc = new XmlDocument();
doc.LoadXml(xml);
log.Debug("Config XML" + xml);
this.objectsRead = true;
}

public string retrieveConfigXml(ICfgQuery query)
{
IMessage request = this.prepareRequestReadObjectsMessage(query);
ConfServerProtocol protocol = getCfgProtocol();
IMessage response = protocol.Request(request);
string xml = "";
if (response is EventObjectsRead)
{
xml = extractXML(response as EventObjectsRead);
}
else if (response is EventError)
{
OnEventError(response);
}
else
{
log.Error("Error on retrieveConfigXml. Response: " + response.ToString());
}
return xml;
}

        protected static string extractXML(EventObjectsRead objects)
        {
            XDocument resultDocument =
                (XDocument)objects.ConfObject;
            String xml = extractXML(resultDocument);
            return xml;
        }

        protected static string extractXML(XDocument document)
        {
            StringBuilder xmlAsText = new StringBuilder();
            StringWriter stringWriter = new StringWriter(xmlAsText);
            XmlTextWriter xmlTextWriter =
                new XmlTextWriter(stringWriter);
            xmlTextWriter.Formatting = Formatting.Indented;

            document.Save(xmlTextWriter);
            String xml = xmlAsText.ToString();
            return xml;
        }

        protected string getAttribute(XmlNode node, string attributeName)
        {
            string res = "null";
            if (node.Attributes[attributeName] != null)
            {
                res = node.Attributes[attributeName].InnerText;
            }
            return res;
        }

        protected string getSectionXML(string sectionName, XmlDocument doc)
        {
            string res = null;
            XmlNode node = getSectionNode(sectionName, doc);
            if (node != null)
            {
                res = node.InnerXml;
            }
            return res;
        }

        protected XmlNode getSectionNode(string sectionName, XmlDocument doc)
        {
            XmlNode res = null;
            foreach (XmlNode node in doc.DocumentElement.ChildNodes)
            {
                foreach (XmlNode innernode in node.ChildNodes)
                {
                    if ("options".Equals(innernode.Name))
                    {
                        foreach (XmlNode optionnode in innernode.ChildNodes)
                        {
                            string key = getAttribute(optionnode, "key");
                            if (key.Equals(sectionName))
                            {
                                res = optionnode;
                            }
                        }
                    }
                }
            }
            return res;
        }

        /// <summary>
        /// Gets a section from the cached application configuration.
        /// </summary>
        /// <param name="sectionName">the name of the section.</param>
        /// <returns>a dictionary with the configuration options for the section.</returns>
        public IDictionary<string, string> getSection(string sectionName)
        {
            if (doc == null)
            {
                ReadObjects();
            }
            IDictionary<string, string> dict;
            if (config.ContainsKey(sectionName))
            {
                dict = config[sectionName];
            }
            else
            {
                dict = new Dictionary<string, string>();
                XmlNode node = getSectionNode(sectionName, doc);
                if (node != null)
                {
                    foreach (XmlNode innernode in node.ChildNodes)
                    {
                        string key = getAttribute(innernode, "key");
                        string value = getAttribute(innernode, "value");
                        dict.Add(key, value);
                    }

                }
                config.Add(sectionName, dict);
            }
            return dict;
        }

       
        /// <summary>
        /// Gets the value of a configuration option from the local cache as a string.
        /// </summary>
        /// <param name="sectionName">the name of the section to read from.</param>
        /// <param name="key">the key for the desired option.</param>
        /// <param name="defaultValue">the default value in case the option is not defined.</param>
        /// <returns>the value for the option (as a string), or the default value if it is undefined.</returns>
        public string requestProperty(string sectionName, string key, string defaultValue)
        {
            if (!objectsRead)
            {
                this.ReadObjects();
            }
            IDictionary<string, string> section = getSection(sectionName);
            return requestProperty(section, key, defaultValue);
        }

        public string requestProperty(IDictionary<string, string> section, string key, string defaultValue)
        {
            string res = null;
            if (section.ContainsKey(key))
            {
                res = section[key];
            }
            if (res == null)
            {
                log.Info("Using default value " + defaultValue + " for option " + key + ".");
                res = defaultValue;
            }
            return res;
        }

       
        /// <summary>
        /// Gets the value of a configuration option from the local cache, if it is a boolean.
        /// </summary>
        /// <param name="sectionName">the name of the section to read from.</param>
        /// <param name="key">the key for the desired option.</param>
        /// <param name="defaultValue">the default value in case the option is not defined.</param>
        /// <returns>the value for the option, or the default value if it is undefined or not a boolean.</returns>
        public bool requestProperty(string sectionName, string key, bool defaultValue)
        {
            bool res = defaultValue;
            string defString = defaultValue ? "true" : "false";
            string value = this.requestProperty(sectionName, key, defString);
            string lowervalue = value.ToLower();
            if ("true".Equals(lowervalue))
            {
                res = true;
            }
            else if ("false".Equals(lowervalue))
            {
                res = false;
            }
            else
            {
                log.Warn("The value for option " + key + " should be boolean, but it is not.");
            }
            return res;
        }

        /// <summary>
        /// Gets the value of a configuration option from the local cache, if it is an integer.
        /// </summary>
        /// <param name="sectionName">the name of the section to read from.</param>
        /// <param name="key">the key for the desired option.</param>
        /// <param name="defaultValue">the default value in case the option is not defined.</param>
        /// <returns>the value for the option, or the default value if it is undefined or not an integer.</returns>
        public int requestProperty(string sectionName, string key, int defaultValue)
        {
            int res = defaultValue;
            string defString = defaultValue.ToString();
            string value = this.requestProperty(sectionName, key, defString);
            try
            {
                res = int.Parse(value);
            }
            catch (Exception ex)
            {
                log.Warn("The value for option " + key + " should be an integer, but it is not.", ex);
                res = defaultValue;
            }
            return res;
        }

        /// <summary>
        /// Updates the local application configuration cache by reading the configuration from the config server.
        /// </summary>
        public void ReadObjects()
        {
//Initialize the dictionary which will store the cached application configuration on demand.
            config = new Dictionary<string, IDictionary<string, string>>();
            KeyValueCollection filterKey = new KeyValueCollection();
            filterKey.Add("name", this.appName);
            RequestReadObjects requestReadObjects =
                RequestReadObjects.Create(
                    (int)CfgObjectType.CFGApplication,
                    filterKey);
            ConfServerProtocol protocol = getCfgProtocol();
            IMessage response = protocol.Request(requestReadObjects);
            if (response is EventObjectsRead)
            {
                OnEventObjectsRead(response);
            }
            else if (response is EventError)
            {
                OnEventError(response);
            }
            else {
                log.Error("Response: "+response.ToString());
            }
        }

        protected static ConfServerProtocol getCfgProtocol()
        {
            return this.cfgProtocol;
        }

        public string getApplicationName()
        {
            return this.appName;
        }
    }
}
[/code]
« Last Edit: April 21, 2016, 02:00:38 PM by Gabi »