Eclipselink Moxy error for native datatype - eclipselink

I'm able to bind complex objects (bs2 in code below) but getting error while doing for String (bs1 in code below) . using Eclipselink 2.4.2. Please see code:
private static void initJAXBContext() {
String bs1 = "<?xml version=\"1.0\"?>\n" +
"<xml-bindings\n" +
" xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence/oxm\"\n" +
" package-name=\"java.lang\" >\n" +
" <xml-schema element-form-default=\"QUALIFIED\" namespace=\"java.lang\">\n" +
" <xml-ns prefix=\"sc\" namespace-uri=\"java.lang\"/>\n" +
" </xml-schema>\n" +
" <java-types>\n" +
" <java-type name=\"java.lang.String\">\n" +
" <xml-root-element/>\n" +
" </java-type>\n" +
" </java-types>\n" +
"</xml-bindings>";
String bs2 = "<?xml version=\"1.0\"?>\n" +
"<xml-bindings\n" +
" xmlns=\"http://www.eclipse.org/eclipselink/xsds/persistence/oxm\"\n" +
" package-name=\"test\" >\n" +
" <xml-schema element-form-default=\"QUALIFIED\" namespace=\"test\">\n" +
" <xml-ns prefix=\"sc\" namespace-uri=\"test\"/>\n" +
" </xml-schema>\n" +
" <java-types>\n" +
" <java-type name=\"test.TestService\">\n" +
" <xml-root-element/>\n" +
" </java-type>\n" +
" </java-types>\n" +
"</xml-bindings>";
List<Object> fl = new ArrayList<Object>();
Map<String, Object> properties = new HashMap<String, Object>();
try {
InputStream iStream2 = new ByteArrayInputStream(bs1.getBytes("UTF-8"));
fl.add(iStream2);
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, fl);
System.out.println("before jaxb");
JAXBContext context = (org.eclipse.persistence.jaxb.JAXBContext) JAXBContext.newInstance("test", Class.forName("test.TestService").getClassLoader(), properties);
System.out.println("after jaxb");
} catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
}
Above code works fine for bs2. But gives following exception for bs1:
---------------------------------------------------------------------------------------
javax.xml.bind.JAXBException
- with linked exception:
[java.lang.NullPointerException]
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:915)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:848)
at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:182)
at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:249)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at GenericTest.initJAXBContext(GenericTest.java:337)
at GenericTest.main(GenericTest.java:366)
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.jaxb.compiler.XMLProcessor.processXML(XMLProcessor.java:249)
at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:104)
at org.eclipse.persistence.jaxb.JAXBContext$ContextPathInput.createContextState(JAXBContext.java:912)
... 12 more
---------------------------------------------------------------------------------------
Can you please let me know the issue with binding string bs1.
Thanks in advance,
Vikas

EclipseLink JAXB (MOXy) does not allow you to treat a data type as a domain object. Below is an example of handling a String as a top level object.
import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
public class Example {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Example.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource xml = new StreamSource(new StringReader("<foo>Hello World</foo>"));
JAXBElement<String> unmarshalJAXBElement = unmarshaller.unmarshal(xml, String.class);
String string = unmarshalJAXBElement.getValue();
System.out.println(string);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement<String> marshalJAXBElement = new JAXBElement<String>(new QName("bar"), String.class, string);
marshaller.marshal(marshalJAXBElement, System.out);
}
Output from running above code:
Hello World
<?xml version="1.0" encoding="UTF-8"?>
<bar>Hello World</bar>
}

Related

JSR223 Sampler SSL certificate issues

I have the following code in JSR223 Sampler and I get SSL certificate error. Is there any way to do disable?
Problem in JSR223 script JSR223 Sampler, message: javax.script.ScriptException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed
import org.apache.http.HttpHeaders;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;
List<String> sendRequest(String url, String method, String body) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(2000)
.setSocketTimeout(3000)
.build();
StringEntity entity = new StringEntity(body, "UTF-8");
HttpUriRequest request = RequestBuilder.create(method)
.setConfig(requestConfig)
.setUri(url)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8")
.setEntity(entity)
.build();
String req = "REQUEST:" + "\n" + request.getRequestLine() + "\n" + "Headers: " +
request.getAllHeaders() + "\n" + EntityUtils.toString(entity) + "\n";
HttpClientBuilder.create().build().withCloseable {httpClient ->
httpClient.execute(request).withCloseable {response ->
String res = "RESPONSE:" + "\n" + response.getStatusLine() + "\n" + "Headers: " +
response.getAllHeaders() + "\n" +
(response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n";
System.out.println(req + "\n" + res );
return Arrays.asList(req, res);
}
}
}
List test1 = sendRequest("https://testserver.com","POST", "");
log.info(Arrays.toString(test1));
Just use normal HTTP Request sampler instead, as per documentation:
The JMeter HTTP samplers are configured to accept all certificates, whether trusted or not, regardless of validity periods, etc. This is to allow the maximum flexibility in testing servers
However if you're doing something very special and need to do the same in Groovy - here is example solution:
import org.apache.http.HttpHeaders
import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.RequestBuilder
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.conn.ssl.SSLConnectionSocketFactory
import org.apache.http.conn.ssl.TrustStrategy
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.HttpClients
import org.apache.http.ssl.SSLContextBuilder
import org.apache.http.util.EntityUtils
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
List<String> sendRequest(String url, String method, String body) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(2000)
.setSocketTimeout(3000)
.build();
StringEntity entity = new StringEntity(body, "UTF-8");
HttpUriRequest request = RequestBuilder.create(method)
.setConfig(requestConfig)
.setUri(url)
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8")
.setEntity(entity)
.build();
String req = "REQUEST:" + "\n" + request.getRequestLine() + "\n" + "Headers: " +
request.getAllHeaders() + "\n" + EntityUtils.toString(entity) + "\n";
def builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
#Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
});
def trustAllFactory = new SSLConnectionSocketFactory(builder.build(), new NoopHostnameVerifier());
HttpClients.custom().setSSLSocketFactory(trustAllFactory).build().withCloseable { httpClient ->
httpClient.execute(request).withCloseable { response ->
String res = "RESPONSE:" + "\n" + response.getStatusLine() + "\n" + "Headers: " +
response.getAllHeaders() + "\n" +
(response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "") + "\n";
System.out.println(req + "\n" + res);
return Arrays.asList(req, res);
}
}
}
List test1 = sendRequest("https://testserver.com", "POST", "");
println(Arrays.toString(test1));
More information:
Trusting all certificates using HttpClient over HTTPS
Apache Groovy - Why and How You Should Use It

Scope validation fails when running the (new) published API of WSO2 AM 1.10.0

I provide a working code in the answer below, as this set of API's is relatively new, and I could not see other end-to-end examples in the web, so may be useful as a reference for anyone wishing to use the new set of API's.
I'm trying to use the new set of published APIs of WSO2 AM 1.10.0. I wrote a sample client, based on an article of Sanjeewa Malalgoda: http://wso2.com/library/articles/2015/11/article-introducing-wso2-api-manager-new-rest-api-for-store-and-publisher-operations
Here is the code, based on that article and fixes some minor errors/typos:
package test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
public class test
{
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
// PHASE 1: REGISTER CLIENT
// ------------------------
String dcrEndpointURL = getKeyManagerURLHttp() +
"client-registration/v0.9/register";
String applicationRequestBody = " {\n" +
" \"callbackUrl\": \"google.sk\",\n" +
" \"clientName\": \"test_11\",\n" +
" \"tokenScope\": \"Production\",\n" +
" \"owner\": \"admin\",\n" +
" \"grantType\": \"password refresh_token\",\n" +
" \"saasApp\": true\n" +
" }";
Map<String, String> dcrRequestHeaders = new HashMap<String, String>();
// This is base 64 encoded basic Auth value for user name admin and password admin.
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(dcrRequestHeaders.get("Authorization"));
dcrRequestHeaders.put("Content-Type", "application/json");
JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
new URL(dcrEndpointURL),
applicationRequestBody,dcrRequestHeaders));
System.out.println(clientRegistrationResponse);
consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
System.out.println(consumerKey);
System.out.println(consumerSecret);
Thread.sleep(2000);
// PHASE 2: REQUEST TOKEN
// ----------------------
String requestBody = "grant_type=password&username=admin&password=admin&scope=API_CREATOR_SCOPE";
URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");
Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
String basicAuthConsumer = consumerKey + ":" + consumerSecret;
byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));
JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
System.out.println(accessTokenGenerationResponse);
//Get access token and refresh token from token API call.
//Now we have access token and refresh token that we can use to invoke API.
JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
String userAccessToken = tokenData.getString("access_token");
String refreshToken = tokenData.getString("refresh_token");
System.out.println("Access token: " + userAccessToken);
System.out.println("Refresh token: " + refreshToken);
// PHASE 3: CALL THE API
// ---------------------
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Bearer " + userAccessToken);
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
The code registers the client and returns access and refresh token successfully.
Here is the response of the token request:
"data":
{
"access_token": "bb5176def22ffbc4a7b12d2fd1ee9733",
"refresh_token": "357926275971df21f9529ebb30ba36d1",
"scope":"default",
"token_type":"Bearer",
"expires_in":2502
}
However, when I send this token in the header of the API query:
{Authorization=Bearer bb5176def22ffbc4a7b12d2fd1ee9733}
I get error code 401/Unauthorized.
Looking at the server log, I get the following:
[2016-02-07 17:38:20,371] ERROR - WebAppAuthenticatorImpl You cannot access API as scope validation failed
[2016-02-07 17:38:20,372] WARN - PhaseInterceptorChain Interceptor for {http://publisher.api.rest.apimgt.carbon.wso2.org/}SubscriptionsApi has thrown exception, unwinding now
org.apache.cxf.interceptor.security.AuthenticationException: Unauthenticated request
at org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.OAuthAuthenticationInterceptor.handleMessage(OAuthAuthenticationInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:217)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:268)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.wso2.carbon.tomcat.ext.valves.CompositeValve.continueInvocation(CompositeValve.java:99)
at org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve$1.invoke(CarbonTomcatValve.java:47)
at org.wso2.carbon.webapp.mgt.TenantLazyLoaderValve.invoke(TenantLazyLoaderValve.java:57)
at org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer.invokeValves(TomcatValveContainer.java:47)
at org.wso2.carbon.tomcat.ext.valves.CompositeValve.invoke(CompositeValve.java:62)
at org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve.invoke(CarbonStuckThreadDetectionValve.java:159)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve.invoke(CarbonContextCreatorValve.java:57)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1698)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
Some notes
I'm running version 1.10.0, from http://wso2.com/api-management/try-it
WSO2 Published API's that I have on this deployment are all v0.9 (and not v1, as appear in some of the examples)
I tried the token request with both API_CREATOR_SCOPE, API_PUBLISHER_SCOPE. Both fail.
In the response of the token request, it says "scope: default". Not sure if this is ok or not.
The exception says "You cannot access API as scope validation failed", so I guess there is an issue with the scope. But I'm not sure why and how to fix.
Please check roles and scope available in /_system/config/apimgt/applicationdata/tenant-conf.json file. Then request token with scopes mentioned there. Then you will get access token with correct scope. Please note that tokens with default scope cannot use for REST API functionalities.
For basic authentication, change beans.xml of repository\deployment\server\webapps\api#am#publisher#v0.9\WEB-INF to:
<bean id="AuthenticationInterceptor" class="org.wso2.carbon.apimgt.rest.api.util.interceptors.auth.BasicAuthenticationInterceptor" />
And then code is much simplified:
public class test {
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
String dcrEndpointURL = getKeyManagerURLHttp()+"client-registration/v0.9/register";
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
System.out.println(response.getData());
HttpResponse response1 = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/subscriptions",requestHeaders);
System.out.println(response1.getResponseCode());
System.out.println(response1.getResponseMessage());
System.out.println(response1.getData());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
Here is a working example, following Sanjeewa's fix.
package test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import org.wso2.carbon.automation.engine.exceptions.AutomationFrameworkException;
import org.wso2.carbon.automation.test.utils.http.client.HttpRequestUtil;
import org.wso2.carbon.automation.test.utils.http.client.HttpResponse;
public class test
{
public static void main(String[] args) throws
UnsupportedEncodingException,
AutomationFrameworkException,
InterruptedException,
MalformedURLException,
IOException
{
// PHASE 1: REGISTER CLIENT
// ------------------------
String dcrEndpointURL = getKeyManagerURLHttp() +
"client-registration/v0.9/register";
String applicationRequestBody = " {\n" +
" \"callbackUrl\": \"google.sk\",\n" +
" \"clientName\": \"test_11\",\n" +
" \"tokenScope\": \"Production\",\n" +
" \"owner\": \"admin\",\n" +
" \"grantType\": \"password refresh_token\",\n" +
" \"saasApp\": true\n" +
" }";
Map<String, String> dcrRequestHeaders = new HashMap<String, String>();
// This is base 64 encoded basic Auth value for user name admin and password admin.
String basicAuthAdmin = "admin" + ":" + "admin";
byte [] encodedBytesAdmin = Base64.getEncoder().encode(basicAuthAdmin.getBytes("UTF-8"));
dcrRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesAdmin, "UTF-8"));
System.out.println(dcrRequestHeaders.get("Authorization"));
dcrRequestHeaders.put("Content-Type", "application/json");
JSONObject clientRegistrationResponse = new JSONObject(HttpRequestUtil.doPost(
new URL(dcrEndpointURL),
applicationRequestBody,dcrRequestHeaders));
System.out.println(clientRegistrationResponse);
consumerKey = new JSONObject(clientRegistrationResponse.getString("data")).get("clientId").toString();
consumerSecret =new JSONObject(clientRegistrationResponse.getString("data")).get("clientSecret").toString();
System.out.println(consumerKey);
System.out.println(consumerSecret);
Thread.sleep(2000);
// PHASE 2: REQUEST TOKEN
// ----------------------
String requestBody = "grant_type=password&username=admin&password=admin&scope=apim:view_api";
URL tokenEndpointURL = new URL(getGatewayURLNhttp() + "token");
Map<String, String> authenticationRequestHeaders = new HashMap<String, String>();
String basicAuthConsumer = consumerKey + ":" + consumerSecret;
byte [] encodedBytesConsumer = Base64.getEncoder().encode(basicAuthConsumer.getBytes("UTF-8"));
authenticationRequestHeaders.put("Authorization", "Basic " + new String(encodedBytesConsumer, "UTF-8"));
JSONObject accessTokenGenerationResponse = new JSONObject(HttpRequestUtil.doPost(tokenEndpointURL, requestBody, authenticationRequestHeaders));
System.out.println(accessTokenGenerationResponse);
//Get access token and refresh token from token API call.
//Now we have access token and refresh token that we can use to invoke API.
JSONObject tokenData = new JSONObject(accessTokenGenerationResponse.getString("data"));
String userAccessToken = tokenData.getString("access_token");
String refreshToken = tokenData.getString("refresh_token");
System.out.println("Access token: " + userAccessToken);
System.out.println("Refresh token: " + refreshToken);
// PHASE 3: CALL THE API
// ---------------------
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Authorization", "Bearer " + userAccessToken);
System.out.println(requestHeaders);
HttpResponse response = HttpRequestUtil.doGet(getKeyManagerURLHttp()+"api/am/publisher/v0.9/apis?query=admin&type=provide",requestHeaders);
System.out.println(response.getResponseCode());
System.out.println(response.getResponseMessage());
System.out.println(response.getData());
}
static String getKeyManagerURLHttp()
{
return "http://127.0.0.1:9763/";
}
static String getGatewayURLNhttp()
{
return "http://127.0.0.1:8280/";
}
}
Result:
200
OK
{"count":1,"next":"","list":[{"name":"employees","context":"/employees","id":"09cef2c8-89f0-405e-97af-225942a52d83","description":null,"version":"1.0.0","provider":"admin","status":"PUBLISHED"}],"previous":""}

SubreportProcessingEventHandler is not firing even without parameters in the subreport

I'm trying to use the subreport component in my main report but does not fire the event SubreportProcessingEventHandler even without any parameter in the sub-report that can generate any errors.
public ActionResult MyReport(DateTime dateReport)
{
var root = Path.GetDirectoryName(this.Server.MapPath("~"));
if (string.IsNullOrEmpty(root))
{
return this.HttpNotFound();
}
var path = Path.Combine(root, "bin\\Reports\\MainReport.rdlc");
if (System.IO.File.Exists(path))
{
this.reportViewer.LocalReport.ReportPath = path;
}
else
{
return this.View("Index");
}
this.LoadData(dateReport);
var reportType = "PDF";
string mimeType;
string encoding;
string fileNameExtension;
var deviceInfo = "<DeviceInfo>" + " <OutputFormat>" + reportType + "</OutputFormat>"
+ " <PageWidth>8.5in</PageWidth>" + " <PageHeight>11in</PageHeight>"
+ " <MarginTop>0.2in</MarginTop>" + " <MarginLeft>0.4in</MarginLeft>"
+ " <MarginRight>0.4in</MarginRight>" + " <MarginBottom>0.1in</MarginBottom>"
+ "</DeviceInfo>";
Warning[] warnings;
string[] streams;
var renderedBytes = this.reportViewer.LocalReport.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return this.File(renderedBytes, mimeType);
}
private void LoadData(DateTime dateReport)
{
........
this.reportViewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(this.MySubreportEventHandler);
this.reportViewer.LocalReport.DataSources.Add(new ReportDataSource("UserDataSet", users.DistinctBy(u => u.UserName)));
this.reportViewer.LocalReport.DataSources.Add(new ReportDataSource("EluateReportDataSet", radiopharmacyEluateReports));
this.reportViewer.LocalReport.DataSources.Add(new ReportDataSource("MarkingProtocolReportDataSet", radiopharmacyMarkingProtocolReports));
this.reportViewer.LocalReport.Refresh();
}
public void MySubreportEventHandler(object sender, SubreportProcessingEventArgs e)
{
.....
e.DataSources.Add(new ReportDataSource("RadiopharmaceuticalQualityControlDataSet", radiopharmacyReportQualityControls));
}
I have checked the output and this warning is raised:
Warning: Warnings occurred while executing the subreport ‘Subreport1’. (rsWarningExecutingSubreport)
After more detailed observation, i noticed that subreport really need an parameter that matches with a parameter passed by main report. Without any parameter the subreport just don't work.

Error code 706 when signing PDF using Web Agent in Java

When testing the Web Agent sample in Java, I am getting an error reply
<?xml version="1.0" encoding="utf-8"?>
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="error">
<Error>
<returnCode>706</returnCode>
<errorMessage>Value cannot be null.
Parameter name: s</errorMessage>
</Error>
</response>
I followed the Ruby example in the CoSign Web Agent samples and the documentation
I have used the demo.pdf file provided in the sample.
This is the XML (from test app) sent in the POST request (the <content></content> has the Base64 encoded PDF, but omitted because of length).
<?xml version="1.0" encoding="utf-8" ?>
<request>
<Logic>
<allowAdHoc>true</allowAdHoc>
<workingMode>pull</workingMode>
<enforceReason>false</enforceReason>
</Logic>
<Url>
<finishURL>http://localhost:64956/retrieveSignedFile.aspx</finishURL>
</Url>
<Document>
<fileID>1234567890</fileID>
<contentType>pdf</contentType>
<content>{BASE64 encoded pdf content}</content>
</Document>
</request>
The following is the java code I have used:
public class CoSignTest {
private static final String INPUT = "D:\\tmp\\demo.pdf";
private static final String PRECONTENT = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
"<request>\n" +
" <Logic>\n" +
" <allowAdHoc>true</allowAdHoc>\n" +
" <workingMode>pull</workingMode>\n" +
" <enforceReason>false</enforceReason>\n" +
" </Logic>\n" +
" <Url>\n" +
" <finishURL>http://localhost:64956/retrieveSignedFile.aspx</finishURL>\n" +
" </Url>\n" +
" <Document>\n" +
" <fileID>1234567890</fileID>\n" +
" <contentType>pdf</contentType>\n" +
" <content>";
private static final String POSTCONTENT = "</content>\n" +
" </Document>\n" +
"</request>";
private static final String POST_URL = "https://webagentdev.arx.com/Sign/UploadFileToSign";
private static final String PULL_URL = "https://webagentdev.arx.com/Sign/DownloadSignedFileG";
public static final int TIMEOUT = 300000;
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream(INPUT);
String content = PRECONTENT + new String(Base64.encodeBase64(loadResource(is)), "UTF-8") + POSTCONTENT;
System.out.println(content);
String reply = new String(sendDocForProcessing(URLEncoder.encode(content, "UTF-8")));
System.out.println(reply);
System.out.println("DONE");
}
private static String sendDocForProcessing(String content) throws Exception {
HttpClient client = null;
HttpMethodBase method = null;
SimpleHttpConnectionManager mgr = new SimpleHttpConnectionManager();
String reply = "";
try {
mgr.getParams().setConnectionTimeout(TIMEOUT);
mgr.getParams().setSoTimeout(TIMEOUT);
client = new HttpClient(mgr);
method = new PostMethod(POST_URL);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
method.getParams().setParameter("http.socket.timeout", TIMEOUT);
client.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT);
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
method.getParams().setParameter("inputXML", content);
client.executeMethod(method);
reply = new String(method.getResponseBody());
} catch (Exception e) {
e.printStackTrace();
} finally {
if(method != null) {
method.releaseConnection();
}
client = null;
mgr.shutdown();
}
if (isSigningSuccessful(reply)) {
return reply;
} else {
throw new Exception("Failed in signing the document. Error: " + reply);
}
}
private static boolean isSigningSuccessful(String reply) throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(reply.getBytes()));
Element elem = doc.getDocumentElement();
String type = elem.getAttribute("type");
return !"error".equals(type);
}
public static byte[] loadResource(InputStream in) {
if (in == null) {
return new byte[0];
}
try {
int indice, tempIndice;
byte[] tempArr;
byte[] mainArr = new byte[0];
byte[] byteArr = new byte[65535];
for (indice = 0; (indice = in.read(byteArr)) > 0;) {
tempIndice = mainArr.length + indice;
tempArr = new byte[tempIndice];
System.arraycopy(mainArr, 0, tempArr, 0, mainArr.length);
System.arraycopy(byteArr, 0, tempArr, mainArr.length, indice);
mainArr = tempArr;
}
in.close();
return mainArr;
} catch (Exception e) {
e.printStackTrace();
}
return new byte[0];
}
}
The XML elements are case sensitive and must be passed as shown in the documentation (e.g. Document instead of document, Auth instead of auth and so on). In addition, your XML request is missing the finishURL parameter which is mandatory.
Also note that some parameters in your XML request are obsolete. See the updated request parameter list in the link above. A sample XML is available here.
Thanks for adding your Java code. Note that the HttpClient instance is configured incorrectly and as a result the http-post request is sent empty. Take a look at the modifications I did in your sendDocForProcessing function in order to properly post the XML content:
private static String sendDocForProcessing(String content) throws Exception {
HttpClient client = null;
PostMethod method = null;
String reply = "";
try {
client = new HttpClient();
method = new PostMethod(POST_URL);
method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
NameValuePair[] data = { new NameValuePair("inputXML", content) };
method.setRequestBody(data);
client.executeMethod(method);
reply = method.getResponseBodyAsString();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(method != null) {
method.releaseConnection();
}
}
if (isSigningSuccessful(reply)) {
return reply;
} else {
throw new Exception("Failed in signing the document. Error: " + reply);
}
}
The content passed to the above function should not be URL-encoded as it is already done by the HttpClient library.
In addition, when analyzing the response, I suggest you to check the value of the returnCode element rather than the type property. The response is always of type 'error'.
Also note that the function name isSigningSuccessful is misleading as this stage is still prior to the act of signing.

NotSerializableException with BasicDataSource in JNDI

I am setting up a standalone JNDI and loading a Datasource to the JNDI.
DataSource I use is: org.apache.commons.dbcp.BasicDataSource
The JNDI is set up as follows
String detectorHost = InetAddress.getLocalHost().getHostName();
System.out.println("detectorHost: " + detectorHost);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
final NamingBeanImpl namingInfo = new NamingBeanImpl();
namingInfo.start();
final Main JNDIServer = new Main();
JNDIServer.setNamingInfo( namingInfo );
JNDIServer.setPort( 5400 );
JNDIServer.setBindAddress(InetAddress.getLocalHost().getHostName());
JNDIServer.start();
final Hashtable _properties = new Hashtable();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://" + InetAddress.getLocalHost().getHostName() + ":5400");
final Context _context = new InitialContext(_properties);
_context.createSubcontext("jdbc");
String JNDI_PATH = "jdbc" + "/" + "mydbname";
_context.bind(JNDI_PATH, getDataSource());
I get the following exception
javax.naming.CommunicationException [Root exception is java.io.NotSerializableException: org.apache.commons.dbcp.BasicDataSource]
at org.jnp.interfaces.NamingContext.bind(NamingContext.java:677)
at org.jnp.interfaces.NamingContext.bind(NamingContext.java:611)
at javax.naming.InitialContext.bind(Unknown Source)
at com.lombardrisk.reform.integration.ReformIntegration.createJNDIServer(ReformIntegration.java:93)
at com.lombardrisk.reform.integration.ReformIntegration.main(ReformIntegration.java:44)
Caused by: java.io.NotSerializableException: org.apache.commons.dbcp.BasicDataSource
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.rmi.MarshalledObject.<init>(Unknown Source)
at org.jnp.interfaces.MarshalledValuePair.<init>(MarshalledValuePair.java:65)
at org.jnp.interfaces.NamingContext.createMarshalledValuePair(NamingContext.java:1425)
at org.jnp.interfaces.NamingContext.bind(NamingContext.java:640)
I don't quite follow why I am getting a NotSerializableException exception, this is a local JNDI in the same JVM and not a remote JNDI. Not sure why this occurs.
Can some one advise what is wrong here.
regards
D
The exception was misleading. The exception became clear after adding the following to the JVM startup
-Dsun.io.serialization.extendedDebugInfo=true
It appears I was not using the correct libraries.
I have explained the full problem and solution here in this link.
https://community.jboss.org/thread/241498
//Code to start a JNDI Server and a test client for the JNDI Context
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.log4j.Logger;
import org.jnp.server.Main;
import org.jnp.server.NamingBeanImpl;
//Snippet of the code
System.setProperty("java.rmi.server.hostname", "localhost");
System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
System.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
final NamingBeanImpl namingInfo = new NamingBeanImpl();
namingInfo.start();
final Main jndiServer = new Main();
jndiServer.setNamingInfo(namingInfo);
jndiServer.setPort(1099);
jndiServer.setBindAddress("localhost");
jndiServer.setRmiPort(1098);
jndiServer.setRmiBindAddress("localhost");
jndiServer.start();
final Hashtable<String, String> _properties = new Hashtable<String, String> ();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
final Context _context = new InitialContext(_properties);
_context.createSubcontext("jdbc");
JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource());
System.out.println("jdbcTemplate: " + jdbcTemplate.getClass());
System.out.println("getDataSource(): " + getDataSource().getClass());
_context.bind("/jdbc/reformDS", getDataSource());
//JNDI started
//Test the JNDI context
// There are 2 ways to test -
// Option 1: create a HashTable and pass the properties to the InitialContext constructor
final Hashtable<String, String> _properties = new Hashtable<String, String> ();
_properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
_properties.put(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
final Context _context = new InitialContext(_properties);
Object obj = _context.lookup("/jdbc/reformDS");
if (null != obj) {
System.out.println("OBJ: " + obj.getClass());
org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");
int update = jdbcTemplate2.update(sql);
System.out.println("Update*****************: " + update);
}
// Option 2: Set the System.properties and call the InitialContext
System.getProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.getProperty(Context.PROVIDER_URL, "jnp://" + "localhost" + ":1099");
final Context _context = new InitialContext();
Object obj = _context.lookup("/jdbc/reformDS");
if (null != obj) {
System.out.println("OBJ: " + obj.getClass());
org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)obj;
JdbcTemplate jdbcTemplate2 = new JdbcTemplate(ds);
String sql = String.format("update MESSAGE_LOG set PROCESS_INSTANCE_ID = 123456 where ID =42395 ");
int update = jdbcTemplate2.update(sql);
System.out.println("Update*****************: " + update);
}