In the previous post, I discussed database design for saas application. To continue design discussion for our social pie saas application, in this post, we will discuss a few more ideas about how a user and user’s company will sign up for application. This will be a user story. We are building a SAAS application. To make it more viable, this application will use the freemium and pay model.
In the freemium model – Any company can join and review what reports it will be able to see and what kind of marketing strategies it can design using those reports.
5 Reports
Free Marketing Strategies
Up to 3 users
Limited usage of twitter and Instagram APIs
In pay model – If a company opts to join a pay subscription, it will be able to get more advance reports, will be able to see reports in a different format, and can also get consultation about strategies for marketing.
N number of reports – Your data, your freedom
Marketing Consultation
KPI tracker and notification
Up to N users (won’t be implemented in first version)
User Flow
Once the user lands on the home page, he can opt for either model and sign up. An automated email will be sent to the user for a demo or sign up. Upon sign up, where the user will be entering details about himself and his company. This user will be an administrator and he can add other users with custom roles. The same user can go to reports tab and click on sync data. This will get the latest data from social media and update it in the database. Every new request will compare newly fetched data with current data in the database. If the new request has brought changes, it will be updated in the database. When generating reports, this data from the database will be cached.
We will not be fetching any on-the-fly data from Twitter and Instagram. Administrator users will have an option to send reports to other people from the company. There will be an email/download option.
There are some nitty-gritty details that I have not covered in this post. But with this post, we will be starting to develop a Saas application using java and spring-boot.
To continue the development of a spring-based web application, this post will discuss using of Twitter API in saas application. If you want to understand, what we are building, you can read the first two posts of this series where we discussed the design of the application we are building:
In the previous post, we discussed the Instagram API that we will be using. With recent events around Facebook, I have decided not to use Facebook API for application development. We will still use Instagram and Twitter API.
Using Twitter API in SAAS Application
Firstly, Twitter offers different APIs for developers to build applications. We will be using Engagement API. You can find more details Twitter API.
Our goal is to use this Twitter API to collect engagement metrics in the Saas application.
Secondly, Engagement API offers us details about account engagement metrics which can help us to design marketing strategy. Sample response of this API looks like the below:
Therefore this API provides metrics for tweets, which tweet generated more traffic. The key decision that can be devised based on these metrics is what kind of tweet, moment or incident generates the traffic.
What fields we will use in our database?
In conclusion, we will be using the following fields in our database table TwitterData
tweet id
engagements
impressions
tweet
Twitter is a viable medium. This data will provide small businesses with a key metric about what tweets have worked with their followers and how they can leverage that pattern. Once the small businesses sort out these patterns, they will be able to create a number of tweets to engage with customers. Eventually, the goal here is to help small businesses to attract customers, and repeat customers.
In the previous post Redis Caching, we saw how to use Redis caching with all default settings. We didn’t have any Cache Manager or anything, but we were able to cache data. In this post, we will show how to use RedisCacheManager to cache the data. This manager can further be extended to customize the caching configuration even more. But we will not be looking into customization in this post particularly.
Implement CacheManager for RedisCacheManager
Most of the code for this post will be similar to what we implemented in the previous post. We will just show how to use CacheManager.
To implement CacheManager first we remove @EnableCaching annotation from the main class SpringAppCacheApplication. Now we add a new CacheConfig class to configure our cache manager.
Basically, this CacheConfig will define CacheManager which build a redisTemplate to get JedisConnectionFactory which will be our java client to connect to our Redis server. This JedisConnectionFactory will get server host and port properties from application.properties file. The source code will look like below:
In this introductory post, we will show how to use Redis caching in a simple spring boot application. In subsequent posts, we will evaluate different factors of Redis caching. But for now, we will try to focus on the simple problem of providing caching to a rest service that provides companies-related data to the user interface. This data is in a database, but caching will help us improve the performance.
What you need
Java 8
MySQL Database
IntelliJ Editor
Gradle
Redis Server and Redis Desktop Manager
Spring Boot Based Rest Service
As part of this post, we will build a simple spring-boot based rest service. This rest service will provide data related to companies which will be stored in mysql database.
We will be using Gradle to build our dependencies in this project. Important dependencies for this project are spring-boot-starter, spring-boot-jpa and spring-boot-starter-data-redis With all the needed Gradle dependencies, our Gradle script will look like below:
Here you can see, we have enabled caching with annotation @EnableCaching.
Now in our RestController class CompanyController , this will show annotation of @Cachable that helps decide when to cache data for the incoming request. This annotation caches data that has been fetched for the request based on configuration.
Here is a controller, if you see we are caching the data coming from the database with annotation @Cacheable
To make sure data gets cached with Redis server, we will need certain properties where these annotations will help us to cache the data. The properties to configure Redis server are below:
Once you build the project and run it, we will be able to perform the REST requests to fetch data. If we perform the same requests multiple times, we will be able to see the data in redis.
Conclusion
In this post, we showed how to use redis-caching to cache the data for a spring boot based REST service. The code from this post is available to download github
In this post, I will discuss one tip everyone can use to avoid bouncy castle error.
Problem
Recently I was working on building a SOAP webservice where we were using Apache CXF libraries along with Spring boot. We built the webservice, but when we were sending a SOAP request through the client, we kept getting following error:
Caused by: java.lang.NoSuchMethodError: org.bouncycastle.math.ec.ECCurve$Fp.<init>(Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;)V
at org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertCurve(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertPoint(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey.<init>(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at sun.security.ssl.HandshakeMessage$ECDH_ServerKeyExchange.<init>(HandshakeMessage.java:1075)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:284)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:553)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:328)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at org.springframework.ws.transport.http.HttpComponentsConnection.onSendAfterWrite(HttpComponentsConnection.java:121)
A Simple tip to avoid this error –
We tried different things to resolve this issue. We tried to exclude bouncycastle jars from cxf-rt-ws-security dependencies we were using as we were pulling them from other dependencies. But this error would still pop up intermittently. Eventually, I figured out the issue. We had to add this dependency of bouncycastle explicitly as below in our Gradle build file. That’s when the error went away.
compile (‘org.bouncycastle:bcprov-jdk15on:1.56’)
Conclusion
In this post, I showed how to use this one tip to avoid the error caused by the bouncy castle. If you enjoyed this post, subscribe to my blog here.