from example create consuming java spring soap wsdl workday

example - soap java



Authenticaion Spring SOAP to Workday (1)

Principalmente, parece que te faltan las piezas de autenticación a través de un SOAPHandler para las Credenciales de WS-Security. FYI, esto no es Spring, pero estaba funcionando el código a partir de v16 de la API.

Gracias por el viaje por el carril de la memoria.

Pasos

  1. Establecer el nombre de usuario y el inquilino de Workday
  2. Establecer la contraseña de Workday
  3. Establecer el código del cliente del servicio web (ex HumanResourcesService)
  4. Establecer el puerto del cliente del servicio web
  5. Agregue el controlador WorkdayCredentials al código auxiliar del cliente, con una referencia al puerto, usuario del día laborable @ inquilino y contraseña del día laborable.
  6. Obtener el contexto de solicitud
  7. Establezca el punto final del servicio web del día de trabajo del contexto Solicitud (consulte wdEndPoint)
  8. GetWorkersRequestType
  9. Opcionalmente establezca algunos parámetros para su solicitud
  10. Obtenga la respuesta
  11. Obtenga los datos de respuesta

Rutinas

  • GetWorkers
  • WorkdayCredentials

Código de GetWorkers

package com.workday.demo; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.Map; import java.math.BigDecimal; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.ws.BindingProvider; import com.workday.human_resources.*; public class GetWorkers { public static void main(String[] args) { try { // Enter user/password and endpoint information for Proof of Concept final String wdUser = "user@tenant"; final String wdPassword = "zzz"; // final String wdEndpoint = // "https://e2-impl-cci.workday.com/ccx/service/exampleTenant/Human_Resources/v16"; final String wdEndpoint = "https://impl-cc.workday.com/ccx/service/exampleTenant/Human_Resources/v16"; System.out.println("Starting..."); // Create the Web Service client stub HumanResourcesService service = new HumanResourcesService(); HumanResourcesPort port = service.getHumanResources(); // Add the WorkdayCredentials handler to the client stub WorkdayCredentials.addWorkdayCredentials((BindingProvider) port, wdUser, wdPassword); // Assign the Endpoint URL Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wdEndpoint); // Define the paging defaults final int countSize = 200; int totalPages = 1; int currentPage = 1; // Set the current date/time GregorianCalendar cal = new GregorianCalendar(); XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal); // Loop over all of the pages in the web service response while (totalPages >= currentPage) { // Create a "request" object GetWorkersRequestType request = new GetWorkersRequestType(); // Set the WWS version desired request.setVersion("v10"); // Set the date/time & page parameters in the request ResponseFilterType responseFilter = new ResponseFilterType(); responseFilter.setAsOfEntryDateTime(xmlCal); responseFilter.setAsOfEffectiveDate(xmlCal); responseFilter.setPage(BigDecimal.valueOf(currentPage)); responseFilter.setCount(BigDecimal.valueOf(countSize)); request.setResponseFilter(responseFilter); // Set the desired response group(s) to return WorkerResponseGroupType responseGroup = new WorkerResponseGroupType(); responseGroup.setIncludeReference(true); request.setResponseGroup(responseGroup); // Submit the request creating the "response" object GetWorkersResponseType response = port.getWorkers(request); // Display all Workers Iterator<WorkerType> i = response.getResponseData().getWorker() .iterator(); while (i.hasNext()) { WorkerType worker = i.next(); { System.out.println(worker.getWorkerReference() .getDescriptor()); } } // Update page number if (totalPages == 1) { totalPages = response.getResponseResults().getTotalPages() .intValue(); } currentPage++; } } catch (ProcessingFaultMsg e) { e.printStackTrace(); } catch (ValidationFaultMsg e) { e.printStackTrace(); } catch (DatatypeConfigurationException e) { e.printStackTrace(); } } }

Código de WorkdayCredentials

package com.workday.demo; import java.util.List; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.ws.BindingProvider; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import javax.xml.namespace.QName; import java.util.Set; /** * This class creates a handler that will add the WS-Security username and * password to the to the SOAP request messages for a client side proxy. * */ public class WorkdayCredentials implements SOAPHandler<SOAPMessageContext> { /** Namespace for the SOAP Envelope. */ private static String SOAPENVNamespace = "http://schemas.xmlsoap.org/soap/envelope/"; /** The prefix that will be used for the SOAP Envelope namespace. */ private static String SOAPENVPrefix = "soapenv"; /** Namespace for the WS-Security SOAP header elements. */ private static String WSSENamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; /** The prefix that will be used for the WS-Security namespace. */ private static String WSSEPrefix = "wsse"; /** * The WS-Security URI that specifies that the password will be transmitted * as plain text. */ private static String WSSEPasswordText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; /** * The user name that will be sent in the WS-Security header on the SOAP * request message. This is of the form systemid@tenant. */ private String username; /** * The password that will be sent in the WS-Security header on the SOAP * request message. */ private String password; /** * This method created an instance of the WorkdayCredentials class and adds * it as a handler to the bindingProvider supplied. * * @param bindingProvider * The client stub to which the handler will be added. The most * convenient way to obtain the required bindingProvvider is to * call one of the getPort methods on the Service class for the * Web service and then cast the returned object to a * BindingProvider. * @param username * The id and tenant name for the user. This is of the form * systemid@tenant. * @param password * The password for the system user. */ @SuppressWarnings("unchecked") public static void addWorkdayCredentials(BindingProvider bindingProvider, String username, String password) { List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain(); handlerChain.add(new WorkdayCredentials(username, password)); bindingProvider.getBinding().setHandlerChain(handlerChain); } /** * Creates a WorkdayCredentials handler and initialises the member * variables. In most cases, the addWorkdayCredentials static method should * be used instead. * * @param username * The id and tenant name for the user. This is of the form * systemid@tenant. * @param password * The password for the system user. */ public WorkdayCredentials(String username, String password) { this.username = username; this.password = password; } /** * Returns null as this handler doesn''t process any Headers, it just adds * one. */ public Set<QName> getHeaders() { return null; } /** * Adds WS-Security header to request messages. */ public boolean handleMessage(SOAPMessageContext smc) { Boolean outboundProperty = (Boolean) smc .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outboundProperty.booleanValue()) { addWSSecurityHeader(smc, username, password); } return true; } /** * Returns true, no action is taken for faults messages. */ public boolean handleFault(SOAPMessageContext smc) { return true; } public void close(MessageContext messageContext) { } /** * Adds a WS-Security header containing a UsernameToken to a SOAP message. * * @param smc * The SOAPMessageContent to which the WS-Security header will be * added. * @param username * The WS-Security username. * @param password * The WS-Security password. * * @throws java.lang.RuntimeException * This exception will be thrown if a SOAPException occurs when * modifying the message. */ private void addWSSecurityHeader(SOAPMessageContext smc, String username, String password) throws java.lang.RuntimeException { try { // Get the SOAP Header SOAPMessage message = smc.getMessage(); SOAPHeader header = message.getSOAPHeader(); if (header == null) { // Create header as it doesn''t already exist message.getSOAPPart().getEnvelope().addHeader(); header = message.getSOAPHeader(); } // Add WS-Security SOAP Header SOAPElement heSecurity = header.addChildElement("Security", WSSEPrefix, WSSENamespace); heSecurity.addAttribute(message.getSOAPPart().getEnvelope() .createName("mustUnderstand", SOAPENVPrefix, SOAPENVNamespace), "1"); // Add the Usernametoken element to the WS-Security Header SOAPElement heUsernameToken = heSecurity.addChildElement( "UsernameToken", WSSEPrefix, WSSENamespace); // Add the Username element to the UsernameToken Element heUsernameToken.addChildElement("Username", WSSEPrefix, WSSENamespace).addTextNode(username); // Add the Password element to the UsernameToken Element SOAPElement hePassword = heUsernameToken.addChildElement( "Password", WSSEPrefix, WSSENamespace); hePassword.addAttribute(message.getSOAPPart().getEnvelope() .createName("Type"), WSSEPasswordText); hePassword.addTextNode(password); } catch (SOAPException e) { throw new RuntimeException( "Failed to add WS-Security header to request", e); } } }

Soy muy nuevo en el manejo de solicitudes SOAP y estoy tratando de consumir la API SOAP de Workday enumerada aquí . He usado un gradle/ant para generar las clases del WSDL basado en el tutorial de Spring aquí

Ahora que las clases se han generado, puedo acceder a las funciones que necesito. El problema es que no sé cómo autenticar mis solicitudes.

Esto es lo que tengo hasta ahora:

import org.springframework.oxm.jaxb.Jaxb2Marshaller; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import workday_Staffing.wsdl.GetWorkersRequestType; import workday_Staffing.wsdl.GetWorkersResponseType; public class StaffingClient extends WebServiceGatewaySupport { public StaffingClient() { Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); jaxb2Marshaller.setContextPath("workday_Staffing.wsdl"); setMarshaller(jaxb2Marshaller); setUnmarshaller(jaxb2Marshaller); } public void makeWorkdayRequest() { // make the request - missing some authentication here GetWorkersRequestType request = new GetWorkersRequestType(); GetWorkersResponseType workersResponseType = (GetWorkersResponseType) getWebServiceTemplate() .marshalSendAndReceive(request); } }

La respuesta aquí parece una buena pista pero me falta cómo construir el cliente y agregar la autenticación.

Cualquier ayuda será apreciada.