Clarity

  • 1.  XOG .NET interface retrieve the XOGOutput

    Posted 12-15-2015 03:04 AM

    Hi,

     

    I'v created a .NET interface using webservice with PPM 14.3. It works fine but I would like to handle issues.

    Currently I do not get the XOGOutput tag back in fact nothing at all which is very difficult to handle possible errors.

     

    Created a .NET project add the webreference.

    It works transactions are xogged, but no result is returned:

     

    .NET Code

    -------------------------------------------------------------------------------------------------------

       

                XmlDocument doc = new XmlDocument();

                doc.LoadXml(soapMessage);

          

          

                XOGALL.Auth objAuth = new XOGALL.Auth();

                XOGALL.Login loginXOG = new XOGALL.Login();

                loginXOG.TenantID = ConfigurationManager.AppSettings["SoapMethod"];

                loginXOG.Username = ConfigurationManager.AppSettings["SoapUserId"];

                loginXOG.Password = ph.Decrypt(ConfigurationManager.AppSettings["SoapPassword"].ToString()).ToString();

                XOGALL.AllObjectsPortClient tranReq = new XOGALL.AllObjectsPortClient();

          

                try

                {

                    objAuth.Username = ConfigurationManager.AppSettings["SoapUserId"];

                    objAuth.Password = ConfigurationManager.AppSettings["SoapPassword"];

                 

                    if (sessionid == "")

                    {

                        sessionid = tranReq.Login(loginXOG);

                        objAuth.SessionID = sessionid;

                    }

     

     

                   XmlElement XOGOutput;

                    XOGOutput = tranReq.WriteTransaction(objAuth, doc.DocumentElement);

                  -- The XOGOutput is always null !!!! ;-(

     

                    tranReq.Close();

     

                }

     

    kind regards,

     

    Elwin

     

    Message was edited by: Elwin van BOMMEL



  • 2.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 12-28-2015 01:09 PM

    What I find interesting is that on my 14.3 system the WriteTransaction doesn’t have a method signature like this: (objAuth, doc.DocumentElement);

     

     

    I attached the AuthValue in a CaLogin function within a Helper class.

     

    public Boolean CaLogin()
    {
        var clarityAllOjbectsUri = new UriBuilder(ObjectsService.Url)
            {
                Host = HostName
            };
    
        try
        {
            ObjectsService.Url = clarityAllOjbectsUri.ToString();
    
            var login = new ClarityAllObjects.Login {Username = UserName, Password = Password};
            var auth = new ClarityAllObjects.Auth {SessionID = ObjectsService.Login(login)};
            ObjectsService.AuthValue = auth;
    
            if (auth.SessionID.IsNullOrEmpty())
            {
                NLogger.Error("Unable to login to {0} using {1}", HostName, UserName);
            }
        }
        catch (Exception ex)
        {
            NLogger.Error("Unable to login to {0} using {1}", HostName, UserName);
            NLogger.Error(ex.Message);
            throw;
        }
        IsLoggedIn = true;
        return IsLoggedIn;
    }
    

     

    This I then build up my soap document in an object / serialize and pull off the root element for the input to one of the  AllObjects methods.

     

    var xog = NewNikuBus(instanceType.objectCode);
    try
    {
        var controlObject = QueryControlCode(instanceType, spisLookupRecord);
        if (controlObject == null)
        {
            xog.Header.args = new List<args> { new args { name = "overrideAutoNumbering", value = "false" } };
        }
        else
        {
            instanceType.instanceCode = controlObject.code;
            var code = instanceType.CustomInformation.ColumnValue.Find(x => x.name.IsEqualTo("code", true));
            if (code != null) code.Value = controlObject.code;
        }
        xog.customObjectInstances[0].instance.Add(instanceType);
        xog.XOGOutput = null;
    
        var xogString = xog.SerializeObject();
        var writeCustomObject = GetElement(xogString);
        var responseElement = ObjectsService.WriteCustomObjectInstance(writeCustomObject);
        var responseCustom = GetCustomInstanceResponse(responseElement);
        if (responseCustom.Statistics.failureRecords != 0)
        {
            NLogger.Error(responseElement.OuterXml);
            return false;
        }
    

     

     

    Where GetCustomInstanceResponse looks like this:

     

    private static XOGOutput GetCustomInstanceResponse(XmlNode responseWriteCustomObject)
    {
        XOGOutput retVal = null;
        try
        {
            retVal = XOGOutput.Deserialize(responseWriteCustomObject.OuterXml);
        }
        catch (Exception ex)
        {
            NLogger.Error(ex.Message);
        }
        return retVal;
    }
    

    Do you have an overloaded method?

     

    V/r,

    Gene



  • 3.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 12-28-2015 02:31 PM

    I'm not sure what is going on with your proxy classes, this also comes from 14.3 and seems correct:

     



  • 4.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 12-28-2015 04:38 PM

    Here is my system version which is an OnDemand system.

     

     

    So are you adding the reference as a service reference or a web reference?  I have mine as a web reference.  I suspect you are using wcf.

     

     

     

     

    V/r,

    Gene



  • 5.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 12-28-2015 05:21 PM

    Yes, as a Service Reference - just as a first preference and I believe either approach is just as correct to use for Clarity's purposes.



  • 6.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 12-28-2015 02:26 PM

    I have near-identical code that works for me.

     

    Key differences:

    1) I do not set the TenantID property.  You aren't in a multi-tenant environment (nobody is at this time).

    2) I do not re-include the username/password into the objAuth instance, I store only the session ID in it.  Whilst not necessarily critical, it might save on unnecessary additional sessions being created.

    3) I didn't use 'transaction write' since my system wasn't ready to receive that request, so I went with a 'project read' test instead.

     

    Things to check:

    1) Does your XOG user have permissions to call transaction XOG actions?  E.g. "Transaction - XOG Access" rights?

    2) What was the contents of your soapMessage variable, and did this content work directly with the XOG client using the same username/password?

    3) How about with a tool like SoapUI, and if so, what was the full response received from the WriteTransaction call?

    4) Is the SOAP endpoint address defined correctly when you go to http[s]://yourserver[:port]/niku/wsdl/Object/AllObjects and does it correctly look like http[s]://yourserver[:port]/niku/xog ?

     

    Source:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;

    namespace xogoutput
    {
        class Program
        {
            static void Main(string[] args)
            {
                String soapMessage = @"<NikuDataBus xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""../xsd/nikuxog_read.xsd"">
      <Header version=""6.0.11"" action=""read"" objectType=""project"" externalSource=""NIKU"">
        <!-- you change the order by simply swap 1 and 2 number in the name attribute -->
        <args name=""order_by_1"" value=""name""/>
        <args name=""order_by_2"" value=""projectID""/>
        <args name=""include_tasks"" value=""true""/>
        <args name=""include_dependencies"" value=""true""/>
        <args name=""include_subprojects"" value=""true""/>
        <args name=""include_resources"" value=""true""/>
        <args name=""include_baselines"" value=""true""/>
        <args name=""include_allocations"" value=""true""/>
        <args name=""include_estimates"" value=""true""/>
        <args name=""include_actuals"" value=""true""/>
        <args name=""include_custom"" value=""true""/>
        <args name=""include_burdening"" value=""false""/>
      </Header>
      <Query>
          <Filter name=""projectID"" criteria=""EQUALS"">cf1</Filter>
      </Query>
    </NikuDataBus>";

     

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(soapMessage);

     

                XOGALL.Auth objAuth = new XOGALL.Auth();
                XOGALL.Login loginXOG = new XOGALL.Login();

     

                loginXOG.Username = "admin";
                loginXOG.Password = "admin";

     

                XOGALL.AllObjectsPortClient tranReq = new XOGALL.AllObjectsPortClient();
                objAuth.SessionID = tranReq.Login(loginXOG);

     

                System.Console.WriteLine("Login session ID returned: " + objAuth.SessionID);

     

                if (objAuth.SessionID != null && !objAuth.Equals(""))
                {
                    XmlElement x = tranReq.ReadProject(objAuth, doc.DocumentElement);
                    System.Console.WriteLine(x.GetElementsByTagName("Statistics").Item(0).OuterXml);
                    try
                    {
                        tranReq.Logout(objAuth.SessionID);
                    }
                    catch (System.ServiceModel.ProtocolException e)
                    {
                        // Happens during logout since a valid http response was provided but none was expected
                        // Reference: http://stackoverflow.com/questions/643241/problem-with-wcf-client-calling-one-way-operation
                    }
                }

     

            }
        }
    }

     

    Results:

     

    My console project just contained a Service Reference to my http://server/niku/wsdl/Object/AllObjects as 'XOGALL' (presumably the same as yours does), the rest is all above.



  • 7.  Re: XOG .NET interface retrieve the XOGOutput

    Posted 01-04-2016 02:58 AM

    Hi,

     

    Back from holiday, In reaction of your questions:

     

    Key differences:

    1) I do not set the TenantID property.  You aren't in a multi-tenant environment (nobody is at this time). --> removed no result

    2) I do not re-include the username/password into the objAuth instance, I store only the session ID in it.  Whilst not necessarily critical, it might save on unnecessary additional sessions being created. --> removed no result

    3) I didn't use 'transaction write' since my system wasn't ready to receive that request, so I went with a 'project read' test instead.

     

    Things to check:

    1) Does your XOG user have permissions to call transaction XOG actions?  E.g. "Transaction - XOG Access" rights? --> All rights, so no issues regarding authorisation

    2) What was the contents of your soapMessage variable, and did this content work directly with the XOG client using the same username/password? --> via cmd line no issues, with same soapMessage, got the xogoutput back.

    3) How about with a tool like SoapUI, and if so, what was the full response received from the WriteTransaction call? --> works fine via SOAP UI get a result back.

    4) Is the SOAP endpoint address defined correctly when you go to http[s]://yourserver[:port]/niku/wsdl/Object/AllObjects and does it correctly look like http[s]://yourserver[:port]/niku/xog ? --> yes, it works all fine only no xogOutput.

     

    Regarding Reference, I got both working with service and web reference but both no XOGOutput. The transactions are xogged in but no output via Dotnet via otherways I get the output.

     

     

    I Rebuild the example and the readworks, and the write for resources also:

     

      {

                String soapMessage = @"<NikuDataBus xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""../xsd/nikuxog_read.xsd"">

      <Header version=""6.0.11"" action=""read"" objectType=""project"" externalSource=""NIKU"">

        <!-- you change the order by simply swap 1 and 2 number in the name attribute -->

        <args name=""order_by_1"" value=""name""/>

        <args name=""order_by_2"" value=""projectID""/>

        <args name=""include_tasks"" value=""true""/>

        <args name=""include_dependencies"" value=""true""/>

        <args name=""include_subprojects"" value=""true""/>

        <args name=""include_resources"" value=""true""/>

        <args name=""include_baselines"" value=""true""/>

        <args name=""include_allocations"" value=""true""/>

        <args name=""include_estimates"" value=""true""/>

        <args name=""include_actuals"" value=""true""/>

        <args name=""include_custom"" value=""true""/>

        <args name=""include_burdening"" value=""false""/>

      </Header>

      <Query>

          <Filter name=""projectID"" criteria=""EQUALS"">cf1</Filter>

      </Query>

    </NikuDataBus>";

     

     

                String soapMessage1 = @"<NikuDataBus xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:noNamespaceSchemaLocation=""../xsd/nikuxog_read.xsd"">

      <Header version=""6.0.11"" action=""write"" objectType=""resource"" externalSource=""NIKU"">

          </Header>

      <Resources>

          <Resource entityCode=""entity"" externalId="" "" includeInDatamart=""true"" isActive=""true"" isExternal=""false"" resourceId=""EXP_08"" resourceType=""EXPENSE"">

    </Resource>

    </Resources>

    </NikuDataBus>";

     

                XmlDocument doc = new XmlDocument();

                doc.LoadXml(soapMessage1);

     

                XOGALL.Auth objAuth = new XOGALL.Auth();

                XOGALL.Login loginXOG = new XOGALL.Login();

     

                loginXOG.Username = "admin";

                loginXOG.Password = "admin";

     

                XOGALL.AllObjectsPortClient tranReq = new XOGALL.AllObjectsPortClient();

                objAuth.SessionID = tranReq.Login(loginXOG);

     

                System.Console.WriteLine("Login session ID returned: " + objAuth.SessionID);

     

                if (objAuth.SessionID != null && !objAuth.Equals(""))

                {

                    XmlElement x = tranReq.WriteResource(objAuth, doc.DocumentElement);

                    System.Console.WriteLine(x.GetElementsByTagName("Statistics").Item(0).OuterXml);

                    try

                    {

                        tranReq.Logout(objAuth.SessionID);

                    }

                    catch (System.ServiceModel.ProtocolException e)

                    {

                        // Happens during logout since a valid http response was provided but none was expected

                        // Reference: http://stackoverflow.com/questions/643241/problem-with-wcf-client-calling-one-way-operation

                    }

                }

     

            }



  • 8.  Re: XOG .NET interface retrieve the XOGOutput
    Best Answer

    Posted 01-04-2016 04:43 AM

    SOLVED, :-)

     

    I reused an XSLT, and the xog went well as mentioned before but due some tags it blocks the results part of the XOG.

     

    I changed my xslt and removed the tags:

      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

          <soap:Body>

            <NikuDataBus xsi:noNamespaceSchemaLocation="../xsd/nikuxog_transaction.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

      

    Thanks for the input!