Tuesday, June 11, 2013

Tutorial Oracle Coherence #1

Oracle Coherence adalah in-memory data grid yang biasanya digunakan di aplikasi kritikal berkaitan dengan pembacaan data berulang-ulang secara cepat. Data Grid merupakan solusi yang handal dalam pengolahan data object di memori. Oracle Coherence dapat melakukan synchronize secara otomatis dengan database (persistance).

Tutorial ini dibagi menjadi beberapa posting. Untuk saat ini kita akan membahas

  • Instalasi Oracle Coherence
  • Running and Testing Oracle Coherence

Instalasi Oracle Coherence
Untuk proses instalasi Oracle Coherence cukup dengan dua langkah, yaitu :
  1. Download Coherence di http://www.oracle.com/technology/products/coherence/index.html
  2. Extract ZIP file.

Running and Testing Oracle Coherence
Disini kita akan membahas dua hal, yaitu :
  • Running Oracle Coherence 
  • Testing Oracle Coherence
Sebelum kita menjalankan Oracle Coherence, ada dua hal yang perlu kita setting dahulu, yaitu :
  1. Set JAVA_HOME
  2. Set COHERENCE_HOME
Sedangkan untuk menjalankan Oracle Coherence, adalah :
  1. cd $COHERENCE_HOME/bin
  2. ./cache-server.sh
Hasilnya seperti berikut:
Running Oracle Coherence
 Untuk testing disini kita menggunakan CohQL (Coherence Query Language). CohQL adalah Query Language yang digunakan untuk berinteraksi dengan coherence cache.

Sedangkan untuk menjalankan CohQL, adalah :
  1. cd $COHERENCE_HOME/bin
  2. ./query.sh
Hasilnya seperti berikut:
CohQL

 CohQL hampir sama seperti SQL yang kita kenal. Berikut contoh penggunaan CohQL:
  • Membuat cache dengan nama product, create cache "products"
  • Input nilai ke dalam cache, insert into "products" key "television" value "ID-5070"
  • Update nilai di dalam cache, update "products" set value() = "ID-5080" where key() like "television"
  • Melihat data yang ada di dalam cache, select * from "products" 
 Itulah sekilas tentang Oracle Coherence. Yang kita bahas baru installasi, menjalankan dan CohQL. Untuk blog selanjutnya kita akan membahas pemrograman Oracle Coherence dengan menggunakan. 

Parsing ISO 8583 dengan jPOS Library

Sekilas Mengenai ISO 8583

ISO 8583 adalah sebuah standar internasional format message untuk transaksi finansial, khususnya yang berbasis kartu. iso8583 secara garis besar memiliki 3 component besar: header, data, trailer. di dalam data, terbagi 3 lagi: MTI, bitmap, data element.

MTI (Message Type Indicator) = 4 digit field numerik, yang mengklasifikasikan fungsi message. terdiri dari 4 komponen: ISO 8583 version, Message Class, Message Sub-class, dan Transaction Originator. penjelasan dan contoh2 MTI dapat dilihat di http://www.codeproject.com/Articles/100084/Introduction-to-ISO-8583.

Bitmap = 16 digit field hexadecimal, teknik indexing utk menunjukkan bit berapa yang digunakan di data element. contoh sebuah nilai bitmap di wikipedia, misalnya 4210001102C04804. 
gimana cara nentuin bit mana yang aktif?

4210001102C04804 -> 8 byte. dipecah per byte: 42 10 00 11 02 C0 48 04.
kemudian tiap byte kita ubah jadi binary
42 => 01000010,
10 => 00010000,
00 => 00000000,
dan seterusnya sampai byte ke-8,
kemudian susun kembali sesuai posisi bytenya, kita dapat nilai binary
0100001000010000000000000001000100000010110000000100100000000100.
hitung dari kiri dimulai dari 1, index yang bernilai 1 menunjukkan bit yang aktif pada data element, yaitu: 2, 7, 12, 28, 32, 39, 41, 42, 50, 53 dan 62.

Data Element = fixed-length string atau byte[]. data element menyimpan field2 yang digunakan dalam transaksi. length tiap field bisa berbeda, sesuai dengan spesifikasinya. spesifikasi data element bisa dilihat di wikipedia. tidak semua field tersebut digunakan dalam tiap transaksi. biasanya hanya beberapa field saja yang terpakai, tergantung kesepakatan antara pemilik sistem dengan third party.

Contoh iso specification requirement bisa didownload di sini https://docs.google.com/file/d/0B_bLNqTuGdsGQUJ2WDctbkFiNmM/edit?usp=sharing.

Contoh Implementasi Parsing ISO 8583 dengan Java (jpos library)

library yang digunakan misalnya jPOS, ambil aja dependencynya dari maven:
 <dependency>  
   <groupId>org.jpos</groupId>  
   <artifactId>jpos</artifactId>  
   <version>1.9.0</version>  
 </dependency>  
 <dependency>  
   <groupId>commons-cli</groupId>  
   <artifactId>commons-cli</artifactId>  
   <version>1.2</version>  
 </dependency>  
 <dependency>  
   <groupId>org.jdom</groupId>  
   <artifactId>jdom</artifactId>  
   <version>1.1.3</version>  
 </dependency>  
note: jpos memiliki dependency ke commons-cli dan jdom.

Kita akan membutuhkan kedua file di bawah ini, silakan didownload:
Simpan keduanya di dalam struktur project, folder src/main/resources/.

Untuk packing ke Iso Message, bisa gunakan method:
 public String packToIso() {  
   String result = null;  
   org.jpos.iso.packager.GenericPackager genericPkg; //spec teknis yg dijadikan acuan fixed-length utk parsing  
   org.jpos.iso.ISOMsg isoMsg; //utk menyimpan nilai2 pada field2 transaksi, utk diparsing ke byte[] atau string.  
   try {  
     genericPkg = new org.jpos.iso.packager.GenericPackager("src/main/resources/isoPackager.xml");  
     isoMsg = new org.jpos.iso.ISOMsg();  
     isoMsg.setPackager(genericPkg);  
     //value2nya di-set sesuai dengan acuan spec isoSpecSample  
     isoMsg.setMTI("0200"); //request financial transaction  
     isoMsg.set(3, "123456");  
     isoMsg.set(4, "300000");  
     String formattedDate = new java.text.SimpleDateFormat("MMddhhmmss").format(new Date());  
     isoMsg.set(7, formattedDate);  
     isoMsg.set(11, "654321"); //bebas, can be sequencial  
     isoMsg.set(22, "123"); //special specification from channel  
     isoMsg.set(24, "123"); //special specification from channel  
     isoMsg.set(35, "AAAAAAAAAAAAAAA"); //special specification from channel  
     isoMsg.set(37, "1234567890AB"); //bebas, can be sequencial  
     isoMsg.set(41, "CAT12345"); //special specification from channel  
     isoMsg.set(42, "MERCHANT1234567"); //special specification from channel  
     isoMsg.set(48, "000"); //special specification from host  
     isoMsg.set(63, "020010023110030001"); //special specification from host  
     byte[] isoMsgByte = isoMsg.pack();  
     result = new String(isoMsgByte);  
     System.out.println(result);  
   } catch (org.jpos.iso.ISOException e) {  
     e.printStackTrace();  
   }  
   return result;  
 }  

Jalankan method di atas, resultnya adalah:
02003220050028C10002123456000000300000061103381365432112312315AAAAAAAAAAAAAAA1234567890ABCAT12345MERCHANT1234567003000018020010023110030001

Coba kita lihat char ke-1 sampai 4 adalah MTI, sesuai yang kita input yaitu 0200.
Char ke-5 sampai 20 adalah bitmap, yaitu 3220050028C10002. Bisa dicek dengan cara yang sama seperti di bagian pertama di atas apakah bit yang aktif sesuai dengan yang kita set.

Sedangkan untuk membongkar string iso 8583, misalnya ke Map, bisa gunakan method ini:
 public Map unpackFromIso(String stringMsg){  
   Map map = new HashMap();  
   try{  
     org.jpos.iso.ISOMsg isoMsg = new org.jpos.iso.ISOMsg();  
     isoMsg.setPackager(new org.jpos.iso.packager.GenericPackager("src/main/resources/isoPackager.xml"));  
     isoMsg.unpack(stringMsg.getBytes());  
     for(int i=1; i<=isoMsg.getMaxField(); i++){  
       if(isoMsg.hasField(i)){  
         map.put("bit-"+i, isoMsg.getString(i));  
       }  
     }  
   }catch(ISOException e){  
     e.printStackTrace();  
   }  
   return map;  
 }  

utk mencoba, bisa dengan main method ini:
 public static void main(String[] args) {  
   String parsed = packToIso();  
   Map map = unpackFromIso(parsed);  
   Iterator it = map.keySet().iterator();  
   while(it.hasNext()){  
     String key = (String)it.next();  
     System.out.println(key+" = "+map.get(key));  
   }  
 }  

selamat mencoba.

Monday, June 10, 2013

Konfigurasi JPA dengan JDBC Data Source pada WebLogic 10.3

Sekilas tentang Connection Pooling

Connection Pool merupakan sebuah teknik untuk membuat aplikasi langsung dapat menggunakan koneksi database tanpa harus menangani pembuatan atau pemutusan koneksi tersebut.

Sekilas tentang JDBC Data Source

Data Source menyediakan koneksi ke database melalui connection pooling, dan dapat me-manage koneksinya. Umumnya sebuah data source memiliki JNDI name, yang akan digunakan oleh aplikasi untuk me-lookup data source lalu kemudian dapat mengambil koneksi dari connection pooling.

Keuntungan dari penggunaan connection pooling dan data source antara lain ialah :
  • Aplikasi tidak lagi perlu mengurus bagaimana membuat/memutus koneksi ke database.
  • Apabila ada perubahan koneksi database, aplikasi tidak perlu berubah. Karena perubahan terjadi pada konfigurasi data source.
  • Jumlah koneksi database yang digunakan oleh aplikasi dapat terkontrol sesuai dengan konfigurasi pada data source, misal maximum jumlah koneksi 10 pada konfigurasi, maka dengan jumlah yang sama koneksi akan dibuat oleh data source.

Konfigurasi persistence.xml

<persistence-unit name="samplePersistenceUnit" transaction-type="JTA">
 
 <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
 <jta-data-source>jdbc/sampleDS</jta-data-source>
 <non-jta-data-source>jdbc/sampleDS</non-jta-data-source>
 <class>com.nostra.um.domain.User</class>
 <exclude-unlisted-classes>true</exclude-unlisted-classes>
 
 <properties>
 <property name="eclipselink.ddl-generation" value="create-tables" />
 <property name="eclipselink.logging.level" value="FINEST" />
 <property name="eclipselink.target-server" value="WebLogic_10" />
 </properties>
</persistence-unit>

  • Jika di-deploy pada container JEE (seperti WebLogic) default transaction-type-nya ialah JTA.
  • Isi elemen jta-data-source dan non-jta-data-source dengan JNDI Name pada Home -> Summary of JDBC Data Sources 
  • Pada property eclipselink.ddl-generation, jika berisi : 
    • create-tables : jpa akan melakukan proses create tabel sesuai dengan object model yang terdaftar di persistence.xml. 
    • drop-and-create-tables : jpa akan melakukan proses drop dan create tabel sesuai dengan object model yang terdaftar di persistence.xml. 
    • none : jpa tidak akan melakukan proses create/drop tabel.
  • Dan jika ingin merubah koneksi database pada JDBC Data Source seperti host, username, password dan lainnya, maka server harus di-restart. Karena proses pembuatan koneksi pada connection pooling terjadi saat server di-start.


Semoga bermanfaat, Cheers!

Sunday, June 9, 2013

Load Balancing dengan Zen Load Balancer


Zen Load Balancer (ZenLB) merupakan sebuah load balancer yang bersifat open source. Ada cukup banyak pilihan open source load balancer lainnya seperti HAProxy, BalanceNG, Crossroads, Apache HTTP Server, dsb. Namun perbedaan utama yang saya perhatikan adalah ZenLB merupakan sebuah appliance berbasis Debian. Seperti yang bisa diharapkan dari sebuah software appliance, konfigurasi yang perlu dilakukan minimal untuk dapat segera up-and-running. Selain itu tampilan Web management-nya juga menarik dan sangat informatif. Dua alasan itulah yang membuat saya ingin mencoba ZenLB ketika saya membutuhkan komponen load balancer pada simulasi high availability yang sedang saya lakukan beberapa minggu ini. Saya akan melakukan instalasi ZenLB menggunakan Oracle VM VirtualBox, hypervisor type-2 favorit saya. :)

Download ZenLB CD ISO image dari sini, kemudian buatlah sebuah virtual machine bertipe Linux Debian 32-bit. Letakkan CD ISO ZenLB yang sudah selesai di-download sebagai boot CD dari virtual machine tersebut dan jangan lupa untuk mengkonfigurasi network adapter-nya. Berhubung saya sedang terhubung dengan jaringan Wi-Fi, maka saya pilih "Bridged Adapter". Oh iya, sedikit tips untuk meningkatkan kinerja virtual machine di Oracle VM VirtualBox adalah agar memilih "User host I/O cache" pada SATA storage controller dan memilih "Paravirtualized Network (virtio-net)" pada tipe adapter jaringan jika menjalankan virtual machine bertipe Linux. Langkah-langkah yang saya lakukan ketika instalasi ZenLB dapat dilihat detilnya di sini. Restart virtual machine untuk menyelesaikan instalasi.

Ketika ZenLB sudah up kembali, akses ZenLB Web management ke https://<ZenLB_IP>:444 dengan menggunakan username "admin" dan password "admin" yang merupakan konfigurasi default-nya. Segera ubah password default ke menu Settings -> Change Password. Pada menu tersebut juga terdapat pilihan untuk sinkronisasi password dengan password root Debian yang kita masukkan ketika melakukan instalasi. Jika telah berhasil mengubah password, lakukan login kembali dengan password yang baru.
Zen Load Balancer dashboard

Pada dashboard utama Zen Load Balancer kita dapat memonitor secara penggunaan memory ZenLB, load cycle prosesor, dan network traffic dari network interface yang terdaftar di ZenLB. Pada bagian atas dashboard terdapat informasi global farms. Pada ZenLB, sebuah global farm adalah sebuah profil  load balancer atau rules configuration. Sebagai contoh saya akan mengkonfigurasi load balancer virtual name oid.nostratech.com (IP: 11.22.33.251) di port 389 sebagai front-end dari cluster Oracle Internet Directory (OID) yang terdiri dari oid1.nostratech.com dan oid2.nostratech.com.

Pertama-tama kita perlu membuat Virtual IP (VIP) terlebih dahulu untuk VIP 11.22.33.251, yaitu dengan cara memilih menu Settings -> Interfaces. Kemudian pilih "Add virtual network interface" pada eth0. Masukkan IP 11.22.33.251 pada interface eth0:1, kemudian pilih simpan untuk membuat virtual network interface tersebut.
Membuat virtual network interface eth0:1
Pilih menu Manage -> Farms untuk membuat global farm yang bernama oid.nostratech.com dengan IP 11.22.33.251 di port 389. Simpan konfigurasi tersebut kemudian pilih Edit Farm untuk melakukan konfigurasi lebih jauh terhadap farm tersebut.
Membuat farm oid.nostratech.com dengan VIP baru
Pada halaman edit farm kita dapat mengubah algoritma load balancing yang berlaku untuk sebuah farm. Ada 4 jenis algoritma yang di-support ZenLB, yaitu:

  1. Round Robin: untuk setiap koneksi yang diterima oleh ZenLB akan diteruskan secara rata ke backend server yang terdaftar di dalam global farm.
  2. Hash: untuk setiap koneksi yang diterima oleh ZenLB akan diteruskan kepada backend server yang sama sesuai dengan hasil kalkukasi hash terhadap IP address dari client.
  3. Weight: setiap backend server yang terdaftar diberikan bobot kerja, sehingga koneksi yang diterima oleh ZenLB akan diteruskan ke backend server sesuai dengan bobot kerjanya.
  4. Priority: masing-masing backend server diberikan skala prioritas, setiap koneksi yang diterima oleh ZenLB akan diteruskan ke backend server dengan skala prioritas tertinggi. Jika backend server tersebut down, maka koneksi yang diterima akan diteruskan ke backend server dengan skala prioritas tertinggi selanjutnya.

Pada bagian bawah halaman edit farm, terdapat konfigurasi Farm Guardian. Farm Guardian merupakan mekanisme ZenLB untuk melakukan verifikasi terhadap service backend server. Apabila hasil pengujian gagal, maka backend server tersebut diasumsikan dalam status down, sehingga ZenLB dapat meneruskan koneksi ke backend server yang tersisa. Sebagai contoh, kita dapat mengkonfigurasi Farm Guardian untuk memeriksa HTTP service dari backend server dengan menggunakan perintah "check_http". ZenLB telah menyediakan 5 buah script untuk Farm Guardian, yaitu "check_http", "check_ldap", "check_smtp", "check_tcp", dan "check_uplink". Pada dasarnya sebuah backend service akan diasumsikan down oleh Farm Guardian jika return value dari script yang dijalankan adalah selain 0. Sehingga kita juga dapat menggunakan custom script untuk verifikasi Farm Guardian.
Daftar backend service dari farm oid.nostratech.com:389 

Di bawah konfigurasi Farm Guardian, terdapat tabel daftar backend server dari sebuah farm. Isilah tabel tersebut dengan 2 hostname pada contoh sebelumnya, yaitu oid1.nostratech.com dengan port 389 dan oid2.nostratech.com pada port yang sama.
Backend status untuk farm oid.nostratech.com:389
Konfigurasi telah selesai, kita dapat melihat status dari backend service dengan memilih "View oid.nostratech.com backends status" pada kolom "Actions" dari tabel Farms table. Pada tabel status tersebut di atas, terlihat kedua status dari backend service oid1.nostratech.com:389 dan oid2.nostratech.com:389 berada pada status hijau yang berarti sedang up. Pada kesempatan berikutnya saya akan menggunakan ZenLB ini untuk mensimulasikan konfigurasi high availability pada Oracle Identity Management 11gR1.


Monday, June 3, 2013

Mengupdate Task pada Oracle BPM dengan BPM API

Pada blog sebelumnya, sudah dijelaskan sedikit untuk initiate task pada Oracle BPM. Sekarang saya akan coba menjelaskan sedikit untuk mengupdate task pada Oracle BPM.

1. Berangkat dari blog sebelumnya, setelah mendapatkan process instance id pada saat initiate task misal 1001. Gunakan itu untuk mengupdate task dengan APPROVE/REJECT atau outcome lain yang ada pada task tersebut.

2. Gunakan oracle.bpel.services.bpm.common.IBPMContext dan process instance id untuk mendapatkan task-task yang terdapat pada process instance dari process instance id
IBPMContext ctx = processUtils_.getBPMContext();

// Navigate to the process
IProcessInstance processInstance = processUtils_.getBPMServiceClient().getInstanceQueryService().getProcessInstance(ctx, 
         processInstanceId);

// Find the task(s) for the process.  This search is through the TaskQueryService with a predicate that
// constrains the search based on process instance id
List<task> tasks = processUtils_.findTasksForProcess(ctx, null, null, null, processInstanceId);

3. Gunakan perulangan untuk mendapatkan task yang sesuai dengan taskName yang dicari, dan task tersebut statusnya bukan COMPLETED dan nextOutcome tidak null.
for (Task processTask : tasks) {
 String taskState = processTask.getSystemAttributes().getState();
            
 //iterate until task state is not COMPLETED 
 if ( !taskState.equals(ProcessUtils.STATE_COMPLETED) && nextOutcome != null) {
 // if next outcome is set we also want to advance the next task.  
 //this is to setup the process query sample
 String taskName = processTask.getSystemAttributes().getTaskDefinitionName();
                
 if (taskName != null && taskName.equals(taskNameParameter)) {
     int taskNumber = processTask.getSystemAttributes().getTaskNumber();
     String taskId = processTask.getSystemAttributes().getTaskId();

     Task task = processUtils_.findTaskById(ctx, taskId);
     //Updating task
     task.setPayloadAsElement(payload);
     processUtils_.updateTask(ctx, task);
     //Updating outcome for task
     processUtils_.updateTaskOutcome(ctx, task.getSystemAttributes().getTaskId(), nextOutcome);
     Thread.sleep(5000);
           
     return "Success";
  }else{
     return "Not update task, taskName not equals " + taskNameParameter;
  }
 }
}
return "No task to process";

4. Berikut potongan kode pada fungsi mainnya
public static void main(String[] args) {
  BPMServiceClientFactory cf =
      ProcessUtils.getServiceClientFactory("user2","welcome1","t3://localhost:7878");
      ProcessUtils processUtils = new ProcessUtils(cf);
        
      TaskClient client = new TaskClient(processUtils);
      try {            
        String processInstanceId = "10001";
        String response = client.updateTask(processInstanceId, null, "ApproveLeaveTask","REJECT");
            
        System.out.println(response);
      } catch (WorkflowException e) {
        e.printStackTrace();
      } catch (JAXBException e) {
        e.printStackTrace();
      } catch (ParserConfigurationException e) {
        e.printStackTrace();
      } catch (Exception e) {
        e.printStackTrace();
      }
}

Code ini terinspirasi dari java.net.
Semoga bermanfaat. Cheers!!!