Forum Discussion

Tim_Arp_112576's avatar
Tim_Arp_112576
Icon for Nimbostratus rankNimbostratus
Aug 12, 2004

Handling returned parameters with SOAP and Java

Hi, I have been working on some code to basically mimic the b virtual command line. I'm trying to display the pool members status (up or down) . According to the SDK , the function is like this.

 

 

void get_member_active_states(

 

in SessionCredentials creds, <== CORBA Specific

 

in String pool_name,

 

in IPPortDefinition[] member_defs,

 

out MemberState[] member_states

 

);

 

 

ITCMLocalLB.Pool.wsdl

 

 

In all of the previous examples I have seen the desired result is return value. How do I retrieve out variables in soap this way.

 

 

My code goes like this

 

//get member stats

 

call.setMethodName("get_all_member_statistics");

 

resp = call.invoke(destURI, urn);

 

 

if (resp.generatedFault()){

 

Fault fault = resp.getFault();

 

throw new SOAPException(fault.getFaultCode(), fault.getFaultString());

 

} else {

 

MemberStatisticsEntry[] PoolMembers = (MemberStatisticsEntry[]) resp.getReturnValue().getValue();

 

for (int i=0; i < PoolMembers.length; i++) {

 

PoolParams.addElement(new Parameter("member_defs", IPPortDefinition.class,PoolMembers[i].getMember_definition(), null));

 

call.setParams(PoolParams);

 

call.setMethodName("get_member_active_states");

 

resp = call.invoke(destURI, urn);

 

//this is wrong below

 

MemberState[] PoolMemberState = (MemberState[]) resp.getReturnValue().getValue(); //this is wrong

 

 

String sAddress = PoolMembers[i].getMember_definition().getAddress();

 

long nPort = PoolMembers[i].getMember_definition().getPort();

 

long bits_in = PoolMembers[i].getStats().getThruput_stats().getBits_in();

 

long bits_out = PoolMembers[i].getStats().getThruput_stats().getBits_out();

 

long packets_in = PoolMembers[i].getStats().getThruput_stats().getPackets_in();

 

long packets_out = PoolMembers[i].getStats().getThruput_stats().getPackets_out();

 

long current_connection = PoolMembers[i].getStats().getConnection_stats().getCurrent_connections();

 

long maximum_connection = PoolMembers[i].getStats().getConnection_stats().getMaximum_connections();

 

long total_connection = PoolMembers[i].getStats().getConnection_stats().getTotal_connections();

 

out.println ("Member " + ((PoolMemberState[i].getActive_state())?"UP":"DOWN") + " {" + sAddress + ":" + nPort + "}

 

");

 

out.println ("\tbits (in, out) (" + bits_in + ", " + bits_out + ")");

 

out.println ("\tpackets (in, out) (" + packets_in + ", " + packets_out + ")");

 

out.println ("\tconnection (cur, max, tot) (" + current_connection + ", " + maximum_connection + ", " + total_connection + ")");

 

out.println ("

 

");

 

}

 

}

6 Replies

  • The problem I see is that the method takes an array as input for the member_defs.

    void get_member_active_states( 
        in String pool_name, 
        in IPPortDefinition [] member_defs, 
        out MemberState[] member_states);

    You are passing in a single value:

     MemberStatisticsEntry[] PoolMembers = (MemberStatisticsEntry[]) resp.getReturnValue().getValue(); 
     for (int i=0; i < PoolMembers.length; i++) { 
      
     >>    PoolParams.addElement(new Parameter("member_defs", IPPortDefinition.class,PoolMembers[i].getMember_definition(), null)); 
      
         call.setParams(PoolParams); 
         call.setMethodName("get_member_active_states"); 
         resp = call.invoke(destURI, urn); 
         //this is wrong below 
         MemberState[] PoolMemberState = (MemberState[]) resp.getReturnValue().getValue(); //this is wrong

    You can either

    1. Pass in an array of size 1 (right now you are just passing in the element).

    -or-

    2. Create an array of all the member_defs and pass them in a single call:

    // Extract statistics return value 
     MemberStatisticsEntry[] PoolMembers = (MemberStatisticsEntry[]) resp.getReturnValue().getValue();  
      
     // build input array 
     long num_members = PoolMembers.length; 
     IPPortDefinition [] member_defs = new IPPortDefinition[num_members]; 
      
     for(int i=0; i { 
         member_defs[i] = PoolMembers[i].getMember_definition(); 
     } 
      
     PoolParams.addElement(new Parameter("member_defs", IPPortDefinition[].class, member_defs, null)); 
     call.setParams(PoolParams); 
     call.setMethodName("get_member_active_states"); 
     resp = call.invoke(deskURI, urn); 
      
     // Extract return values...

    That would explain the error of element "address" not found. It's expecting an array in and you are passing it by value.

    -Joe
  • I think I'm closer but I'm still getting a null pointer exception.

     

     

    Here the code I have now

     

    if (resp.generatedFault()){

     

    Fault fault = resp.getFault();

     

    throw new SOAPException(fault.getFaultCode(), fault.getFaultString());

     

    } else {

     

    //Getting network statistics per Pool Member

     

    MemberStatisticsEntry[] PoolMembers = (MemberStatisticsEntry[]) resp.getReturnValue().getValue();

     

     

    for (int i=0; i < PoolMembers.length; i++) {

     

    //Getting active status per member

     

    PoolParams.addElement(new Parameter("member_defs", IPPortDefinition.class,PoolMembers[i].getMember_definition(), null));

     

    call.setParams(PoolParams);

     

    call.setMethodName("get_member_active_states");

     

    resp = call.invoke(destURI, urn);

     

    //Deal with the return value

     

    Vector ReturnParams = resp.getParams();

     

    Parameter member_state_list_param = (Parameter) ReturnParams.elementAt(0);

     

    MemberState[] member_state_list = (MemberState[])member_state_list_param.getValue();

     

    //create a nice text status.

     

    String Status = (member_state_list[0].getActive_state())?"UP":"DOWN";

     

    String Member = PoolMembers[i].getMember_definition().getAddress() + ":" + PoolMembers[i].getMember_definition().getPort() + " " + Status;

     

    out.println (Stats2HTML("Member " + Member,PoolMembers[i].getStats().getThruput_stats(),PoolMembers[i].getStats().getConnection_stats()));

     

    } :?
  • I traced there error to the resp object I get

     

    Could not find element by name: address

     

    I'm not sure what address is refering to. But it looks like the call to the function is failing.

     

    :?
  • I can't test this right now but if memory serves me correctly I think this is one of the fun little quirks with Apache SOAP. I "think" that if there is no return value but there are out params, it makes the first outparam the return value accessible from resp.getReturnValue() and all subsequent out params accessible from the getParams() call starting at index 0.

     

     

    Sorry for the go-around here but I haven't actively used Apache SOAP for a while and we don't have many methods in the SDK that have no return value but do have out params. I don't believe there are any samples in the SDK with this usage.

     

     

    Keep us posted.

     

     

    -Joe
  • You need to use the getParams() method on the Response object. This is illustrated in the following sample apps in the SDK.

    System\ConfigSync.java

    System\SystemInet.java

    System\SystemServices.java

    Here's basically what it looks like

    Response resp = call.invoke(...); 
     Vector params = resp.getParams(); 
     Parameter member_state_list_param = params.elementAt(0); 
     MemberState[] member_state_list = (MemberState[])member_state_list_param.getValue(); 
      
     -or- 
      
     MemberState[] member_state_list = (memberState[])((Parameter)resp.getParams().elementAt(0)).getValue();<

    You use the elementAt() member to extract the correct out variable starting at 0.

    Let me know if this works for you.

    -Joe
  • Great! I'm glad to be of some help. Like I said earlier, I believe the Apache SOAP toolkit will convert the first out param to the return value if the return value is void. Not sure the reason behind this but it looks like it does.

     

     

    -Joe