Author Archives: yogesh.mali@gmail.com

How to add SOAP headers to Request/Response

Use Case

In this post, I show how to add SOAP headers to SOAP request/response. If you have Code First Webservice OR WSDL Contract based WebService, you will be responding to your client requests with a SOAP response. In my case, it was a WS-Trust Security Token Web Service and the endpoint was correctly responding with a WS-Trust Response. This SOAP response will include SAMLv1.1 OR SAMLv2.0 token. Now consumer of this web service can either trust the server response or also validate the response for few things like time validity, signature validity, and even security header validity.

If you are supporting Transport Binding on this Web Service endpoint, it will be straight forward. Web Service response will have security headers

But as per my use case, if you are merely using UsernameToken Binding , Web Service response will not include security headers, especially if you are using Apache CXF libraries, these libraries will not always add security headers.

Likewise, if a consumer needs security headers for validation purposes, how do you add these security headers in response from your server endpoint?

Solution

In this particular case, the Web Service response needed Security header with timestamp only.

What is the security header and why Timestamp is required?

In a SOAP request or response, you will need Security header element based on security policy that Web Service will be using. This header in a request will look like below:


<wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
     <wsu:Timestamp wsu:Id="TS-D3788B6EB508E3A553155173495342917">
         <wsu:Created>2019-03-04T21:29:13.429Z</wsu:Created>
         <wsu:Expires>2019-03-04T21:30:13.429Z</wsu:Expires>
     </wsu:Timestamp>
     <wsse:UsernameToken wsu:Id="UsernameToken-6CBAAFA3A8815F71FC15511581437664">
        <wsse:Username>john.doe@betterjavacode.com</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">********</wsse:Password>
     </wsse:UsernameToken>
</wsse:Security>

Once a Web Service endpoint receives this request, it will validate the username and password and will verify if timestamp validity is accurate. On successful validation, Web Service will generate a response that will also include Security header with Timestamp. Consumer will validate that timestamp. Having a timestamp in SOAP header minimizes the risk of Replay attack as in an attacker can’t either use the SOAP response after Expiration time or even can’t send the same request after Expiration time.

How do you add this security header of timestamp if using Apache CXF libraries?

Apache CXF libraries offer few ways to achieve this:

  1. JAX-WS standard way is to write a SOAP handler that will add headers to the SOAP message. To simplify this, you will have to register the SOAP handler on the client or server-side.
  2. JAX-WS offers another way through annotation @WebParam(header = true, mode = Mode.OUT).
  3. wsdl first way wherein your WSDL operation you specify SOAPHeader as part of your SOAP binding.
  4. CXF offers its own way to add these headers. In this post, I will show how you can leverage CXF libraries to add these headers.

How to add Security headers using CXF libraries?

Assumption is that you have used apache CXF libraries to build Web Service endpoint. JAX-WS offers a WebServiceContext which makes a Web Service endpoint to access message context. This message context can help to retrieve details for username, password, and other security headers from the request.

Same way, this message context can be used to grab a list of headers List<org.apache.cxf.headers.Header> . We will create our Soap header for security element and then add this header in the list of headers. The code for this will look like below:


SOAPFactory soapFactory = SOAPFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);

SOAPElement securityElement = soapFactory.createElement("Security",
        "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement timestampElement = soapFactory.createElement("Timestamp",
        "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
timestampElement.setAttribute(WSTrustConstants.WSU_ID, "_0");

String created = getCurrentDateTime();
String expires = getCurrentDateTimePlusDelay(300L);
SOAPElement createdSOAPElement = soapFactory.createElement("Created",
        "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
createdSOAPElement.addTextNode(created);
SOAPElement expiresSOAPElement = soapFactory.createElement("Expires",
        "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
expiresSOAPElement.addTextNode(expires);

timestampElement.addChildElement(createdSOAPElement);
timestampElement.addChildElement(expiresSOAPElement);
securityElement.addChildElement(timestampElement);
SoapHeader soapHeader = new SoapHeader(securityElement.getElementQName(), securityElement);

List<Header> headers = new ArrayList<>();
headers.add(soapHeader);
webServiceContext.getMessageContext().put(Header.HEADER_LIST, headers); 

Conclusion

In this post, I showed how we can leverage Apache CXF libraries to add SOAP headers in a web service response. Similarly, the same libraries can be used to add these headers to the request.

References

  1. Apache CXF Libraries – Apache CXF
  2. Adding SOAP header – Adding SOAP header
  3. Interceptors – interceptors

 

 

Social KPI Application Progress

In this post, I will be showing the progress of Social KPI Application so far through a screencast. This is my first screencast, so learning about OBS (Open Broadcast Software) along the way.

 

Future Sprint Stories

  1. Add Jasper Reports
  2. Integrate with Instagram and Twitter APIs
  3. User Management for administrators
  4. Role Management for users and reports according to roles
  5. Report Management according to account type

JAXB and XML processing

Lately, I have been working on a few interesting problems that I wanted to talk about. So I started studying more of JAXB APIs and the whole rabbit hole is huge. There are a lot of things that I can focus on these APIs. In this post, I will show how to use JAXB APIs for XML processing.

What’s JAXB and how to use APIs for XML Processing?

First, let me talk about JAXB APIs. So XML has been a language for data exchange for some time now. Java and XML came up with a partner to help developers a standard to facilitate between applications, web services, organizations using a similar technology stack. So all developers came together and they built a standard API for Java Architecture for XML Binding (JAXB). I will not describe any other detail about these API in this post, but you can check out this official documentation JAXB. JAXB APIs help to convert XML documents into Java Object and vice versa.

Scenario 1

In this scenario, how do bind a schema to Java object?

JAXB basically simplifies the access of the XML document in Java program. So as part of this, we bind schema for XML document into a set of Java classes.

To demonstrate this example, I am showing a sample XML books.xml as below:


<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>

To convert this XML into Java object, we will follow the following process

  1. Create a JAXBContext Object
  2. Create a Unmarshaller using JAXBContext Object
  3. Call Unmarshal method on Unmarshaller
  4. The result will be a Java object

package com.betterjavacode.jaxbexample;

import java.util.ArrayList;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement
@XmlType(propOrder = {"bookcategory"})
public class Bookstore
{
   private String bookCategory;
   private List books;

   public Bookstore(){}

   public String getBookCategory()
   {
      return this.bookCategory
   }

   public void setBookCategory(String bookCategory)
   {
     this.bookCategory = bookCategory;
   }

   public List getBooks()
   {
      return this.books;
   }

   public void setBooks(List books)
   {
      this.books = books;
   }
}


package com.betterjavacode.jaxbexample;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(namespace = "com.betterjavacode.jaxbexample.Bookstore")
public class Book
{
   private String title;
   private String author;
   private int year;
   private long price;

   public Book()
   {
   }
   
   public Book(String title, String author, int year, long price)
   {
      this.title = title;
      this.author = author;
      this.year = year;
      this.price = price;
   }

   public String getTitle()
   {
     return title;
   }

   public void setTitle(String title)
   {
     this.title = title;
   }

   public String getAuthor()
   {
     return author;
   } 

   public void setAuthor(String author)
   {
     this.author = author;
   }

   public int getYear()
   {
     return year;
   }

   public void setYear(int year)
   {
     this.year = year;
   }

   public long getPrice()
   {
     return price;
   }

   public void setPrice(long price)
   {
     this.price = price;
   }

}

Using annotations and base classes, we can convert xml into java object easily. That process as described will look like below in program:


package com.betterjavacode.jaxbexample;

import java.io.File;
import java.util.ArrayList;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class JAXBXMLToJava
{
    public static final Logger LOGGER = LogFactory.getLogger(JAXBXMLToJava.class);

    public static void main(String[] args)
    {
        try
        {
           JAXBContext jaxbContext = JAXBContext.newInstance(Bookstore.class);
           Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
           File xmlFile = new File("C:\\temp\\books.xml");
           Bookstore bookStore = (Bookstore) unmarshaller.unmarshal(xmlFile);

           ArrayList books = bookStore.getBooks();
           for(Book book:books)
           {
              System.out.println("Book: " + book.getTitle());
           }
        }
        catch(JAXBException e)
        {
           LOGGER.debug("unable to unmarshal", e);
        }
    }
}

So in this scenario, we took an xml and converted that into a java object.

Scenario 2

In this scenario, I will show one of the features of JAXB APIs.

How to change the namespace prefixes?

By default when you marshal Java object to XML, JAXB Marshaller uses default namespace prefixes like ns1, ns2, ns3 etc. While this can be perfectly valid XML for readability purposes, you might run into an issue like signature validation if Signature validation API was expecting different namespaces.

In such cases, JAXB offers a NamespacePrefixMapper which allows you to change your namespace prefixes.

Advantages of JAXB

  • JAXB offers different ways to handle the large size of XML
  • Dealing with XML data can be complex, but in Java world, it is easier to deal with objects. JAXB makes that easy.
  • JAXB allows you to access data in non-sequential order, but unlike DOM-based processing, it doesn’t force you to navigate through a tree to access the data.
  • And JAXB is flexible

Conclusion

Previously, I had shown how to consume a SOAP webservice using JAXB marshaller. In this post, I have given a brief introduction to JAXB APIs and how to use them for XML processing. There are a lot of other features that JAXB APIs offer.

References

  1. JAXB User guide – user guide
  2. Java Architecture for XML Binding – JAXB

 

 

 

All about Kafka Streaming

Lately, I have been hearing a lot about Kafka streaming. Even though I have worked on microservices, I haven’t really tackled heavy data applications. In my previous experience, where we did deal with heavy data for health insurance benefits, it was very different.

Now with Netflix and Amazon, data streaming has become a major target. With growing technology and information, it has become even more important to tackle the growing data. In simple terms, all web applications should be able to process large data sets with improved performance. Data sets size should not deter applications usage.

What is Kafka Data Streaming?

Firstly we used to process large data in batch, but that is not continuous processing and sometimes, it doesn’t work in real-time scenarios for applications. Like Netflix, batch processing will never work. What’s the alternative? The data streaming. Data streaming is a process of sending data sets continuously. This process is the backbone for applications like Netflix and Amazon. Also the growing social network platforms, data streaming is at the heart of handling large data.

The streamed data is often used for real-time aggregation and correlation, filtering, or sampling. One of the major benefits of data streaming is that it allows us to view and analyze data in real-time.

Few challenges that data streaming often faces

  1. Scalability
  2. Durability of data
  3. Fault Tolerance

Tools for Data Streaming

There are a bunch of tools that are available for data streaming. Amazon offers Kinesis, Apache has few open-source tools like Kafka, Storm, and Flink. Similarly, in future posts, I will talk more about Apache Kafka and its usage. Here I am just giving a brief idea about Apache Kafka.

Apache Kafka Streaming

Apache Kafka is a real-time distributed streaming platform. Basically it allows us to publish and subscribe to streams of records.

There are two main usages where Apache Kafka is used:

  1. Building data pipelines where records are streamed continuously.
  2. Building applications that can consume data pipelines and react accordingly

Above all, the basic idea that Kafka has adapted is from Hadoop. It runs as a cluster of one or more servers that can span multiple data centers. These clusters store data streams. Each record in the stream comprised of key, value, and timestamp. Kafka provides four main APIs Producer, Consumer, Streams, Connector.

Similarly, in future posts, I will break down these APIs in detail with their usage in a sample application.

References

  1. Apache Kafka – Kafka
  2. Data Streaming – Data Streaming
  3. Stream Processing – Stream Processing

 

 

 

How to send email with Spring Boot

Scenario

In this post, I show how to use email configuration inside a spring boot application. The use case I want to discuss here is if you have Contact Us page on your web application where you allow users to send email to your sales team or support team, then how do you accomplish this feature about sending an email with contact us form using Spring Boot.

What will you need

  • Java 8
  • IntelliJ
  • A Spring boot based web application

Use case solution

As part of this post, I will not be describing how to build a spring boot based web application. You can visit some of my older posts Saas applicationWeb application with Spring boot security OR Spring boot application with docker. Even though none of these applications have Contact Us page, I will recommend to add that page with a simple form like below:

Contact Us

I have used Bootstrap template to build this form. This form is outside the web application, but I have similar form inside the web application for users to contact sales or support team. In this case, user who wants to sign up for the application can contact my sales team.

Now to use Spring provided facility for sending email from the application to your designated email, we will add following library:

compile('it.ozimov:spring-boot-email-core:0.6.3')

This library provides a EmailService which covers the spring library for spring-boot-starter-mail and do not have to write part of the code to send email. In this example, I will show this EmailService can be used to write a simple method to send email.

First we need to enable email tools by an annotation @EnableEmailTools in our main Spring application. Once we do that, I have written a simple method to send email. This method will look like below:

@Autowired
private EmailService emailService;

private void sendEmail(String emailAddress, String message, String phoneno) throws UnsupportedEncodingException, AddressException
{
    ArrayList<InternetAddress> emails = new ArrayList<>();
    emails.add(new InternetAddress("betterjavacode.com@gmail.com"));
    final Email email = DefaultEmail.builder()
            .from(new InternetAddress(emailAddress))
            .to(emails)
            .subject("Sales Support")
            .body(message + "\n" + phoneno)
            .encoding("UTF-8").build();

    emailService.send(email);
}

Now to make this email service to work, we still have to provide SMTP server properties and a from sender email and password. In this example above, I showed betterjavacode.com as my from gmail address.

Adding following properties in application.properties will set up our SMTP host for sending the email.

spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.username = betterjavacode.com@gmail.com
spring.mail.password =*****************
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000

Conclusion

In this post, I showed how to send email using the Spring boot email configuration feature.