axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bill Treuman" <Bill.Treu...@CARQUEST.com>
Subject RE: All Methods in ServiceSkeleton Generated by WSDL2Java.bat with Void Return Types
Date Fri, 06 Apr 2007 11:33:55 GMT
I'm afraid that still doesn't work - or at least not entirely.  All service
skeleton methods are now being populated, which is an improvement.  However,
I'm getting the following stack trace:
       [java] 'com.carquest.ws.testvehicle.test.TestClient'
       [java]
       [java] The ' characters around the executable and arguments are
       [java] not part of the command.
       [java] In TestClient.testAcesOptions, attribute: empty Attribute
       [java]    and array.length: 3
       [java]    id: 21, description: First type of make
       [java]    id: 22, description: Second type of make
       [java]    id: 23, description: Third type of make
       [java]
       [java] Entering TestClient.testFindVehicle
       [java] In TestClient.testFindVehicle, will now display some debugging
information
       [java]    - debuggingVehicle.getVehicle returns: 77
       [java]    - debuggingVehicle.getMake returns: 99
       [java]    - debuggingVehicle.getYear returns: 88
       [java] Display of findVehicle debugging information
completed -------------------
       [java] In TestClient.testFindVehicle, ready to invoke
stub.findVehicle

       [java] java.lang.NullPointerException
       [java]     at
com.ctc.wstx.sw.BaseNsStreamWriter.doWriteDefaultNs(BaseNsStreamWriter.java:
528)
       [java]     at
com.ctc.wstx.sw.SimpleNsStreamWriter.writeDefaultNamespace(SimpleNsStreamWri
ter.java:111)
       [java]     at
com.ctc.wstx.sw.SimpleNsStreamWriter.writeNamespace(SimpleNsStreamWriter.jav
a:119)
       [java]     at
org.apache.axiom.om.impl.MTOMXMLStreamWriter.writeNamespace(MTOMXMLStreamWri
ter.java:146)
       [java]     at
org.apache.axiom.om.impl.serialize.StreamingOMSerializer.serializeElement(St
reamingOMSerializer.java:
  243)
       [java]     at
org.apache.axiom.om.impl.serialize.StreamingOMSerializer.serializeNode(Strea
mingOMSerializer.java:76)

       [java]     at
org.apache.axiom.om.impl.serialize.StreamingOMSerializer.serialize(Streaming
OMSerializer.java:59)
       [java]     at
org.apache.axiom.om.impl.util.OMSerializerUtil.serializeByPullStream(OMSeria
lizerUtil.java:473)
       [java]     at
org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.
java:823)
       [java]     at
org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMEl
ementImpl.java:848)
       [java]     at
org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.
java:819)
       [java]     at
org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvel
opeImpl.java:180)
       [java]     at
org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMEl
ementImpl.java:848)
       [java]     at
org.apache.axiom.om.impl.llom.OMNodeImpl.serializeAndConsume(OMNodeImpl.java
:419)
       [java]     at
org.apache.axis2.transport.http.SOAPOverHTTPSender$AxisSOAPRequestEntity.han
dleOMOutput(SOAPOverHTTPS
  ender.java:190)
       [java]     at
org.apache.axis2.transport.http.SOAPOverHTTPSender$AxisSOAPRequestEntity.wri
teRequest(SOAPOverHTTPSen
  der.java:232)
       [java]     at
org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody
(EntityEnclosingMethod.ja
  va:495)
       [java]     at
org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.jav
a:1973)
       [java]     at
org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993
)
       [java]     at
org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethod
Director.java:397)
       [java]     at
org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDir
ector.java:170)
       [java]     at
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
       [java]     at
org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
       [java]     at
org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTT
PSender.java:541)
       [java]     at
org.apache.axis2.transport.http.SOAPOverHTTPSender.send(SOAPOverHTTPSender.j
ava:119)
       [java]     at
org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithC
ommons(CommonsHTTPTranspo
  rtSender.java:335)
       [java]     at
org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTT
PTransportSender.java:204
  )
       [java]
       [java]     at
org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:674)
       [java]
       [java]     at
org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperatio
n.java:237)
       [java]
       [java]     at
org.apache.axis2.description.OutInAxisOperationClient.execute(OutInAxisOpera
tion.java:202)
       [java]
       [java]     at
com.carquest.ws.testvehicle.TestVehicleServiceStub.findVehicle(TestVehicleSe
rviceStub.java:483)
       [java]     at
com.carquest.ws.testvehicle.test.TestClient.testFindVehicle(TestClient.java:
113)
       [java]     at
com.carquest.ws.testvehicle.test.TestClient.main(TestClient.java:37)

  BUILD SUCCESSFUL-----Original Message-----

  Here is the test client method which invokes stub.findVehicle(), which
then causes an exception to be thrown.

      public static void testFindVehicle(TestVehicleServiceStub stub){
          try{
              System.out.println("\nEntering TestClient.testFindVehicle");

              FindVehicleDocument req =
FindVehicleDocument.Factory.newInstance();
              FindVehicleDocument.FindVehicle data =
                  req.addNewFindVehicle();

     XMLInputFactory factory = XMLInputFactory.newInstance();
     XMLStreamReader reader = factory.createXMLStreamReader(new
StringReader("<vehicle></vehicle>"));

     Vehicle initialVehicle = Vehicle.Factory.parse(reader);

              //Vehicle initialVehicle = data.getVehicle();
     initialVehicle.setVehicle(new NonNegativeInteger("77") );
     initialVehicle.setYear(new NonNegativeInteger("88") );
     initialVehicle.setMake(new NonNegativeInteger("99") );

              data.setVehicle(initialVehicle);

              data.setAttribute("make");

              System.out.println("In TestClient.testFindVehicle, will now
display some debugging information");

              //------------------------------------------------------------
---------------------------------
              Vehicle debuggingVehicle = data.getVehicle();

              BigInteger vehicleId = debuggingVehicle.getVehicle();
              BigInteger yearId = debuggingVehicle.getYear();
              BigInteger makeId = debuggingVehicle.getMake();

     System.out.println("   - debuggingVehicle.getVehicle returns: " +
debuggingVehicle.getVehicle() );
     System.out.println("   - debuggingVehicle.getMake returns: " +
debuggingVehicle.getMake() );
     System.out.println("   - debuggingVehicle.getYear returns: " +
debuggingVehicle.getYear() );

              System.out.println("Display of findVehicle debugging
information completed -------------------");
              //------------------------------------------------------------
---------------------------------

              System.out.println("In TestClient.testFindVehicle, ready to
invoke stub.findVehicle");
              FindVehicleResponseDocument res = stub.findVehicle(req);
//Exception thrown within this call !!!

              FindVehicleResponseDocument.FindVehicleResponse response =
res.getFindVehicleResponse();
              AcesOptions acesOptions = response.getAcesOptions();
              Vehicle returnedVehicle = response.getVehicle();
              if (returnedVehicle == null)  {
               System.out.println("In TestClient.testFindVehicle,
returnedVehicle == null");
     }

              String attribute = acesOptions.getAttribute();
              System.out.println("In TestClient.testFindVehicle, attribute:
" + attribute);

              AcesOption[] array = acesOptions.getOptionArray();
              System.out.println("   and array.length: " + array.length);
              for (int i=0; i<array.length;i++)  {
      AcesOption option = array[i];
               System.out.println("   id: " + option.getId() + ",
description: " + option.getDescription() );
     }

     System.out.println("   and returnedVehicle.getVehicle returns: " +
returnedVehicle.getVehicle() );
     System.out.println("   and returnedVehicle.getMake returns: " +
returnedVehicle.getMake() );
     System.out.println("   and returnedVehicle.getYear returns: " +
returnedVehicle.getYear() );

          } catch(Exception e){
              e.printStackTrace();
              System.out.println("\n\n\n");
          }
      }

  Thanks and regards.

  [Bill Treuman]


  From: Amila Suriarachchi [mailto:amilasuriarachchi@gmail.com]
  Sent: Friday, April 06, 2007 2:36 AM
  To: axis-user@ws.apache.org; Bill.Treuman@carquest.com
  Subject: Re: All Methods in ServiceSkeleton Generated by WSDL2Java.bat
with Void Return Types


  remove
  <wsdl:operation name="findVehicle">

       <wsdlsoap:operation soapAction="AcesOptions"/>

       <wsdl:input name="findVehicle">
         <wsdlsoap:body use="literal"/>
       </wsdl:input>

       <wsdl:output name="findVehicleResponse">
         <wsdlsoap:body use="literal"/>
       </wsdl:output>

     </wsdl:operation>

  names from here as well as follows

  <wsdl:operation name="findVehicle">

       <wsdlsoap:operation soapAction="AcesOptions"/>

       <wsdl:input >
         <wsdlsoap:body use="literal"/>
       </wsdl:input>

       <wsdl:output>
         <wsdlsoap:body use="literal"/>
       </wsdl:output>

     </wsdl:operation>





  On 4/5/07, Bill Treuman <Bill.Treuman@carquest.com> wrote:
    Thank yo very much, Amila.  This change has worked great for three of
the four web service methods.  But the fourth method (in the original wsdl,
included below), which follows a somewhat different naming convention, still
causes an empty method which takes no parameter and returns void to be
included in the xyzServiceSkeleton module.  Here are what I believe are the
relevant portions of the wsdl:


          <element name="findVehicle">
            <complexType>
              <sequence>
                <element name="vehicle" type="tns:Vehicle"/>
                <element name="attribute" type="string"/>
              </sequence>
            </complexType>
          </element>

          <element name="findVehicleResponse">
            <complexType>
              <sequence>
                <element name="acesOptions" type="tns:AcesOptions"/>
                <element name="vehicle" type="tns:Vehicle"/>
              </sequence>
            </complexType>
          </element>

      <wsdl:message name="findVehicleRequestMessage">
        <wsdl:part element="wns:findVehicle" name="input"/>
      </wsdl:message>
      <wsdl:message name="findVehicleResponseMessage">
        <wsdl:part element="wns:findVehicleResponse" name="output"/>
      </wsdl:message>

        <wsdl:operation name="findVehicle"  parameterOrder="input">
          <wsdl:input message="wns:findVehicleRequestMessage"/>
<!--name attribute removed -->
          <wsdl:output message="wns:findVehicleResponseMessage"/>
<!--name attribute removed -->
        </wsdl:operation>


    Thanks very much again. . . Bill
      -----Original Message-----
      From: Amila Suriarachchi [mailto:amilasuriarachchi@gmail.com]
      Sent: Thursday, April 05, 2007 5:35 AM
      To: axis-user@ws.apache.org; Bill.Treuman@carquest.com
      Subject: Re: All Methods in ServiceSkeleton Generated by WSDL2Java.bat
with Void Return Types


      hi,
      in your operations you have specified the input name as it is in the
Message name

      <wsdl:operation name="VehicleWithIdPlusTenThousand"
parameterOrder="input">

           <wsdl:input
message="wns:VehicleWithIdPlusTenThousandRequestMessage"
                       name="VehicleWithIdPlusTenThousandRequestMessage"/>
           <wsdl:output
message="wns:VehicleWithIdPlusTenThousandResponseMessage"
                        name="VehicleWithIdPlusTenThousandResponseMessage"/>
         </wsdl:operation>

      here message name (VehicleWithIdPlus
      TenThousandRequestMessage) and the input name
(VehicleWithIdPlusTenThou
      sandRequestMessage) are equeal.

      In this case wsdl4j set null to wsdlmessage. I am not sure this is
wrong with the wsdl spec. But removing input and output message names would
make it fine.

      <wsdl:operation name="VehicleWithIdPlusTenThousand"
parameterOrder="input">

           <wsdl:input
message="wns:VehicleWithIdPlusTenThousandRequestMessage" />
           <wsdl:output
message="wns:VehicleWithIdPlusTenThousandResponseMessage"  />
         </wsdl:operation>








      On 4/4/07, Bill Treuman <Bill.Treuman@carquest.com > wrote:
        I'm using wsdl2java.bat to generate the Axis2 server-side, as
follows:

        wsdl2java -uri  testVehicle.wsdl -p com.carquest.ws.testvehicle -o
        server -s -ss -sd -d adb -wv 1.1

        Oddly, in the generated file xyzServiceSkeleton.java, every
generated method
        has a void return type and takes no input arguments.  Likewise, in
the
        generated file xyzServiceMessageReceiverInOut.java, every referenced
method
        uses getDefaultEnvelope( ).  Here is an example of the generated
code in the
        latter file:

        //doc style
        skel.AcesOptions();
        envelope = getSOAPFactory(msgContext).getDefaultEnvelope();

        When I generate your sample service and client, from Axis2UserGuide,
the
        proper argument values and return types are included, and the code
in the
        generated MessageReceiverInOut reflects this.

        I presume there must be some problem in my wsdl file, but I can't
find it.
        The entire contents of testVehicle.wsdl follows.  What am I missing?

        Thank you very much.
        --------------------------------------------------------------------
---

        <?xml version="1.0" encoding="UTF-8"?>
        <wsdl:definitions
        targetNamespace="http://ws.carquest.com/2006/services/vehicle "
            xmlns:wns="http://ws.carquest.com/2006/services/vehicle"
            xmlns:tns="http://ws.carquest.com/2006/types/vehicle "
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:wsdlsoap=" http://schemas.xmlsoap.org/wsdl/soap/ ">
          <wsdl:types>

            <schema elementFormDefault="qualified"
                targetNamespace="http://ws.carquest.com/2006/services/vehicl
e "
                xmlns="http://www.w3.org/2001/XMLSchema">

              <!--
              This wsdl is used for my initial XmlBeans test.
              There is no double-wrapping of any request or response soap
element.
              The xxxServiceSkeleton.java module is generated by WSDL2Java.
(The
        generated
                methods contain empty method bodies, which must be populated
with
        the
                desired functionality).
              The operation name in the <portType> section becomes the name
of the
        method
                in xxxServiceSkeleton.java.
              The request element name such as
VehicleWithIdPlusTenThousandRequest
        directly below
                becomes the (only) parameter name in the
xxxServiceSkeleton.java
        method.  Each
                method generated by WSDL2Java receives one and only one
parameter.
              The response element name such as
VehicleWithIdPlusTenThousandResponse
        directly
                below becomes the return type from the
xxxServiceSkeleton.java
        method (unless
                the method returns void, when there is no response element
below).
              The interior elements below such as componentName and vehicle
can be
        accessed
                via get/set methods in the parameter type, e.g.
                VehicleWithIdPlusTenThousandRequest.getComponentname().
              Likewise multiple interior elements in the method response
type can be
        accessed
                via code such as . . .
              The request and response element names are both present in the
        corresponding soap
                messages, directly below <soapenv:Body>.  So are the
interior
        element names such
                as echoString in the request and response above.  These
interior
        elements are
                direct children of the request or response soap elements.
              -->

              <element name="VehicleWithIdPlusTenThousandRequest">
                <complexType>
                  <sequence>
                    <element name="componentName" type="string"/>
                    <element name="vehicle" type="tns:Vehicle"/>
                  </sequence>
                </complexType>
              </element>
              <element name="VehicleWithIdPlusTenThousandResponse">
                <complexType>
                  <sequence>
                    <element name="vehicle" type="tns:Vehicle"/>
                  </sequence>
                </complexType>
              </element>

              <element name="AcesAttributeRequest">
                <complexType>
                  <sequence />
                </complexType>
              </element>
              <element name="AcesAttributeResponse">
                <complexType>
                  <sequence>
                    <element name="acesAttribute" type="tns:AcesAttribute"/>
                  </sequence>
                </complexType>
              </element>

              <element name="AcesOptionsRequest">
                <complexType>
                  <sequence>
                    <element name="id" type="string"/>
                  </sequence>
                </complexType>
              </element>
              <element name="AcesOptionsResponse">
                <complexType>
                  <sequence>
                    <element name="AcesOptionsBlock"
type="tns:AcesOptions"/>
                  </sequence>
                </complexType>
              </element>

              <element name="findVehicle">
                <complexType>
                  <sequence>
                    <element name="vehicle" type="tns:Vehicle"/>
                    <element name="attribute" type="string"/>
                  </sequence>
                </complexType>
              </element>

              <element name="findVehicleResponse">
                <complexType>
                  <sequence>
                    <element name="acesOptions" type="tns:AcesOptions"/>
                    <element name="vehicle" type="tns:Vehicle"/>
                  </sequence>
                </complexType>
              </element>

            </schema>


            <!-- Note the schema shown above is for services/vehicle. -->
            <!-- The second schema shown below is for types/vehicle. -->

            <schema elementFormDefault="qualified"
                targetNamespace="http://ws.carquest.com/2006/types/vehicle "
                xmlns=" http://www.w3.org/2001/XMLSchema">

              <complexType name="Vehicle">
                <sequence>
                  <element name="vehicle" type="nonNegativeInteger"
minOccurs="0"/>
                  <element name="year" type="nonNegativeInteger"
minOccurs="0"/>
                  <element name="make" type="nonNegativeInteger"
minOccurs="0"/>
                  <element name="model" type="nonNegativeInteger"
minOccurs="0"/>
                  <element name="submodel" type="nonNegativeInteger"
minOccurs="0"/>
                  <element name="region" type="nonNegativeInteger"
minOccurs="0"/>

                  <element name="bedConfig" type="nonNegativeInteger"
        minOccurs="0"/>
                  <element name="bedLength" type="nonNegativeInteger"
        minOccurs="0"/>
                  <element name="bedType" type="nonNegativeInteger"
minOccurs="0"/>

                </sequence>
              </complexType>

              <complexType name="AcesAttribute">
                <sequence>
                  <element name="option" type="string"/>
                </sequence>
              </complexType>

              <complexType name="AcesOption">
                <sequence>
                  <element name="id" type="nonNegativeInteger"/>
                  <element name="description" type="string"/>
                </sequence>
              </complexType>

              <complexType name="AcesOptions">
                <sequence>
                  <element name="attribute" type="string"/>
                  <element name="option" type="tns:AcesOption"
        maxOccurs="unbounded"/>
                </sequence>
              </complexType>

            </schema>

          </wsdl:types>


          <wsdl:message name="VehicleWithIdPlusTenThousandRequestMessage">
            <wsdl:part element="wns:VehicleWithIdPlusTenThousandRequest"
        name="input"/>
          </wsdl:message>
          <wsdl:message name="VehicleWithIdPlusTenThousandResponseMessage">
            <wsdl:part element="wns:VehicleWithIdPlusTenThousandResponse"
        name="output"/>
          </wsdl:message>

          <wsdl:message name="AcesAttributeRequestMessage">
            <wsdl:part element="wns:AcesAttributeRequest" name="input"/>
          </wsdl:message>
          <wsdl:message name="AcesAttributeResponseMessage">
            <wsdl:part element="wns:AcesAttributeResponse" name="output"/>
          </wsdl:message>

          <wsdl:message name="AcesOptionsRequestMessage">
            <wsdl:part element="wns:AcesOptionsRequest" name="input"/>
          </wsdl:message>
          <wsdl:message name="AcesOptionsResponseMessage">
            <wsdl:part element="wns:AcesOptionsResponse" name="output"/>
          </wsdl:message>

          <wsdl:message name="findVehicleRequestMessage">
            <wsdl:part element="wns:findVehicle" name="input"/>
          </wsdl:message>
          <wsdl:message name="findVehicleResponseMessage">
            <wsdl:part element="wns:findVehicleResponse" name="output"/>
          </wsdl:message>


          <wsdl:portType name="TestVehiclePortType">

            <wsdl:operation name="VehicleWithIdPlusTenThousand"
        parameterOrder="input">
              <wsdl:input
message="wns:VehicleWithIdPlusTenThousandRequestMessage"
                          name="VehicleWithIdPlusTenThousandRequestMessage"/
>
              <wsdl:output
message="wns:VehicleWithIdPlusTenThousandResponseMessage"
                           name="VehicleWithIdPlusTenThousandResponseMessage
"/>
            </wsdl:operation>

            <wsdl:operation name="AcesAttribute"  parameterOrder="input">
              <wsdl:input message="wns:AcesAttributeRequestMessage"
                          name="AcesAttributeRequestMessage"/>
              <wsdl:output message="wns:AcesAttributeResponseMessage"
                           name="AcesAttributeResponseMessage"/>
            </wsdl:operation>

            <wsdl:operation name="AcesOptions"  parameterOrder="input">
              <wsdl:input message="wns:AcesOptionsRequestMessage"
                          name="AcesOptionsRequestMessage"/>
              <wsdl:output message="wns:AcesOptionsResponseMessage"
                           name="AcesOptionsResponseMessage"/>
            </wsdl:operation>

            <wsdl:operation name="findVehicle"  parameterOrder="input">
              <wsdl:input message="wns:findVehicleRequestMessage"
                          name="findVehicleRequestMessage"/>
              <wsdl:output message="wns:findVehicleResponseMessage"
                           name="findVehicleResponseMessage"/>
            </wsdl:operation>

          </wsdl:portType>

          <wsdl:binding name="TestVehicleSoapBinding"
        type="wns:TestVehiclePortType">

            <wsdlsoap:binding style="document"
        transport=" http://schemas.xmlsoap.org/soap/http"/>

            <wsdl:operation name="VehicleWithIdPlusTenThousand">

              <wsdlsoap:operation
soapAction="VehicleWithIdPlusTenThousand"/>

              <wsdl:input name="VehicleWithIdPlusTenThousandRequest">
                <wsdlsoap:body use="literal"/>
              </wsdl:input>

              <wsdl:output name="VehicleWithIdPlusTenThousandResponse">
                <wsdlsoap:body use="literal"/>
              </wsdl:output>

            </wsdl:operation>

            <wsdl:operation name="AcesAttribute">

              <wsdlsoap:operation soapAction="AcesAttribute"/>

              <wsdl:input name="AcesAttributeRequest">
                <wsdlsoap:body use="literal"/>
              </wsdl:input>

              <wsdl:output name="AcesAttributeResponse">
                <wsdlsoap:body use="literal"/>
              </wsdl:output>

            </wsdl:operation>

            <wsdl:operation name="AcesOptions">

              <wsdlsoap:operation soapAction="AcesOptions"/>

              <wsdl:input name="AcesOptionsRequest">
                <wsdlsoap:body use="literal"/>
              </wsdl:input>

              <wsdl:output name="AcesOptionsResponse">
                <wsdlsoap:body use="literal"/>
              </wsdl:output>

            </wsdl:operation>

            <wsdl:operation name="findVehicle">

              <wsdlsoap:operation soapAction="AcesOptions"/>

              <wsdl:input name="findVehicle">
                <wsdlsoap:body use="literal"/>
              </wsdl:input>

              <wsdl:output name="findVehicleResponse">
                <wsdlsoap:body use="literal"/>
              </wsdl:output>

            </wsdl:operation>

          </wsdl:binding>

          <wsdl:service name="TestVehicleService">

            <wsdl:port binding="wns:TestVehicleSoapBinding"
name="TestVehicle">
              <wsdlsoap:address
        location="http://localhost:8080/axis2/services/testVehicle "/>
            </wsdl:port>

          </wsdl:service>

        </wsdl:definitions>


        --------------------------------------------------------------------
-
        To unsubscribe, e-mail: axis-user-unsubscribe@ws.apache.org
        For additional commands, e-mail: axis-user-help@ws.apache.org





      --
      Amila Suriarachchi,
      WSO2 Inc.



  --
  Amila Suriarachchi,
  WSO2 Inc.

Mime
View raw message