Domino: Webservice: Class do not have a property of the name - web-services

I have the following Problem.
I tried to create a web service a standard cmis Webservice Interface on IBM, Domino with wsdl2java (with cxf). After creating all java classes I tried to get answers from the webservice with the eclipse Java Client. It works find. After this test I import the generated java classes into a Domino Database.
Now I have the problem to run the webservice, because the following error message:
class org.oasis_open.docs.ns.cmis.messaging._200908.GetTypeDefinition
do not have a property of the name {URL..}repositoryId
In the JAVA Class the following code:
public class GetTypeDefinition {
#XmlElement(required = true)
protected String repositoryId;
#XmlElement(required = true)
protected String typeId;
#XmlElementRef(name = "extension", namespace = "http://docs.oasis-open.org/ns/cmis/messaging/200908/", type = JAXBElement.class)
protected JAXBElement<CmisExtensionType> extension;
The Domino JAVA Env. does not understand the Tag #XmlElement(required = true) without the name, namespace and the type definition.
If I add in the same line the following code:
#XmlElement(required = true, name = "repositoryId", namespace = "http://docs.oasis-open.org/ns/cmis/messaging/200908/", type = String.class)
protected String repositoryId;
it works (error then in the next line:
GetTypeDefinition do not have a property of the name {URL}typeId
Now the question is: why? Can I generate the java classes with an other tool (not with cxf wsdl2java) or do I need other parameters to get the complete code?
In the generated JAVA Classes are round about 170 lines with the problematic code.
Have somebody an Idea to solve the problem on the Domino Server (x64 9.0)?

Related

Not able to get values from the yaml file using Mock in Groovy test case

I'm writing a unit test case for my functionality using Groovy. But, however I'm not able to configure the values that are available in the class. The values are configured in my yaml file.
Here is my code
class UpdateServiceImplTest extends Specification {
DataSourceRestTemplateConfig dataSourceRestTemplateConfig
def setup() {
dataSourceRestTemplateConfig= Mock(DataSourceRestTemplateConfig )
}
}
This DataSourceRestTemplateConfig class is using some properties, which is coming as null while executing the test
public class DataSourceRestTemplateConfig {
#Autowired
RestTemplate restTemplate;
#Value("${datasource.auth.username}")
private String userNameNew;
#Value("${datasource.auth.password}")
private String passwordNew;
// Method to call DB here
}
The above values are coming as null when I evaluate the expression. Are there any other configurations am I missing?
Any ideas would be greatly helpful to me.

Unit Testing ODataQueryOptions Gives MissingMethodException DependencyInjection

So here is my problem, I have an OData Web Api service that uses ODataQueryOptions to filter data from our sql server and I am trying to setup a .Net Framework Unit Test project to test the controllers with different query options. I have been searching for several days now and found many examples but most of them use an older version of OData. This example is the best one I have found so far, the only problem is that calling config.EnableDependencyInjection(); gives me the following exception:
Method not found: 'System.IServiceProvider Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(Microsoft.Extensions.DependencyInjection.IServiceCollection)'.
Here is an example of my code:
using System.Collections.Generic;
using System.Web.Http.Results;
using System.Web.OData;
using System.Web.OData.Query;
using System.Net.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using University.API.OData.Controllers;
using University.API.OData.Models;
using System.Web.OData.Routing;
using System.Web.Http;
using System.Web.OData.Extensions;
[TestClass]
public class SalesforceUnitTest
{
private HttpRequestMessage request;
private ODataQueryOptions<Product> _options;
[TestInitialize]
public void TestInitialize()
{
request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/odata/product?$top=5");
var model = WebApiConfig.GetModel();
HttpConfiguration config = new HttpConfiguration();
config.EnableDependencyInjection(); //Throws Missing Method Exception
WebApiConfig.Register(config);
config.EnsureInitialized();
request.SetConfiguration(config);
ODataQueryContext context = new ODataQueryContext(
model,
typeof(Product),
new ODataPath(
new Microsoft.OData.UriParser.EntitySetSegment(
model.EntityContainer.FindEntitySet("product"))
)
);
_options = new ODataQueryOptions<Product>(context, request);
}
[TestMethod]
public void ProductTest()
{
var controller = new ProductController();
controller.Request = request;
var response = controller.Get(_options);
var contentResult = response as OkNegotiatedContentResult<List<Product>>;
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
}
}
Let me know if there is any other information you may need.
Thank you for any help you can provide.
EDIT:
Here what is referenced in the unit test project:
EntityFramework
EntityFramework.SqlServer
Microsoft.Data.Edm
Microsoft.Data.OData
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.OData.Core
Microsoft.Odata.Edb
Microsoft.Spatial
Microsoft.Threading.Tasks
Microsoft.Threading.Tasks.Extensions
Microsoft.Threading.Tasks.Extensions.Desktop
Microsoft.VisualStudio.TestPlatform.TestFramework
Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions
System
System.ComponentModel.DataAnnotations
System.Net
System.Net.Http
System.Net.Http.Extensions
System.Net.Http.Primitives
System.Net.Http.WebRequest.
System.Spatial
System.Web
System.Web.Http
System.Web.OData
ODataAPI
I figured it out after some more digging. It seems that my Unit Test project was using a different version than my ODataApi project. This for some weird reason was causing the MissingMethodException instead of a VersionMismatchException. Hopefully this helps someone else who is looking into why Dependency Injection isnt working for your Unit Test project.

unit testing -Mock JNDI lookup in WebSphere LIberty

I am using WebSphere Liberty 8.5.5 server and writing some batch test cases on this server. I am trying to mock jndi lookup object for testing but while setting up dataSource object in test case I am getting below error, Does anyone know how to set INITIAL_CONTEXT_FACTORY
ERROR : javax.naming.NoInitialContextException: Need to specify class name in environment or system prop
erty, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:344)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
You need to set the class name of your initial context factory in the environment of the InitialContext constructor.
For example:
Hashtable<Object, Object> env = new Hashtable<>();
env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.example.MockICF");
new InitialContext(env);
Where com.example.MockICF might be written as:
public class MockICF implements InitialContextFactory {
private static Context ctx = new Mockery().mock(Context.class);
#Override
public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
return ctx;
}
}

Add SOAP header object using pure JAX-WS

I'm trying to implement simple web service client for PayPal Express Checkout API using JAX WS. PayPal Express Checkout API provides WSDL file, from which I was able to generate Java classes using CXF's wsdl2java utility.
From authentication reasons, it demands adding SOAP Header to each request. This header is quite simple and should look like here:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECSOAPAPIBasics#id09C3I0CF0O6
Generated from WSDL classes include ebay.apis.eblbasecomponents.CustomSecurityHeaderType class which represents header which I need to add to each request.
So the question is: how can I add manually created instance of CustomSecurityHeaderType class to SOAP request's header taking into account following conditions:
I'm not very eager to use classes from com.sun.* package as mentioned in answer here: JAX-WS - Adding SOAP Headers (mainly because of possible portability issues between different JDK's)
I don't want to manually marshal that object into nested javax.xml.soap.SOAPElement instances as mentioned in answer here:
How do I add a SOAP Header using Java JAX-WS
So, it looks like I've found possible answer while combining JAX-WS & JAXB related answers from SO (I would really appreciate if somebody experienced in these technologies can check whether following is correct):
The obvious thing for me is to add SOAP message handler and alter header of SOAPMessage instance in it:
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.soap.SOAPHeader;
import ebay.api.paypalapi.ObjectFactory; // class generated by wsdl2java
// following class is generated by wsdl2java utility Service class
final PayPalAPIInterfaceService payPalService = new PayPalAPIInterfaceService();
final PayPalAPIAAInterface expressCheckoutPort = payPalService.getPayPalAPIAA();
final Binding binding = ((BindingProvider) expressCheckoutPort).getBinding();
List<Handler> handlersList = new ArrayList<Handler>();
// now, adding instance of Handler to handlersList which should do our job:
// creating header instance
final CustomSecurityHeaderType headerObj = new CustomSecurityHeaderType();
final UserIdPasswordType credentials = new UserIdPasswordType();
credentials.setUsername("username");
credentials.setPassword("password");
credentials.setSignature("signature");
headerObj.setCredentials(credentials);
// bookmark #1 - please read explanation after code
final ObjectFactory objectFactory = new ObjectFactory();
// creating JAXBElement from headerObj
final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);
handlersList.add(new SOAPHandler<SOAPMessageContext>() {
#Override
public boolean handleMessage(final SOAPMessageContext context) {
try {
// checking whether handled message is outbound one as per Martin Strauss answer
final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(requesterCredentials, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
// ... default implementations of other methods go here
});
// as per Jean-Bernard Pellerin's comment setting handlerChain list here, after all handlers were added to list
binding.setHandlerChain(handlersList);
Explanation of bookmark #1:
one should marshal not the header object itself, but JAXBElement representing that object, because otherwise one will get an exception. One should use one of ObjectFactory classes which are generated from WSDL for creating needed JAXBElement instances from original objects.
(Thanks #skaffman for answer: No #XmlRootElement generated by JAXB )
One should also refer to Martin Straus answer which extends this one
This solution works great, but there's a catch. It generates this error when the inbound message is processed:
dic 19, 2012 7:00:55 PM com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl addHeader
SEVERE: SAAJ0120: no se puede agregar una cabecera si ya hay una
Exception in thread "main" javax.xml.ws.WebServiceException: java.lang.RuntimeException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:167)
at com.sun.xml.ws.handler.HandlerTube.processResponse(HandlerTube.java:174)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:1074)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:979)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:950)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:825)
at com.sun.xml.ws.client.Stub.process(Stub.java:443)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:174)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:102)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:154)
at $Proxy38.wsRdyCrearTicketDA(Unknown Source)
at ar.com.fit.fides.remedy.api.ws.ServicioCreacionTickets.crearTicket(ServicioCreacionTickets.java:55)
at ar.com.fit.fides.remedy.api.ws.ConectorRemedyWS.crearTicket(ConectorRemedyWS.java:43)
at ar.com.fit.fides.remedy.api.ws.ConectorRemedyWS.main(ConectorRemedyWS.java:90)
Caused by: java.lang.RuntimeException: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:50)
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:23)
at com.sun.xml.ws.handler.HandlerProcessor.callHandleMessageReverse(HandlerProcessor.java:341)
at com.sun.xml.ws.handler.HandlerProcessor.callHandlersResponse(HandlerProcessor.java:214)
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:161)
... 14 more
Caused by: com.sun.xml.messaging.saaj.SOAPExceptionImpl: Can't add a header when one is already present.
at com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl.addHeader(EnvelopeImpl.java:128)
at com.sun.xml.messaging.saaj.soap.impl.EnvelopeImpl.addHeader(EnvelopeImpl.java:108)
at ar.com.fit.fides.remedy.api.ws.AuthenticationHandler.handleMessage(AuthenticationHandler.java:45)
So, the solution is to check whether the message being handled if the outbound message, like this:
public boolean handleMessage(SOAPMessageContext context) {
try {
Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(AuthenticationInfo.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(info, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
I created a web service exposing method with params user and password as header like this:
#WebService(serviceName="authentication")
public class WSAuthentication {
String name = null;
String password = null;
public WSAuthentication() {
super();
}
public WSAuthentication(String name, String password) {
this.name = name;
this.password = password;
}
private static String getData(WSAuthentication sec) {
System.out.println("********************* AUTHENTICATION ********************" + "\n" +
"**********USER: " + sec.name + "\n" +
"******PASSWORD: " + sec.password + "\n" +
"******************************** AUTHENTICATION ****************************");
return sec.name + " -- " + sec.password;
}
#WebMethod(operationName="security", action="authenticate")
#WebResult(name="answer")
public String security(#WebParam(header=true, mode=Mode.IN, name="user") String user, #WebParam(header=true, mode=Mode.IN, name="password") String password) {
WSAuthentication secure = new WSAuthentication(user, password);
return getData(secure);
}
}
Try compiling it and testing generated from WSDL class. I hope this helps.
I found this answer:
JAX-WS - Adding SOAP Headers
Basically you add -XadditionalHeaders to the compiler options and objects in the headers also appear in your generated code as parameters of the method.
If you are using maven, and the jaxws-maven-plugin all you have to do is add the xadditionalHeaders flag to true and the client will be generated with the methods that have the headers as input.
https://jax-ws-commons.java.net/jaxws-maven-plugin/wsimport-mojo.html#xadditionalHeaders

CXF JAXB JAXBEncoderDecoder unmarshalling error : unexpected element when having qualified elements

I have the following problem and cannot find a solution:
The WSDL has elementFormDefault="qualified", in the response that I receive in my CXF client all the elements are prefixed with namespace but JAXB throws an exception
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"unm:ENTSCWS", local:"searchReturn"). Expected elements are
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:661)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:533)
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:128) ...
If i change in the WSDL elementFormDefault="unqualified" it is working, but I am not allowed to change the WSDL, it should have the elements prefixed with the namespace.
The package-info.java contains the annotaction:
#javax.xml.bind.annotation.XmlSchema(namespace = "unm:ENTSCWS", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package entscws;
The response class contains the annotation:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"searchReturn"
})
#XmlRootElement(name = "searchResponse")
public class SearchResponse {
Do you have any idea why I get this error?
Are you running in OSGi? I've seen some similar issues with package-info's not being picked up properly there.
Another option could be to add the -xjc-npa flag to the wsdl2java command to have it not use the package-info at all and stick the namespaces in all the other places.