Marshalling via WebServiceGatewaySupport fails with JAXBException: class <classname> nor any of its super class is known to this context - jaxb

I want to call webservices via clients. The clients are instantiated as beans:
#Configuration
public class ServiceClientConfiguration {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(CONTEXT_PATH);
return marshaller;
}
#Bean
public Service1Client authenticate(Jaxb2Marshaller marshaller) {
Service1Client client = new Service1Client();
client.setDefaultUri("http://localhost:8292/service1");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
#Bean
public Service2Client broker(Jaxb2Marshaller marshaller) {
Service2Client client = new Service2Client();
client.setDefaultUri("http://localhost:8192/service2");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
Though the both of the services are different, the request and responses are defined via xsd-files to the same package name - which is provided here as String 'CONTEXT_PATH' to the marshaller.
The clients itself look like this:
public class Service1Client extends WebServiceGatewaySupport {
private static final Logger log = LoggerFactory.getLogger(Tools.getClassName());
public Service1Response process(Service1Request request) {
Service1Response response = null;
try {
response = (Service1Response) getWebServiceTemplate()
.marshalSendAndReceive("http://localhost:8292/service1", request);
} catch (Exception e) {
log.error("", e);
}
return response;
}
}
and
public class Service2Client extends WebServiceGatewaySupport {
private static final Logger log = LoggerFactory.getLogger(Tools.getClassName());
public Service2Response process(Service2Request request) {
Service2Response response = null;
try {
response = (Service2Response) getWebServiceTemplate()
.marshalSendAndReceive("http://localhost:8192/service2", request);
} catch (Exception e) {
log.error("", e);
}
return response;
}
}
While running Service1Client is fine, the Service2Client fails with
javax.xml.bind.JAXBException: class <package>.Service2Request nor any of its super class is known to this context.
I removed "Service1Client" from the code - but the error remained to be the same.

I have renamed the pathname of the CONTEXT_PATH. It was "types.". I changed it to "dto.". Now it works as expected.
For me the reason for the problem looks sort of strange - maybe somebody can explain it.

Related

Mocking JestClient in SpringBoot

Springboot application is not autowiring all the instances so I manually wire all of them. Now JestClient mock is not getting set I only see the live object. Next actually I want to test if "aMethod is having jestclient.execute() then return jestResult"
#RunWith(SpringRunner.class)
#SpringBootTest(classes = IngestionApplicationTests.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#TestPropertySource(locations = "classpath:application-test.yml")
#ComponentScan(basePackages = { "com.package.accounts" })
public class IngestionApplicationTests {
#Autowired
private IngestionServiceImpl vaService;
#Autowired
private IngestionQueryUtil queryUtil;
#Mock
private JestClient client;
private JestResult result;
...
#Before
public void setUp() {
client = mock(JestClient.class);
String resultString="<jsonString>";
result.setJsonString(resultString);
result.setJsonObject(new JsonParser().parse(resultString).getAsJsonObject());
result.setSucceeded(true);
try {
when(client.execute(anyObject())).thenReturn(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I see that Spring-Boot is creating a new context of its own and not running in test context.

Alaways goin in onFailure in retrofit2.0

I am trying to hit the api : www.xyz.com/abc_cc/cc/userregister/newuser
This is my Code :
public class MainActivity extends AppCompatActivity {
public static final String BASE_URL = "abc.com/abc_cc/cc/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getUnsafeOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
Endpoints endpoints= retrofit.create(Endpoints.class);
endpoints.newuser("{\"full_name\":\"sss\",\"states_id\":\"20\",\"mobile\":\"9876543210\",\"password\":\"******\",\"accept_terms\":true,\"Userid\":\"0\",\"refer\":\"\",\"ip-address\":\"1.2.3.4\",\"device_type\":\"samsung J5\",\"os-version\":\"5.0.1\",\"client\":\"app\",\"secret_key\":\"44\"}")
.enqueue(new retrofit2.Callback<Items>() {
#Override
public void onResponse(retrofit2.Call<Items> call, retrofit2.Response<Items> response) {
System.out.println("onResponse : "+response.message());
System.out.println("onResponse : "+response.body());
System.out.println("onResponse : "+response.code());
System.out.println("onResponse : "+response.errorBody());
System.out.println("onResponse : "+response.isSuccessful());
System.out.println("onResponse : "+response.raw());
System.out.println("onResponse : "+response);
}
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
}
});
}
public static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient = okHttpClient.newBuilder()
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Interface :
public interface Endpoints {
#POST("/userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
POJO class :
public class Items {
#SerializedName("Response-Status")
#Expose
private Boolean responseStatus;
#SerializedName("Response-Validate")
#Expose
private Boolean responseValidate;
#SerializedName("Response-Message")
#Expose
private String responseMessage;
#SerializedName("Response-Data")
#Expose
private ResponseData responseData;
public Boolean getResponseStatus() {
return responseStatus;
}
public void setResponseStatus(Boolean responseStatus) {
this.responseStatus = responseStatus;
}
public Boolean getResponseValidate() {
return responseValidate;
}
public void setResponseValidate(Boolean responseValidate) {
this.responseValidate = responseValidate;
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public ResponseData getResponseData() {
return responseData;
}
public void setResponseData(ResponseData responseData) {
this.responseData = responseData;
}
}
I am getting this response :
{protocol=http/1.1, code=404, message=Not Found, url=www.xyz.com/userregister/newuser}
I have given the proper url then why is it taking only half of it?
I have tried the example from https://code.tutsplus.com/tutorials/sending-data-with-retrofit-2-http-client-for-android--cms-27845. This example and the link given in the example are working fine, but if I do the same with my url then I get the above error
I Hope kindly check your parsing issues may occurred.
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
//add this lije you got exceptions.
t.printStackTrace();
}
Change your Endpoints interface for this:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
Note that I removed the trailing slash /. This way Retrofit appends the path you defined to the BASE_URL.
refer to the docs for Retrofit.Builder for a more detailed explanation, but pay particular attention to these bits:
Base URLs should always end in /.
A trailing / ensures that endpoints values which are relative paths
will correctly append themselves to a base which has path components.
...
Endpoint values which contain a leading / are absolute.
Absolute values retain only the host from baseUrl and ignore any
specified path components.
as presently written, the path referenced in your call to Endpoints.newuser() is absolute, and therefore the path segments after the host in your base URL are dropped (as this is the documented behavior).
therefore, you should change your Endpoints interface to use relative paths instead, like so:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}

Spring Integration TcpInboundGateway sending conditional reply

I have configured TcpInboundGateway to receive requests from client and my configuration is as follows. So as per below configuration every client requested is responded back,but what i want is response should be send back only if certain condition is true,not the every time, what changes needs to be done in configuration?
#SpringBootApplication
#IntegrationComponentScan
public class SpringIntegrationApplication extends SpringBootServletInitializer{
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext ctx = SpringApplication.run(SpringIntegrationApplication.class, args);
System.in.read();
ctx.close();
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringIntegrationApplication.class);
}
private static Class<SpringIntegrationApplication> applicationClass = SpringIntegrationApplication.class;
#Bean
TcpNetServerConnectionFactory cf(){
TcpNetServerConnectionFactory connectionFactory=new TcpNetServerConnectionFactory(8765);
return connectionFactory;
}
#Bean
TcpInboundGateway tcpGate(){
TcpInboundGateway gateway=new TcpInboundGateway();
gateway.setConnectionFactory(cf());
gateway.setRequestChannel(requestChannel());
return gateway;
}
#Bean
public MessageChannel requestChannel(){
return new DirectChannel();
}
#MessageEndpoint
public class Echo {
#ServiceActivator(inputChannel="requestChannel")
public byte[] echo(byte[] in,#SuppressWarnings("deprecation") #Header("ip_address") String ip){
byte[] rawbytes = gosDataSerivce.byteArrayToHex(in,ip);//Process bytes and returns result
return rawbytes;
}
}
}
Not sure where is your problem, but you can just simply return null from your echo(). In that case the ServiceActivatingHandler doesn't care and stops it work. Just because of requiresReply = false.
From other side the TcpInboundGateway doesn't care about null, too:
Message<?> reply = this.sendAndReceiveMessage(message);
if (reply == null) {
if (logger.isDebugEnabled()) {
logger.debug("null reply received for " + message + " nothing to send");
}
return false;
}
That is possible because of replyTimeout option for the MessagingTemplate on the background. By default it is 1 sec. After that the sendAndReceiveMessage() just returns null to the caller.
You can adjust this option on the TcpInboundGateway.

Spring Boot #RestController rejects a POST request

A POST request
http://localhost:9278/submitEnrollment
to a Spring Boot application that encapsulates an external SOAP call results in the following:
{
"timestamp": 1439480941381,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/submitEnrollment"
}
This doesn't seem to be a normal behavior, I'm wondering what Spring Boot configurations I need to relax/disable to prevent this client authentication.
Here are relevant pieces of code:
Configuration for the app (that entails all the necessary plumbing to send a secured SOAP call over SSL and should affect web tier):
#Configuration
#ComponentScan({"a.b.c.d", "com.submit.enrollment"})
#PropertySource("classpath:/submit-enrollment.properties")
public class SubmitEnrollmentConfig {
#Value("${marshaller.contextPaths}")
private String[] marshallerContextPaths;
#Value("${default.Uri}")
private String defaultUri;
#Bean
public FfmSoapClient connectivityClient() throws Throwable {
FfmSoapClient client = new FfmSoapClient();
client.setWebServiceTemplate(webServiceTemplate());
return client;
}
#Bean
public KeyStore keyStore() throws Throwable {
KeyStoreFactoryBean keyStoreFactory = new KeyStoreFactoryBean();
keyStoreFactory.setPassword("!zxy!36!");
keyStoreFactory.setLocation(new ClassPathResource("zxy.jks"));
keyStoreFactory.setType("jks");
keyStoreFactory.afterPropertiesSet();
return keyStoreFactory.getObject();
}
#Bean
public KeyManager[] keyManagers() throws Throwable{
KeyManagersFactoryBean keyManagerFactory = new KeyManagersFactoryBean();
keyManagerFactory.setKeyStore(keyStore());
keyManagerFactory.setPassword("!zxy!36!");
keyManagerFactory.afterPropertiesSet();
return keyManagerFactory.getObject();
}
#Bean
public HttpsUrlConnectionMessageSender httpsUrlSender() throws Throwable {
HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
sender.setSslProtocol("TLS");
sender.setKeyManagers(keyManagers());
return sender;
}
#Bean
public WebServiceTemplate webServiceTemplate() throws Throwable {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(marshaller());
webServiceTemplate.setUnmarshaller(marshaller());
webServiceTemplate.setDefaultUri(defaultUri);
webServiceTemplate.setMessageFactory(messageFactory());
webServiceTemplate.setMessageSender(/*new HttpComponentsMessageSender()*/httpsUrlSender());
webServiceTemplate.setInterceptors(new ClientInterceptor[] { wss4jSecurityInterceptor(), new LogbackInterceptor() }); //order matters
webServiceTemplate.setMessageSender(httpsUrlSender());
return webServiceTemplate;
}
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPaths(marshallerContextPaths);
return marshaller;
}
#Bean
public SaajSoapMessageFactory messageFactory() {
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
messageFactory.setSoapVersion(SoapVersion.SOAP_12);
return messageFactory;
}
#Bean
public Wss4jSecurityInterceptor wss4jSecurityInterceptor() throws Throwable{
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions(/*"UsernameToken"*/WSHandlerConstants.USERNAME_TOKEN + " "+ WSHandlerConstants.TIMESTAMP);
//wss4jSecurityInterceptor.setSecurementActions("Signature");
wss4jSecurityInterceptor.setSecurementUsername("07.ZIP.NJ*.390.639");
wss4jSecurityInterceptor.setSecurementPassword("oLD#cDh$(dKnCM");
wss4jSecurityInterceptor.setSecurementPasswordType(/*"PasswordDigest"*/WSConstants.PW_DIGEST);
wss4jSecurityInterceptor.setSecurementEncryptionCrypto(crypto());
wss4jSecurityInterceptor.setSecurementEncryptionKeyIdentifier("DirectReference");
//wss4jSecurityInterceptor.setValidationActions("Signature");
//wss4jSecurityInterceptor.setValidationSignatureCrypto( crypto() );
wss4jSecurityInterceptor.setSecurementTimeToLive(300);
return wss4jSecurityInterceptor;
}
#Bean
public Crypto crypto() throws Throwable {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(new ClassPathResource("zipari.jks"));
cryptoFactoryBean.setKeyStorePassword("!zxy!36!");
cryptoFactoryBean.afterPropertiesSet();
Crypto crypto = cryptoFactoryBean.getObject();
System.out.println("created crypto store: "+ crypto);
return crypto;
}
#Configuration
static class DatabaseConfig {
#Bean #Lazy
DataSource dataSource() {
return null;
}
}
}
Application:
public static void main(String[] args) throws Throwable {
SpringApplication app = new SpringApplication(SubmitEnrollmentApplication.class);
//app.addListeners(new ApplicationPidFileWriter());
ApplicationContext ctx = app.run(args);
Controller:
#RestController
public class SubmitEnrollmentController {
private final Logger logger = LoggerFactory.getLogger(SubmitEnrollmentController.class);
//#Autowired #Qualifier("brokerService")private BrokerService service;
#RequestMapping(value = "/submitEnrollment", method = RequestMethod.POST, consumes="application/json")
public String submitEnrollment(#RequestBody String jsonIn){
logger.info("Received submit enrollment request: {}, start processing...", jsonIn);
The following addition to the main Spring config file helped me achieve what I needed:
#Configuration
static class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/**");
}
}
Your problem is, your rest endpoints are authenticated with spring security. So the error message clearly indicates that, you want to be authenticate yourself before sending the request. You can ignore the authentication, until you make sure everything is working. What you will need is something like this.
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/submitEnrollment").permitAll().and().csrf().disable();
}
You can find a good config from here. If you need more complex config, go through this jhipster project, and specifically this file.
It is better you can go through these docs as well. Hope this helps.

Dummy backend for ISO 8583 message

I want to create dummy backend for ISO 8583 messages. The necessary condition for this problem is "to run the jPos/other ATM test-suite against this backend".
You may try simple jReactive-iso8583 server.
Have a look at client-server integration test.
Usage example:
Spring config:
#Configuration
public class Iso8583ServerConfig {
#Value("${iso8583.connection.port}")
int port;
#Bean
public org.jreactive.iso8583.server.Iso8583Server iso8583Server() throws IOException {
return new org.jreactive.iso8583.server.Iso8583Server(port, serverMessageFactory());
}
#Bean
MessageFactory serverMessageFactory() throws IOException {
MessageFactory messageFactory = ConfigParser.createDefault();
messageFactory.setCharacterEncoding(StandardCharsets.US_ASCII.name());
messageFactory.setUseBinaryMessages(false);
messageFactory.setAssignDate(true);
return messageFactory;
}
}
Add custom message listener somewhere:
server.addMessageListener(new IsoMessageListener() {
#Override
public boolean applies(IsoMessage isoMessage) {
return isoMessage.getType() == 0x200;
}
#Override
public boolean onMessage(ChannelHandlerContext ctx, IsoMessage isoMessage) {
capturedRequest = isoMessage;
final IsoMessage response = server.getIsoMessageFactory().createResponse(isoMessage);
response.setField(39, IsoType.ALPHA.value("00", 2));
response.setField(60, IsoType.LLLVAR.value("XXX", 3));
ctx.writeAndFlush(response);
return false;
}
});
Then run a server:
server.init();
server.start();
Shutdown server:
server.shutdown();

Resources