Sep 28, 2013

AWS SDK for Java - Tutorial 2 : EC2

Introduction

Amazon Elastic Compute Cloud (Amazon EC2) service provides resizable compute capacity in the cloud. It is designed to make web-scale computing easier for developers.
Let’s create EC2 instance using Java SDK.  

Prerequisite  

1. EC2 Instance (OnDemand, Reserved and Spot Instance)
2. KeyPair (Pem File)
3. EC2 Security Group
4. AWS AccessKey & SecretKey
5. EndPoint
6. Region


Step 1: Launch Eclipse
Step 2: File->New->Other->AWS
Step 3: Select “AWS Java Project”


Step 4: Create new class named “Main.java” with public static void main method.

Step 5: Define few constances, that we will use to create security group, keypair and ec2 instance.


 private Logger log = Logger.getInstance(Main.class);
 
 // require variable for every operation 
 private String accessKey = "YOUR ACCESS KEY";
 private String secretKey = "YOUR SECRET KEY" ;
 private AWSCredentials credentials;
 private String endPoint ;
 private Region region ;
 private AmazonEC2Client ec2client ;
 
 // EC2 Security Group  Variables
 private String groupName = "kpbirdec2securitygroup";
 private String groupDescription = "This is description";
 
 private String sshIpRange = "YOUR PUBLIC IP/32";
 private String sshprotocol = "tcp";
 private int sshFromPort = 22;
 private int sshToPort =22;
 
 private String httpIpRange = "0.0.0.0/0";
 private String httpProtocol = "tcp";
 private int httpFromPort = 80;
 private int httpToPort = 80;
 
 private String httpsIpRange = "0.0.0.0/0";
 private String httpsProtocol = "tcp";
 private int httpsFromPort = 443;
 private int httpsToProtocol = 443;
 
 // KeyPair variables
 private String keyName = "kpbirdkeypair";
 private String pemFilePath  = "PATH TO STORE PEM FILE"; //   /Users/kpbird/Desktop
 private String pemFileName = "kpbird_keypair.pem";
 
 
 // EC2 Instance variables
 private String imageId ="ami-64084736";
 private String instanceType ="t1.micro";
 private String instanceName = "kpbirdt1micro";
 
 // EC2 Spot Instance
 private String spotPrice = "0.080";
Step 6: initialize method create object of credentials, AmazonEC2Client and set endpoint and region for ec2client. Click here to read more about EndPoint and Region.
private void init(){
 credentials  = new BasicAWSCredentials(accessKey, secretKey);
 // end point for singapore 
 endPoint = "https://rds.ap-southeast-1.amazonaws.com";
 // regions for singapore
 region = Region.getRegion(Regions.AP_SOUTHEAST_1);
 ec2client = new AmazonEC2Client(credentials);
 ec2client.setEndpoint(endPoint);
 ec2client.setRegion(region); 
}
Step 7: Create Security Group includes three things 1. Security Group name and description 2. Permission (IP,Protocol and port range)and 3. Attach owner (AWS Account Owner) to security group.

 private void createEC2SecurityGroup(){
  try {
   log.Info("Create Security Group Request");   
   CreateSecurityGroupRequest createSecurityGroupRequest =  new CreateSecurityGroupRequest();
   createSecurityGroupRequest.withGroupName(groupName)
   .withDescription(groupDescription);
   createSecurityGroupRequest.setRequestCredentials(credentials);
   CreateSecurityGroupResult csgr = ec2client.createSecurityGroup(createSecurityGroupRequest);
   
   String groupid = csgr.getGroupId();
   log.Info("Security Group Id : " + groupid);
   
   log.Info("Create Security Group Permission");
   Collection<IpPermission> ips = new ArrayList<IpPermission>();
   // Permission for SSH only to your ip
   IpPermission ipssh = new IpPermission();
   ipssh.withIpRanges(sshIpRange).withIpProtocol(sshprotocol)
   .withFromPort(sshFromPort).withToPort(sshToPort);
   ips.add(ipssh);
   
   // Permission for HTTP, any one can access
   IpPermission iphttp = new IpPermission();
   iphttp.withIpRanges(httpIpRange).withIpProtocol(httpProtocol)
   .withFromPort(httpFromPort).withToPort(httpToPort);
   ips.add(iphttp);
   
   //Permission for HTTPS, any one can accesss
   IpPermission iphttps = new IpPermission();
   iphttps.withIpRanges(httpsIpRange).withIpProtocol(httpsProtocol)
   .withFromPort(httpsFromPort).withToPort(httpsToProtocol);
   ips.add(iphttps);
   
   log.Info("Attach Owner to security group");
   // Register this security group with owner
   AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest = new AuthorizeSecurityGroupIngressRequest();
   authorizeSecurityGroupIngressRequest
   .withGroupName(groupName).withIpPermissions(ips);
   ec2client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
   
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(0);
  }
 }
Step 8: Amazon EC2 uses public–key cryptography to encrypt and decrypt login information. Public–key cryptography uses a public key to encrypt a piece of data, such as a password, then the recipient uses the private key to decrypt the data. The public and private keys are known as a key pair.

To log in to your instance, you must create a key pair, specify the name of the key pair when you launch the instance, and provide the private key when you connect to the instance. Linux/UNIX instances have no password, and you use a key pair to log in using SSH. Click here to read more about keypair.

 private void createKeyPair(){
  try {
   CreateKeyPairRequest ckpr = new CreateKeyPairRequest();
   ckpr.withKeyName(keyName);
   
   CreateKeyPairResult ckpresult = ec2client.createKeyPair(ckpr);
   KeyPair keypair = ckpresult.getKeyPair();
   String privateKey = keypair.getKeyMaterial();
   log.Info("KeyPair :" + privateKey);
   writePemFile(privateKey,pemFilePath,pemFileName); 
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(0);
  }
 }


Step 9: EC2 instance require three things to create
1. Image ID (AMI), AMI -Amazon Machine Image, AMI is image of operating system and few extra software configured with it. There can be two type of AMI a) public AMI which I am using in following code b) Private AMI, To read more about AMI click here
2. Instance Type, Amazone provides different hardware configuration, you can choose as per your requirement, in this example I am using t1.micro which is smallest instance provided by Amazon AWS. To read more about Instance Type click here
3. Keypair name and security group name

Step 9a Create OnDemand Instance
 private void createEC2OnDemandInstance(){
  try {
   
   // request for new on demand instance
   RunInstancesRequest rir = new RunInstancesRequest();
   rir.withImageId(imageId);
   rir.withInstanceType(instanceType);
   rir.withMinCount(1);
   rir.withMaxCount(1);
   rir.withKeyName(keyName);
   rir.withMonitoring(true);
   rir.withSecurityGroups(groupName);
   
   RunInstancesResult riresult = ec2client.runInstances(rir);
   log.Info(riresult.getReservation().getReservationId());
   
   /// Find newly created instance id
   String instanceId=null;
   DescribeInstancesResult result = ec2client.describeInstances();
   Iterator<Reservation> i = result.getReservations().iterator();
   while (i.hasNext()) {
    Reservation r = i.next();
    List<Instance> instances = r.getInstances();
    for (Instance ii : instances) {
     log.Info(ii.getImageId() + "t" + ii.getInstanceId()+ "t" + ii.getState().getName() + "t"+ ii.getPrivateDnsName());
     if (ii.getState().getName().equals("pending")) {
      instanceId = ii.getInstanceId();
     }
    }
   }
   
   log.Info("New Instance ID :" + instanceId);
   /// Waiting for Instance Running////
   boolean isWaiting = true;
   while (isWaiting) {
    log.Info("*** Waiting ***");
    Thread.sleep(1000);
    DescribeInstancesResult r = ec2client.describeInstances();
    Iterator<Reservation> ir= r.getReservations().iterator();
    while(ir.hasNext()){
     Reservation rr = ir.next();
     List<Instance> instances = rr.getInstances();
     for(Instance ii : instances){
      log.Info(ii.getImageId() + "t" + ii.getInstanceId()+ "t" + ii.getState().getName() + "t"+ ii.getPrivateDnsName());
      if (ii.getState().getName().equals("running") && ii.getInstanceId().equals(instanceId) ) {
       log.Info(ii.getPublicDnsName());
       isWaiting=false;
      }
     }
    }
   }
   
   /// Creating Tag for New Instance ////
   log.Info("Creating Tags for New Instance");
   CreateTagsRequest crt = new CreateTagsRequest();
   ArrayList<Tag> arrTag = new ArrayList<Tag>();
   arrTag.add(new Tag().withKey("Name").withValue(instanceName));
   crt.setTags(arrTag);
   
   ArrayList<String> arrInstances = new ArrayList<String>();
   arrInstances.add(instanceId);
   crt.setResources(arrInstances);
   ec2client.createTags(crt);
   
   
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(0);
  }
 }

Step 9b Create Spot Instance

 private void createEC2SpotInstance(){
  try {
   /// Creating Spot Instance ////
   
   // Initializes a Spot Instance Request
   RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();
   // Request 1 x t1.micro instance with a bid price of $0.03.
   requestRequest.setSpotPrice(spotPrice);
   requestRequest.setInstanceCount(Integer.valueOf(1));
   LaunchSpecification launchSpecification = new LaunchSpecification();
   launchSpecification.setImageId(imageId);
   launchSpecification.setInstanceType(instanceType);
   launchSpecification.setMonitoringEnabled(true);
   
   // Add the security group to the request.
   ArrayList<String> securityGroups = new ArrayList<String>();
   securityGroups.add(groupName);
   launchSpecification.setSecurityGroups(securityGroups);
   
   launchSpecification.setKeyName(keyName);

   // Add the launch specifications to the request.
   requestRequest.setLaunchSpecification(launchSpecification);

   // Call the RequestSpotInstance API.
   RequestSpotInstancesResult requestResult = ec2client.requestSpotInstances(requestRequest);
   
   List<SpotInstanceRequest> requestResponses = requestResult.getSpotInstanceRequests();

   // Setup an arraylist to collect all of the request ids we want to
   // watch hit the running state.
   ArrayList<String> spotInstanceRequestIds = new ArrayList<String>();

   // Add all of the request ids to the hashset, so we can determine when they hit the
   // active state.
   for (SpotInstanceRequest requestResponse : requestResponses) {
       System.out.println("Created Spot Request: "+requestResponse.getSpotInstanceRequestId());
       spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId());
       log.Info(requestResponse.getInstanceId() + "t" + requestResponse.getState());
   }
   
   String instanceId=null;
   boolean isWaiting=true;
   while(isWaiting){
    log.Info("*** Waiting for Spot Instance Request ***");
    Thread.sleep(5000);
     DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest();
     describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);
     
     DescribeSpotInstanceRequestsResult describeResult = ec2client.describeSpotInstanceRequests(describeRequest);
        List<SpotInstanceRequest> describeResponses = describeResult.getSpotInstanceRequests();
        for (SpotInstanceRequest describeResponse : describeResponses) {
         log.Info(describeResponse.getInstanceId() + "t" + describeResponse.getState() + "t" + describeResponse.getSpotInstanceRequestId() + "t" + describeResponse.getStatus().getCode() + "t" + describeResponse.getStatus().getMessage());
           if (describeResponse.getState().equals("active")) {
               isWaiting = false;
               instanceId = describeResponse.getInstanceId();
               break;
           }
        }
    
   }
   isWaiting = true;
   while (isWaiting) {
    log.Info("*** Waiting for Instance Running ***");
    Thread.sleep(1000);
    DescribeInstancesResult r = ec2client.describeInstances();
    Iterator<Reservation> ir= r.getReservations().iterator();
    while(ir.hasNext()){
     Reservation rr = ir.next();
     List<Instance> instances = rr.getInstances();
     for(Instance ii : instances){
      log.Info(ii.getImageId() + "t" + ii.getInstanceId()+ "t" + ii.getState().getName() + "t"+ ii.getPrivateDnsName());
      if (ii.getState().getName().equals("running") && ii.getInstanceId().equals(instanceId) ) {
       log.Info(ii.getPublicDnsName());
       String publicDNS = ii.getPublicDnsName();
       log.Info("Public DNS :" + publicDNS);
       isWaiting=false;
      }
     }
    }
   }
   
   /// Creating Tag for New Instance ////
   log.Info("Creating Tags for New Instance");
   CreateTagsRequest crt = new CreateTagsRequest();
   ArrayList<Tag> arrTag = new ArrayList<Tag>();
   arrTag.add(new Tag().withKey("Name").withValue(instanceName));
   crt.setTags(arrTag);
   
   ArrayList<String> arrInstances = new ArrayList<String>();
   arrInstances.add(instanceId);
   crt.setResources(arrInstances);
   ec2client.createTags(crt);
   
   
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

Amazon AWS Management Console Screen Shots

EC2 Instance

EC2 Security Group

KeyPair

References


continue reading AWS SDK for Java - Tutorial 2 : EC2

AWS SDK for Java - Tutorial 1 : Introduction

Introduction


Amazon Web Services (AWS) is popular cloud service provider. AWS provide many choices for the developers, In this article I will focus only on AWS SDK for Java.


source:http://www.vccafe.com/wp-content/uploads/2012/10/AWS-Overview-of-Services.jpg



Prerequisite


1. Knowledge of Core Java
2. Understanding of AWS Services
3. Eclipse IDE
4. AWS Account


AWS provide SDKs for following languages


1. Java
2. Android
3. iOS
3. .NET
4. Node.js
5. PHP
6. Python
7. Ruby


AWS SDKs supports following services, developer can manage and monitor services using SDKs


1. Compute & Networking


AWS Direct Connect
Amazon EC2
Elastic Load Balancing
Auto Scaling
Amazon EMR
Amazon Route 53
Amazon VPC


2. Storage & Content Delivery


Amazon S3
Amazon Glacier
Amazon CloudFront
AWS Storage Gateway
AWS Import/Export


3. App Services


Amazon Elastic Transcoder
Amazon SQS
Amazon SNS
Amazon SES
Amazon SWF
Amazon CloudSearch


4. Database


Amazon DynamoDB
Amazon RDS
Amazon Redshift
Amazon ElastiCache
Amazon SimpleDB


5. Deployment & Management


AWS Elastic Beanstalk
AWS CloudFormation
Amazon CloudWatch
AWS Data Pipeline
AWS Identity and Access Management
AWS OpsWorks


Useful Links for AWS SDK for Java


1. SDK for Java
2. Getting Started
3. AWS Java Blog
4. AWS Forum
5. AWS Java SDK API Document
6. AWS Java Articles


Setup AWS SDK for Java


1. Download & Install Eclipse
2. Download AWS SDK for Java from following link
3. Unzip in your favorite location/folder
4. AWS Java SDK contains API documents, libs, samples and third-party libraries.
AWS Java SDK 
5. Install AWS toolkit for eclipse
6. Launch Eclipse
7. Open Help→Install New Software….
8. Enter http://aws.amazon.com/eclipse in the text box labeled “Work with” at the top of the dialog.
9. Select “AWS Toolkit for Eclipse” from the list below.
10. Click “Next.” Eclipse guides you through the remaining installation steps.

Enter AWS Eclipse Toolkit url, select aws toolkit for eclipse

List of component will install by AWS eclipse toolkit

Licenses for components



AWS Java API naming scheme


1. Amazon<Service Name>Client: Client to access Service
2. Amazon<Service Name>AsyncClient : Asynchronous class to access service
3. Describe<Service Name>Request: It is used to fetch list of ec2 or s3 etc
4. Describe<Operation Name>Result: It will provide result of requested service data
5. delete<Operation Name>: use to remove stuff, normally it return void
6. create<Operation Name>: used to create something in service


 
continue reading AWS SDK for Java - Tutorial 1 : Introduction

Sep 20, 2013

Augmented Reality : Introduction of Metaio SDK

Metaio SDK is advanced as compared to Vuforia SDK, Metaio SDK is developer friendly such that any beginner or novice developer can develop good quality of AR application.

High-level system overview




1. Setup Metaio SDK 4.5
I assume that you already have Android SDK and NDK setup in computer.

Step 1: Download Metaio SDK 4.5 for Android
http://dev.metaio.com/sdk/getting-started/

Step 2: Double click on metaio_4.5_mac.dmg, It will ask for terms & condition, click "Agree"

Step 3: Drag & Drop mataioSDK folder to your desire location


Step 4: _Android Directory has Android SDK

2. Compile and execute example_sdk application

Step 1: Open eclipse
Step 2: Click File->Import->Android->Existing Android Code Into Eclipse
Step 3: Navigate to metaioSDK folder and go to _Android and click next
Step 4: Eclipse will list all Android projects under _Android directory
Step 5: Select metaioSDK and Example_SDK, unselect other projects
Step 6: Click finish, eclipse will import two projects 
Step 7: Right click on "ImageTargats" project -> select run -> Android Application
Step 8: Print PictureMarker.pdf and put your phone in front of printout, App will display 3d object of metaioman
Note: do clean & build if you find error of R.java and make sure that you have android sdk version 2.3 and higher in metaiosdk and example project

3. Understand code of Example

Metaio Example app has code of Tutorial 1 to 8, I am going to explain only code of Tutorial 1, Most enjoyable feature of Metaio SDK is "You don't require NDK code" (I like this feature)

Files & Description
  • Tutorial1.java: It extends ARViewActivity, not by Android Activity, We need to use getUILayout() function to provide xml layout and in loadContents() method we need to provide tracker configuration xml file and content file md2 or obj
  • tutorial1.xml: It has only one image button, nothing else
  • TrackingData_MarkerlessFast.xml: This xml is placed in in Assets/Tutorial1/Assets1, It has all require configuration for tracker, i.e. tracker image, sensor, algorithm use.
  • metaioman.md2: This is our metaioman 3D object which display when tracker found in camera.
That's all, we don't require NDK, C++ or OpenGL.

Metaio also provides cool feature "AREL" - Augmented Reality Experience Language, you might notice AREL button in Tutorial 1,  AREAL is more simpler then normal method. Click here to know more about AREL

continue reading Augmented Reality : Introduction of Metaio SDK

Android Augmented Reality: Introduction of Vuforia SDK

The Vuforia™ SDK allows you to build vision-based augmented reality applications. It is available for Android, iOS and as an Extension to Unity - a cross-platform game engine.

High-level system overview
  • Multiple trackables (tracking types):
  • Image Targets
  • Multi-Targets
  • Cylinder Targets
  • Word Targets
  • Frame Markers
  • Real-world Interactions
  • Virtual Buttons

source : https://developer.vuforia.com/resources/api/index


1. Setup Vuforia SDK v2.6

I assume that you already have Android SDK and NDK setup in computer.

Step 1: Download Vuforia SDK v2.6 For Android 
https://developer.vuforia.com/resources/sdk/android

Step 2: Extract vuforia-sdk-android-2-6-10 in desire folder

Step 3: Download Samples from following link
https://developer.vuforia.com/resources/sample-apps

Step 4: Extract sample zip file vuforia-sampleapps-android-2-6-7

Step 5: Copy all samples from extracted folder and paste in <vuforia_sdk>/samples folder
<vuforia_sdk> is directory location where you extracted SDK in step 2

2. Compile and execute ImageTargats sample app

Sample has NDK and SDK coding, so normally I compile NDK from terminal and SDK using eclipse

Step 1: Open Terminal & go to <vuforia_sdk>/sample/ImageTargats-2-6-7/, 

Step 2: Execute "ndk-build" to compile NDK code, make sure you have environment variable which point to Android NDK directory otherwise terminal will give you "comment not found" error

Step 3: Open eclipse and import ImageTargats-2-6-7 project

Step 4: Set class path variable in eclipse

In Eclipse, go to Window->Preferences.
Navigate to Java->Build Path->Classpath Variables using the hierarchy browser.
Create a new variable by selecting New...

Add:
QCAR_SDK_ROOT
into the Name: field, and navigate using Folder... to the vuforia-sdk-android-xx-yy-zz directory

Step 5: Right click on "ImageTargats" project -> select run -> Android Application

Step 6: Take Print of target image 
https://developer.vuforia.com/sites/default/files/sample-apps/targets/imagetargets_targets.pdf

Step 7: Open ImageTargets Android application in device and place device in front of printed target image, you will see nice 3d teapot

3. Understand code of ImageTargats app



Files & Description
  • SDK
    • AboutScreen.java: Display about content, start ImageTarget activity
    • DebugLog.java: Exposes functionality for logging, support class for logging
    • ImageTargets.java: This class is responsible for almost everything (i.e. managing camera, surface view for rendering, loading texture, etc)
    • ImageTargetsRenderer.java: extends GLSurfaceView.Renderer which is used to render OpenGL graphics, this class is also act as bridge between native code and java code, actual rendering is happening in native code using "renderFrame()" method
    • ImageTargetsSplashScreen.java: display simple image for 2000 milliseconds and open Aboutscreen.java activity
    • QCARSampleGLView.java: This class extends GLSurfaceView, it is responsible for setting up and configuring the OpenGL surface view.
    • Texture.java: Texture is a support class for the QCAR samples applications, It load texture image from asset to memory
  • NDK
    • Android.mk: standard android build script for module
    • Application.mk: standard android build script for application
    • CubeShader.h: Defines OpenGL shaders as char* strings. OpenGL Shading Language (abbreviated: GLSL or GLslang), is a high-level shading language based on the syntax of the C programming language. It was created by the OpenGL ARB to give developers more direct control of the graphics pipeline without having to use ARB assembly language or hardware-specific languages. More.
    • ImageTargets.cpp: It is used to bridge between native and java code, This class has JNI methods, "startCamera" method actually start capturing frame from camera and identify tracker using QCAR tracker manager API
    • SampleUtil.h/cpp: A utility class which define common & static function like printMatrix, checkGLError, setRotationMatrix...
    • Teapot.h: This class define teapot OpenGL co-ordinate, vertices and indices,Vuforia API only identify marker, for content we can use OpenGL, Content generation and display is most important part of Augmented Reality, I personally thing that Metaio has more robust and powerful content generation system.
    • Texture.h/cpp: another utility class, It load Texture buffer from Texture.java object.
continue reading Android Augmented Reality: Introduction of Vuforia SDK