I am writing a java plugin that I plan to use to test a number of web services. These SOAPs for the web services are located in a properties file, and are grouped under which WSDL they fall under (Subscriber, Network, User, etc...). Also, there are some regexs associated with each web service to test the response against.
Properties Example
#Web services to be tested and regexes to test responses
#List of web service groups used (WSDLs)
webservice.list = SubscriberMgmt,NetworkMgmt
# < -- SubscriberMgmt -- >
#getSubscriberDevices
webservice.subscriber = <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.blah.blah.com"><soapenv:Header/><soapenv:Body><ws:getSubscriberDevices><PhoneNumber></PhoneNumber><LastName></LastName><MACAddress></MACAddress><ExternalId></ExternalId><AccountExternalId>john</AccountExternalId><IPAddress></IPAddress></ws:getSubscriberDevices></soapenv:Body></soapenv:Envelope>
webservice.SubscriberMgmt.regex = subscriberId="(.+?)"
webservice.SubscriberMgmt.regex.1 = externalId="(.+?)"
#getMpegResultsById
webservice.subscriber.1 = <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.blah.blah.com"><soapenv:Header/><soapenv:Body><ws:getMpegResultsById><SubscriberId>100016</SubscriberId><Duration>2880</Duration></ws:getMpegResultsById></soapenv:Body></soapenv:Envelope>
webservice.SubscriberMgmt.1.regex = id="(.+?)"
webservice.SubscriberMgmt.1.regex.1 = externalId="(.+?)"
I currently have code to connect using each WSDL from the properties file, so say when the 'webservicegroup' variable is SubscriberMgmt, I'd like to test the .subscriber web service(s) and check the responses if it contains the corresponding regex(es). (the 'data' variable only corresponds to one SOAP request from the property file at the moment)
//Soap Request
try
{
for(String webservicegroup : webserviceList)
{
URL url = new URL("http://" + server + "/webservices/" + webservicegroup);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction", "\"\"");
String loginEnc = new BASE64Encoder().encodeBuffer((username + ":" + password).getBytes());
loginEnc = loginEnc.replaceAll("\n", "");
conn.setRequestProperty("Authorization", "Basic " + loginEnc);
conn.setConnectTimeout(timeout);
conn.setReadTimeout(timeout);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
//Send request
wr.write(data);
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//Save response
String line;
while ((line = in.readLine()) != null)
{
response += line;
}
in.close();
}
}
Any ideas on the best way of doing this? Any help is greatly appreciated
Assuming your connection and POST/GET code is working:
Step 1: Get the entire response as a string:
String response = new String(ByteStreams.toByteArray(inputStream), "UTF-8");
In the above line of code, the ByteStreams class is part of google's guava library. Similar code can be found in apache commons-io, if you prefer that.
Step 2: Test Regular expressions:
if( response.matches(regex) ) { ... }
Don't reinvent the wheel, building a custom testing software mini empire from scratch.
Use SOAPUI open source version to test web services. It allows you to:
generate SOAP tests from web service endpoint WSDL, saving manual labour
avoid processing "pre-canned" SOAP strings and parsing files
automatically generate mocks of your service endpoints, including ability to programmatically control custom responses.
implement test step logic including loops, branches, invoking other test steps, running scripts, and reading/writing parameters from/to property files and data sources (although you must programatically navigate & modify XmlHolder instances via scripts if you wish to "data-drive" your tests)
Execute SOAP, REST, security & load testing of web services, and also JDBC and HTTP test calls.
Integrates with the common build and continuous integration tools for test automation (TDD & continuous delivery).
Use SOAPUI operations within your IDE, via plugins.
It's considered fairly standard "best practice" for testing web services.
To checks SOAP response messages for valid content, using the open source version of SOAPUI:
you can use XPath or XQuery expressions to validate the XML.
you can use script assertions
E.g. if your SOAP response is:
<soap:Body>
<GetEnumResponse xmlns="http://www.xyz.com/">
<GetEnumResult>
<ErrorCode>0</ErrorCode>
<StatusId>0</StatusId>
</GetEnumResult>
<enumsInformation>
<EnumInformation>
<TransactionId>0</TransactionId>
<ConstraintId>5000006</ConstraintId>
<EnumValue>xyz</EnumValue>
<Index>10</Index>
</EnumInformation>
</enumsInformation>
</GetEnumResponse>
</soap:Body>
You can script:
import com.eviware.soapui.support.XmlHolder
def holder = new XmlHolder(messageExchange.responseContentAsXml)
holder.namespaces["tal"]="http://www.xyz.com/"
def node = holder.getNodeValue("//tal:ConstraintId[1]");
log.info(node);
assert node == "5000006";
You can even use the maximum power of standard java regex processing.
Create java classes that do the regex processing and put them into a jar file and place in soapUIinstallation/bin/ext as explained here.
Or wrap your SOAPUI Test inside a JUnit test method, and add standard java code at end to check regexs. This also eases test automation & allows any non-web service tests to be executed as well. This approach works with SOAPUI open source version, whereas the alternative of using SOAPUI assertion steps requires the Pro version.
Steps:
If you choose, install the SOAPUI plugin in your IDE
Use SOAPUI to create a test suite
Use SOAPUI to create test case(s) within the test suite
Use SOAPUI to create test step(s) within the test suite. This is the core of using SOAPUI.
Create a Java project in your IDE. Within this project, add a JUnit test case.
Add all JARs from SoapUI bin and lib directories to Java Build Path.
Within the Junit Test case, add code to execute a SOAPUI test step
Obtain the MessageExchange object, get the response from it, and then get headers, content or attachments. Run a regex check on result.
The following is indicative only. Not intended to be a working example.
package com.example;
import org.junit.Test;
import com.eviware.soapui.tools.SoapUITestCaseRunner;
public class SoapUIProject {
// runs an entire SOAPUI test suite
#Test
public void soapTest1() throws Exception {
SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
runner.setProjectFile("/path/to/your/W3Schools-Tutorial-soapui-project.xml");
runner.run();
}
// runs a single SOAPUI test step - and checks response matches a regex
#Test
public void soapTest2() throws Exception {
WsdlProject project = new WsdlProject( "src/dist/sample-soapui-project.xml" );
TestSuite testSuite = project.getTestSuiteByName("My Test Suite");
TestCase testCase = testSuite.getTestCaseByName("My Test Case");
TestCaseRunner testCaseRunner = new WsdlTestCaseRunner(testCase,null);
// Must have test step setup as WsdlMessageExchange for cast to work
WsdlMessageExchangeTestStepResult testStepResult = (WsdlMessageExchangeTestStepResult)testStep.runTestStepByName("My Test Step");
// TestStep testStep = testCase.getTestStepByName("My Test Step");
// TestCaseRunContext testCaseRunContext = new WsdlTestRunContext(testStep);
// testStep.prepare(testCaseRunner, testCaseRunContext);
// WsdlMessageExchangeTestStepResult testStepResult = (WsdlMessageExchangeTestStepResult)testStep.run(testCaseRunner, testCaseRunContext);
MessageExchange[] messageExchanges = testStepResult.getMessageExchanges();
for (MessageExchange me : messageExchanges) {
String response = me.getResponseContentAsXML();
// do any desired regex processing
// can use any desired assertions
}
assertEquals( Status.FINISHED, runner.getStatus() );
}
}
Further refs: http://www.soapui.org/Scripting-Properties/tips-a-tricks.html#3-xml-nodes
http://books.google.com.au/books?id=DkWx7xZ263gC&printsec=frontcover#v=onepage&q&f=false
Related
I'm using Karate with Gradle, and have 8 feature files that test read / GET functionality for my Spring Boot API.
I'm seeing these tests fail in a way that feels quite random.
The failures are related to Authorisation somehow, but I can't see anything that's wrong on the face of it.
Here's an example,
This fails
Feature: Get Objectives
Background:
* url baseUrl
* def objectiveEndpoint = '/objectives'
* header Authorization = token
Scenario: Get an Objective that exists
Given path objectiveEndpoint + '/37376564-3139-6232-2d66-6631392d3466'
When method GET
Then status 200
And match response contains { objectiveId: '37376564-3139-6232-2d66-6631392d3466' }
And this passes
Feature: Get Assessments
Background:
* url baseUrl
* def assessmentEndpoint = '/assessments'
* header Authorization = token
Scenario: Get an assessment that exists
Given path assessmentEndpoint + '/2900b695-d344-4bec-b25d-524f6b22a93a'
When method GET
Then status 200
And match response contains { odiAssessmentId: '2900b695-d344-4bec-b25d-524f6b22a93a' }
The objective test fails due to a 401 with the following message:
com.intuit.karate.exception.KarateException: objectives-read.feature:12 - status code was: 401, expected: 200, response time: 74, url: http://localhost:8080/objectives/37376564-3139-6232-2d66-6631392d3466, response: {"path":"/objectives/37376564-3139-6232-2d66-6631392d3466","error":"Unauthorized","message":"Unauthorized","timestamp":"2020-06-02T08:04:57.231+0000","status":401}
The assessments test passes.
I'm getting a token by running an Authorisation feature, and storing the result from that into the token variable.
The Auth feature is:
Feature: Log In
Background:
* url 'https://$URL/oauth/token'
* def localSecret = secret
* def localClientId = clientId
Scenario: Get token
Given url 'https://$URL/oauth/token'
And form field grant_type = 'client_credentials'
And form field client_id = localClientId
And form field client_secret = localSecret
And form field audience = 'http://localhost:8080'
When method post
Then status 200
And match response contains { access_token: '#string' }
And def access_token = $.access_token
I then add the token to config, and pass it into each test like this:
var result = karate.callSingle('classpath:login.feature', config);
config.token = 'Bearer ' + result.access_token;
I've confirmed that the token used in the above two features is valid. I've manually tested my API with the token printed in the output of the failed tests, and both of the above tests work fine when I recreate them in Postman. This doesn't feel like a problem with my API because if I rerun the test suite, the tests that fail differ, and on my CI I have a green build with these tests.
I'm experiencing the problem both when running test suites individually like this:
#Karate.Test
Karate testAssessments() {
return Karate.run().relativeTo(AssessmentsRunner.class);
}
and when running all of my tests in parallel like this:
public class SpecTestParallel {
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[]{"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "Test API");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
#Test
void testParallel() {
Results results = Runner.path("classpath:specTests").tags("~#ignore").parallel(5);
generateReport(results.getReportDir());
assertEquals(0, results.getFailCount(), results.getErrorMessages());
}
}
Has anyone had a similar issue before?
As it turns out, this was unexpected behaviour in IntelliJ.
So Karate appears to have a retry policy. If a test failes, it will retry a few times.
When I run tests using the test runner function in IntelliJ, each time a test fails, IntelliJ logs that in the test runner window as it should for a failed test, but Karate keeps running, retries and the test passes. I can see that in the reports now but the IntelliJ test runner doesn't update.
This leads to a confusing situation where tests pass, but appear to fail locally, but the tests pass on CI.
Here is an example of local tests:
and the same commit passing in CI:
I'm not really sure what the fix is here, if there is one. It would be nice if IntelliJ was aware of this behaviour, or maybe Karate could only report the result of a test after all retries have been processed - right now it looks like Karate reports as soon as the first test run is processed.
It's been a confusing few days.
I am trying to do a simple call to JBPM REST API. Doing a GET request via Postman works as expected, for example:
http://localhost:8080/jbpm-console/rest/task/query?potentialOwner=krisv&language=en-UK
returns 3 tasks back.
Then I tried to do a simple java client using JBPM Remote Java API but server is returning NotFoundException (NullPointer exception thrown on client). Code is pretty much copy pasted from JBPM docs:
URL instanceUrl = new URL("http://localhost:8080/jbpm-console/");
String deploymentId = "org.jbpm:Evaluation:1.0";
String processDefId = "evaluation";
String user = "krisv";
String password = "krisv";
// Setup the factory class with the necessarry information to communicate with the REST services
RemoteRuntimeEngineFactory restSessionFactory =
new RemoteRestRuntimeEngineFactory(deploymentId, instanceUrl, user, password);
// Create KieSession instance
RemoteRuntimeEngine engine = restSessionFactory.newRuntimeEngine();
KieSession ksession = engine.getKieSession();
TaskService taskService = engine.getTaskService();
taskService.getTasksAssignedAsPotentialOwner("krisv", "en-UK");
Server log:
2015-09-09 09:26:10,516 WARN [org.jboss.resteasy.core.ExceptionHandler] (default task-46) failed to execute: javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8080/jbpm-console/rest/task/execute
This is not even the REST endpoint that should be called, seems like it is internally executed and fails?? I have absolutely no idea what is wrong.
I am using the demo evaluation project so it can be easily reproducible.
As always you find a solution as soon as you post on SO..
The problem was that I was reading documentation for JBPM 6.1.0 but I was using JBPM 6.2.0. I have included kie-service-client 6.1.0 in my pom.xml but what I should have had is kie-remote-client 6.2.0. Then, following the slightly different 6.2.0 example: https://docs.jboss.org/jbpm/v6.2/userguide/jBPMRemoteAPI.html it started working.
I am making loan app. and I am stuck on this How to Integrate MPESA because I live outside Africa.
Here is the link PESAPI. I am done with step 3 but now I cant understand what to do next.
Q 1) Can I integrate it with my Loan app android ?
Q 2) What to do next please guide me I am stuck on this from last one weak.
If you are still interested, Safaricom recently introduced a REST based interface for consumption of MPesa APIs. They have documentation there, and a pretty good tutorial on how to use it can be found here. For using on your app, you will need a back-end interface to act as a mediator to MPesa, as most of their APIs are asynchronous.
Pesa pi cannot be used for the intended purpose. What pesapi does is take confirmation message from your android mobile and pushes that message to your application.
Message in this context is a message that mpesa sends to the registered mobile number of the payee once a payment is done via lipa na mpesa and pay bill.
What Mutwiri was suggesting, is for you to take the API from mpesa site http://www.safaricom.co.ke/business/sme/m-pesa-payment-solutions/m-pesa-api
and build a middle ware for your application.
Pointers: Check out the B2C and C2B- paybill and lipa na mpesa documentation.
M-PESA API Online Checkout Java / Android How to
Following release of M-PESA API, you will need to create a web service client that does SOAP requests and process responses from API calls
I will provide a quick start guide for java developers geared towards integrating existing Java applications.
Pre-requisites
JDK 7 or latest
Instruction steps
Download Full M-PESA API Guide from safaricom website
Read through Developers Guide C2B_OnlineCheckout_V2.0.doc
Generate JAX-WS artifacts . Your client will use this api to access the published web service.
Generate JAX-WS artifacts
We will use wsimport tool is used to parse checkout WSDL file and generate required files.
mkdir src
wsimport -XadditionalHeaders -clientjar safaricom-lipanampesa-onlinecheckout-wsdl.jar -s src -p ke.co.makara.integration.mpesa.lnmocheckout http://safaricom.co.ke/mpesa_online/lnmo_checkout_server.php?wsdl
Check wsimport --help to understand above options;
Note the package directory for generated artefacts. WSDL is hosted on the lipa na M-PESA endpoint. For this purpose we use the production url. -clientjar option, new in Java 7, simplifies things. You would otherwise have to use -wsdllocation /META-INF/wsdl/Checkout.wsdl option. And copy the wsdl in META-INF after to mitigate the Java 6 wsimport limitation. See limitation below.
Optionally create source jar
While inside src folder run command.
jar cvf safaricom-lipanampesa-onlinecheckout-source-wsdl.jar ke/
Next we use the web service artifacts to invoke the web service from a web service client.
Generated artifacts
Service Endpoint Interface (SEI) - LNMOPortType.java
Service class - LnmoCheckoutService.java
If a wsdl:fault is present in the WSDL, an Exception class
Java classes mapped from schema types eg ProcessCheckOutRequest.java
If a wsdl:message is present in WSDL, asynchronous response beans eg ProcessCheckOutResponse.java
Web Service Client
Next we use the web service artifacts to invoke the web service from a web service client.
This can be a servlet invoked from front-end. Out of scope. For simplicity I will create a java class ~ a standalone console
Create a java class say LNMOCheckoutTester
In the Java client application, create an instance of the LnmoCheckoutService service
LnmoCheckoutService lnmoCheckoutService = new LnmoCheckoutService(); // lina na mpesa online checkout instance
The Service class will be created during the build.
Obtain a proxy to the service from the service using the getLnmoCheckout() method
LNMOPortType soap = lnmoCheckoutService.getLnmoCheckout();
The port carries the protocol binding and service endpoint address information.
Configure the service endpoint
Configure the request context properties on the javax.xml.ws.BindingProvider interface
((BindingProvider)soap).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url + "lnmo_checkout_server.php"); // specifying this property on the RequestContext
JAX-WS provides support for the dynamic invocation of service endpoint operations.
I store the web service url in database and append the wsdl endpoint to this url. This configures the endpoint at runtime.
Compose our client request M-PESA checkout message
This is the message payload
ProcessCheckOutRequest checkOutRequest = objFactory.createProcessCheckOutRequest();
checkOutRequest.setMERCHANTTRANSACTIONID("54635469064");
checkOutRequest.setREFERENCEID("TD346534GH");
checkOutRequest.setAMOUNT(13300);
checkOutRequest.setMSISDN("0721XXXXXX");
checkOutRequest.setENCPARAMS("");
checkOutRequest.setCALLBACKURL("https://makara.co.ke:8443/odt/checkout");
checkOutRequest.setCALLBACKMETHOD("GET");
checkOutRequest.setTIMESTAMP(String.valueOf(date.getTime()));
Configure request headers
Follow business rules in Safaricom document to build the password. See attached code.
For String merchantId, String passkey, Date requestTimeStamp; Convert the concatenated string to bytes, Hash the bytes to get arbitary binary data and Convert the binary data to string use base64
CheckOutHeader requestHeader = objFactory.createCheckOutHeader();
requestHeader.setMERCHANTID(MERCHANT_ID);
Date timestamp = new Date();
String encryptedPassword = getEncryptedPassword(MERCHANT_ID, PASSKEY, timestamp);
requestHeader.setPASSWORD(encryptedPassword.toUpperCase());
requestHeader.setTIMESTAMP(String.valueOf(timestamp.getTime()));
Invoke the service endpoint with the dispatch stab-based client
soap.processCheckOut(checkOutRequest, requestHeader);
Process the response message from the service as per your business requirement
ProcessCheckOutResponse checkOutResponse = new ProcessCheckOutResponse();
checkOutResponse.getRETURNCODE();
checkOutResponse.getDESCRIPTION();
checkOutResponse.getTRXID();
checkOutResponse.getCUSTMSG();
Tracing SOAP Traffic
One of the usual steps involved in the debugging of Web Services applications is to inspect the request and response SOAP messages
Configure client to dump requests and response with JAX-WS
System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
Source code
/*
* LNMOCheckoutTester.java
*
* Nov 20, 2016 Joseph Makara - Created File to tester Lina Na M-PESA Online checkout
*
*
*/
package testMe;
import java.io.*;
import java.security.*;
import java.util.*;
import javax.net.ssl.*;
import javax.xml.ws.*;
import ke.co.makara.integration.mpesa.lnmocheckout.*;
import org.apache.commons.codec.binary.*;
/**
* #author Joseph Makara
*
*/
public class LNMOCheckoutTester {
private static final String PASSKEY = "234fdsghfsg5654dgfhgf6dsfdsafsd43dgfhdgfdgfh74567";
private static final String MERCHANT_ID = "678fsgd54354";
private static final String REFERENCE_ID = "";
private static final String ENDPOINT_URL = "https://safaricom.co.ke/mpesa_online/";
private static final String CALLBACK_URL = "https://makara.co.ke:8443/odt/checkout";
private static final String CALLBACK_METHOD = "GET";
static {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
if (hostname.equals("safaricom.co.ke")) return true;
return false;
}
});
}
/**
* #param args
*/
public static void main(String[] args) {
LNMOPortType soap = outBoundLNMOCheckout(ENDPOINT_URL);
ObjectFactory objFactory = new ObjectFactory();
CheckOutHeader requestHeader = objFactory.createCheckOutHeader();
requestHeader.setMERCHANTID(MERCHANT_ID);
Date timestamp = new Date();
String encryptedPassword = getEncryptedPassword(MERCHANT_ID, PASSKEY, timestamp);
requestHeader.setPASSWORD(encryptedPassword);
requestHeader.setTIMESTAMP(String.valueOf(timestamp.getTime()));
ProcessCheckOutRequest checkOutRequest = objFactory.createProcessCheckOutRequest();
checkOutRequest = processCheckOut(timestamp);
soap.processCheckOut(checkOutRequest, requestHeader);
ProcessCheckOutResponse checkOutResponse = new ProcessCheckOutResponse();
checkOutResponse.getRETURNCODE();
checkOutResponse.getDESCRIPTION();
checkOutResponse.getTRXID();
checkOutResponse.getENCPARAMS();
checkOutResponse.getCUSTMSG();
}
private static ProcessCheckOutRequest processCheckOut(Date date){
ProcessCheckOutRequest checkOutRequest = new ProcessCheckOutRequest();
checkOutRequest.setMERCHANTTRANSACTIONID("54635469064");
checkOutRequest.setREFERENCEID("TD346534GH");
checkOutRequest.setAMOUNT(3.45);
checkOutRequest.setMSISDN("0721826284");
checkOutRequest.setENCPARAMS("");
checkOutRequest.setCALLBACKURL(CALLBACK_URL);
checkOutRequest.setCALLBACKMETHOD(CALLBACK_METHOD);
checkOutRequest.setTIMESTAMP(String.valueOf(date.getTime()));
return checkOutRequest;
}
/**
* Convert the concatenated string to bytes
* Hash the bytes to get arbitary binary data
* Convert the binary data to string use base64
*
* #param merchantId
* #param passkey
* #param date
* #return
*/
private static String getEncryptedPassword(String merchantId, String passkey, Date date) {
String encodedPassword = null;
StringBuilder builder = new StringBuilder(merchantId)
.append(passkey)
.append(date.getTime());
try {
String sha256 = getSHA256Hash(builder.toString());
return new String(Base64.encodeBase64(sha256.getBytes("UTF-8")));;
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
ex.printStackTrace();
}
return encodedPassword;
}
private static LNMOPortType outBoundLNMOCheckout(String url) {
System.setProperty("com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump", "true");
LnmoCheckoutService lnmoCheckoutService = new LnmoCheckoutService();
LNMOPortType soap = lnmoCheckoutService.getLnmoCheckout();
((BindingProvider)soap).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
url + "lnmo_checkout_server.php");
return soap;
}
private static String getSHA256Hash(String input) throws NoSuchAlgorithmException {
MessageDigest mDigest = MessageDigest.getInstance("SHA-256");
byte[] result = mDigest.digest(input.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
Sample Soap Request
[HTTP request - https://safaricom.co.ke/mpesa_online/lnmo_checkout_server.php]---
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<ns2:CheckOutHeader xmlns:ns2="tns:ns">
<MERCHANT_ID>F2678987M</MERCHANT_ID>
<PASSWORD>QQFSOITZB5OJMJTW073/SCWLN5WMDL6LO0FP6DJZ8TQ=</PASSWORD>
<TIMESTAMP>1479116220855</TIMESTAMP>
</ns2:CheckOutHeader>
</S:Header>
<S:Body>
<ns2:processCheckOutRequest xmlns:ns2="tns:ns">
<MERCHANT_TRANSACTION_ID>54635469064</MERCHANT_TRANSACTION_ID>
<REFERENCE_ID>TD346534GH</REFERENCE_ID>
<AMOUNT>3.45</AMOUNT>
<MSISDN>0721826284</MSISDN>
<ENC_PARAMS></ENC_PARAMS>
<CALL_BACK_URL>https://makara.co.ke:8443/odt/checkout</CALL_BACK_URL>
<CALL_BACK_METHOD>lnmo</CALL_BACK_METHOD>
<TIMESTAMP>1479116220855</TIMESTAMP>
</ns2:processCheckOutRequest>
</S:Body>
</S:Envelope>
You will only need to contact Safaricom to get Demo test org details (Merchant ID and PassKey)
Client jar
Source code
The M-Pesa API is currently a SOAP API and SOAP isn't native on Android so it's a bunch of work to integrate the API on your app. I wrote Chowder to help developers handle M-Pesa easily and here's all you have to do:
//Add a new dependency
dependencies {
compile 'com.toe.chowder:chowder:0.7.6'
}
Create a Chowder instance:
//You can create a single global variable for Chowder like this
Chowder chowder = new Chowder(YourActivity.this, PAYBILL_NUMBER, PASSKEY, this);
//You can also add your callback URL using this constructor
Chowder chowder = new Chowder(YourActivity.this, PAYBILL_NUMBER, callbackUrl ,PASSKEY, this);
Process your payment:
//You can then use processPayment() to process individual payments
chowder.processPayment(amount, phoneNumber, productId);
Confirm payment:
chowder.checkTransactionStatus(PAYBILL_NUMBER, transactionId);
There's more sample code and a test Paybill number and passkey here.
This looks like a year ago but you may look at this if still not found a solution.
https://bitbucket.org/mwanzias/mpesaonlinecheckout/downloads/README.md
from here you will be able to post from the android application direct to the back end system that does the mpesa communication.
The demo described here gives online checkout capabilities if you want it extended to B2C, B2B and C2B notifications then you may contact the owner.
you could also look at the following and see if you can fork and adapt it.
https://github.com/aksalj/pesajs
I want to use Jmeter to test a website that uses Servlet+Struts+WebSphereCommerce Technology. I would like to be able to generate Request according to previous response.
I use View Results Tree after html request in order to inspect response of the previous call but i do not see the parameters (responseProperties) i set in response. instead i just see piece of .js code, html code or images.
how to gather response properties?
finally i would like to be able to use such properties to create the following request.
JMeter provides Beanshell scripting as extension mechanism so you can add a Beanshell Post Processor as a child to your HTTP Request and refer to response properties as follows:
String responseCode = prev.getResponseCode();
String responseHeaders = prev.getResponseHeaders();
String responseMessage = prev.getResponseMessage();
String responseData = prev.getResponseDataAsString();
Where prev is a shor-hand for previous SampleResult
If you want to use a part of response in next request (this is called "correlation") JMeter provides other Post Processors which can extract data from response and store it into JMeter Variables for later re-use such as:
Regular Expressions Extractor
CSS/JQuery Extractor
XPath Extractor
etc.
Hope this helps.
In SOAP UI Web service testing,
User imports the Project in to the work space and mentions the End point. Enters the required data in the Request xml and runs to get the resulting response in xml format.
Is there a way we can achieve this using Java only without using the SoapUI tool. I guess the steps should be:
Create a Wsdl Project.
Create a xml request (in the required format)
Send the request to the end point (How to do this?)
Receive response and verify it.
Please help me how to do this using Java only(without using SOAP UI tool). Any links/code will be greatly helpful.
Thanks,
Mike
Use soapUI API.
;
Here are some useful links:
http://www.soapui.org/Developers-Corner/integrating-with-soapui.html
http://pritikaur23.wordpress.com/2013/06/16/saving-a-soapui-project-and-sending-requests-using-soapui-api/
I used the following code to create a project:
File projectFile = new File(filePath);
SoapUI.setSoapUICore(new StandaloneSoapUICore(true));
WsdlProject project = new WsdlProject();
project.setName(projectName);
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, url);
for (WsdlInterface wsdl : wsdls) {
int c = wsdl.getOperationCount();
String reqContent = "";
for (int j = 0; j < c; j++) {
WsdlOperation op = wsdl.getOperationAt(j);
reqContent = op.createRequest(true);
WsdlRequest req = op.addNewRequest(requestName);
req.setRequestContent(reqContent );
}
}
project.saveIn(projectFile);
SoapUI.shutdown();
You can create client and pass in HTTP Request test request populated with needed parameter for testing purpose, below mention question has some useful insights.
Java Web service testing