Showing posts with label Tamy Sihotang. Show all posts
Showing posts with label Tamy Sihotang. Show all posts

Friday, December 14, 2018

SpringBoot Facebook Social Application

Halo sobat Nostra,
kali ini saya akan coba membahas tentang SpringBoot Facebook Social Application dimana datanya akan kita consume dari postingan kita yang ada di facebook

Langkah pertama yang harus kita siapkan tentunya adalah create project baru spring-boot.

Struktur project

















tambah code berikut di pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
</dependency>
Kemudian kita akan membuat page html sebagai tampilan pertama ketika kita menjalankan project spring-boot => resources/templates/connect/facebookConnect.html
<html>
<head>
   <title>SpringBoot Facebook</title>
</head>
<body>
<h3>Connect to Facebook</h3>
<form action="/connect/facebook" method="POST">
    <input type="hidden" name="scope" value="user_posts" />
    <div class="formInfo">
      <p>Anda belum terhubung ke facebook. 
      Tekan button untuk terhubung ke akun facebook.</p>
    </div>
      <p><button type="submit">Connect to Facebook</button></p>
</form>
</body>
</html>
Selanjutnya page jika sudah terhubung ke facebook => resources/templates/connect/facebookConnected.html
<html>
<head>
  <title>Hello Facebook</title>
</head>
<body>
<h3>Connected to Facebook</h3>
   <p> Terhubung ke Facebook
   Klik <a href="/">disini</a> untuk melihat postingan Facebook Anda
</p>
</body>
</html>
Terakhir page untuk tampilan postingan-postingan kita yang ada di Facebook => resources/templates/hello.html
<html>
<head>
     <title>Hello Facebook</title>
</head>
<body>
<h4>Some your feeds:</h4>

<div th:each="post:${feed}">
    <b th:text="${post.from.name}">from</b> wrote:
    <p th:text="${post.message}">post message</p>
    <img th:if="${post.picture}" th:src="${post.picture}"/>
    <hr/>
</div>
</body>
</html>
Nah, untuk controller yang akan get data dari facebook => FacebookFetchFeeds.java
package drools.controller;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.api.PagedList;
import org.springframework.social.facebook.api.Post;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class FacebookFetchFeeds {
    private Facebook facebook;
    private ConnectionRepository connectionRepository;

    public FacebookFetchFeeds(Facebook facebook, 
                   ConnectionRepository connectionRepository) {
        this.facebook = facebook;
        this.connectionRepository = connectionRepository;
    }

    @GetMapping("/")
       public String getFacebookFeed(Model model) {
        if(connectionRepository.findPrimaryConnection(Facebook.class) == null) 
         {
          return "redirect:/connect/facebook";
         }

        PagedList<Post> feed = facebook.feedOperations().getFeed();
        model.addAttribute("feed", feed);
        return "hello";
      }
}
Object Facebook dari controller diatas merupakan reference untuk binding API Spring Facebook.
Aplikasi spring ini akan berinteraksi dengan akun Facebook maka kita akan membutuhkan Application ID dan Application Secret. Nah ini juga bisa digunakan untuk mengintegrasikan login menggunakan Facebook.
Bagaimana cara mendapatkan Aplication ID dan Aplication Secret Facebook?
Gampang . .
Akses halaman https://developers.facebook.com/apps


- Kemudian pilih product => Facebook Login
- Pilih Setting->Basic, maka kita akan mendapatkan App ID dan App Secret
- Pada application.properties tambah App ID dan App secret
spring.social.facebook.appId=990672621133932
spring.social.facebook.appSecret=4f66962b5610358ec55f8ed1b6cc2604
selesai sudah,
Run project spring dan lihat hasilnya




Klik button "Connect to Facebook", dan lakukan autentikasi facebook
Jika sudah terhubung ke facebook maka akan redirect ke page selanjutnya







Kemudian klik button "disini", dan postingan-postingan kita di facebook akan ditampilkan






















Sekian penjelasan saya mengenai springboot facebook social application, semoga bermanfaat
Terima kasih


Create Client Load Balancing with Spring Boot

Halo sobat nostra,
Kali ini saya akan menjelaskan bagaimana cara create client load balancing dengan spring boot

Nah, apa itu load balancing?
Apa sih gunanya load balancing?
Load balancing merupakan teknik yang digunakan untuk mendistribusikan beban trafik pada dua atau lebih jalur koneksi secara seimbang, dimana gunanya agar trafik dapat berjalan secara optimal,  memaksimalkan throughput serta menghindari overload pada salah satu jalur koneksi.

Untuk memulai, pertama kita create 2 project Spring Boot
  • Spring Boot untuk simple restfull service, untuk project ini akan kita jalankan pada port 8090, 8091, dan 8092 (localhost:8090, localhost:8091, localhost:8092)
  • Spring Boot untuk load Balancing yaitu Ribbon Client, dan untuk project ini di jalankan pada port 8080 (localhost:8080)
  1. Create Spring Boot Project for Simple Restfull Service
    Tambah code berikut pada pom.xml
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    Kemudian buat controller untuk request mapping
    package drools.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class WebController {
        @Value("${server.port}")
        String port;
    
        @RequestMapping(value = "/")
        public String home() {
             return "Hello!";    }
    
        @RequestMapping("/greeting")
        public String hello() {
             return "Hello from a service running at port: " + port + "!";
        }
    }
  2. Create Spring Boot Project for Ribbon Client
    Tambah code berikut pada pom.xml
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    Konfigurasi ribbon client pada file application.yaml
    spring:
        application:
            name: Ribbon-Client
    
    helloworld:
        ribbon:
            eureka:
                enabled: false
            listOfServers: localhost:8090,localhost:8091,localhost:8092
            ServerListRefreshInterval: 1000
    
    server:
        port: 8080
    listOfServer merupakan list server untuk load balancing,
    ServerListRefreshInterval merupakan waktu interval. interval yang digunakan untuk refresh ribbon service

    Kemudian create satu class Configuration. config.java
    package drools.config;
    
    import com.netflix.loadbalancer.AvailabilityFilteringRule;
    import com.netflix.loadbalancer.IPing;
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.PingUrl;
    import org.springframework.beans.factory.annotation.Autowired;
    import com.netflix.client.config.IClientConfig;
    import org.springframework.context.annotation.Bean;
    
    public class config {
        @Autowired
        IClientConfig ribbonClientConfig;
    
        @Bean
        public IPing ribbonPing(IClientConfig config) {
            return new PingUrl();
        }
    
        @Bean
        public IRule ribbonRule(IClientConfig config) {
            return new AvailabilityFilteringRule();
        }
    }
    IClientConfig digunakan untuk menyimpan semua konfigurasi client yang kita define dalam code
    IPing merupakan komponen yang menentukan mekanisme yang kita gunakan untuk menentukan ketersediaan server secara real-time, memeriksa server apakah masih hidup
    IRule merupakan komponen logic yang menentukan aturan load balancing yang kita gunakan dalam spring boot. Dalam project ini kita menggunakan AvailabilityFilteringRule, dimana dalam aturan ini akan memilih server yang available atau yang tersedia.

    Create sebuah load balancing controller WebController.java
    package drools.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class WebController {
        @LoadBalanced
        @Bean
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
        @Autowired
        RestTemplate restTemplate;
    
        @RequestMapping("/helloworld")
        public String home() {
             return this.restTemplate.getForObject("http://helloworld/greeting", 
                 String.class);
        }
    }
    Dalam controller diatas, digunakan anotasi @LoadBalanced untuk konfigurasi restTemplate sebagai LoadBalancerClient.
  3. Run and check results
  • Run Restfull Service pada port 8090, 8091, 8092
    mvn spring-boot:run -Dserver.port=8090
         mvn spring-boot:run -Dserver.port=8091
        mvn spring-boot:run -Dserver.port=8092

  • Kemudian run Ribbon Client
    mvn spring-boot:run
        dan jalankan http://localhost:8080/helloworld pada browser atau postman, dan kita akan   menerima output dari service 8090, 8091, 8092


dan log akan seperti gambar diatas jika kita menjalankan service ribbon client

Jika kita mematikan salah satu service pada restfull service maka kita akan menemukan connection refused pada log ribbon client.
Namun demikian, ribbon client akan tetap berjalan dari service yang masih hidup.
Dan Jika kita mematikan semua service, kita akan menemukan pada log no up servers available

Oke, sekian penjelasan saya, semoga bermanfaat
Terima kasih




Sunday, September 9, 2018

How to look session and kill session in oracle database

Halo sobat Nostra,

Kali ini saya akan membahas bagaimana cara melihat session dan kill session tersebut pada oracle database.

Ini pengalaman saya ketika mengerjakan project Jiwasraya, saya tidak bisa alter table dan selalu error. Error nya seperti gambar di bawah ini









Nah ternyata error tersebut dikarenakan table itu di lock.
Bergumul dengan error  dan bertanya tanya dalam hati, kenapa table itu di lock ya? (xixixi cie yang bergumul :D)
Setelah di telusuri lebih jauh, ternyata table tersebut di lock karena transaksi pada table berjalan lama serta banyak aplikasi yang menggunakan table tersebut dan melakukan transaksi secara bersamaan.
Kebetulan pada saat kasus ini, applikasi sedang di test oleh user IT Jiwasraya, dan table yang ingin saya alter adalah salah satu table yang memiliki data yang sangat banyak yang membutuhkan waktu lebih lama dari biasanya jika kita melakukan select table.
Table di lock bisa juga dikarenakan ketika kita melakukan perubahan pada table namun kita lupa commit dan log off dari sistem.

Cara yang saya lakukan agar table tersebut tidak lock, adalah melihat session dan kill session pada table tersbut dengan cara menggunakan SQL command seperti :

SELECT
    O.OBJECT_NAME,
    S.SID,
    S.SERIAL#,
    S.PROGRAM,
    SQ.SQL_FULLTEXT,
    S.LOGON_TIME
FROM
    V$LOCKED_OBJECT L,
    DBA_OBJECTS O,
    V$SESSION S,
    V$SQL SQ
WHERE
    L.OBJECT_ID = O.OBJECT_ID
    AND L.SESSION_ID = S.SID
    AND S.SQL_ADDRESS = SQ.ADDRESS;

Untuk melihat table yang di lock dapat menggunakan view V$Locked_Object, dan nama table yang di lock tersebut ada pada view DBA_Object.
Untuk menemukan session blocked nya, kita bisa join dengan view V$Session

dan untuk kill session bisa dengan command berikut :


alter system kill session 'SID,SERIAL#';

Kita harus berhati-hati dalam menghapus session dalam database. Jangan sampai salah menghapus session table.
Ada baiknya jika kita ingin kill session pada suatu table harus konsultasi terlebih dahulu dengan tim.

Sekian dari saya tentang bagaimana cara melihat session dan kill session pada oracle database

Terima kasih,

Eliminate file duplicate using guava in spring boot


File duplicate adalah dua atau lebih file yang memiliki kesamaan yang berada pada satu tempat. 
Jika file duplicate nya berjumlah puluhan atau bahkan ratusan, tentu akan mengakibatkan ruang penyimpanan atau kapasitas memory kita akan semakin sempit. Lantas, apa yang kita lakukan? Tentu kita harus menghapus file yang duplicate tersebut agar penyimpanan kita terasa ringan. 
Namun jika jumlahnya hingga ribuan atau ratus ribuan, kita mungkin tidak sanggup mencari file yang duplicate dan menghapus nya secara manual. 
Jangan bersedih dulu, disini kita akan membahas bagaimana cara eliminasi file duplicate dengan menggunakan spring boot. Dengan menggunakan spring-boot kita bisa dengan mudah eliminasi file duplicate dengan cepat dan mudah dengan bantuan library google guava. 
Nah google guava itu apa??
Google guava itu adalah library untuk java yang dibangun oleh engineer google. 

  • Pertama yang harus kita lakukan adalah create project baru spring-boot
  • Kemudian pada file pom.xml kita akan menambahkan library google guava

<dependency>
 <groupId>com.google.guava</groupId>
 <artifactId>guava</artifactId>
 <version>23.0</version>
</dependency>

  • Create 1 file java, dalam demo ini saya create FileDuplicator.java

    package drools.model;
    import com.google.common.base.Function;import com.google.common.base.Preconditions;import com.google.common.collect.*;import com.google.common.hash.HashCode;import com.google.common.hash.HashFunction;import com.google.common.hash.Hashing;import com.google.common.io.Files;import lombok.Data;
    import java.io.File;import java.io.IOException;import java.nio.file.Path;import java.util.*;

    public class FileDuplicator {
    File directory;
    FileDuplicator(String filePath){
      this.directory = new File(filePath);  Preconditions.checkState(this.directory.isDirectory(),   "Supplied directory does not exist "); }
    public Collection<FileDuplicate> calculateDuplicaties(){
      FluentIterable<FileDuplicator.FileRecord> records = Files.fileTreeTraverser()
      .breadthFirstTraversal(this.directory)
      .filter(File::isFile)
      .transform(FileDuplicator.FileRecord::new);  Multimap<HashCode, Path> duplicateCandidates = ArrayListMultimap.create();  records.forEach(fileRecord -> duplicateCandidates.put(fileRecord.getHashCode(),   fileRecord.getPath()));

      Multimap<HashCode, Path> dupesOnly = Multimaps.filterKeys(duplicateCandidates,   record -> duplicateCandidates.get(record).size() > 1);

      FluentIterable<FileDuplicator.FileDuplicate> fileDuplicates =
      FluentIterable.from(dupesOnly.asMap()
      .entrySet())
      .transformAndConcat((Function<Map.Entry<HashCode, Collection<Path>>,  Iterable<FileDuplicator.FileDuplicate>>)
       input -> Collections.singleton(new FileDuplicator
       .FileDuplicate(input.getKey(),  input.getValue())));

    return ImmutableSet.copyOf(fileDuplicates);
      }

    public static void
    main(String[] args) {
      FileDuplicator fileDuplicator = new FileDuplicator(
       "/Users/tamy/Documents/Belajar/Folder/");  Collection<FileDuplicator.FileDuplicate> duplicates =
       fileDuplicator.calculateDuplicaties();  System.out.println("\n duplicates : " +duplicates);  String a = "";
      for(FileDuplicator.FileDuplicate fileDuplicate : duplicates){
       Collection test = fileDuplicate.paths;  a = String.valueOf(test);  a = a.substring(a.lastIndexOf("[")+1,a.lastIndexOf("]"));// System.out.println("a : "+test.size());
      for
    (int j=0;j<test.size()-1;j++){
       String[] strArray = new String[] {a};// System.out.println("strArray : "+ strArray.length);   String[] split = strArray[0].split(",");// System.out.println("temps : "+split[j]);   recursiveDelete(new File((split[j].toString().trim())));  }

      }
    }

    public static void recursiveDelete(File file) {
    //to end the recursive loop  if (!file.exists())
       return;
    //if directory, go inside and call recursively  if (file.isDirectory()) {
       for (File f : file.listFiles()) {
    //call recursively   recursiveDelete(f);   }
      }
    //call delete to delete files and empty directory  file.delete();  System.out.println("Deleted file/folder: " +file.getAbsolutePath()); }

    static class FileDuplicate{
      HashCode hashCode;  Collection<Path> paths;
      FileDuplicate(HashCode hashCode, Collection<Path>paths){
       this.hashCode = hashCode;   this.paths = paths;  }
      @Override  public String toString(){
       return this.hashCode + "\n" + "\t" + this.paths +"\n";  }
    }

    @Data static class FileRecord{
      HashCode hashCode;  Path path;
      private final static HashFunction HASH_FUNCTION =
       Hashing.goodFastHash(32);
      FileRecord(File file){
       this.hashCode = hashFile(file);   this.path = file.toPath();  }

      private HashCode hashFile (File file){

      try {
       HashCode hash = Files.asByteSource(file).hash(HASH_FUNCTION);   System.out.println("FILE " +file + " HASHED USING " + HASH_FUNCTION );   return hash;
      }catch (IOException e){
       throw new RuntimeException(e);  } 
     }

    }
    }

Misal saya ingin memeriksa serta menghapus file yang duplicate dalam folder : /User/tamy/Documents/Belajar/Folder/
Dalam method calculateDuplicaties, file-file yang ada dalam folder akan dikumpulkan dalam collection, kemudian file tersebut akan di hash. File yang hasil hash nya sama dan jumlah nya lebih dari satu, itu lah file yang sama dan duplicate. Dan file yang duplicate tersebut akan di tampung dalam satu variable. 
Kemudian file yang duplicate tersebut akan di hapus pada method recursiveDelete .


Sekian dari saya tentang Eliminate file duplicate using guava in spring boot

Saturday, June 30, 2018

Rest API using Play Framework in Java

Halooo . . .
Kali ini saya membuat tulisan mengenai Rest API menggunakan Play Framework khususnya java pada play framework

Sebelumnya, apa itu play framework?
Play Framework adalah framework open souce aplikasi web yang ditulis dengan Scala dan juga pemrograman lainnya seperti Java.
Biasanya pemrograman yang menggunakan java membutuhkan waktu untuk proses build dan deploy. Nah, dengan menggunakan framework ini, hasil coding tersebut hanya cukup kita save dan refresh browser atau postman untuk melihat hasil coding yang kita kerjakan.
Terkadang ada juga pemrograman yang menggunakan java harus restart server terlebih dahulu, padahal yang di edit hanya sedikit line code.

Typesafe Activator merupakan platform yang bisa digunakan untuk membuat dan menjalankan project play framework. Untuk download typesafe activator dapat di download pada link berikut: http://typesafe.com/activator
atau jika anda menggunakan mac, cukup gunakan perintah berikut pada terminal anda :
brew install typesafe-activator

Tanpa basa-basi kita create new project dulu ya . .
  1.  Create new Project

    Pertama buka terminal terlebih dahulu, dan pergi ke direktori dimana kita akan create project baru kita
    Gambar 1

    Kemudian ketik perintah : activator new 

    Gambar 2
    Maka akan muncul beberapa pilihan seperti gambar di atas (Gambar 2). dan kita akan memilih nomor 5

    Gambar 3
    Pada gambar diatas (Gambar 3) project sudah berhasil di create dengan nama project (play-java) 

    Untuk menjalankannya : activator run
    Gambar 4
    untuk testing di postman atau di browser : //localhost:9000

    Gambar 5 Tampilan awal Play Framework
  2.  Konfigurasi database
    Tambahkan code-code berikut pada file:

    Pada file build.sbt :



  3. Pada file plugins.sbt : 

            

     Pada file application.conf :
  4. Models
    Selanjutnya kita akan membuat model
    package models;
    import com.avaje.ebean.Model;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "anggota")
    public class Anggota extends Model {
        @Id    
        private Integer id_anggota;
        private String nama_anggota;
        private String alamat_anggota;
    
        public Integer getId_anggota() {
            return id_anggota;    }
        public void setId_anggota(Integer id_anggota) {
            this.id_anggota = id_anggota;    }
    
        public String getNama_anggota() {
            return nama_anggota;    }
    
        public void setNama_anggota(String nama_anggota) {
            this.nama_anggota = nama_anggota;    }
    
        public String getAlamat_anggota() {
            return alamat_anggota;    }
    
        public void setAlamat_anggota(String alamat_anggota) {
            this.alamat_anggota = alamat_anggota;    }
    }
    
  5. Controller
    Dan ini untuk controller
    package controllers;
    import repository.AnggotaRepository;
    import com.fasterxml.jackson.databind.JsonNode;
    import models.Anggota;
    import org.springframework.beans.factory.annotation.Autowired;
    import play.libs.Json;
    import play.mvc.Controller;
    import play.mvc.Result;
    
    import java.util.List;
    public class AnggotaController extends Controller {
    
        @Autowired    AnggotaRepository anggotaRepository;
        public Result viewAnggota(String nama){
            List<Anggota> anggotas = anggotaRepository.cocoTasks(nama);
    
    return ok(Json.toJson(anggotas));
    } public Result listAnggota(){ List<Anggota> anggotas = anggotaRepository.cocoList();
    return ok(Json.toJson(anggotas));
    } public Result createAnggota() { JsonNode json = request().body().asJson();
    Anggota anggota = new Anggota();   
    anggota = (Anggota)Json.fromJson(json,Anggota.class);  
    anggota.save();
    return ok(Json.toJson(anggota));
    } public Result updateAnggota(){
    JsonNode json = request().body().asJson();
    Anggota anggota = new Anggota(); anggota = (Anggota)Json.fromJson(json, Anggota.class); anggota.update(); return ok(Json.toJson(anggota));
    } public Result delete(Integer id_anggota){ Anggota anggota = anggotaRepository.findById(id_anggota); if(anggota==null){   return notFound(Json.toJson("Anggota not Found"));  } anggota.delete(); return ok(Json.toJson("Anggota "+id_anggota+"has been deleted")); } }
  6. Repository
    Dalam project sederhana ini, saya buat file repository. Dimana dalam file ini berisi query-query data yang saya gunakan
    package repository;
    import com.avaje.ebean.Model;import models.Anggota;
    import java.util.List;
    public class AnggotaRepository {
    
        public static Model.Finder<Integer, Anggota> find = 
            new Model.Finder<Integer, Anggota>(Integer.class, Anggota.class);
    
        public static   List<Anggota> cocoTasks(String nama){
            return  find                .query().where()
                    .ilike("nama_anggota","%"+nama+"%")
                    .orderBy("id_anggota").findList();
        }
        public static List<Anggota> cocoList(){
            return  find.orderBy("id_anggota").findList();
        }
    
        public static Anggota findById(Integer id_anggota){
            return find.byId(id_anggota);    }
    }
    
    
    
    
  7. Mapping
    Action-action yang sudah kita code dalam controller dapat kita mapping. Untuk mapping dapat di kita lakukan pada file play-java/conf/routes
    # Routes
    # This file defines all application routes (Higher priority routes first)
    # ~~~~
    
    # An example controller showing a sample home page
    GET     /                           controllers.HomeController.index
    
    GET  /anggota/nama_anggota=:nama_anggota  controllers.AnggotaController.viewAnggota(nama_anggota:String)
    GET   /list-anggota                       controllers.AnggotaController.listAnggota()
    POST  /create-anggota                     controllers.AnggotaController.createAnggota()
    POST  /update-anggota                     controllers.AnggotaController.updateAnggota()
    DELETE  /delete-anggota/:id_anggota       controllers.AnggotaController.delete(id_anggota:Integer)
    
    # An example controller showing how to use dependency injection
    GET     /count                      controllers.CountController.count
    # An example controller showing how to write asynchronous code
    GET     /message                    controllers.AsyncController.message
    
    # Map static resources from the /public folder to the /assets URL path
    GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)
  8. Demo
    - Action Create
    Gambar 6. Action Create

    - Action View
    Gambar 7. List Anggota

    Gambar 8. search by nama anggota

    - Action Update
    Gambar 9. Action Update

    - Action Delete
    Gambar 10. Action Delete


    Begitu lah sharing singkat mengenai Rest API using Play Framework
    Sekian dari saya dan semoga tulisan ini bermanfaat.
    Terima kasih,

    Salam

    Reference :
    https://www.playframework.com/documentation/
    http://www.baeldung.com/rest-api-with-play
    https://www.youtube.com/watch?v=qKxgtmuPjHQ

Spring Boot Application integrate with JBoss Drools

Halo sobat Nostra,
Postingan kali ini saya akan membahas tentang membuat aplikasi spring boot yang terintegrasi dengan JBoss Drools.

Drools merupakan Business Logic integration Platform (BLip) dimana cara kerja drools itu sendiri adalah memisahkan data dan logic
Didalam drools, session berfungsi untuk menyimpan semua fakta atau object. Kemudian fakta tersebut akan dicocokan terhadap semua rules yang ada


Gambar 1. Proses pembuatan knowledge session dalam drools
1. Proses pertama diawali dengan pembuatan object KnowledgeBuilder oleh KnowledgeBuilderFactory.
2. File yang berisikan rules (.drl) dibaca oleh KnowledgeBuilder.
3. Object KnowledgeBase membaca KnowledgePackage dari KnowledgeBuilder.
4. KnowledgeBase dapat digunakan untuk mebuat knowledge session.

Sekarang kita mulai ya . .
Untuk memulai project Spring boot, kita dapat clone project dari :
git clone https://github.com/spring-guides/gs-rest-service.git

Dalam file pom.xml tambahkan :
<dependency>   
 <groupId>org.kie</groupId>   
 <artifactId>kie-ci</artifactId>   
 <version></version>
</dependency>
- Create model class Java (Product.java)
package com.drools.model;
public class Product {

   private String type;   
   private int discount;
   public String getType() {
      return type;   }

   public void setType(String type) {
      this.type = type;   }

   public int getDiscount() {
      return discount;   }

   public void setDiscount(int discount) {
      this.discount = discount;   }

}
- Create .drl file (rules.drl). File ini berisi type dari product. Pada project ini, file .drl ini saya letakkan di src/main/resources/rules
package rules
 
import com.drools.model.Product
rule "Offer for Keripik"
   when 
      productObject: Product(type=="keripik")
   then
      productObject.setDiscount(20);
   end
rule "Offer for Roti"
   when 
      productObject: Product(type=="roti")
   then
      productObject.setDiscount(17);
   end
Project Drools 6.0 terdiri dari file meta data META-INF/kmodule.xml. File ini terletak di src/main/resources/META-INF . dengan file ini knowledge session akan terbentuk. 
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <kbase name="rules" packages="rules">
       <ksession name="rulesSession" />
    </kbase>
</kmodule>
Kemudian create file controller (CemilanController)
package com.drools.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.drools.model.Product;
import com.drools.service.CemilanService;

@RestController
public class CemilanController {

   private final CemilanService cemilanService;

   @Autowired
   public CemilanController(CemilanService cemilanService) {
      this.cemilanService = cemilanService;
   }

   @RequestMapping(value = "/getDiscount", method = RequestMethod.GET, 
                   produces = "application/json")
   public Product getQuestions(@RequestParam(required = true) String type) {

      Product product = new Product();
      product.setType(type);
      cemilanService.getProductDiscount(product);
      return product;   }

}
Kemudian create CemilanService untuk mendapatkan session dan execute rules
package com.drools.service;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.drools.model.Product;

@Service
public class CemilanService {

   private final KieContainer kieContainer;
   @Autowired   
   public CemilanService(KieContainer kieContainer) {
      this.kieContainer = kieContainer;   
   }

   public Product getProductDiscount(Product product) {
      KieSession kieSession = kieContainer.newKieSession("rulesSession");
      kieSession.insert(product);
      kieSession.fireAllRules();
      kieSession.dispose();
      return product;
   }
}
Dalam service di atas, kita membuat KieSession dengan menginstance KieContainer.
KieSession itu sendiri merupakan tempat dimana data yang di input di masukkan. Dimana KieSession berinteraksi dengan mesin untuk memproses logika bisnis berdasarkan data yang dimasukkan. Dalam code diatas, kita membuat variable kieSession "rulesSession" untuk menyimpan perhitungan produk.
Untuk memasukkan data product ke dalam session, maka perintahnya adalah kieSession.insert(product), kemudian kieSession akan meminta mesin untuk menjalankan logika bisnis dengan perintah fireAllRules(). Untuk menghindari memory penuh, maka perlu membersihkan session dengan dispose(). 


Dalam file Application.java, kita langsung memanggil service yang sudah kita code diatas dengan KieServices.Factory.get()
tambahkan code berikut:
@Beanpublic KieContainer kieContainer() {
   return KieServices.Factory.get().getKieClasspathContainer();
}

Testing
Untuk melihat hasilnya, dapat di akses dengan dan hasil
http://localhost:8080/getDiscount?type=roti
dan hasilnya akan menunjukan nilai diskon dari type yang kita input dalam url

dan sekian postingan saya kali ini, semoga postingan ini bermanfaat
Terima kasih

Salam,