Tuesday, September 17, 2013

Skinning CSS di WebCenter Spaces



Pada post kali ini, penulis akan menjelaskan tutorial untuk custom WebCenter Spaces. Langsung saja kita mulai.


  1. Login WebCenter Spaces lalu masuk menu Admnisitration.
  2. Klik tab resources, pilih page templates
  3. Klik create 
  4. Nah untuk step selanjut, klik edit dan pilih edit source, maka akan muncul source code dari page template tersebut :

    s
  5. Nah untuk mulai skinning di perlukan sedikit pemahaman tentang page template ini , Lihat gambar di bawah yang sebelah kiri merupakan contoh template top navigation  dan di sebelah kanan merupakan source code-nya yang di buka di jdeveloper. Setelah kalian lihat maka kalian harusnya tau apa yang harus di edit (note : untuk bagian content kalian bisa ubah langsung css di menu skins(tab resources).

  6. Nah setelah kalian buka di jdeveloper kalian bisa langsung edit dan menambah kan CSS untuk memperindah website kalian. Langsung aja berikut : 
     <af:resource type="css">
          .xpf[id="T:spcNavPanel:mainTopStretchPanel"]{


    border-bottom:4px solid #FF5E4D; /* Set to desired color of bar under header */
    -webkit-box-shadow: 0px 1px 10px 5px #222;
    -moz-box-shadow: 0px 1px 10px 5px #222;
    box-shadow: 0px 1px 10px 5px #222;
    -webkit-box-shadow: 0 8px 6px -5px #222;
    -moz-box-shadow: 0 8px 6px -5px #222;
           box-shadow: 0 8px 6px -5px #222;
    }
    .x14j .p_AFMaximized {

    background-color: #FFFFFF !important;

    }
    .x1yx {

    }

    .xrw {
    background-image: none;
    height: 0px;

    }
    .xrv[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .xry[theme="webcenter"]{
    background-image: none;
    height: 0px;
    ;
    }
    .xrz[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .xs0[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .xs2[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .xs3[theme="webcenter"]{
    background-image: none;
    height: 0px;
    width: 0px;
    }
    .xs4[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .xs5[theme="webcenter"]{
    background-image: none;
    height: 0px;

    }
    .x1yx {
    background-image: none;
    height: 0px;

    }
    .x12t[theme="webcenter"]{
    color:#000000 !important;

     font-weight: bold;
    }

       </af:resource>

Before : After :

Sekian post dari saya :)

Introduction Node.JS, studi kasus : simple chat aplikasi


hello guys, pada post kali ini saya akan memnbahas tentang Node.JS dan membuat aplikasi chatting menggunakan platform ini :)

Node.js adalah sebuah platform dibangun di Chrome Javascript runtime easily building fast, scalable network applications. Node.js menggunakan model event-driven, non-blocking I/O yang membuatnya ringan dan efisien, cocok untuk real-time aplikasi yang berjalan di perangkat yang didistribusikan. Javascript adalah bahasa berbasis event-driven, dan Node.js menggunakan ini untuk keuntungan menghasilkan server yang scalable. Menggunakan arsitektur yang disebut event-loop. Nah berikut sedikit video persentasi Ryan Dahl : 




Nah langsung aja kita mulai. Pertama -tama tentu saja silahkan download Node.JS di sini http://nodejs.org.. Sebelum mulai kita butuh node package manager(npm) yaitu Socket.IO. Apa itu Socket.IO ? berikut penjelasan singkatnya :
"Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It's care-free realtime 100% in JavaScript." sumber : http://socket.io
Nah sekarang langsung saja install Node.JS dan run, lalu tulis perintah ini : npm install socket.io 


Langkah selanjutnya kita buat script untuk sisi server :
var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')
var usernames={};  
app.listen(9999);

function handler (req, res) {
//console.log(req);
  fs.readFile(__dirname + '/index4.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function(socket){

  console.log("Connection " + socket.id + " accepted.");
   console.log(socket.handshake.foo == true); // writes `true`
  console.log(socket.handshake.address.address); // writes 127.0.0.1
   socket.on('adduser', function(username){
        // store the username in the socket session for this client
        socket.username = username;
        // add the client's username to the global list
        usernames[username] = socket.id;
        // send client to room 1
        console.log(username+' has connected to the server');
  socket.broadcast.emit('updatechat', ' has connected',username);
  });
  // now that we have our connected 'socket' object, we can 
  // define its event handlers
  socket.on('message', function(message){
 // we tell the client to execute 'updatechat' with 2 parameters
 
  io.sockets.emit('updatechat',  message,socket.id);
  
        console.log("Received message: " + message + " - from client " + socket.username);
  });

  socket.on('pmessage',function(message){
  // This works and sends message to all clients
  //io.sockets.emit("updatechat",message,socket.username); 
  console.log(usernames[message] + "  " + socket.id + " to  " + message);
  // THIS DOESNOT
  io.sockets.socket(usernames[message]).emit("updatechat","Ping" + message,socket.username); 

  });
  socket.on('disconnect', function(){
  
  io.sockets.emit('usersleft',  socket.username);
  delete usernames[socket.username];
 //socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
    console.log("Connection " + socket.id + " terminated.");
  });
    
}); 
Selanjutnya kita buat untuk script di sisi client-nya :
 

<!doctype html>
<html>
  <head>
    <title>Socket.io Test</title>
    <script src="/json.js"></script> <!-- for ie -->
 <script src="/socket.io/socket.io.js"></script>
 </head>
  <body>
  <script>
    var firstconnect = true;
    var socket;
 function connect() {
      if(firstconnect) {
        socket = io.connect(null);
  socket.on('message', function(data){ message(data); });
  socket.on('connect', function(){
  
    socket.emit('adduser', prompt("What's your name?"));
    status_update("Connected to Server"); 
    });
        socket.on('disconnect', function(){ status_update("Disconnected from Server"); });
        socket.on('reconnect', function(){ status_update("Reconnected to Server"); });
        socket.on('reconnecting', function( nextRetry ){ status_update("Reconnecting in " 
          + nextRetry + " seconds"); });
        socket.on('reconnect_failed', function(){ message("Reconnect Failed"); });
  socket.on('updatechat', function (message,socketid) {
              document.getElementById('rec').innerHTML += "Socketid :" + socketid+" Broadcast says: " + message + " <br>";
    //$('#conversation').append('<b>'+username + ':</b> ' + data + '<br>');
        });
  socket.on('usersleft', function (socketid) {
              document.getElementById('rec').innerHTML += "<b>Socketid :" + socketid+" has been left</b><br>";
     });
     firstconnect = false;
     }
     else {
        socket.socket.reconnect();
  }
    }
 function disconnect() {
      socket.disconnect();
    }
 function message(data) {
 document.getElementById('message').innerHTML = "Server says: " + data;
    }
 function status_update(txt){
      document.getElementById('status').innerHTML = txt;
    }
 function esc(msg){
      return msg.replace(/</g, '&lt;').replace(/>/g, '&gt;');
    }
 function send() {
 socket.emit('message',document.getElementById('andy').value);    
    };        
 function pingID(id)
  { 
  socket.emit('pmessage',document.getElementById('andy2').value);
  }
  </script>
  <h1>Socket.io Test</h1>
    <div><p id="status">Not Connected</p></div>
    <div><p id="message"></p></div>  
    <button id="connect" onClick='connect()'/>Connect</button>
    <button id="disconnect" onClick='disconnect()'>Disconnect</button>
 <input type="text" id="andy" />
    <button id="send" onClick='send()'/>Send Message</button>
 <input type="text" id="andy2" />
 <button id="send" onClick='pingID()'/>pingID Message</button>
 </hr>
  <div><p id="rec"></p></div>  
  </body>
</html>
Untuk langkah terakhir mari kita jalankan script yang di atas. Silahkan ketika node <nama_file_server>



Dan simple aplikasi chatting sudah jadi :

Sumber :
http://psitsmike.com/2011/09/node-js-and-socket-io-chat-tutorial/
Node: Up and Running

Sunday, September 15, 2013

Konfigurasi dan Behavior Notifikasi Email di Oracle BPM


Blog post kali ini akan membahas bagaimana melakukan konfigurasi mail server agar mengirimkan email ke User yang terlibat dalam workflow BPM. Apabila konfigurasi telah selesai dan berjalan dengan baik, maka kita dapat mengirim notifikasi untuk setiap task yang berjalan di BPM. Notifikasi ini dapat berupa pemberitahuan ketika ada task baru yang harus dikerjakan, sebuah task selesai ataupun ketika sebuah task di-approve/reject.

Langkah-langkahnya adalah sebagai berikut:
  1. Buka Enterprise Manager. Masuk ke farm_domain_soa anda -> User Messaging Service -> akan muncul daftar Email Driver. Klik tombol lambang pulpen di tab Configure Driver. 
  2. Layar konfigurasi akan muncul. Field yang penting yang harus diisi adalah sebagai berikut: 
     
  3. Buka farm_domain_soa -> SOA -> soa_infra -> klik kanan soa_infra -> SOA Administration -> Workflow Properties. Layar konfigurasi notifikasi untuk SOA akan muncul, masukkan From Address, Reply To Address dan Actionable Address berdasarkan data User di mail server anda. Restart Managed Server tempat SOA anda berjalan (misal soa_server1).

    Masukkan From Address, Actionable Address dan Reply To berdasarkan konfigurasi yang sesuai..
  4. Buka farm_domain_soa -> SOA -> soa_infra -> Service Engine -> Human Workflow 
  5. Layar Human Workflow Engine akan terbuka. Buka Tab yang paling kanan yaitu Notification Management -> Send Test Notification 
  6. Pop up akan terbuka dan anda dapat mencoba mengirimkan test email dengan menggunakan konfigurasi yang telah anda set di tahap 1-4. Masukkan alamat email tujuan, subject dan content emailnya. 
  7. Klik Send dan apabila berhasil, maka akan muncul Response SENT. Cek email yang dituju pada langkah nomor 6 untuk memastikan bahwa email test berhasil terkirim. Apabila sukses, maka ini menandakan bahwa konfigurasi mail server anda di BPM sudah benar.
     
    Cek hasil pengiriman email anda untuk memastikan konfigurasi yang dibuat sudah tepat.
  8. Selanjutnya akan kita coba notifikasinya melalui aplikasi real BPM. Buat sebuah aplikasi BPM (contoh sederhana dapat dilihat di salah satu post blog ini). Masukkan Human Activity dan buat Human Task-nya. Buka property dari human task tersebut, masuk ke Tab Notification 
  9. Disini, anda dapat mengatur kepada siapa saja notifikasi akan dikirimkan ketika task tersebut dimulai (Assign), selesai (Complete), error, expire dsb. 

  10. Anda juga dapat mengatur Title dari email yang akan dikirimkan. 
  11. Deploy aplikasi anda dan jalankan Human Task yang notifikasinya telah anda konfigurasi di langkah nomor 9. Cek email dari participant task tersebut, maka anda akan melihat bahwa email akan terkirim berdasarkan informasi yang anda masukkan di langkah nomor 9. 

  12. Email ini dapat anda buka, dimana isinya adalah detail dari sebuah task, baik itu form hasil inputan dan juga datanya.
That's it, anda sudah berhasil melakukan konfigurasi email di BPM :)
Semoga bermanfaat.






WebLogic Pack/Unpack Script

Pertama kali saya mendengar ada sepasang script WebLogic yang bernama pack.sh dan unpack.sh adalah sekitar 2 tahun yang lalu ketika teman saya sedang melakukan konfigurasi high availability untuk Oracle BPM 10g. Saya tidak terlibat pada saat konfigurasinya, sehingga pengertian saya mengenai kedua script tersebut adalah script pack.sh digunakan untuk membuat backup dari sebuah domain dari sebuah mesin, sedangkan script unpack.sh digunakan untuk membuka atau me-restore domain tersebut di mesin yang lain, sehingga kondisi dari kedua domain pada kedua mesin dalam kondisi yang sama. Kemudian muncul pertanyaan ini di benak saya,
"Kenapa tidak menggunakan tarball saja untuk membuat backup dan mengekstrak tarball tersebut di mesin lain?"
Waktu itu teman saya juga tidak secara intensif menggunakan script tersebut, melainkan meng-copy semua konfigurasi domain dari mesin satu ke mesin lainnya. Sehingga pada saat itu pengertian saya adalah pack.sh/unpack.sh adalah serupa dengan fungsi tar. Namun sejak 3-4 bulan yang lalu, saya mulai terlibat di dalam implementasi konfigurasi high availability untuk beberapa aplikasi Oracle Fusion Middleware, seperti Oracle IdM 11g, Oracle WebCenter Suite 11g, Oracle SOA Suite 11g, dan Oracle EM 12c. Dari situlah saya menemui kembali kedua script tersebut, dan kali ini saya lebih memahami maksud dan tujuan dari script tersebut.

Kedua script ini ternyata berperan penting ketika konfigurasi WebLogic, terutama untuk konfigurasi high availability di mana umumnya konfigurasi tersebar di lebih dari satu mesin. Jika mengacu pada salah satu guide dari Oracle, proses pack/unpack pada dokumen tersebut selalu diasosiasikan dengan kegiatan untuk mempropagasi konfigurasi domain WebLogic. Biasanya kegiatan tersebut dilakukan setiap kali perubahan konfigurasi pada domain dilakukan, seperti setiap kali domain selesai di-extend dengan komponen deployment yang baru. Kemudian mungkin pertanyaan yang muncul adalah,
"Oke, lalu perbedaannya dengan membuat tarball adalah...???"
Dari pengamatan yang saya lakukan ketika mengkonfigurasi high availability, kedua script tersebut melakukan hal-hal berikut ini:
  1. Script pack.sh akan membuat sebuah template WebLogic domain berekstensi .jar, berdasarkan lokasi konfigurasi domain yang diberikan. 
  2. Template yang dibuat oleh script pack.sh dapat berupa full-domain template atau managed-domain template. Managed-domain template biasanya digunakan untuk memisahkan antara konfigurasi domain primer untuk AdminServer dengan konfigurasi domain sekunder untuk managed server. Sedangkan full-domain template digunakan untuk membuat template konfigurasi domain secara utuh.*)
  3. Script unpack.sh akan membaca template yang dibuat oleh script pack.sh, kemudian membuat direktori yang berisi konfigurasi domain (full-domain/managed-domain) di lokasi yang telah diberikan.
  4. Script pack.sh akan memasukkan semua isi konfigurasi domain, termasuk jika kita membuat custom scripts seperti custom environment variable script, membuat VIP, dsb. Direktori yang berisi file hasil generate WebLogic server (seperti direktori $ASERVER_HOME/servers) tidak dimasukkan ke dalam template.
  5. Script unpack.sh tidak akan menimpa file yang sudah ada sebelumnya pada lokasi tujuan. Namun script tersebut akan membuat backup-nya terlebih dahulu, biasanya me-rename file original dengan menambahkan ekstensi .ORIG.
  6. Script unpack.sh akan meng-update entry lokasi domain pada file $MW_HOME/domain-registry.xml dan $WL_HOME/common/nodemanager/nodemanager.domains pada mesin tujuan, sehingga ketika selesai propagasi konfigurasi, kita dapat langsung memerintahkan Node Manager di mesin tujuan untuk startup sebuah managed server.
Kejadian yang saya alami ketika melakukan konfigurasi high availability, adalah seringkali konfigurasi yang dilakukan di satu mesin berjalan, tidak berjalan ketika dilakukan di lebih dari satu mesin. Solusinya adalah propagasi konfigurasi kembali dengan menjalankan pack.sh dan unpack.sh. Ada dua kejadian yang saya ingat:
  1. Ketika mengintegrasikan WebCenter Portal: Spaces dengan BPM Workspace, sempat saya tidak dapat login ke dalam BPM Workspace. Seingat saya error-nya adalah credential yang tidak valid ketika saya login menggunakan weblogic. Anehnya kombinasi user dan password pada domain yang sama dapat terotentikasi jika login di Administration Console. Kemudian saya ingat point penting mengenai file cwallet.sso di dalam dokumentasi high availability. Setelah saya copy kembali file cwallet.sso dan kembali propagasikan di masing-masing mesin, isu tersebut hilang.
  2. Ketika mengintegrasikan WebCenter Portal: Spaces dengan WebCenter Portal: Discussions, propagasi kembali harus dilakukan seusai kita meng-generate file default-keystore.jks agar keystore tersebut terpropagasi di masing-masing mesin. Kemudian saya mengalami kesulitan dalam meng-attach OWSM policy di Spaces dan Discussions instance. Solusi yang berhasil dilakukan adalah meng-attach OWSM policy ketika Spaces dan Discussions dijalankan dari $ASERVER_HOME, kemudian shutdown kedua instance dan kembali melakukan propagasi konfigurasi domain menggunakan pack.sh dan unpack.sh.
Sehingga jawaban yang saya pikir lebih tepat untuk pertanyaan saya di awal blog ini adalah,
"Karena pack.sh dan unpack.sh script tidak bertujuan untuk membuat backup dari sebuah konfigurasi domain, melainkan untuk mempropagasi perubahan konfigurasi domain yang tidak terpropagasi secara otomatis dari AdminServer. Gunakan tarball untuk membuat full backup dari konfigurasi domain."
Sekian sharing saya kali ini. Cheers! :)

*) Untuk full-domain template, saya belum terlalu intensif menggunakannya. Sehingga membutuhkan eksperimen dan simulasi kembali untuk dapat menjabarkan fungsinya.

Implementasi UI Pada Oracle BPM

Pada post kali ini, saya hendak menjelaskan bagaimana cara implementasi UI pada BPM. Ikuti langkah dibawah ini :
  1. Pertama-tama kita buat satu bpm application baru, Pilih File->New ,  kemudian pilih BPM Tier, dan pilih BPM Project, kemudian pilih Ok.
  2. Setelah memilih Ok, maka akan keluar windows baru untuk mengisi nama project BPM yang akan dibuat. Pada kali ini saya akan membuat nama project nya Demo, kemudian pilih Next dan Pilih Composite With BPMN Process. Finish.
  3. Setelah memilih Finish, maka akan keluar windows baru untuk memberi nama process yang akan dibuat. Pada kali ini saya akan tetap memakai nama defaultnya yaitu Process, dan Process yang dipilih adalah Manual Process. Setelah itu Pilih Finish.
  4. Jika sudah memilih Finish, maka tampilan nya akan berupa sebagai berikut :
  5. Sampai sini kita sudah membuat satu Project yang bernama Demo Project dan satu Process yang bernama Process, setelah ini kita membutuhkan xsd yang digunakan dalam pembuatan UI. Cara pembuatannya sebagai berikut, klik kanan pada folder xsd yang berada dalam SOA Content, kemudian pilih new.
  6. Setelah memilih New, maka akan keluar windows baru untuk membuat gallery baru, pilih All Technologies pada tab di atas, kemudian pilih XML dan pilih XML Schema, kemudian pilih Ok.
  7. Setelah memilih Ok. maka akan keluar window untuk Create XML Schema. Beri nama file nya dengan Name.xsd, kemudian pilih Ok.
  8. Setelah selesai, maka tampilan nya akan seperti dibawah ini
  9. Pada kali ini kita akan membuat File XML sederhana yang berisikan 1 data string yang bernama Nama. Klik 2 x pada exampleElement dan ganti dengan nama.
  10. Klik kanan pada nama, kemudian pilih Set Type, dan pilih xsd:string, jika sudah save all



  11. Setelah membuat name.xsd maka kita akan membuat Business Object. Caranya ialah pilih View kemudian pilih BPM Project Navigator
  12. Setelah itu klik kanan pada Business Catalog, pilih New dan pilih Business Object

  13. Beri nama DataBO pada Business Object yang akan kita buat, kemudian klik kaca pembesar pada Destination Module, kemudian klik New dan beri nama Module nya dengan Module, kemudian pilih Module yang sudah kita buat tadi. Klik centang pada Based on External Schema, kemudian pilih tanda kaca pembesar lagi untuk mencari xsd yang sudah kita buat tadi. Lihat gambar! Jika sudah sama persis baru klik Ok. Jangan lupa untuk save pekerjaan anda!


  14. Setelah selesai, kita akan membuat Data Object. Caranya yaitu : klik Process yang sedang kita buat, kemudian liat Process Structure nya, kemudian klik kanan pada Process Data Objects dan pilih New. Beri nama namaDO, dengan type nya berupa component, browse cari NamaBO yang sudah kita buat tadi, kemudian klik Ok.

  15. Klik kanan dan pilih properties pada User Task yang sudah terauto generate pada saat kita membuat Process diawal.

  16. Pilih Tab Implementation, dan klik tanda + dibagian human task, beri nama Human Task yang akan kita buat dengan NamaHumanTask, kemudian pilih Ok, dan pilih Ok lagi

  17. Klik kanan pada User Task lagi dan pilih Open Human Task, kemudian akan muncul tab baru yang berisi informasi tentang Human Task yang sudah kita buat tadi. Kemudian pilih Data,dan pilih tanda + untuk menambah data yang kita mau, pada kali ini kita akan memilih yang Add String Parameter. Setelah itu pilih element untuk memilih dari xsd yang sudah kita buat tadi, cari xsd nya kemudian pilih nama:string, kemudian pilih Ok dan pilih Ok.



  18. Save semua pekerjaan anda, kemudian klik kanan lagi pada User Task, pilih tab Implementation, dan pilih Data Assosiation, pada tab Input, drag namaDO pada folder Data Objects ke nama yang berada di Arguments, dan pada tab Output, drag nama yang berada di folder Arguments ke namaDO yang berada di folder DataObjects, kemudian pilih Ok dan save pekerjaan anda.


  19. Klik kanan lagi pada User Task dan pilih Open Human Task, kemudian pilih Create Form dan pilih Auto Generate Task Form, Beri Nama Project UI anda dengan Nama apa saja, namun disarankan sama seperti nama Human Task yang sudah anda buat dan di tambahkan UIProject diblakangnya untuk memudahkan pencarian. Karena itu saya akan memberi nama NamaHumanTask_UIProject, kemudian pilih Ok dan tunggu sebentar untuk proses autogenerate form nya.


  20. Selesai, maka tampilan UI nya akan seperti ini : 
    Anda telah berhasil mengimplementasikan UI sederhana,

    That's all, Semoga Membantu !