31/10/2561
https://aircondition-soap.herokuapp.com/service/wsdl
https://bitbucket.org/sarik_kumpan/aircondition-soap/src/master/
เตรียมอุปกรณ์ดังนี้
- Git
- Bitbucked
- Github
- Virtual Studio Code
- Ruby
- gem wash_out
- Ruby on Rails
- Heroku Repository, Heroku CLI, Heroku Postgresql
- SOAP_UI
และเตรียมตัวมาก่อนดังนี้
- เตรียม Heroku Respository ที่เชื่อมต่อกับ ฐานข้อมูล Postgresql แล้ว และ ทำการ Clone project ลง Notebook , init git, push repository ขึ้น bitbucked ลง Gem ที่จำเป็นต้องใช้
- เตรียม Soap ui ให้ใช้งานได้
- เตรียม อัพเดท version ruby , ruby on rails ให้ตรงกับของ Heroku รองรับ
* git ของ heroku และ bitbucket ต้องอัพแยกกัน
** ตอนทดสอบ ไม่ได้ทำฐานข้อมูลในเครื่องไว้ ดังนั้นเวลาจะทดสอบต้อง push ขึ้น Heroku ก่อน
ซึ่งจะต้องแก้ไขภายหลัง เพราะมันจะทำให้มี การ commit เยอะ
Commit แรก
https://bitbucket.org/sarik_kumpan/aircondition-soap/commits/4681da82211a1a7daecc592a531e5d089818d4bfข้อที่ 0 : ข้อมูล แอร์
งานชิ้นแรกเป็น service สำหรับ เก็บข้อมูล แอร์ และ นำข้อมูล แอร์ทั้งหมดมานำเสนอ
โดย ข้อมูล ที่ได้ จัดการทำ นั้น จะมีโครงสร้าง ที่ประกอบด้วยข้อมูลดังต่อไปนี้
- ข้อมูลหมายเลข แอร์
- ข้อมูล อุณหภูมิ
- ข้อมูล ความชื้น
- เวลาที่ เครื่องส่งออกมา
- [ เวลาที่ database บันทึก เอง ]
ซึ่งจาก Commit แรก นั้น มีการสร้าง ฐานข้อมูลเอาไว้อยู่แล้ว โดยใช้คำสั่งของ
Rails เช่น rails g migrate , rails g models "name of model or table"
ซึ่ง คำสั่งพวกนี้จะทำการสร้างไฟล์ที่จำเป็นในการใช้งาน ฐานข้อมูล ของ Rails Framwork
ซึ่ง ถ้าหากใช้คำสั่ง Rails g models "name" จะดีที่สุด เพราะ จะมีการสร้างไฟล์
Migrate ที่ใช้ในการสร้าง ฐานข้อมูล ครั้งแรก และการเปลี่ยนแปลงต่างๆ
และ ไฟล์ Model ที่ ทำการ ตั้งค่า การเข้าถึงข้อมูลในฐานข้อมูลนั้นๆ และสามารถ กำหนด
ฟังก์ชั่น ต่างๆ จำเพาะ แต่ละ Table ได้ และ ยังสร้าง ไฟล์สำหรับทดสอบ ซึ่ง ตอนนี้เราจะยังไม่ใช้งาน
ในส่วนนี้
ซึ่งจาก Commit แรก นั้นเราได้ทำการดัดแปลง ข้อมูล ในตาราง ฐานข้อมูล เพิ่ม
https://bitbucket.org/sarik_kumpan/aircondition-soap/commits/4a686e5781ba665811a9918f231eb78c55e1e182
ซึ่ง จะมีส่วนโค้ดดังนี้ในไฟล์ Migrate
เพิ่มในส่วน ข้างล่าง ฟังก์ชั่น change ซึ่ง ตอนแรกเขา ทำมาให้อยู่แล้ว และ กำหนด ค่าใน columns
ฐานข้อมูล ให้มีคุณสมบัติ ดังภาพ โดย t.timestamps จะเป็นการเพิ่มเวลา จากฐานข้อมูลเอง
โดย หลังจากที่ เรา แก้ในในส่วนนี้ แล้ว เราจำเป็นต้องทำการสร้างฐานข้อมูล สำหรับ ครั้งแรกที่ใช้งาน
การเปลี่ยนแปลง นี้ โดยใช้คำสั่ง
- rake db:migrate
- heroku run rake db:migrate
โดย ขึ้นกับว่าจะ ทำการสร้างฐานข้อมูลที่ไหน ซึ่งเราใช้งานบน Heroku ดังนั้น จึงใช้คำสั่งที่ 2
heroku run rake db:migrate
จากนั้น ระบบ จะทำการ สั่งให้ทาง heroku สร้างฐานข้อมูล table ตามที่เราตั้งค่าเอาไว้ ให้กับ HerokuPosrgresql
ซึ่ง จะมีการแก้ ฟังก์ชั่น ตาม commit เพื่อแก้บัคต่างๆเล็กน้อย ซึ่ง สุดท้ายแล้วจะได้ ฟังก์ชั่นสำหรับ ใช้งาน ดังนี้
ในส่วนของการ ส่งค่าเพื่อ บันทึกเข้าฐานข้อมูล service
ซึ่ง ในส่วนที่ กำหนด input สำหรับ soap service นี้ นั้นจะอยู่ในส่วน
:args => { :no => :string , :temperature => :string, :humid => :string, :date_t => :string },
โดยต้องการ จะรับ ค่าต่างๆ เช่นเลขแอร์ อุณหภูมิ ความชื้น และ เวลาต่างๆ
และ จะ คืนค่า การอัพเดทข้อมูล ดังนี้
:return => :string
ซึ่งจะคืนค่าเป็น XMLที่มีคุณสมบัติเป็น String
จากนั้นข้างใน ฟังก์ชั่น นั้น จะมีการกำหนดเงื่อนไขเช็คว่า เพิ่มข้อมูลได้มั้ยใน if else
ซึ่งเนื้องจากใช้ฟังก์ชั่นดังนี้
if(Aircondition.create!( :no => params[:no],:temperature => params[:temperature],:humid => params[:humid],:date_t => params[:date_t]))
xxx.create! ซึ่ง คำสั่ง Aircondition เป็น model ที่เชื่อมกับ ฐานข้อมูลอยู่ ส่วน .create! นั้น จะคืนค่ากลับมาว่าเพิ่มสำเร็จหรือไม่
ต่อมาในส่วนของการ อ่านค่าทั้งหมดที่อยู่ในฐานข้อมูล ส่วนนี้ เป็นส่วนที่ ค่อนข้างจะเสียเวลาไปกับการ หาวิธีส่งค่าแบบหลายๆ
ส่วนข้อมูล มาก เพราะ soap_wash ไม่มีตัวอย่างมาให้
สุดท้ายแล้วจะได้ผลเป็นโค้ด ดังนี้
ต้องการ input จึงไม่จำเป็นต้องมี :args
:return => [{:aircondition_info => [ { :no => :integer, :temp => :float, :humid => :float, :date => :date } ] } ]
โดย จะคืนค่าเป็น xml ที่มีหลายๆส่วน แต่เวลาจะกำหนดในโค้ดนั้นจะใช้เป็นอาเรย์ของแฮช แทน
และในส่วนของเนื้อหาในฟังก์ชั่นจะมีดังนี้
def get_info @info = Aircondition.all array_info = [] @info.each do |info| hsh = {} hsh["no"] = info.no hsh["temp"] = info.temperature hsh["humid"] = info.humid hsh["date"] = info.date_t array_info.push(hsh) end render :soap => {:aircondition_info => array_info} end
จะมีส่วน ดึงข้อมูลทั้งหมดมาก่อน คือ
@info = Aircondition.all
ฐานข้อมูลจะไปดึงข้อมูลทั้งหมดในตาราง Aircondition มาให้ จากการคิวรี่ select * from Aircondition
จาก นั้น วนลูป ในแต่ละแถวของข้อมูลนั้นๆ จับเข้า แฮชฟังก์ชั่น และ ทำเป็นอาเรย์ เอาไว้
array_info = [] @info.each do |info| hsh = {} hsh["no"] = info.no hsh["temp"] = info.temperature hsh["humid"] = info.humid hsh["date"] = info.date_t array_info.push(hsh) end
และส่งค่ากลับไป
render :soap => {:aircondition_info => array_info}ซึ่งในส่วนของ wsdl ที่ทาง wash_out generate มาให้ ก็จะมีลักษณะ ประมาณนี้
คือมีการกำหนด schema คร่าวๆมาให้แล้ว เป็นต้น
ก็้เป็นอันเสร็จสิ้น เมื่อทดลอง ดังนี้
ใช้งานโดย Soap_UI
โดยจะเริ่มจากการส่งค่าให้เข้าไปในฐานข้อมูล
ได้รับข้อความว่า เพิ่มเสร็จแล้ว โดยเป็น soap xml จากนั้นเราจะทำการเช็คข้อมูล ว่า เพิ่มไปจริงมั้ย
โดยใช้ soap ui เช่นเดิม จากนั้น ผลลัพธ์จะได้ดังนี้
จะพบว่า ข้อมูลทั้งหมดถูกส่งกลับมาเป็น XML และ รวมข้อมูลใหม่ด้วย
ต่อมาจะลองใช้ Ruby ในการ ลองดึงข้อมูล ดูบ้าง
require 'savon'
require 'pp'
client = Savon::Client.new(wsdl: "https://aircondition-soap.herokuapp.com/service/wsdl")
result = client.call(:get_info)
pp result.to_hash
ได้ผลลัพธ์ดังนี้
หรือก็คือใช้งานได้เหมือนกัน แต่ ว่า library มันดันแปลง xml เป็นรูปแบบอื่นก่อนนำมาแสดงผลแทน
-------------------------------------------------------------------------------------------------------------------------
ข้อที่ 1 : ทำ service ตอบข้อมูลส่วนตัวแบบค่าตายตัว
soap_action "you_info",
:return => {:my_info => {
:name => :string,
:number => :integer,
:hobbie => { :firsts => :string,
:second => :string
}
}}
def you_info
@hobbie = {}
@hobbie["firsts"] = "anime"
@hobbie["second"] = "run"
@info = {}
@info[:name] = "sarik kumpan"
@info[:number] = 5801012610164
@info[:hobbie] = @hobbie
render :soap => { :my_info => @info}
end
ก็ได้ทำมาเป็น โค้ดส่วนนี้ โดยจะใช้งานในส่วนของ gem wash_out ช่วยในการทำให้เป็นการส่งแบบ
Soap ซึ่ง จะใช้งานโดยการแปลงจาก Hash function เป็น ข้อมูลที่เป็น XML ให้
โดยในส่วน
soap_action "you_info",:return => {:my_info => {:name => :string,:number => :integer,:hobbie => { :firsts => :string,:second => :string}}}
จะเป็นส่วนกำหนด ค่า Input , Output service ที่เราต้องการ โดย
Soap _action ตามด้วยชื่อ ฟังก์ชั่น ที่จะใช้งานการกำหนดค่าตัวนี้
ซึ่งการกำหนดค่าตัวนี้นั้นจะทำให้การเรียกใช้งาน Soap service ตัวนี้ Package
ที่ต้องการส่งจะมีลักษณะดังนี้
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:WashOut"><soapenv:Header/><soapenv:Body><urn:you_info soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></soapenv:Body></soapenv:Envelope>
และ ในส่วนของ Wsdl จะมีการกำหนดในส่วนของ Types มาให้แบบอัตโนมัติดังนี้
( ซึ่งในส่วนอื่นๆก็กำหนดมาให้เช่นกัน ) สามารถเข้าไปดูได้หลังการเปิดเซิฟเวอร์ที่
https://aircondition-soap.herokuapp.com/service/wsdl
ต่อมาในส่วนของ
def you_info@hobbie = {}@hobbie["firsts"] = "anime"@hobbie["second"] = "run"@info = {}@info[:name] = "sarik kumpan"@info[:number] = 5801012610164@info[:hobbie] = @hobbierender :soap => { :my_info => @info}end
นั้นคือฟังก์ชั่นที่ ใช้ในการตอบค่ากลับ โดย จะมีการกำหนด Hash แบบตายตัวเอาไว้
คือ มีการกำหนด Hash hobbie ที่จะมีการกำหนดค่า ต่างๆ ไว้ 2 ค่า่ และ มี Hash info
ที่เป็น Hash รวมที่คอยเก็บค่าต่างๆ เอาไว้ และส่งกลับในทีเดียว ซึ่งค่า Hash
ค่านี้จำเป็นต้องมีรูปแบบ ข้อมูลที่ตรงกับ การกำหนด Soap_action ก่อนหน้านี้ เท่านั้น
ซึ่ง ในตอนที่ได้ทำการทดสอบนั้น มักจะมีปัญหา ในเรื่องของการแปลง ข้อมูล ในตรงตาม hash
ที่กำหนด เอาไว้ เพราะ ยังไม่คุ้นชิน กับ การใช้ Gem wash_out มากนัก
จึงทำให้เกิดหลาย Commit
แต่สุดท้ายแล้ว จะได้ Commit ดังนี้
https://bitbucket.org/sarik_kumpan/aircondition-soap/commits/ba7e2987cc8804e63f571e2092a4077beb266f54
เพิ่มฟังก์ชั่น
ส่วน Commit ที่เหลือ จะเป็นการ แก้บัคที่พยายามจะแก้ใขให้ตรงรูปแบบที่ รองรับอีกจำนวนหนึ่ง
หลังจากนั้น จะได้ผลลัพธ์ ดังนี้
จาก Soap_ui
ในส่วนของ Python
ได้ผลลัพธ์ดังนี้import datetimefrom zeep import Clientclient = Client('https://aircondition-soap.herokuapp.com/service/wsdl')print(client.service.you_info())
และ จาก Ruby
require 'savon'require 'pp'client = Savon::Client.new(wsdl: "https://aircondition-soap.herokuapp.com/service/wsdl")
result = client.call(:you_info)pp result.to_hash
ได้ผลลัพธ์ดังนี้
ซึ่ง ได้ตามที่คาดหวัง แต่ ขาดแค่ การนำเสนอ ของ library ของ python , ruby ไม่นำเสนอ เป็น
XML object ให้ดูเท่านั้น
------------------------------------------------------------------------------------------------------------------
ข้อที่ 2 : ข้อมูล การให้บริการส่งสินค้า การแสดงว่าส่งหรือยัง เป็นรายการ กับการ เพิ่มรายการการส่ง
จากในกรณี นี้ เนื้องจากต้องการเก็บข้อมูลของการ บริการ การส่งสินค้า
ที่มีการ เก็บข้อมูล ดังนี้ เป็นหลัก
ยืนยันสินค้าได้ และ status ที่ระบุว่า ถึงไหนแล้ว หรือส่งหรือยัง แล้วก็เวลาการบันทึก รายการจาก ตัว
ฐานข้อมูล เอง ซึ่งในภาพ ด้านบน เป็นผลจากการ generate models และพร้อมจะไป migrate แล้ว
ซึ่งจะอยู่ใน Commit
https://bitbucket.org/sarik_kumpan/aircondition-soap/commits/d208b1999c6b275b4f911ce4a18bd331c9830294
หลังจากนั้น แก้บัค การพิมไม่ตรงเงื่อนไข ต่างๆ จนได้ ผลลัพธ์ของฟังก์ชั่น การส่ง รายะเอียดการ
สั่งสินค้า ดังนี้
ซึ่งก็จะใช้หลักการ เหมือนกับ ข้อที่ 1 ที่จะมีการเช็คว่า มีการสร้าง ตาราง ได้หรือไม่
แล้วจึงส่งผลลัพธ์ มา ซึ่ง จะทำการทดสอบ ด้วย Soap_ui เนื่องจากง่ายและสดวกสุด
ดังนี้
ตัวส่ง
และผลการตอบกลับ
จะเห็นได้ว่ามีการตอบกลับมาด้วย โค้ดของ การรับใช้บริการนั้นๆ ที่ได้ส่งไปใน การ
ร้องขอรับบริการ ซึ่ง ความเป็นจริง ต้องเป็น ฝั่ง client , server gen ขึ้นมาให้
แต่ในที่นี้เราสมมุติไปก่อน เนื่องจาก แค่ต้องการทดสอบ
และ เมื่อมีการตอบกลับ ตรงตามที่คาดการไว้ ต่อไป ก็จะเป็นฟังก์ชั่น สำหรับ เช็ค นั้น
จะอยู่ในขั้นตอนต่อไป ซึ่งจะมีหน้าที่ไว้ดึงข้อมูลทั้งหมดมาว่า บริการไหน ถึงขั้นตอนไหน
เสร็จหรือ ยัง เป็นต้น
ซึ่ง ต่อมาใน commit
https://bitbucket.org/sarik_kumpan/aircondition-soap/commits/f716a75fe0fc3c51ad4dd8f902178d61086eba5d
จะเป็น โค้ด ตั้งต้นที่คาดว่าควรจะใช้งานได้ แต่เกิดปัญหา ต่างๆ กับทาง heroku
งาน sqlite บน local ได้แทน เพื่อที่จะไม่ต้อง อัพลง heroku เพื่อเทสบ่อยๆ
และได้ ผลลัพธ์ ดังนี้
1 . เพิ่ม class สำหรับ map ข้อมูลใน ไฟล์ model order
soap_action "get_info_package",
:args => nil,
:return => [OrderData]
def get_info_package
array_of_package = []
Order.all.find_each do |package|
hsh = {}
array_of_package = []
Order.all.find_each do |package|
hsh = {}
hsh["code"] = package.code
hsh["status"] = package.status
hsh["reciver"] = package.reciver
hsh["destination"] = package.destination
hsh["weight"] = package.weight
array_of_package.push(hsh)
end
render :soap => [ :order_imformation => array_of_package ]
end
soap_action "get_info_package_non_finish",
:args => nil,
render :soap => [ :order_imformation => array_of_package ]
end
soap_action "get_info_package_non_finish",
:args => nil,
: return => [OrderData]
def get_info_package_non_finish
array_of_package = []
Order.where(status: "store").find_each do |package|
hsh = {}
array_of_package = []
Order.where(status: "store").find_each do |package|
hsh = {}
hsh["code"] = package.code
hsh["status"] = package.status
hsh["reciver"] = package.reciver
hsh["destination"] = package.destination
hsh["weight"] = package.weight
array_of_package.push(hsh)
array_of_package.push(hsh)
end
render :soap => [:order_imformation => array_of_package]
end
soap_action "update_status",
:args => { :code => :string , :status => :string },
render :soap => [:order_imformation => array_of_package]
end
soap_action "update_status",
:args => { :code => :string , :status => :string },
:return => :string
def update_status
if params[:code].nil?
raise SOAPError, "Code Package is empty"
if params[:code].nil?
raise SOAPError, "Code Package is empty"
else
package = Order.find_by code: params[:code]
package = Order.find_by code: params[:code]
if package.nil?
raise SOAPError, "not found package"
else
package.status = params[:status]
package.save
end
end
render :soap => "successfully update status package."
end
render :soap => "successfully update status package."
end
ซึ่งจะเป็นฟังก์ชั่นสำหรับ ดึงข้อมูลทั้งหมดสำหรับการรับให้บริการส่ง
ฟังก์ชั่นสำหรับ การอัพเดท สถาณะ
ฟังก์ชั่นสำหรับ การแสดงการบริการที่มีสถาณะอยู่ในคลัง "store" หรือยังไม่ได้ส่ง
( ซึ่ง อาจจะมีนอกเหนือเช่น finish , กำลังส่ง, เมืองใดๆ )
ซึ่งจากการทดลองใช้งานกับ Soap ui จะได้ผลดังนี้
เริ่มจาก เรียกดูทั้งหมดว่าบริการใด มีสถาณะอะไร
จะเห็นได้ว่ามีการเก็บข้อมูล ต่างๆ เอาไว้ จากนั้นทดลองใช้คำสั่งอัพเดทค่า
ให้ การบริการที่มี code = x005 มีสถาณะเป็น finish
และลองใช้เช็คดูอีกรอบ
จะพบว่าข้อมูลถูกเปลี่ยนไปแล้ว
และต่อมาจะเช็คด้วย บริการ แสดง การส่งที่ยังไม่เสร็จ หรือมีสถาณะ store
ผลลัพธ์ออกมาได้ถูกต้อง ว่าแสดงเฉพาะ บริการที่ยังไม่ถูกส่งไป
** ข้อมูลอาจจะดูไม่เรียบร้อยเนื่องจาก ช่วงแรกมีการทดลองใส่ค่าแบบรีบมากเกินไป และยังไม่ได้ลบ รวมถึง ชนิดข้อมูลด้วย ที่ได้ถูกสร้างมาในช่วงทดสอบ
ไม่มีความคิดเห็น:
แสดงความคิดเห็น