Personal Project

Showing posts with label Tomcat. Show all posts
Showing posts with label Tomcat. Show all posts

Monday, September 12, 2016

How to Automatically Scale Up Your Application on AWS ?

This basic rule is you have to make your application servers and databases to be independent of each other. The application servers are only responsible for processing game or business logic without saving any cache data at local. The databases are used for saving game or user data. In front of the application servers, it is necessary to set up a load balancer - while there is any problem occurring to make a server become unavailable - to redirect the user traffic to available servers.  

Moreover, if you want to reduce the overhead of MYSQL such as the number of current connections to improve performance, you can use shared memory servers like Redis or Memcached to save user sessions to decrease the number of SQL queries on MYSQL.

In addition, NoSQL database, Couchbase or MongoDB, would be a better alternative to replace MYSQL database. It can dramatically improve the performance of web applications.

As the user traffic grows, you can easily add one EC2 application server on AWS or  improve MYSQL/NoSQL database specs to meet this need.  

The proposed methods below will teach you how to set up an auto-scale
infrastructure for your applications. 


1.Create StartApp Script for Java Application/Tomcat  at startup time


Initial an EC2 instance and deploy your Java Application on this EC2 and set up a startApp script below at startup time. 

vim startapp

#!/bin/bash

cd /home/weishihhsun/app/
nohup java -jar p2pServer.jar &

sudo cp startapp /etc/init.d

sudo chmod +x /etc/init.d/startapp
sudo update-rc.d startapp defaults 98 02

98 and 02 are the start and stop sequence numbers respectively.
Both are numbers between 00 and 99 and specify how early or late a service is started or killed

By doing so, your Java or Tomcat application would be booted up at startup time.


2. Create an image of EC2 instance on AWS

You need to create an image of EC instance - a clone of this server - by AWS Control UI.    

3. Setup Auto-Scaling Group

You need to add an image of EC2 instance to the auto-scaling group and set up some thresholds to trigger different types of alarms, such as the usage of CPU, hard disk, and internet traffic. 

The usage of CPU, for example, is more than 80%, then automatically increase the EC2 instance of a server; if it is below 10%, then decrease the EC2 instance of  a server.

To conclude, you have learned how to build a high availability and scalability infrastructure for your applications. By making use of the proposed methods, you can automatically scale up your application servers developed by PHP, Java, C# or C/C++ on AWS, as long as you make your applications independent of the database.


Thursday, June 16, 2016

Tutorial (2) : How to send Push Notifications to iPhone using Java ?



Generate aps_developer.p12 for JavaPNS

Download and Upzip openssl-0.9.8k_WIN32.zip
Goto windows dos command mode

// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_developer.cer -inform DER -out aps_developer.pem -outform PEM 

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile PushChat.certSigningRequest -name "aps_developer" -out aps_developer.p12


Obtain Device token from iOS

Add the following code in the method of AppDelegate.didFinishLaunchingWithOptions

IOS Code:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];  

To setup registerForRemoteNotificationTypes for app to receive notification message.

To extract device token by the following codes:

IOS Code: 

 - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {   
    NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
    NSLog(@"My token is:%@", token);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {    
    NSString *error_str = [NSString stringWithFormat: @"%@", error];
    NSLog(@"Failed to get token, error:%@", error_str);

 
iOS device needs to implement two features: one is to register app as receiving notification type, the other is to send its token to backend JavaPNS via HTTP or TCP protocol.


Setup JavaPNS Sample code

Please add the following .jar library in your project:
1. bcprov-jdk15-146.jar
2. log4j-1.2.15.jar
3. JavaPNS_2.2.jar ( unzip JavaPNS_2.2_complete.zip )
4. Compile the source code : PushTest.java

(PS: Or simply import the testSample code by eclipse and run it)
  
JavaPNS needs certificate aps_developer.p12, and iOS token id to accomplish the function of sending Push Messages. The following codes below detail how to make it work.

public static void main(String[] args) {
                       
                        // iOS Private key as a p12 file exported by MAC
                        String keynotePath = "aps_developer.p12";
                       
                        // iOS developer certificate password exported by MAC
                        String password = "Your Pasword";
                       
                        // iOS device Token id
                        String token = "Your Device Token";
                       
                        // Test environment: Production or Sandbox(simulation)
                        String environment = "simulation";
                       
                        // Push message mode: Simple or complex or thread
    // Simple: Simple msg, complex: complex message, thread: Add multiple threads support
                        String pushMode = "complex";
                       
                        // Number of received devices
                        String deviceNum = "1";
                       
                        // Number of sender threads
                        String threadNum = "1";
                       
                        /* Initialize Log4j to print logs to console */
                        configureBasicLogging();

                        /* Push an alert */
                        try {
pushTest(keynotePath, password, token, environment, pushMode, deviceNum, threadNum);
                                   
                        } catch (CommunicationException e) {
                                    e.printStackTrace();
                        } catch (KeystoreException e) {
                                    e.printStackTrace();
                        }
            }




How to generate iOS development certificate for Push Server ?

// For Development Environment
// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_development.cer -inform DER -out aps_developer.pem -outform PEM

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12   // Input your password

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_developer" -out aps_developer.p12


How to generate iOS Production certificate for Push Server?

// For Production
// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_production.cer -inform DER -out aps_production.pem -outform PEM

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12 

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_production.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_production" -out aps_production.p12


Next  - Tutorial(1) : How to send Push Notifications to Android using Java ?

Tuesday, June 14, 2016

Tutorial (1) : How to send Push Notifications to iPhone using Java ?

Get Started

In this tutorial, you will lean how Push Notifications work and how to send Push Notifications to iPhone using an open source library - JavaAPNS.

Apple Push Service Overview


1. An app registers to iOS to enable Push notification; iOS sends device`s UDID to APNS.
2. The app receives a “device token” from APNS. You can think of the device token as the address that push notifications will be sent to.
3. The app sends the device token to your server.
4. When something of interest to your app happens, the server sends a push notification to the Apple Push Notification Service with device token id.
5. APNS sends the push notification to the user’s device.

 Enable Provisioning Profiles and Certificates

To enable push notifications in your app, it needs to be signed with a provisioning profile that is configured for push. In addition, your server needs to sign its communications to APNS with an SSL certificate.

There are also two types of push server certificates:
- Development. If your app is running in Debug mode and is signed with the Development provisioning profile (Code Signing Identity is “iPhone Developer”), then your server must be using the Development certificate.

- Production. Apps that are distributed as Ad Hoc or on the App Store (when Code Signing Identify is “iPhone Distribution”) must talk to a server that uses the Production certificate. If there is a mismatch between these, push notifications cannot be delivered to your app.


Generating the Certificate Signing Request (CSR)

The first thing you need is your Push certificates. These identify you when communicating with APNS over SSL.

Generating the Apple Push Notification SSL certificate on Mac:






Enter your email address here. I’ve heard people recommended you use the same email address that you used to sign up for the iOS Developer Program, but it seems to accept any email address just fine.

Enter “PushChat” for Common Name. You can type anything you want here, but choose something descriptive. This allows us to easily find the private key later.

Check Saved to disk and click Continue. Save the file as “PushChat.certSigningRequest”.



Generating the private key




If you go to the Keys section of Keychain Access, you will see that a new private key has appeared in your keychain. Right click it and choose Export.

Save the private key as “PushChatCert.p12” and enter a passphrase.



4.   Making the App ID and SSL certificate
Log in to the iOS Provisioning Portal.

First, we are going to make a new App ID. Each push app needs its own unique ID because push notifications are sent to a specific application. (You cannot use a wildcard ID.)



Filled in the fields as follows:
Description: PushChat
Bundle Seed ID: Generate New (this is the default option)
Bundle Identifier: com.hollance.PushChat

It is probably best if you choose your own Bundle Identifier here – com.companyName.PushChat – instead of using mine. You will need to set this same bundle ID in your Xcode project.
This certificate is linked with your App ID. Your server can only send push notifications to that particular app, not to any other apps.
After you have made the App ID, it shows up like this in the list:



Click on the Configure link to open the Configure App ID screen.



choose Certificate Signing Request file, “PushChat.certSigningRequest” for the Development Push SSL Certificate.




Download SSL certificate.
Click Done to close the assistant and return to the Configure App ID screen.


As you can see, we have a valid certificate and push is now available for development. The development certificate is only valid for 3 months. When you are ready to release your app, repeat this process for the production certificate. The steps are the same.

Note: The production certificate remains valid for a year, but you want to renew it before the year is over to ensure there is no downtime for your app.



Until now, we have generated three files:

1. Push.certSigningRequest
2. PushChatCert.p12
3. aps_developer.cer

Friday, June 3, 2016

Is OAuth secure enough for REST API ?

OAuth protocol is widely used for authorization of logging in users. Some famous social gaming platform companies like Line, Mobage, Gree, and DMM have also adapted this technology to develop their REST API.

You might have a question - is it secure enough to only use OAuth for REST API ?

From my experience, the answer is no.

Even if you adapt OAuth 2.0 to your REST system, your system still could be vulnerable to Man-In-Middle Attack. Because OAuth is based on HTTP protocol, you must set up SSL encryption protocol to assure your message being sent over HTTPS. Otherwise, the hacker can wiretap your communication and retrieve your account and password from wire packets.

In terms of development, it is actually very easy to develop a secure REST API server with high performance using Spring framework. I already created a very simple template at github. You just need to configure some settings and modify API controller files of Java as needed.

The source codes of Secure REST API  Server can be seen here

Monday, May 30, 2016

How to set up Master Slave replication for REST server using Spring framework ?


MYSQL replication architecture is vital for building high available REST API servers.
In order to avoid singe-point of failure problem, it`s recommended that setting 2 application servers and  Master-Slave database in MYSQL. Of course, you have to set up the application servers behind the load balancer.

The following details how to setup  REST API server by using Spring framework of Java.
How to set up MYSQL Master/Slave replication ?
// Edit
vim /src/main/resources/application.properties

## Master and Slave
spring.datasource.url = jdbc:mysql:replication://localhost1:3306,localhost2:3306/userdb 

The source codes of REST server can be seen here.

Tuesday, May 10, 2016

How to develop a secure REST server with high performance using OAuth, HIBERNATE, and MYSQL in Spring framework ?

I found it difficult to develop a secure REST API Server from scratch with features like OAuth, MYSQL, HIBERNATE, MYSQL Token Store, JDBCTemplate, and HTTPS. It will take lots of time to put all the features together and make them work properly. 

In order to reduce redundant work, I therefore created the REST API server template in Spring framework. With this server template, you can focus on developing REST API to meet your needs without being distracted by other technologies.

Get Started

This project is a very simple REST and OAuth server template with high performance. Since the authenticated token is stored in MYSQL, its easy to scale up your server to meet high user traffic.

Project

This project includes the following features.
MVN
Spring-Boot
REST
JPA
MYSQL + HIBERNATE 
MYSQL Token Store
JDBCTemplate
Https

Setup MYSQL Database

Import userdb.sql into your database.
import database/userdb.sql into MYSQL database

Enable SSL

// Create key store 
bash
keytool -genkey -alias tomcat -keyalg RSA

// Edit 
vim /src/main/resources/application.properties

// Uncomment the following lines and set up your key store path
## SSL
server.port=8443
server.ssl.key-store=./src/main/resources/your.jks
server.ssl.key-store-password=your store passowrd
server.ssl.key-password=your pass

Building

You need Java (1.7 or better) and Maven (3.0.5 or better):
$ mvn clean package
$ mvn package
$ java -jar target/*.jar
...

// Http
<app starts and listens on port 8080>

// Https
<app starts and listens on port 8443>

Here are some curl commands to use to get started:
// Get Token
curl -k -X POST -d 'grant_type=client_credentials' --user 'my-client-with-secret:secret' https://localhost:8443/oauth/token
{"access_token":"bf12a9c8-c341-44a6-9ce6-084a8ba86652","token_type":"bearer","expires_in":43199,"scope":"read"}

// hasUserId GET
curl -k -H "Authorization: 5470484a-148d-479f-988e-89dfce617bb1" https://localhost:8443/user/hasUserId?uid=336u594534
{"status":200, "userId": 336u594534}

// Twitter Login POST
curl -k -H "Authorization: Bearer b61db2dd-0af4-4e3c-b2b9-7c307a9d7c69" -X POST -H "Content-Type: application/json" -d "{\"twitterId\": \"0926841831\", \"deviceId\": \"2222\"}" https://localhost:8443/user/twitterLogin

How to optimize MYSQL connection pool ?

// Edit
vim /src/main/resources/application.properties

// Configure initial and maximal connections 
spring.datasource.initialSize= 15
spring.datasource.maxActive= 30