Showing posts with label Spring. Show all posts

Client Backend - Project for interview

by GarciaPL on Sunday, 1 October 2017

Recently I was creating small distributed application called ClientBackend just for interview purpose. Solution consists of thee microservices :

  • Client (received request from API Gateway and sends it to Backend)
  • Backend (performs operation defined in request)
  • Discovery (Spring Eureka)
  • API Gateway (Spring Zuul)
Technology stack :
  • Java 8
  • Spring Boot
  • Hystrix
  • Eureka
  • Feign
  • Zuul
  • TypeOf

More info about the solution https://github.com/GarciaPL/ClientBackend

Spring Integration - Header Routing by Header Key

by GarciaPL on Sunday, 8 January 2017

As you can see Spring Integration posts are going to be continued! This time I would like to share with you small hint of code which will help you to route your message based on existing or not key Signature in your headers.

<int:router id="headerRouter" expression="headers.containsKey('Signature')"
            default-output-channel="processFurther">
    <int:mapping value="false" channel="drop"/>
    <int:mapping value="true" channel="processFurther"/>
</int:router>

References :  [1] Spring Docs - Message Routing

Spring Integration - Cache requests for inbound/outbound gateway

by GarciaPL

Do you use inbound or outbound http gateway in Spring Integration and you was thinking about caching some requests ? There is a solution for that! It's can be achieved with <request-handler-advice-chain> and Spring Cache Advice.

<int-http:outbound-gateway>
   <int-http:request-handler-advice-chain>
        <cache:advice>
              <cache:caching cache="cacheKey">
                    <cache:cacheable method="handle*Message" key="#a0.payload.id"/>
              </cache:caching>
        </cache:advice>
   </int-http:request-handler-advice-chain>
</int-http:outbound-gateway>

You might see above that handle*Message will be considered by Spring Cache Advice to invoke cache functionality. To be more specific we are thinking about handleRequestMessage method and it's parameters defined as a part of HttpRequestExecutingMessageHandler which will be considered as a key - id in our case. Moreover you need to define explicitly cacheManager bean and define key for cache entry (cacheKey in our case) using for instance EhCache.

References : [1] Spring Integration - Cache for inbound/outbound gateway

Spring Test DBUnit - Table already exists

by GarciaPL on Saturday, 16 April 2016

I had a chance to work with Spring Test DBUnit [1] (integration between Spring testing framework and DBUnit) with few tests related with Spring Integration. Most of them use the same common text context which contains embedded database H2. Funny thing was that some tests failed, because of some tables already exist. The issue is that embedded database is not cleared between tests and it is reused within the same context. That's why you should use @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) with @TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) like below :

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class YourTest {

}




Reference :
[1] Spring Test DBUnit

[2] Spring Framework - DirtiesContext

Pack CSV files in ZIP Archive

by GarciaPL on Saturday, 5 March 2016

This time I would like to share with small snippet of code written in Java and Spring MVC which might allow you to pack and download some files (in this case .csv file) in ZIP archive. So, if you will hit URL http://localhost:8090/yourApp/download/zip, Zip archive will be downloaded with name 'download.zip'.

    @ResponseBody
    @RequestMapping(value = {"/download/zip"}, method = RequestMethod.GET)
    public void downloadZipArchive(HttpServletResponse response) throws IOException {

        List<MyClass> list; //should contains some records!
        if (list != null && !list.isEmpty()) {
            if (list.size() > 200000) {

                response.setContentType("application/zip");
                response.addHeader("Content-Disposition", "attachment; filename=\"download.zip\"");
                response.addHeader("Content-Transfer-Encoding", "binary");

                OutputStream servletOutputStream = response.getOutputStream();
                ZipOutputStream zos = new ZipOutputStream(servletOutputStream);

                int counter = 0;
                List<List<MyClass>> dividedlist = Lists.partition(list, 200000);
                for (List<MyClass> partition : dividedlist) {
                    zos.putNextEntry(new ZipEntry("file_" + counter + ".csv"));
                    CSVWriter writer = new CSVWriter(new OutputStreamWriter(zos));
                    writer.writeNext(new String[]{"HEADER"});
                    for (MyClass item : partition) {
                        writer.writeNext(new String[]{item.getText()});
                    }
                    writer.flush();
                    zos.closeEntry();
                    counter++;
                }
                zos.close();
                response.getOutputStream().flush();
                response.getOutputStream().close();
            }
        }
    }

Guava FluentIterable - Get only first object or null from list

by GarciaPL on Tuesday, 23 February 2016

A few days ago I had issue, that I need to get first object from some list which meet my requirements. Of course I can create some loop, write some if statement. If I will find interesting me object, then I am gonna return it. If I will not find any useful in whole list, then I am will return null.

Above solution is done in quite old-style approach. Now it is time for functional programming! I found very useful a library called Guava and it's utility class called FluentIterable. It supports you to manipulate Iterable instances in a chained fashion. This class has a lot of functionalities, but I would like to focus only on one case - get first interesting object to my pattern or just return null.

MyClass interestingObjectOrNull = FluentIterable.from(myList)
    .firstMatch(new Predicate<MyClass>() {
      @Override
      public boolean apply(MyClass element) {
        return element.getId == 125L
      }
    })
    .orNull();


And that's it! Simple, isn't ? All you need to remember to check returned object if it is null or not. Of course you might write as much complex apply pattern as you like.
Reference :
[1] Stackoverflow - Get only element of a collection view with Guava, without exception when there are multiple elements
[2] Pastebin - Source code

Spring MVC Formatters for BigDecimal and Long

by GarciaPL on Saturday, 23 January 2016

In recent times I had issue with web application written in Spring. The problem was that some numbers stored in database as a BigDecimal's and Long's were not being stored/processed properly for different locales. On backend the numbers were processed of course using English locale, but when you have number saved with different locale the calculations might be different.

Saved BigDecimal's and Long's were processed against English locale, but presentation of numbers were based on appropriate locale of present user context.


Parse BigDecimal => 12,333,444
English => 12333444
Indonesian => 12333444

Print BigDecimal => 12345.50
English => 12345.50
Indonesian => 12345,50


Only difference for printed numbers for above locales was how decimal places is presented. For English we use dot. For Indonesian comma is used.


Parse Long => 12,333,444
English => 12333444
Indonesian => 12333444

Print Long => 12333444
English => 12333444
Indonesian => 12333444


For Long's the formatter we are going to just remove grouping commas.

So, below you can find CurrencyLocaleBigDecimalFormatter :

package pl.garciapl.test;

import org.springframework.format.Formatter;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

public class CurrencyLocaleBigDecimalFormatter implements Formatter<BigDecimal> {

    @Override
    public BigDecimal parse(String text, Locale locale) throws ParseException {
        DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
        format.applyPattern("#,##0.00");
        format.setParseBigDecimal(true);
        format.setGroupingUsed(true);
        return (BigDecimal) format.parse(text);
    }

    @Override
    public String print(BigDecimal object, Locale locale) {
        DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(locale);
        format.applyPattern("#,##0.00");
        format.setParseBigDecimal(true);
        format.setGroupingUsed(false);
        return format.format(object);
    }
}



and CurrencyLocaleLongFormatter :


package pl.garciapl.test;

import org.springframework.format.Formatter;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

public class CurrencyLocaleLongFormatter implements Formatter<Long> {

    @Override
    public Long parse(String text, Locale locale) throws ParseException {
        DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
        format.applyPattern("#,##0.00");
        format.setParseBigDecimal(false);
        format.setGroupingUsed(true);
        return (Long) format.parse(text);
    }

    @Override
    public String print(Long object, Locale locale) {
        DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(locale);
        format.applyPattern("#,##0.00");
        format.setParseBigDecimal(false);
        format.setGroupingUsed(false);
        return format.format(object);
    }
}


Also CurrencyLocaleFormatterRegistrar is needed because of Spring framework needs to register formatters in registry to use them.

package pl.garciapl.test;

import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;

import java.util.HashSet;
import java.util.Set;

public class CurrencyLocaleFormatterRegistrar implements FormatterRegistrar {

    private Set<Formatter> formatters = new HashSet<>();

    public CurrencyLocaleFormatterRegistrar(Set<Formatter> formatters) {
        this.formatters = formatters;
    }

    @Override
    public void registerFormatters(FormatterRegistry registry) {
        for (Formatter element : this.formatters) {
            registry.addFormatter(element);
        }
    }
}

And finally whole beans configuration for Spring

    <bean id="currencyLocaleBigDecimalFormatter" class="ie.garciapl.test.CurrencyLocaleBigDecimalFormatter"/>
    <bean id="currencyLocaleLongFormatter" class="ie.garciapl.test.CurrencyLocaleLongFormatter"/>
    <bean id="currencyLocaleRegistrar" class="ie.garciapl.test.CurrencyLocaleFormatterRegistrar">
        <constructor-arg>
            <set>
                <ref bean="currencyLocaleBigDecimalFormatter"/>
                <ref bean="currencyLocaleLongFormatter"/>
            </set>
        </constructor-arg>
    </bean>

Do not forget to plug into your conversionCurrencyService as below :

<mvc:annotation-driven conversion-service="conversionCurrencyService"/>

Reference : [1] Spring Docs - Formatters [2] Javabeat.net - Introduction to Spring Converters and Formatters [3] CurrencyLocaleBigDecimalFormatter [4] CurrencyLocaleLongFormatter [5] CurrencyLocaleFormatterRegistrar [6] CurrencyLocaleBigDecimalFormatterTest [7] CurrencyLocaleLongFormatterTest

Cross Site Scripting - XSSRequestWrapper

by GarciaPL on Saturday, 5 December 2015

We all know what Cross Site Scripting (XSS) [1] means. In short the idea is that input parameters in our application should be checked for containing characters with special meaning in HTML for instance <, >, /. Those signs should be escaped by application into &amp;, &lt;, &gt;, &#x27;, &quot;, &#x2F before they will be processed by backend.

First of all you need implement Filter [7][2] which will intercept incoming requests to backend for further processing.

package pl.garciapl.xss;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import java.io.IOException;

public class RequestFilter implements Filter {

    private final static Logger logger = LoggerFactory.getLogger(RequestFilter.class);

    public void init(FilterConfig fConfig) throws ServletException {
        logger.debug("RequestFilter initialized");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
    }

    public void destroy() {
    }
}

Then you need define XSSRequestWrapper [3] used to filter every request. You can also find test class XSSRequestWrapperTest [4] which might give you preview what kind of malicious HTML might occur and what might be desirable output.

package pl.garciapl.xss;

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.owasp.esapi.ESAPI;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class XSSRequestWrapper extends HttpServletRequestWrapper {

    public XSSRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);

        if (values == null) {
            return null;
        }

        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = stripXSS(values[i]);
        }

        return encodedValues;
    }

    @Override
    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        return stripXSS(value);
    }

    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        return stripXSS(value);
    }

    private String stripXSS(String value) {
        if (value != null) {
            // It's highly recommended to use the ESAPI to avoid encoded attacks.
            value = ESAPI.encoder().canonicalize(value);
            // Avoid null characters
            value = value.replaceAll("", "");

            value = Jsoup.clean(value, Whitelist.none());
        }
        return value;
    }

}

Above class filters also headers and content of requests. As you can see method stripXSS uses ESAPI [6] library. The ESAPI (Enterprise Security API) is an OWASP project to create simple strong security controls for every web platform. I also use library called Jsoup [5] to clean once again suspect HTML [8].



Reference : [1] Cross Site Scripting Wikipedia [2] RequestFilter Pastebin [3] XSSRequestWrapper Pastebin [4] XSSRequestWrapperTest Pastebin [5] Jsoup 1.8.3 Maven [6] ESAPI 2.1.0 Maven [7] Servlet Filters and Event Listeners Doc [8] Jsoup Sanitize untrusted HTML (to prevent XSS)

SimpleUrlAuthenticationFailureHandler Locale based

by GarciaPL on Saturday, 26 September 2015

Some of you may use Spring Security in your application. Let's assume that your application is localized for many different languages. In this post I would like to give you some solution for case when user loggs into your application and should be redirected to specified address with appropriate locale for that user. I think, because I am not sure that in this case LocaleResolver would not work because before user loggs in, you will receive for instance English locale which depends on what configuration is on your server. In this case you need to use CookieLocaleResolver. Another assumption - I hope that your app uses cookies.


package com.garciapl.security;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;

public class AuthenticationFailureImpl extends SimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler {

    private String defaultFailureUrl;
    private String langToken = "?lang=";
    private CookieLocaleResolver localeResolver;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

        Locale requestLocale = localeResolver.resolveLocale(request);
        saveException(request, exception);
        if (requestLocale != null) {
            new DefaultRedirectStrategy().sendRedirect(request, response, defaultFailureUrl + langToken + requestLocale.getLanguage());
        } else {
            new DefaultRedirectStrategy().sendRedirect(request, response, defaultFailureUrl + langToken + Locale.ENGLISH.getLanguage());
        }
    }

    public void setDefaultFailureUrl(String defaultFailureUrl) {
        this.defaultFailureUrl = defaultFailureUrl;
    }

    public void setLocaleResolver(CookieLocaleResolver localeResolver) {
        this.localeResolver = localeResolver;
    }
}

Of course there is a bean configuration for this class :


        
        
    

Gson Timestamp deserialization

by GarciaPL

Google Gson [1] is very useful library for parsing JSON to our domain object. It supports mapping JSON to such formats as Long, String, Integer, Boolean etc. The problem is when you have Timestamp [2] in your domain object. You are forced to write Adapter [3] which will help you to make it happen.

package com.garciapl.parser;


import com.google.gson.*;
import com.garciapl.model.dto.ExampleDTO;

import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TimestampAdapter implements JsonDeserializer {

    private final DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public ExampleDTO deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) {
        if (json.isJsonObject()) {
            JsonObject jsonObject = (JsonObject) json;
            String startDate = jsonObject.has("startDate") ? jsonObject.get("startDate").getAsString() : null;
            String endDate = jsonObject.has("endDate") ? jsonObject.get("endDate").getAsString() : null;

            Timestamp startDateStamp = null;
            Timestamp endDateStamp = null;
            if (startDate != null && endDate != null) {
                startDateStamp = createTimestamp(startDate);
                endDateStamp = createTimestamp(endDate);
            }

            return new ExampleDTO(startDateStamp, endDateStamp);
        }
        return new ExampleDTO();
    }

    private Timestamp createTimestamp(String json) {
        try {
            Date date = format.parse(json);
            return new Timestamp(date.getTime());
        } catch (ParseException e) {
            throw new JsonParseException(e);
        }
    }
}


Below you can find how to use this above adapter in GsonBuilder :


package com.garciapl.parser;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.garciapl.model.dto.ExampleDTO;
import com.garciapl.util.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Modifier;
import java.lang.reflect.Type;

@Component
public class JsonParser {

    private final static Logger logger = LoggerFactory.getLogger(JsonParser.class);

    private Gson gson;

    public JsonParser() {
        gson = new GsonBuilder()
                .serializeNulls()
                .disableHtmlEscaping()
                .setDateFormat(Localization.BASE_DATE_FORMAT)
                .registerTypeAdapter(ExampleDTO.class, new TimestampAdapter())
                .excludeFieldsWithModifiers(Modifier.TRANSIENT)
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
                .setPrettyPrinting()
                .create();
    }

    public  T fromJson(String json, Class destinationClass) {
        if (json == null || json.isEmpty()) {
            try {
                return destinationClass.newInstance();
            } catch (InstantiationException e) {
                logger.error("JsonParser exception : ", e);
                return null;
            } catch (IllegalAccessException e) {
                logger.error("JsonParser exception : ", e);
                return null;
            }
        } else {
            return gson.fromJson(json, destinationClass);
        }
    }
}







Reference: [1] https://github.com/google/gson [2] Timestamp Java Doc [3] Gson TypeAdapter

Recruitment Tech Test #2

by GarciaPL on Saturday, 15 August 2015

Some time ago I have solved another technical test for one company. As the same before this test was performed for recruitment process.

This application is dedicated for tellers which provides functionalities like :

  1. Create account(s) - a user can create an account, associate a name with it, give it a unique account number, add a starting balance etc.
  2. Make lodgement - a user can lodge an amount into an account (balance increase)
  3. Make transfer - a user can transfer an amount from one account to another (balance transfer)
  4. View transactions - a user can view recent, or all, transactions for an account (statement)
Application was developed using Java 7 and Spring Framework 4.0.1. Below you can find out what libraries were used in application :

  • Spring Beans – 4.0.1.RELEASE
  • Spring Tx – 4.0.1.RELEASE
  • Spring Context – 4.0.1.RELEASE
  • Spring Context Support – 4.0.1.RELEASE
  • Spring Orm – 4.0.1.RELEASE
  • Spring Jdbc – 4.0.1.RELEASE
  • Spring Web – 4.0.1.RELEASE
  • Spring Web MVC – 4.0.1.RELEASE
  • Spring Test - 4.0.1.RELEASE
  • Joda Money - 0.10.0
  • Jackson Core - 2.5.0
  • Jackson Databind - 2.5.0
  • Jackson Annotations - 2.5.0
  • Javax Servlet API – 3.1.0
  • JSTL – 1.2
  • Hibernate Core - 4.3.5.Final
  • Hibernate Entitymanager - 4.3.5.Final
  • HSQLDB - 2.3.3
  • SLF4J - 1.7.8
  • Commons Logging - 1.2
  • JUnit - 4.10
  • Mockito - 1.9.5
  • Hamcrest - 1.3
  • Twitter Bootstrap - 3.3.4
  • DataTables - 1.10.7
  • jqBootstrapValidation - 1.3.6


Home screen


Create new account

Deposit money


Transfer money

Transactions


Application for tellers has also built-in Jetty web sever container which allows you run it very quickly using command mvn jetty:run in directory of project. After that application should be accessible under context http://localhost:9090/banknow/.
You can also build own WAR file using command mvn war:war in directory of project. War will be accessible under directory /target and called banknow.war.
Reference :
[1] GarciaPL Github.com BankNow
[2] Jetty
[3] HSQLDB
[4] jQuery DataTables
[5] jQuery jqBootstrapValidation

Recruitment Tech Test

by GarciaPL on Tuesday, 23 June 2015

Some of you might have a knowledge that one of the IT company has created a technical test. For recruitment process of course. I decided to take up this challenge. Below you can find a solution of it. I posted this only for educational purposes.

The projects is splited into two modules : currencyfair-gateway and currencyfair-consumer.

The first module currencyfair-gateway is responsible for exposing endpoint used for retriving from user request in JSON format. Request is validated due to it's fields. If request is not valid user will receive detailed information about which fields are incorrect. Otherwise request will be forwarded to message broker RabbitMQ.

The second module currencyfair-consumer fetches messages from message broker RabbitMQ to process it via Data Processor. Once it's done the processed data are broadcasted to frontend.
Application was developed using of course Java and Spring Framework. Those above two modules were connected via message broker RabbitMQ. Below you can see what is the overall architecture of this application. Other used libraries :

  • Spring Beans – 4.0.1.RELEASE
  • Spring Tx – 4.0.1.RELEASE
  • Spring Context – 4.0.1.RELEASE
  • Spring Context Support – 4.0.1.RELEASE
  • Spring Aop – 4.0.1.RELEASE
  • Spring Aspects - 4.0.1.RELEASE
  • Spring Web – 4.0.1.RELEASE
  • Spring Web MVC – 4.0.1.RELEASE
  • Spring AMQP - 1.4.5.RELEASE
  • Spring Erlang - 1.4.5.RELEASE
  • Spring Rabbit - 1.4.5.RELEASE
  • Spring WebSocket - 4.0.1.RELEASE
  • Spring Messaging - 4.0.1.RELEASE
  • Spring Integration - 4.1.0.RELEASE
  • Spring Integration AMQP - 4.1.0.RELEASE
  • Spring Integration Stream - 4.1.0.RELEASE
  • Spring Test - 4.0.1.RELEASE
  • Jackson Core - 2.5.0
  • Jackson Databind - 2.5.0
  • Jackson Annotations - 2.5.0
  • Jackson Mapper ASL – 1.9.10
  • Gson – 2.2.4
  • Guava - 18.0
  • Unirest - 1.4.5
  • Javax Servlet API – 3.1.0
  • JSTL – 1.2
  • SLF4J - 1.7.8
  • Commons Logging - 1.2
  • JUnit - 4.10
  • Mockito - 1.9.5
  • Hamcrest - 1.3
  • Highcharts - 4.1.5
  • Twitter Bootstrap - 3.3.4
  • SockJS - 0.3.4
I also used external resource like ECB Currency Rates (European Central Bank) for calculating income financial data from various currencies to one based EUR currency.

Architecture

Endpoint

Endpoint consumes JSON data on context /currencyfair-gateway/endpoint like below :


{ 
    "userId": "12345",
    "currencyFrom": "EUR",
    "currencyTo": "GBP",
    "amountSell": 1000,
    "amountBuy": 747.10,
    "rate": 0.7471,
    "timePlaced" : "24-JAN-15 10:27:44",
    "originatingCountry" : "FR"
}

Message is validated under empty of above fields, timePlaced format (dd-MMM-yy hh:mm:ss), existing of currencyFrom and currencyTo in ISO 4217, existing of originatinCountry in ISO 3166-1 and by calculations of amountSell, amountBuy and rate.


Data processor

Module is reponsible for calculating all data required by frontend to display it on charts.

GraphBroker

Module sends data supplied by Data processor to specific Stomp endpoints.

Frontend

Each graph subscribes data via Stomp over WebSocket from specific context. At this moment there are implemented some graphs which can be found on GitHub repository. 


References :  [1] https://github.com/GarciaPL/CurrencyFair

Portfolio

by GarciaPL

I recently uploaded my portfolio on GitHub Pages. If you are interested in projects which was developed just visit below website :

GarciaPL.github.io




Could not Autowire. No beans of 'SimpMessagingTemplate' type found

by GarciaPL on Saturday, 6 June 2015

My main IDE which is used at this time to develop for example Spring application is IntelliJ IDEA 13.1. My last project is built on Spring Framework 4. There is no so much problems with it, but there is one with Spring WebSocket. When you are going to autowire SimpMessagingTemplate object there is an error :

"Could not Autowire. No beans of 'SimpMessagingTemplate' type found"

The solution is very simple. Just add in your bean xml, in my case it's dispatcher-servlet.xml this line :

<context:component-scan base-package="org.springframework.web.socket.config"/>

As far as I know this problem is fixed in Intellij IDEA 14.0. Below you can read about ticket which is strictly related with this issue.

If this solution above did not work perhaps you need to move bean definition of your class which contains Autowired field of SimpMessagingTemplate to dispatcher-servlet.xml, I mean context which is pointed in your web.xml by org.springframework.web.servlet.DispatcherServlet.


Reference :
[1] Jetbrains IDEA-123964

TrafficCity BIHAPI Orange

by GarciaPL on Saturday, 14 March 2015

Today I have released on GitHub two repositories which contain one of my recent project called TrafficCity. It was developed on hackathon called BIHAPI (Business Intelligence Hackathon API) organized by Orange Poland.

Briefly describing what's it's about in this app - on the mobile app you can place your markers (waypoints) on Google Maps which describes your daily route to work/school. After that you can send those waypoints to server to further processing.

In Backend you can see what's routes are defined by users. Additionally you can upload OSM file which is strongly related with OpenStreetMap and after that you can see on particular area what's is the chance to appear traffic jam.

An application consists of Backend app written in Spring and mobile app written in Android. Application was mainly deployed on JBoss AS 7.1. Backend part is also using interfaces provided by Orange - SIM GeoLocalization API, SMS API, USSD API and by Warsaw City - Transport POI Maps.

Unfortunately, I think that application which is in alpha phase, probably would remain so. There a few things to do/fix on the Backend and Mobile part, but not at this moment. I hope that more appropriate time will come.

Below I allowed myself to post some screenshots from backend and mobile part of this application.

Dashboard

Markers
OSM Upload
OSM Projects
HeatMap


Home
Settings
Transport Type
First marker
Multiple markers
Daily route
Settings


Reference :
[1] GitHub TrafficCity Backend
[2] GitHub TrafficCity Android
[3] BIHAPI

Spring Remoting - RmiServiceExporter

by GarciaPL on Saturday, 22 November 2014

I would like to present you very quick cheat sheet about how implement RMI (Remote Method Invocation) [3] which performs the object-oriented equivalent of RPC in Spring using RmiServiceExporter [1] (used to expose RMI interface) and RmiProxyFactoryBean [2] (used to consume RMI interface).

First of all, you must create some interface which will be used to expose your methods [4]

public interface IUser {
        UserDTO retrieveUserById(Long userId);
        UserDTO register(UserDTO user) throws RegisterException;
}

Next provide some implementation for interface IUser in the form of class [5]

public class UserManager implements IUser {
    private IUserDao userDao;
 
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public UserDTO retrieveUserById(Long userId) {
        return userDao.retrieveUserById(userId);
    }
 
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
    public UserDTO register(final UserDTO user) throws AVValidationException {
 
        if (user == null) {
            throw new IllegalArgumentException("Wrong params. user cannot be NULL");
        }
 
        return userDao.register(user);
    }
 
    public IUserDao getUserDao() {
        return userDao;
    }
 
    public void setUserDao(final IUserDao userDao) {
        this.userDao = userDao;
    }
}
And of course you must provide XML Bean definition [6].
Next in your XML with Beans you should export RMI using RmiServiceExporter [7].
Now you can use this RMI exposed under service name called JSUserManager after providing definition in XML Bean [8].
Please do not forget about initialization your RMI like below [9].
    private void run() {
        logger.info("creating ctx...");
        final AbstractApplicationContext ctx;
        try {
            ctx = new ClassPathXmlApplicationContext(
                    "/garciapl-service-rmi-ctx.xml"
            );
            logger.info("ctx created; registering shutdown hook");
            ctx.registerShutdownHook();
 
            logger.info("Starting up the application.  Stand by... ;)");
 
            logger.info("Creating MP service...");
            ctx.getBean("userManagerRMI");
 
        } catch (Throwable e) {
            logger.fatal("exception caught during initialization: ", e);
            System.exit(-1);
        }
        logger.info("app is up and running");
 
        synchronized (this) {
            try {
                wait();
            } catch (InterruptedException e) {
                logger.error("wait interrupted", e);
            }
        }
        logger.info("Exiting...");
        System.exit(0);
    }

Reference : [1] Spring Docs - RmiServiceExporter [2] Spring Docs - RmiProxyFactoryBean [3] Oracle Docs - RMI [4] Pastebin - RMI Interface [5] Pastebin - Interface implementation [6] Pastebin - Interface implementation XML Bean [7] Pastebin - RmiServiceExporter [8] Pastebin - RmiProxyFactoryBean [9] Pastebin - Register RMI

Send email using Gmail account

by GarciaPL on Wednesday, 10 September 2014

I would like to share with you a small snippet which will allow you to send email using Gmail account. In this case I will use JavaMail (javax.mail) interface for sending email messages. More information about JavaMail API reference you can find below.

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

private void sendEmail() {

        String sender = "sender@gmail.com";
        String receiver = "receiver@gmail.com";
        String title = "YOUR_TITLE_TEXT";
        String body = "YOUR_BODY_TEXT";

        Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "25");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.EnableSSL.enable", "true");
        props.put("mail.smtp.auth", "true");
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");

        Authenticator authenticator = new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("login@gmail.com", "password");
            }
        };

        Session session = Session.getDefaultInstance(props, authenticator);

        try {
            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress(sender));
            msg.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(receiver, receiver));
            msg.setSubject(title);
            msg.setText(body);
            Transport.send(msg);
        } catch (MessagingException e) {
            System.out.println("sendEmail (MessagingException) : " + e.getMessage());
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            System.out.println("sendEmail (UnsupportedEncodingException) : " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("sendEmail (Exception) : " + e.getMessage());
            e.printStackTrace();
        }
}
If you are using Gmail account to send emails, properties related with smtp configuration in this snippet will remain, but you should change variables like sender, receiver, title and body to your needs. You should also change login and password in below line which will be used to authenticate with gmail account :


return new PasswordAuthentication("login@gmail.com", "password");
Reference : [1] Oracle®'s JavaMail API reference [2] Pastebin Source

Spring Data Access Object (DAO)

by GarciaPL on Saturday, 26 October 2013

I would like to present a small example of using Data Access Object (DAO) in Spring. This is a kind of component which provides unified interface to communication between application and source of data for instance database or file. Application using DAO does not have to know the way the data is stored or manipulated in database. This component is commonly used in MVC (Model-View-Controller) which allows to separate data access model from business logic and presentation layer. In this example datasource is NoSQL Database MongoDB.

Below I put some example of DAO Entity called SettingsDao and its Implementation called SettingsDaoImpl.

Entity SettingsDAO :

package pl.eventoo.mongodb.dao;

import pl.eventoo.domain.Settings;

/**
 * Interface of credentials settings
 *
 * @author lukasz
 */
public interface SettingsDao {

    /**
     * Interface for save credentials
     *
     * @param settings 
     */
    public void saveSettings(Settings settings);
    
    /**
     * Interface for update credentials
     * 
     * @param settings
     * @return
     */
    public boolean updateSettings(Settings settings);

    /**
     * Interface for read credentials
     *
     * @return
     */
    public Settings readSettings();
}



Implementation of Entity DAO SettingsDaoImpl :

package pl.eventoo.mongodb.dao;

import com.google.code.morphia.DAO;
import com.google.code.morphia.query.UpdateOperations;
import com.google.code.morphia.query.UpdateResults;
import pl.eventoo.domain.Settings;
import pl.eventoo.mongodb.factory.MongoConnectionManager;

/**
 * Implementation Dao for credentials settings
 *
 * @author lukasz
 */
public class SettingsDaoImpl extends DAO Settings, String implements SettingsDao {

    public SettingsDaoImpl() {
        super(Settings.class, MongoConnectionManager.instance().getDb());
    }

    @Override
    public void saveSettings(Settings settings) {
        save(settings);
    }

    @Override
    public Settings readSettings() {
        return ds.find(Settings.class).get();
    }

    @Override
    public boolean updateSettings(Settings settings) {
        UpdateOperations createUpdateOperations = ds.createUpdateOperations(Settings.class).set("interval_cron", settings.getInterval_cron()).set("time_difference_event", settings.getTime_difference_event());
        UpdateResults update = ds.update(ds.createQuery(Settings.class), createUpdateOperations);
        return update.getHadError();
    }
}


Reference : [1] Springbyexample.org Person DAO [2] Spring Framework 3.0 Docs DAO [3] Spring Framework 3.2 Docs MVC
[4] Pastebin Settings DAO Source
[5] Pastebin Settings Implementation DAO Source

Google Maps JSP in Spring

by GarciaPL on Thursday, 14 March 2013


I had a small issue with adding dynamically markers which were stored in database (mongodb) to google map which was placed on JSP page in Spring application. I hope that someone could use it too own purposes ;)

        
        


Reference :
[1] Pastebin Source
[2] Stackoverflow.com Google Maps JSP in Spring
[3] Google Groups Warszawa JUG