09 Aug 2012
Sejak pertama saya membuat blog, aplikasi yang saya gunakan adalah Wordpress. Aplikasi Wordpress sangat mudah digunakan dan banyak fiturnya. Selain itu, themes gratisan di internet juga berlimpah ruah, sehingga kita bisa ganti tampilan setiap hari kalau mau.
Walaupun demikian, zaman berganti, dan cara kita bekerja juga berubah. Saya saat ini lebih banyak berkutat di pemrograman dengan workflow sebagai berikut :
- Buka text editor
- Edit source code
- Jalankan di local dan test
- Kalau sudah ok, simpan di version control (commit)
- Ulangi ke langkah 2 sampai selesai
- Begitu sudah siap untuk sharing hasil pekerjaan, upload (push) perubahan ke version control pusat.
Workflow ini sayangnya tidak dapat dilakukan untuk menulis blog. Workflow saya dalam menulis blog biasanya seperti ini:
- Buka text editor
- Ketik dalam format text file biasa, dengan menggunakan HTML tag bila perlu
- Simpan di folder Dropbox selama masih draft
- Setelah siap dipublish, buka Wordpress di browser
- Login ke Wordpress
- Create New Post
- Copy - Paste dari text editor
- Preview dan rapikan lagi
- Publish
Seperti bisa kita lihat, dengan workflow di atas, praktis fitur-fitur Wordpress yang serba canggih tidak termanfaatkan. Oleh karena itu, sudah tiba saatnya untuk mencari aplikasi blogging yang lebih sedikit fiturnya. Biasanya orang mengganti aplikasi dengan yang lebih banyak fiturnya, tapi kali ini saya melakukan hal yang sebaliknya.
Lanjut membaca ...
26 Aug 2011
Seberapa penting file di komputer kita? Tentu tidak ternilai harganya. Tapi apakah kita melakukan backup secara terhadap file-file di komputer kita? Beberapa menit yang lalu, saya menjawab tidak untuk pertanyaan tersebut.
Kenapa backup tidak dilakukan? Penyebab utamanya biasanya adalah karena merepotkan. Kita harus pilih file yang mau dibackup, membuka aplikasi backup, lalu menjalankannya. Walaupun cuma butuh waktu beberapa menit, tapi biasanya kita sering menunda dan akhirnya lupa.
Cara paling efektif untuk melakukan backup rutin adalah dengan mengotomasinya. Effort untuk melakukan setup cukup sekali saja, selanjutnya backup akan berjalan otomatis tanpa kita sadari. Pada artikel ini, saya akan posting teknik backup yang saya gunakan.
Sebelum kita mulai, terlebih dulu kita tentukan requirementnya, supaya jelas apa yang kita ingin capai. Saya ingin membackup folder tertentu di komputer saya (misalnya /home/endy dan /opt/multimedia/Photos). Backup ini dilakukan secara rutin (misalnya satu jam sekali, satu hari sekali, atau satu minggu sekali). Selain rutin, juga harus incremental. Artinya kalau saya punya backup hari ini jam 11, maka backup selanjutnya di jam 12 hanya menyimpan file yang berubah saja. Dengan demikian, saya bisa jalankan backupnya satu jam sekali dan tidak akan menyebabkan harddisk menjadi penuh dalam beberapa jam saja.
Lanjut membaca ...
16 Aug 2011
Staged Deployment
Pada waktu kita coding, tentunya kita melakukan test terhadap kode program yang kita tulis. Kita jalankan langkah-langkah sesuai yang telah didefinisikan dalam test scenario. Setelah test di komputer kita sendiri (local) selesai dilakukan, tentunya kode program tersebut tidak langsung kita deploy ke production. Best practicesnya adalah, kita deploy aplikasinya ke server testing untuk kemudian ditest oleh Software Tester. Barulah setelah dinyatakan OK oleh tester, aplikasi versi terbaru tersebut kita deploy ke production.
Dengan demikian, kita memiliki tiga deployment environment, yaitu :
Environment ini bisa lebih banyak lagi kalau aplikasi kita harus dites kompatibilitasnya dengan berbagai hardware atau sistem operasi.
Cara kerja seperti ini disebut dengan istilah staged deployment atau deployment bertahap. Dengan menggunakan staged deployment, kita mencegah terjadinya bug fatal di production/live system.
Tantangan yang kita hadapi adalah, bagaimana cara mengelola konfigurasi aplikasi kita sehingga bisa dideploy di berbagai environment secara baik. Teknik bagaimana cara melakukan ini berbeda-beda, tergantung bahasa pemrograman, framework, dan library yang kita gunakan.
Pada artikel ini, kita akan membahas cara mengelola konfigurasi deployment menggunakan teknologi yang biasa digunakan di ArtiVisi, yaituSpring Framework dan Logback.
Alternatif Solusi
Manajemen konfigurasi ini bisa kita lakukan dengan dua pendekatan, yaitu dikelola dengan Maven Profile, atau dengan konfigurasi Spring Framework.
Jika kita menggunakan Maven Profile, kita menambahkan opsi pada saat melakukan build, kira-kira seperti ini :
mvn -P production clean install
atau
mvn -Denv=production clean install
Dalam konfigurasi profile, kita bisa memilih file mana yang akan diinclude di dalam hasil build. Hasilnya, kita bisa menghasilkan artifact yang berbeda tergantung dari opsi yang kita berikan pada saat build.
Walaupun demikian, berdasarkan hasil Googling, ternyata metode ini tidak direkomendasikan. Justru konfigurasi melalui Spring lebih disarankan.
Dengan menggunakan konfigurasi Spring, artifact yang dihasilkan oleh build hanya satu jenis saja. Artifact ini berisi semua pilihan konfigurasi. Konfigurasi mana yang akan aktif pada saat dijalankan (runtime) akan ditentukan oleh setting environment variable, bukan oleh artifactnya.
Selanjutnya, kita akan membahas metode manajemen konfigurasi menggunakan Spring.
Konfigurasi Database
Konfigurasi yang biasanya berbeda adalah informasi koneksi database. Untuk membedakan masing-masing environment, kita akan membuat tiga file, yaitu:
-
jdbc.properties : digunakan di laptop programmer
-
jdbc.testing.properties : digunakan di server test
-
jdbc.production.properties : digunakan di live
Berikut contoh isi jdbc.properties, yaitu konfigurasi koneksi database di laptop saya :
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon?zeroDateTimeBehavior=convertToNull
jdbc.username = kasbon
jdbc.password = kasbon
Kemudian, ini file jdbc.testing.properties :
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon_testing?zeroDateTimeBehavior=convertToNull
jdbc.username = root
jdbc.password = admin
Perhatikan bahwa informasi nama database, username, dan password databasenya berbeda dengan yang ada di konfigurasi laptop.
Terakhir, jdbc.production.properties
hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost/kasbon_live?zeroDateTimeBehavior=convertToNull
jdbc.username = root
jdbc.password = admin
Ketiga file konfigurasi ini akan dibaca oleh konfigurasi Spring, yaitu di file applicationContext.xml. Isi lengkap dari file ini adalah sebagai berikut.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="
classpath*:jdbc.properties,
classpath*:jdbc.${stage}.properties
" />
<tx:annotation-driven />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driver}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" p:maxWait="40000"
p:maxActive="80" p:maxIdle="20" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocations="classpath*:com/artivisi/**/hibernate.cfg.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
</beans>
Untuk lebih spesifik, konfigurasinya ada di baris berikut
<context:property-placeholder location="
classpath*:jdbc.properties,
classpath*:jdbc.${stage}.properties
" />
Di sana kita melihat ada variabel ${stage}.
Variabel ${stage} ini akan dicari dari beberapa tempat, diantaranya environment variabel yang bisa diset di JVM ataupun di sistem operasi. Cara mengeset variabel ${stage} akan kita bahas sebentar lagi.
Di situ kita menyuruh Spring untuk membaca file jdbc.properties dan jdbc.${stage}.properties. Jika ada nilai variabel yang sama (misalnya jdbc.username), maka nilai variabel di file yang disebutkan belakangan akan menimpa nilai yang didefinisikan file di atasnya.
Contohnya, misalnya variabel ${stage} nilainya adalah testing. Maka Spring akan membaca file jdbc.properties dan jdbc.testing.properties. Karena kedua file memiliki variabel jdbc.url, maka isi jdbc.url di file jdbc.testing.properties akan menimpa nilai jdbc.url di jdbc.properties.
Bila variabel ${stage} tidak ada isinya, Spring akan mencari file yang namanya jdbc.${stage}.properties, dan tidak akan ketemu. Dengan demikian, nilai yang digunakan adalah yang ada di jdbc.properties.
Dengan demikian, behavior aplikasi adalah sebagai berikut
Bila variabel stage diset production atau testing, maka yang digunakan adalah nilai konfigurasi di jdbc.production.properties atau jdbc.testing.properties. Bila tidak diset atau diset selain itu, maka yang digunakan adalah konfigurasi di jdbc.properties
Behavior seperti inilah yang kita inginkan. Selanjutnya, tinggal kita isi nilai variabel stage.
Setting Environment Variabel
Variabel stage bisa diset dengan berbagai cara. Bila kita menggunakan Apache Tomcat, maka kita mengedit file startup.sh atau startup.bat. Modifikasi baris yang berisi CATALINA_OPTS menjadi seperti ini :
export CATALINA_OPTS="-Dstage=production"
Atau, kita bisa jalankan dengan Jetty melalui Maven
mvn jetty:run -Dstage=testing
Bisa juga melalui environment variabel sistem operasi, di Linux kita set seperti ini.
Konfigurasi Logger
Dengan menggunakan Spring seperti di atas, kita bisa membaca konfigurasi apa saja, misalnya
-
Konfigurasi email : bila aplikasi kita mengirim/menerima email
-
Konfigurasi server lain : bila aplikasi kita berinteraksi dengan aplikasi orang lain, misalnya webservice atau koneksi socket
-
dsb
Walaupun demikian, konfigurasi logger biasanya tidak diload oleh Spring, melainkan langsung dibaca oleh library loggernya.
Kita di ArtiVisi menggunakan SLF4J dan Logback. Cara konfigurasinya mirip dengan Spring. Kita punya satu master file yang akan membaca file lain sesuai isi variabel stage. Untuk itu kita siapkan beberapa file berikut:
-
logback.xml : file konfigurasi utama
-
logback.production.xml : konfigurasi logger production, akan diinclude oleh logback.xml
-
logback.testing.xml : konfigurasi logger testing, akan diinclude oleh logback.xml
-
logback.development.xml : konfigurasi logger development, akan diinclude oleh logback.xml
Berikut isi file logback.xml.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${catalina.home:-.}/logs/kasbon-${stage:-development}.log</file>
<encoder>
<pattern>%d %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<include resource="logback-${stage:-development}.xml"/>
</configuration>
Seperti kita lihat, file ini berisi konfigurasi yang berlaku umum, seperti appender yang digunakan. Di file ini kita menulis variabel seperti ini
Yang artinya adalah, isi dengan variabel stage, kalau variabel tersebut tidak diset, defaultnya adalah development. Ini sesuai dengan keinginan kita seperti pada waktu mengkonfigurasi Spring di atas.
Isi file logback-development.xml dan teman-temannya dapat dilihat di Github.
Demikianlah tutorial cara mengelola konfigurasi untuk keperluan staged deployment. Semoga bermanfaat.