How to integrate pact-jvm provider only with json file - unit-testing

I want to test my spring-boot Rest API by using a pact json file provided. The thing is all the resources on internet points to verifying using pact-broker. I will get there but currently, working on a POC for this is turning out to be quite difficult.
No matter what pom configuration, it tries to connect to localhost.
Here's my pom.xml
<plugin>
<groupId>au.com.dius.pact.provider</groupId>
<artifactId>maven</artifactId>
<version>4.1.11</version>
<configuration>
<serviceProviders>
<serviceProvider>
<name>Service</name>
<consumers>
<consumer>
<name>consumer123</name>
<pactSource>/Usr/Pact-JVM-Example/pacts/</pactSource>
</consumer>
</consumers>
</serviceProvider>
</serviceProviders>
<pactBrokerUrl/>
</configuration>
</plugin>
Please note that the json is physically residing on the provided path /Usr/Pact-JVM-Example/pacts/. Also, I've intentionally removed pactBrokerUrl as I am not planning to connect to a remote pact json.
In the end, I want the test to pass/fail on the basis of the json file in /Usr/Pact-JVM-Example/pacts/ when I run ./mvnw pact:verify

Please check the main readme here https://github.com/pact-foundation/pact-jvm/tree/master/provider/maven
This plugin is for verifying a running provider
It always tries to call a localhost server by default. You need Junit4 or Junit5 libraries

Related

Customizing JWT generation not working in WSO2 APIM 3.1.0

I tried to implement the steps given in WSO2 3.1.0 documentation (https://apim.docs.wso2.com/en/3.0.0/learn/api-gateway/passing-end-user-attributes-to-the-backend/passing-enduser-attributes-to-the-backend-using-jwt/) for customizing JWT.
As given in the documentation, I created the custom JWT generator java class, generated the jar and placed it under WSO2 Home/repository/components/lib folder. Did the necessary configurations in deployment.toml for enabling JWT and restarted the server.
When i hit an API with the bearer token, i am getting the X-JWT-Assertion header in the carbon logs but when i decode it, it doesn't contain the custom claims that i added in the custom JWT generator java class.
It contains the standard claims as seen in the below image and not the custom claims that were added (current_timestamp, message).
Need suggestions on this as i have followed the steps given in the documentation.
After some research I found out it is a OSGi bundle that runs on top of Apache Felix.
Please check following import available in sample code (CustomGatewayJWTGenerator):
import org.osgi.service.component.annotations.Component;
See also sample pom.xml. It adds some information about OSGi bundle:
Here is the important part:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
org.wso2.carbon.test.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
As you can see, it exports components as OSGi. See bellow my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.wso2</groupId>
<artifactId>wso2</artifactId>
<version>1.2</version>
</parent>
<groupId>org.example</groupId>
<artifactId>CustomGatewayJWTGenerator</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.apimgt</groupId>
<artifactId>org.wso2.carbon.apimgt.gateway</artifactId>
<version>${carbon.apimgt.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.orbit.com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>7.3.0.wso2v1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name>
<Export-Package>
la.foton.wso2.apim.custom.*
</Export-Package>
<Import-Package>
org.wo2.carbon.apimgt.gateway.*,
org.wso2.carbon.apimgt.impl.*
com.nimbusds.jwt.*,
*;resolution:=optional
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<carbon.apimgt.version>6.6.163</carbon.apimgt.version>
</properties>
</project>
I believe you just need to change package information in <Export-Package>, copy JAR file to $APIM_HOME/repository/components/dropins and restart server.
Please let me know if something goes wrong. If it works, please mark answer as correct to help others. :)
I have kept the default JWT properties and values that come predefined with the product as is and have added the one you told. Placed the CustomGatewayJWTGenerator jar in the dropins folder.
The JWT properties look as below now in deployment.toml. Please let me know if the configurations shown below are correct.
[apim.jwt]
enable = true
encoding = "base64" # base64,base64url
generator_impl = "org.wso2.carbon.apimgt.keymgt.token.JWTGenerator"
claim_dialect = "http://wso2.org/claims"
header = "X-JWT-Assertion"
signing_algorithm = "SHA256withRSA"
enable_user_claims = true
claims_extractor_impl = "org.wso2.carbon.apimgt.impl.token.DefaultClaimsRetriever"
[apim.jwt.gateway_generator]
impl = "org.wso2.carbon.test.CustomGatewayJWTGenerator"
Restarted the server and now when i test the API with JWT access token, the invocation fails and getting null pointer exception.
Error Details are as shown below:
ERROR {org.apache.synapse.transport.passthru.ServerWorker} - Error processing GET request for : /pizzashack/1.0.0/menu. java.lang.NullPointerException
at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken_aroundBody2(JWTValidator.java:353)
at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.generateAndRetrieveJWTToken(JWTValidator.java:336)
at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate_aroundBody0(JWTValidator.java:319)
at org.wso2.carbon.apimgt.gateway.handlers.security.jwt.JWTValidator.authenticate(JWTValidator.java:110)
at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate_aroundBody4(OAuthAuthenticator.java:334)
at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:109)
at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate_aroundBody42(APIAuthenticationHandler.java:419)
at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.isAuthenticate(APIAuthenticationHandler.java:413)
at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest_aroundBody36(APIAuthenticationHandler.java:349)
at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:320)
at org.apache.synapse.rest.API.process(API.java:367)
at org.apache.synapse.rest.RESTRequestHandler.apiProcessNonDefaultStrategy(RESTRequestHandler.java:149)
at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:95)
at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:71)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:327)
at org.apache.synapse.core.axis2.SynapseMessageReceiver.receive(SynapseMessageReceiver.java:98)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:368)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:189)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:813)
I tried to reproduce this scenario locally. It was reproducible when we are using JWT access tokens to invoke the API.
But I was able to successfully get the custom claims in the X-JWT-Assertion header when using OAuth tokens. Please see the below image.
You need to follow this documentation to do the customisation when using JWT access tokens to invoke the API.
I followed the documentation that you shared for invoking the API with JWT access token. I cloned the GIT repository given in the doc.: https://github.com/wso2/samples-apim/tree/master/CustomGatewayJWTGenerator, imported the CustomGatewayJWTGenerator code into eclipse. After the import was successful, i could see a build path error in eclipse: joda-time-2.9.4.wso2v1.jar' in project 'CustomGatewayJWTGenerator' cannot be read or is not a valid ZIP file. Even though the error was seen in eclipse, i was able to build the jar using Maven. I placed the generated jar in lib folder and after server restart verified that the jar was present in dropins folder as well. But somehow, the custom claims that i added in the CustomGatewayJWTGenerator java class are still not coming in the X-JWT-Assertion header. Is it something to do with the error that i got in eclipse after importing the CustomGatewayJWTGenerator project or am i going wrong somewhere else?
The CustomGatewayJWTGenerator java class:
X-JWT-Assertion header:

Azure flask <handler> scriptProcessor could not be found in <fastCGI> application configuration

I am trying to deploy Python Flask application in the Azure web app. I had create web app(Flask) and published my code. After publish, I am getting below error from the site.
The page cannot be displayed because an internal server error has
occurred.
When check the Log, i could see the below error.
But this was happening only in my subscription(free subscription got with MSDN). But working fine in the Organisation subscription.
The <fastCGI> settings must be in the applicationHost.config file (in the system.webServer section) of IIS. Just putting it into web.config does not work (confirmed by testing it on a local IIS, not in Azure). An example configuration may look like this:
<fastCgi>
<application
fullPath="D:\home\Python27\python.exe"
arguments="D:\home\Python27\wfastcgi.py"
maxInstances="16"
idleTimeout="21600"
instanceMaxRequests="10000000"
signalBeforeTerminateSeconds="60"
xdt:Transform="InsertIfMissing"
xdt:Locator="Match(fullPath)">
<environmentVariables>
<environmentVariable name="PYTHONHOME" value="D:\home\Python27" />
</environmentVariables>
</application>
</fastCgi>
You may want to adjust this configuration.
This should solve it for a local IIS where you can edit applicationHost.config. I'm not sure about Azure, but maybe you can find some hints here: https://github.com/Azure/azure-python-siteextensions/issues/2.

integrating generated CXF client jar with Spring Boot fails when cxf-rt-transports-http is missing in pom.xml

I want to migrate a Spring application to Spring Boot. The original application is composed out of several maven modules, I want to reuse one of the existing modules. The module that I want to reuse is a generated cxf web service client. It is linked in the application's pom.xml like this:
<dependency>
<groupId>generated.package</groupId>
<artifactId>cxf-service-adapter</artifactId>
<version>1.0</version>
</dependency>
The generated GenCxfService interface within that module looks like this
#WebService(targetNamespace = "https://the-domain/the-service/", name = "genCxfService")
#XmlSeeAlso({ObjectFactory.class})
public interface GenCxfService {
// the anotated web service methods
// ....
}
I need the web service client interface GenCxfService to be managed by Spring Boot so that I can pass it into an spring security AuthenticationProvider.
Well, I thought it wouldn't be a big deal. I took the compiled cxf-service-adapter-1.0.jar from the module, placed it into an own in-project repository and tried to setup the java configuration to #autowire the bean. First I tried it like this:
import generated.package.GenCxfService;
...
#ComponentScan({"generated.package.*","my.package.*"})
...
#Bean
public MyAuthenticationProvider myAuthenticationProvider() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("https://the-domain/the-service/");
factory.setServiceClass(GenCxfService.class);
GenCxfService genCxfService = (GenCxfService) factory.create();
return new my.package.authentication.MyAuthenticationProvider(userDAO, genCxfService);
}
This gives me the following exception during runtime:
javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: https://the-domain/the-service/the-wsdl.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy126.validateMyUser(Unknown Source)
at my.package.authentication.MyAuthenticationProvider.authenticate(MyAuthenticationProvider.java:47)
I thought I would simply have a faulty java configuration and tried to do a workaround by reusing the exiting xml configuration from the original project module, using
#ImportResource({"classpath:web-service.xml"})
with xml file:
<jaxws:client id="genCxfService"
serviceClass="generated.package.GenCxfService"
address="https://the-domain/the-service/the-wsdl.asmx">
</jaxws:client>
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="logInbound" />
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="logInbound" />
</cxf:inFaultInterceptors>
</cxf:bus>
This is how a client is configured in the cxf documentation (Configuring a Spring Client Option 1). Nevertheless, I still get the same error.
What am I doing wrong?
UPDATE
Adding cxf-rt-transports-http to the pom did the trick:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
Could anybody explain why the absence of the library doesn't throw exceptions during start-up but during runtime?
Thanks in advance.
Spring boot will find the classes at runtime so you don't have to depend on a specific library, it will use reflection to look up the classes that fulfill the interfaces it needs to allow easy swapping of implementations.
The classes are also lazily initiated or looked up so that's why it happens only when a request is sent through and not when it's started.

Compact Framework - Invalid URI: Hostname could not be parsed

I'm writing a compact framework 3.5 application for a windows mobile device. In this application I'm consuming a web service in order to sync with our database. However, whenever I try to make a call to the web service from the device or the emulator, I get the following error: Invalid URI: Hostname could not be parsed. I'm connected to the network via R-NDIS. The service is running on my development machine right now, and I'm actually able to browse to the asmx page through pocket IE. What am I missing?
Thanks!
This might be a proxy problem. The following worked for me.
var service = new WebService.Service();
service.Proxy = GlobalProxySelection.GetEmptyWebProxy();
You might not be picking up the proxy server IE is using, or pocket IE might be displaying a cached version of the ASMX page (and thus not really able to access it either). Probably neither one of these is your problem, however.
Update: try putting this in your application's config file:
<configuration>
<system.net>
<defaultProxy>
<proxy autoDetect="true" />
</defaultProxy>
</system.net>
</configuration>

JAX-WS using Maven2 Not able to access wsdl using browser

Trying to create some sample prgms using jax-ws.
I am able to successfully generate the required artifacts(java files) and the wsdl file using wsgen. and finally a .war file is generated by maven.
Deployed this .war file in weblogic 9.2 and tried to access the wsdl using the IE browser.But it did not work.
I observed two things
The java and complied class files are generated and are bundled inside the .war file.But the wsdl file is generated outside and not a part of
.war.
Generally wsgen itself will provide the wsdl url.
My queries are:
In order to get the wsdl in IE browser what changes I need to do in POM.
wsdl file should be part of .war.If yes then where should I keep the file.
what changes I need to do to get the soap location url in the wsdl file.
How are you triggering wsgen? It needs to be invoked during the build lifecycle before the war is packaged by Maven. The configuration below will bind the wsgen execution to the process-resources phase, this should mean the wsdl is output below target/classes and included in the war.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<executions>
<execution>
<id>wsgen</id>
<phase>process-resources</phase>
<goals>
<goal>wsgen</goal>
</goals>
</execution>
</executions>
<configuration>
...
As far as part 3 of your question, I'm no expert on these things and don't see a means in the plugin to change it. I did find a post that shows how it can be changed programmatically, which may help.