2013年4月23日 星期二

Implement REST API Querying by iphone from HDFS and Hypertable


Service Preparation


 172.16.43.X         172.16.43.145                           192.168.122.X
                        +-----+                     +--------+    |
   O              50070 |     | <-----------> 50070 |master01| ---+
  -+-   --------> 50075 | pen |               9000  +--------+    |
   |              10080 |     | <------+             @VM/Guest    |
  / \                   +-----+        |                          |
 iphone-3GS              @HOST         |            +--------+    |
                                       +----> 50075 |knode???| ---+
                                                 80 +--------+    | hypertable's REST 80 port 
                                                     @VM/Guest
REST API test by curl command line from PC

[List files]
curl -i "http://172.16.43.145:50070/webhdfs/v1/tmp/?op=LISTSTATUS"
    172.16.43.X   ==> OK
    172.16.43.145 ==> OK

[Read a file]
curl -i -L "http://172.16.43.145:50070/webhdfs/v1/tmp/Capfile3?op=OPEN"
    172.16.43.X   ==> X
    172.16.43.145 ==> OK

curl -i -L "http://172.16.43.145:50075/webhdfs/v1/tmp/Capfile3?op=OPEN&namenoderpcaddress=master01:9000"
    172.16.43.X   ==> OK
    172.16.43.145 ==> OK

[Create and Write a file]
curl X PUT -L "http://172.16.43.145:50070/webhdfs/v1/tmp/Capfile5?op=CREATE" -T /root/anaconda-ks.cfg
    172.16.43.X   ==> X
    172.16.43.145 ==> OK

curl -i -X PUT -L "http://172.16.43.145:50075/webhdfs/v1/tmp/Capfile4?op=CREATE&namenoderpcaddress=192.168.122.11:9000" -T ./index.html
    172.16.43.X   ==> OK
    172.16.43.145 ==> OK

[Overwrite a file]
curl -i -X PUT -L "http://172.16.43.145:50070/webhdfs/v1/tmp/Capfile3?op=CREATE&overwrite=true" -T /root/anaconda-ks.cfg
    172.16.43.X   ==> X
    172.16.43.145 ==> OK

curl -i -X PUT -L "http://172.16.43.145:50075/webhdfs/v1/tmp/Capfile3?op=CREATE&namenoderpcaddress=master01:9000&overwrite=true" -T ./index.html
    172.16.43.X   ==> OK
    172.16.43.145 ==> OK

[Query hypertable "RS_METRICS" within "sys" database]
curl -i "http://172.16.43.145:10080/rest/api-ht.php?rquest=scanner"
    172.16.43.X   ==> OK
    172.16.43.145 ==> OK


[Append a line to a file]
## !!! NOT implmentment here
##reference : http://blog.cloudera.com/blog/2009/07/file-appends-in-hdfs/
##                http://docs.fluentd.org/articles/out_webhdfs#parameters
##hdfs-site.xml setting
  <property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
  </property>

  <property>
    <name>dfs.support.append</name>
    <value>true</value>
  </property>

  <property>
    <name>dfs.support.broken.append</name>
    <value>true</value>
  </property>


Client Testing Tool

Xcode : 4.6
iphone: 3GS (iOS6.1) or simulator
libcurl: 7.30.0

[import libcurl into testRest project]
download and uncompress curl-7.30.0( from http://home.comcast.net/~seiryu/software/ioscurl-7.30.0.tar.gz)
[user@testRest_witCurl]mkdir libcurl
[user@testRest_witCurl]cp ~/Downloads/ioscurl-7.30.0.tar
[user@testRest_witCurl]cd libcurl
[user@libcurl] tar -xvf ioscurl-7.30.0.tar

Open testRest_withCurl\testRest.xcodeproj by Xcode4.6
Project -> TARGETS -> testRest -> Build Phases -> Link Binary With Libraries -> Add Item(+)
  (1) Add Other...
      libcurl/libcurl-device.a
      libcurl/libcurl-sumulator.a
  (2) Add
      CFNetwork.framework
      Security.framework
      libz.dylib


   
[testRest_withCurl/AppDelegate.h]
//
//  AppDelegate.h
//  testRest
//
//  Created by kway on 13/4/22.
//  Copyright (c) 2013年 kway. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef enum {
    actGET = 1,
    actPOST,
    actPUT,
    actDELETE
} Actions;


@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    BOOL isLocation; // -L
    BOOL isUpload;   // -T

    Actions action;  // -X GET
}

-(size_t) showRest:(char *)data onlysize:(size_t)size;

@property (strong, nonatomic) IBOutlet UIWindow *window;
@property (strong, nonatomic) IBOutlet UITextField *textIP;
@property (strong, nonatomic) IBOutlet UITextField *textPort;
@property (strong, nonatomic) IBOutlet UITextView *tvURI;
@property (strong, nonatomic) IBOutlet UITextView *tvRest;
@property (strong, nonatomic) IBOutlet UISegmentedControl *scType;

-(IBAction)scTypeChangeHandler:(id)sender;
-(IBAction)btnSend;



@end
//global function for callback when curl
size_t handle(char * data, size_t size, size_t count, void * ptr2AppDelegate);


[testRest_withCurl/AppDelegate.m]
//
//  AppDelegate.m
//  testRest
//
//  Created by kway on 13/4/22.
//  Copyright (c) 2013年 kway. All rights reserved.
//

#import "AppDelegate.h"
#import "../libcurl/iOScURL/curl/curl.h"



@implementation AppDelegate



- (void)dealloc
{
    [_window release];
    [_tvRest release];
    [_tvURI release];
    [_textIP release];
    [_textPort release];
    [_scType release];
    [super dealloc];
}
-(void) initApp{
    action=actGET;
    isLocation=false;
    isUpload=false;
    _tvRest.text = @"";
    _textIP.text=@"172.16.43.145";
    _textPort.text=@"50070";
    _tvURI.text=[NSString stringWithFormat:@"http://%@:%@/webhdfs/v1/tmp/?op=LISTSTATUS",_textIP.text,_textPort.text];
}
-(IBAction)scTypeChangeHandler:(id)sender{
//    int selectedIndex=[self.scType selectedSegmentIndex];
    int selectedIndex=[sender selectedSegmentIndex];
    switch(selectedIndex)
    {
        case 0: // DIR
            action=actGET;
            isLocation=false;
            isUpload=false;
            _textPort.text=@"50070";
            _tvURI.text=[NSString stringWithFormat:@"http://%@:%@/webhdfs/v1/tmp/?op=LISTSTATUS",_textIP.text,_textPort.text];
            break;
        case 1: // CAT
            action=actGET;
            isLocation=true;
            isUpload=false;
            _textPort.text=@"50075";
            _tvURI.text=[NSString stringWithFormat:@"http://%@:%@/webhdfs/v1/tmp/Capfile?op=OPEN&namenoderpcaddress=master01:9000",_textIP.text,_textPort.text];
            break;
        case 2: //SCANNER
            action=actGET;
            isLocation=false;
            isUpload=false;
            _textPort.text=@"10080";
            _tvURI.text=[NSString stringWithFormat:@"http://%@:%@/rest/api-ht.php?rquest=scanner",_textIP.text,_textPort.text];
            break;
    }
}

-(size_t) showRest:(char *)data onlysize:(size_t)size
{
    if(size >0)
    {
        _tvRest.text=[NSString stringWithFormat:@"%s",data];
    }
    else
    {
        _tvRest.text=@"";
    }
    return size;
}
-(IBAction)btnSend
{
    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl;
    CURLcode res;
    curl = curl_easy_init();
    if(curl!=NULL)
    {
        curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,handle);
        curl_easy_setopt(curl,CURLOPT_WRITEDATA,self);
        curl_easy_setopt(curl, CURLOPT_URL,[_tvURI.text UTF8String]);
        if(isLocation) // for -L option
        {
            curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1);
        }
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
//    self.window.backgroundColor = [UIColor whiteColor];

    [self.window makeKeyAndVisible];
    [self initApp];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

//global function for callback when curl
size_t handle(char * data, size_t size, size_t count, void * ptr2AppDelegate)
{
    if(ptr2AppDelegate != nil)
        [ (AppDelegate *)ptr2AppDelegate showRest:data onlysize:size*count];
    return size*count;
}

Result



Reference:
http://home.comcast.net/~seiryu/libcurl-ios.html
http://curl.haxx.se/libcurl/c/allfuncs.html

2013年4月11日 星期四

dlopen and LoadLibrary


嚐試不同使用動態模組(.so or .dll)的方法

[sean_bcd.h]

#if defined(__cplusplus)
#if defined(_MSC_VER)
   #define HANDLE_PRAGMA_PACK_PUSH_POP    //WIN32 style pack
   #define X_FASTCALL
   #define X_IMPORT          __declspec(dllimport)
   #define X_EXPORT          __declspec(dllexport)
#elif defined(__BORLANDC__)
   #define HANDLE_PRAGMA_PACK_PUSH_POP    //WIN32 style pack
   #define X_FASTCALL        __fastcall
   #define X_FASTCALL_CTOR   X_FASTCALL
   #define X_IMPORT          __declspec(package)
   #define X_EXPORT          __declspec(package)
#else
   #define X_IMPORT
   #define X_EXPORT
   #define X_FASTCALL
   #define X_FASTCALL_CTOR
#endif

#if defined(SEAN_DLL_IMPL)
#define SEAN_CLASS_DECL X_IMPORT
//#pragma comment(lib, "<DLL ...>.lib")
#else
#define SEAN_CLASS_DECL X_EXPORT
#endif

class  SEAN_CLASS_DECL sean_bcd
{
    public:
    int bcd2num( char *out, int outsz, char *in,  int inlen );
    char asc2bin( char c );

};

extern "C" {
#endif

int bcd2num_( char *out, int outsz, char *in,  int inlen );


#if defined(__cplusplus)
}
#endif




[sean_bcd.cpp]

#include "sean_bcd.h"
#include <ctype.h>
char sean_bcd::asc2bin( char c )
{
        if ( isdigit( c ) )   return( c - '0' );
        if ( isalpha( c ) )
        {
                c = toupper( c );
                return( c - 'A' + 10 );
        }
        else
                return 0;
}
int sean_bcd::bcd2num( char *out, int outsz, char *in,  int inlen )
{
        int    i,j;
        int    limit = outsz*2;
        int    left=limit-inlen;
        char   c, c1;

        for ( i=0,j=0; i<limit ; i+=2 )
        {
                if(left > 0)
                {
                    c = 0;
                    left--;
                }
                else
                {
                    c = asc2bin( *( in + j ) );
                    j++;
                }

                c1 = ( c << 4 ) & 0xf0;

                if(left > 0)
                {
                    c = 0;
                    left--;
                }
                else
                {
                    c = asc2bin( *( in + j ) );
                    j++;
                }

                *( out + i/2 ) = c | c1;
        }
        return i;
}


[make so file]

g++ -shared -fPIC  -o libbcd.so sean_bcd.cpp

BTW. (c file make to so file)
gcc -shared -fPIC  -o libbcd.so sean_bcd.c


[c with make option]

vi sean_c_op.c
#include <stdio.h>
#include "./sean_bcd.h"
int main(int argc , char *argv[])
{
        unsigned char buf[10];
        int i;
        if(argc < 2)
        {
                printf("give a bcd parameter !!\n");
                return 1;
        }
        bcd2num_(buf,sizeof(buf),argv[1],strlen(argv[1]));
        printf("bcd[%s] to number[",argv[1]);
        for ( i = 0 ; i<sizeof(buf) ; i++)
        {
                printf("%02X",buf[i]);
        }
        printf("]\n");


        return 0;
}


gcc -o sean_c_op sean_c_op.c -lbcd -L.

[root@localhost ~]# export LD_LIBRARY_PATH=.;./sean_c_op "123456789012345"
bcd[123456789012345] to number[00000123456789012345]

[c with dlopen]

vi sean_c_dlopen.c

#include <stdio.h>
#include "./sean_bcd.h"
#include <dlfcn.h>

int (*sean_bcd_dl)(char *out, int outsz, char *in,  int inlen);
#define LoadLibrary(path)        dlopen(path,RTLD_NOW)
#define FreeLibrary(handle)      dlclose(handle)
#define GetProcAddress(h,sym)    dlsym(h,sym)

void * attach_bcblib(const char *path)
{
        void *handle = dlopen(path, RTLD_NOW);
//      void *handle = LoadLibrary(path);
        sean_bcd_dl = dlsym(handle, "bcd2num_");
//      sean_bcd_dl = GetProcAddress(handle, "bcd2num_");
        return handle;
}
void detach_bcblib(void* handle)
{
        if(handle)
        {
                dlclose(handle);
//              FreeLibrary(handle);
                handle=NULL;
        }
}
int main(int argc , char *argv[])
{
        unsigned char buf[10];
        void *handle=NULL;
        int i;
        if(argc < 2)
        {
                printf("give a bcd parameter !!\n");
                return 1;
        }

        handle = attach_bcblib("./libbcd.so");

        sean_bcd_dl(buf,sizeof(buf),argv[1],strlen(argv[1]));
        printf("bcd[%s] to number[",argv[1]);
        for ( i = 0 ; i<sizeof(buf) ; i++)
        {
                printf("%02X",buf[i]);
        }
        printf("]\n");

        detach_bcblib(handle);


        return 0;
}


gcc -o sean_c_dlopen sean_c_dlopen.c -ldl

[root@localhost ~]# export LD_LIBRARY_PATH=.;./sean_c_dlopen "123456789012345"
bcd[123456789012345] to number[00000123456789012345]


[cpp]

vi sean_cpp.cpp
#include <stdio.h>
#include <string.h>
#include "./sean_bcd.h"
int main(int argc , char *argv[])
{
        unsigned char buf[10];
        sean_bcd seanobj;
        int i;
        if(argc < 2)
        {
                printf("give a bcd parameter !!\n");
                return 1;
        }
          seanobj.bcd2num((char*)buf,sizeof(buf),argv[1],strlen(argv[1]));
        printf("bcd[%s] to number[",argv[1]);
        for ( i = 0 ; i<sizeof(buf) ; i++)
        {
                printf("%02X",buf[i]);
        }
        printf("]\n");


        return 0;
}


g++ -o sean_cpp sean_cpp.cpp -lbcd -L.  -DSEAN_DLL_IMPL
[root@localhost ~]# export LD_LIBRARY_PATH=.;./sean_cpp "123456789012345"
bcd[123456789012345] to number[00000123456789012345]


文章分類