Friday, December 14, 2012

KM: เรื่องมันมีอยู่ว่า - ต้องส่ง email ให้ตรงเวลาเป๊ะ

เรื่องมันมีอยู่ว่า

เมื่อวาน ผบ ไป dinner กับเพื่อนสาว พูดคุยกันถึงกระเป๋ายี่ห้อนึง กำลังเป็นที่ต้องการของสาวๆ ถึงขนาดซื้อขายกันกำไร 100% O_o สาเหตุก็มาจาก คนขายมันเก่งการตลาด จำกัดจำนวนสินค้าที่จะขาย และที่สำคัญต้องส่ง email สั่งซื้อตามเวลาที่คนขายกำหนด!!! (โอ้แม่เจ้า มันจะอะไรขนาดนั้น) เป็นที่โจษจันว่าการที่จะจองได้สำเร็จ ต้องเล็งเวลาส่งเป๊ะๆ ถึงขั้น millisecond กันทีเดียว

เอาละกลับเข้าเรื่อง จะทำไงกับโจทย์ที่ได้รับมา

  • ถึกโหมด นั่งอดตาหลับขับตานอนส่ง mail ตามเวลานั้น แต่ขืนทำแบบนั้น เสียชื่อ programmer หมด ต้องหาทางที่มันเท่กว่านี้
  • googling ซิ ใน internet คงมี solution ที่คนอื่นเค้าทำกัน (อิโถ่ programmer  เค้าทำงานกันแบบนี้ใช่มั๊ย) นั่นไงเจอละ มี web รับส่ง email ล่วงหน้าได้ 555 เสร็จตรู....แต่เด๋วก่อน แล้วมันปลอดภัยเหรอ จะส่ง email ได้มันต้อง authen กับ mail server นั่นหมายความว่าเราต้องให้ email account กับ password ไปด้วย ไม่ได้ๆ เป็น programmer ทั้งทีมาตกม้าตายโดนขโมย email แบบนี้ เสียชื่อ programmer หมด ต้องหาทางที่มันเท่กว่านี้
  • เขียนโปรแกรมส่ง email แม่งเล๊ย!!! ผูกกับ scheduler ซักตัว ให้ส่งตรงเวลา...เหมือนจะเท่ แต่ในฐานะที่เป็น senior programmer แล้ว ทำไมเราต้อง reinvent the wheel ด้วย มันต้องมีเครื่องมือที่จะช่วยเราได้ซิ เอะอะก็เขียนโปรแกรม เสียชื่อ senior programmer หมด ต้องหาทางที่มันเท่กว่านี้
  • นี่ไง Automator ช่วยเราได้ ไม่ต้องเขียนโปรแกรม แค่ลากแปะ ใส่ข้อมูล โอ้วววว มันช่างเลิศหรูสมกับเป็น senior programmer จริงๆ (ป่าวหรอก ขี้เกียจหาละ 555)

ลงมือปฏิบัติกัน

ใช้งานบน MacOS รุ่นเสือภูเขา

1. เปิดโปรแกรม Automator 




2. เริ่มต้นโปรแกรมจะให้เลือกว่าต้องการ trigger แบบไหน ให้เลือก Calendar Alarm

 

3. โปรแกรมสามารถค้นหา Action ที่ต้องการใช้งานจาก Library ในที่นี้ต้องการเขียน email เพื่อส่งก็เลือก New Mail Message แล้วลากไปวางที่ panel ขวามือ


4. กรอกข้อมูลใน New Mail Message และเลือก Account ว่าต้องการให้ส่งจาก mail account ไหน (แนะนำว่าควรจะเป็น mail server เดียวกันเพื่อลด delay ระหว่าง mail server)


5. เลือก Action Send Outgoing Messages โดยลากไปวางให้อยู่ถัดจาก New Mail Message


6. หลังจากที่กด Save โปรแกรมจะเรียก Calendar ให้มาตั้งว่าจะให้ Task ทำงานตอนไหน


7. กดไปที่ Task เพื่อแก้ไขวันเวลาที่ต้องการ


8. Tips: ด้วยข้อจำกัดที่การตั้งเวลาทำได้ในระดับนาที และพบว่าเวลาที่ส่ง email จาก Automotor มันจะ delay ประมาณนึง ดังนั้นหากต้องการให้ส่งเวลาที่ต้องการพอดีเป๊ะก็ต้องตั้งให้ task ให้ทำงานเร็วขึ้นแล้ว pause ไว้ให้สอดคล้องกับเวลาที่ delay ก็จะทำให้ส่งได้แม่นยำขึ้น



ผลการทดสอบ

พบว่าสามารถส่ง email ได้ในเวลาที่ต้องการเป๊ะ (ถึงระดับ second) แต่ด้วยข้อจำกัดอื่นๆ อาจทำให้เวลาที่ส่งเปลี่ยนแปลงได้ ที่เหลือก็ขึ้นกับดวงว่าจะสามารถจองกระเป๋าได้หรือไม่ ^^





Sunday, November 11, 2012

KM: WebLogic - การใช้งาน jconsole เพื่อ connect ไปยัง WebLogic JVM

การใช้งาน jconsole เพื่อ connect ไปยัง WebLogic JVM


Problem

jconsole สามารถใช้เป็นเครื่องมือในการ monitor jvm behavior ได้ในระดับหนึ่ง โดยแนวทางที่จะเสนอนี้เป็นการแก้ปัญหาการใช้ jconsole เพื่อไป monitor jmx component บน remote WebLogic Server (version 10.3.x) ซึ่งถึงแม้จะระบุ parameter เพื่อเปิด jconsole ขึ้นมา ก็ยังได้ error no permission

## Command to start jconsole for WebLogic Server
prompt>jconsole -J-Djava.class.path=%JAVA_HOME%/lib/jconsole.jar;%JAVA_HOME%/lib/tools.jar;C:/bea_103/wlserver_10.3/server/lib/wljmxclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug

## Error message
Caused by: javax.naming.NamingException: Unhandled exception in lookup [Root exception is org.omg.CORBA.NO_PERMISSION:   vmcid: 0x0  minor code: 0  completed: No] at weblogic.corba.j2ee.naming.Utils.wrapNamingException(Utils.java:83) at weblogic.corba.j2ee.naming.ContextImpl.lookup(ContextImpl.java:232) at weblogic.corba.j2ee.naming.ContextImpl.lookup(ContextImpl.java:168) at javax.naming.InitialContext.lookup(InitialContext.java:392) at weblogic.management.remote.common.ClientProviderBase.makeConnection(ClientProviderBase.java:144) ... 6 more

จากที่ลองหาข้อมูล พบว่าเป็นเรื่องของการ mapping credential info ตอนที่ jconsole จะไป browse jndi tree เพื่อเข้าถึง jmx

Assumption

ปัญหาเกิดจากการใช้งาน WebLogic Server 10.3.0

Troubleshooting

  1. download ตาม link t3jconsole.jar
  2. สร้าง WebLogic full client jar ตาม command ด้านล่างก็จะได้ file ที่ชื่อว่า wlfullclient.jar
  3. เปิดใช้งาน jmx agent โดยสามารถ download file ที่เกี่ยวข้อง ตาม link jmx.zip -Dcom.sun.management.config.file=%SOME_PATH%/jmx/management.properties
  4. เปิด jconsole ด้วย command ตามด้านล่าง
    prompt>jconsole -J-Djava.class.path=C:/bea_103/wlserver_10.3/server/lib/t3jconsole.jar;%JAVA_HOME%/lib/jconsole.jar;%JAVA_HOME%/lib/tools.jar;C:/bea_103/wlserver_10.3/server/lib/wlfullclient.jar -J-Djmx.remote.protocol.provider.pkgs=fr.xebia.jmx.remote  -debug
  5. ใส่ input parameter เพื่อต่อไปยัง remote WebLogic
    Remote url=service:jmx:t3://[host]:[port]/jndi/weblogic.management.mbeanservers.runtime Username=usernamePassword=password
  6. ใส่ข้อมูล remote JVM
    ตัวอย่างหน้าการใช้งาน (ไม่ได้เปิดจาก remote JVM แต่เหมือนกัน)


Thursday, November 8, 2012

KM: JEE Series - การใช้งาน JPA caching

JPA Caching โดยใช้ Native Query

Problem

เนื่องจากต้องการทำ entity caching เพื่อ join ข้อมูลจาก 2 table โดยมีการจัด priority ของข้อมูลคือให้เอาจาก table แรกเป็นหลัก ถ้าไม่เจอให้ไปดึงข้อมูลจาก table สอง 

Assumption

พัฒนาโดยใช้
  • JPA 1.0
  • Hibernate 3
  • WebLogic Workshop 10.3

Troubleshooting

  1. เริ่มต้นด้วยการสร้าง Named Query จากเงื่อนไขของปัญหาข้างต้น จึงใช้ Native Query เพื่อ join 2 table เข้าด้วยกัน และเลือกข้อมูลจาก priority ของ table เป็นค่าส่งกลับไปใช้งาน โดยทำการระบุ hint ว่าจะทำ caching บน entity นี้


  2. สร้าง file ehcache.xml และวางตามตัวอย่าง


  3. config ค่า parameter สำหรับการทำ caching ในที่นี้ตั้ง TTL ไว้ที่ 60 วินาที


  4. แก้ไข persistence.xml เพื่อเปิดการใช้งาน caching โดยในที่นี้ใช้ ehcache library


  5. เพิ่ม backport-util-concurrent-3.0.jar และ ehcache-1.5.0.jar ใน server class path


  6. เรียกใช้งาน Named Query ที่สร้างไว้

Conclusion

จากการทดสอบ ได้ผลลัพธ์ออกมาถูกต้อง โดยดูจาก sql statement ที่แสดงออกใน console จะไม่พบ statement ที่ทำการ caching ไว้ แต่ใน JPA น่าจะมีวิธีทำที่ถูกต้องกว่านี้