יצירת Data Service ב-EI
מבוא
בניגוד ל-dblookup שיודע להחזיר ערך בודד אחד בלבד מתוך ה-DB, אם נרצה לחלץ מספר ערכים מה-DB – נצטרך לייצר Data Service.
Data Service יכול לגשת ל-Data source ולשלוף משם נתונים, זה יכול להיות פרמטר אחד, מספר פרמטרים או ללא פרמטרים כלל.
Data Service יכול לעבוד מול כל Data source שהוא – כלומר MSSQL, MySQL, MongoDB, CSV וכו'.
בסופו של דבר, לאחר יצירת ה-Data Service, נוצרת כתובת Endpoint שאליה ניתן לשלוח את הפרמטר/ים הדרושים.
במדריך הזה, נלמד כיצד לייצר Data Service מתוך ה-Enterprise Integration ע"מ שנוכל להשתמש בו בהמשך במסגרת API ב-WSO2.
לצורך יצירת ה-Data Service, יש לבצע לוג-אין ל-Enterprise Integration.
יצירת Data Service חדש
בדף הראשי של ה-IE, יש ללחוץ בתפריט הצד על "List".
במסך זה ניתן לראות את כל ה-Data Services שקיימים.
כל אחד מה-Data Services ניתן לערוך או למחוק.
על מנת לייצר Data Service חדש, יש ללחוץ על כפתור "Create".

בשלב זה נדרש לבחור שם ל-Data Service, בשדה "Data Service Name".
השם שיבחר הוא משמעותי מאחר ויהיה בהמשך חלק מהכתובת אליה פונים.
ניתן להחליט איך לפנות ל-Data Service, אם ב-http/https/local.
בסיום יש ללחוץ על כפתור Next למעבר לבחירת בסיס הנתונים הנדרש.
בחירת Data source
ניתן לבחור Data source אחד או מספר Data sources מהם ניתן לשלוף נתונים.
כדי לבחור את ה-Data source הרצוי, יש ללחוץ על כפתור Add New Datasources.

יש לבחור שם ל-Data source בשדה Datasource Id.
בדוגמה של מדריך זה, נבחר ב-Data source רלציוני מסוג MSSQL, לכן בשדה Datasource Type נבחר באפשרות RDBMS. (קיצור של Relational DataBase Management System)
לאחר שבחרנו, יפתח חלק נוסף בו נדרש למלא את השדות הבאים:
- Database Engine – יש לבחור את ה-DB הרלציוני, במקרה של מדריך זה – נבחר באופציה של Microsoft SQL Server.
- Driver Class – שדה זה מכיל את את כתובת ה-Driver לחיבור ה-DB.
שדה זה יתמלא באופן אוטומטי. - URL – שדה זה מכיל את ה-Connection String לחיבור ה-DB.
שדה זה יתמלא באופן אוטומטי.
עם זאת, יש לשנות את הכתובת [HOST] לכתובת ה-DB עם ה-Port הרלוונטי.
כמו כן, במקום [DB] יש למלא את שם ה-DB הרלוונטי.
למשל – ;jdbc:sqlserver://localhost:1433;databaseName=myDatabaseName;encrypt=true;trustServerCertificate=true. - User name – המשתמש איתו נכנסים ל-DB.
- Password – סיסמת המשתמש איתו נכנסים ל-DB.

על מנת שנוכל לוודא כי קיים חיבור תקין ל-DB לאחר הזנת כל הנתונים, יש ללחוץ על כפתור Test Connection, במידה וחיבור יצליח – נקבל חיווי כי החיבור תקין.

לאחר שכל הפרטים נכונים ויש חיווי תקין ל-DB, יש ללחוץ על כפתור Save.
כעת נחזור לדף המכיל את רשימת כל ה-Data sources, אם נדרש להוסיף Data source נוסף, יש לחזור על הפעולות שתוארו בסעיף זה.
אם אין צורך ב-Data sources נוספים, יש ללחוץ על כפתור Next.
יצירת Query
באיזור זה מגדירים באמצעות שאילתא (Query) מה לבצע.
ניתן לייצר יותר מ-Query אחד לשימושים שונים.
ליצירת Query חדש נדרש ללחוץ על כפתור Add new query.
במסך יצירת Query, יש לבחור את שם ה-Query בשדה Query ID.
לאחר מכן יש לבחור בשדה Datasource מתוך רשימת ה-Dropdown את ה-Data source אשר מולו מעוניינים לעבוד, כאמור, בשדה זה יופיע כל ה-Data sources שיצרנו תחת ה-Data Service הנוכחי.
במקרה של מדריך זה, נבחר ב-Datasource שיצרנו ל-MSSQL.
לאחר בחירת ה-Data source ובמקרה של MSSQL בפרט, נדרש לכתוב את השאילתא בשדה SQL.
יש לשים לב כי את הערך לפיו מחפשים בשאילתא (ב-WHERE) ניתן לרשום כסימן שאלה כאשר הוא משתנה. (למשל לפי ת.ז, GUID או כל פרמטר אחר שיכול להשתנות)
לדוגמה –
? = SELECT * FROM tableName WHERE changeParam
במקרה זה, במידה ואכן קיים ערך משתנה, יש ללחוץ על כפתור Generate Input Mapping (נמצא תחת שדה SQL) – מה שיקרה הוא שכל המקומות עם הסימן שאלה יזוהו באופן אוטומטי ויוגדרו כפרמטרים.
לאחר לחיצה על Generate Mapping, יתווספו לאזור של Input Mapping כל הפרמטרים שזוהו, כאשר השם שלהם יהיה בסדר עולה param0, param1, param2…

את השמות ניתן לשנות לשמות שאנחנו נבחר ע"י לחיצה על Edit לצד כל שם.
במקרה זה, ניתן לשנות את ה-Mapping Name.


בסיום, יש ללחוץ על Save ו-Main Configuration לחזרה לדף עריכת ה-Query.
דרך נוספת שיכולה לקצר את הגדרת הפרמטרים המשתנים היא ע"י סימונם באופן הבא – fieldName =: paramName.
למשל,
SELECT * FROM tableName WHERE fieldName =: paramName
במקרה הזה, ה-Mapping name של הפרמטר יהיה כפי שקבענו לעיל, ללא הצורך לשנות את השם לאחר מכן.
במידה ומעוניינים שהמערכת תחזיר תוצאה ב-jSON, יש לשנות את שדה Output type ל-jSON. (ברירת המחדל הינה XML)
אם אכן נדרשת תשובה ב-jSON, יפתח אזור נוסף עבור מבנה התשובה.
פרמטרים אלו הם הפרמטרים שאנחנו רוצים לראות ב-Result של ה-Request.
להלן דוגמה –
{"users": {"entry": [ {"userFirstName": "$userFirstName", "userLastName": "$userLastName", "userAddress": "$userAddress" } ] }}

בסיום, יש ללחוץ על Save (תחתית המסך) לשמירת ה-Query ואז נחזור לדף עם רשימת כל ה-Queries.
ניתן כמובן להוסיף Queries נוספים לפי הצורך, באותו האופן שתואר לעיל.
אם אין צורך ב-Queries נוספים, יש ללחות על כפתור Next.
יצירת Operation
משמעות ה-Operation היא למעשה הפעלת השאילתא שהגדרנו קודם לכן.
לשם ה-Operation יש משמעות גדולה מבחינת ה-URL מאחר וכאשר מבצעים קריאה ל-Operation, אנחנו נקרא ל-Data service הרלוונטי, לאחר מכן ל-Operation המיועד ואז נשלח את הפרמטרים.
לדוגמה, אם שם ה-Data service שנתנו יקרא "DataTest" ושם ה-Operation שנתנו נקרא "OperationTest", כך יראה ה-URL ב-Request –
http://localhost:8280/services/DataTest/OperationTest/?userid=12345678
כמובן שבדוגמה לעיל, ה-localhost יתחלף בכתובת וה-port של השרת הרלוונטי. (services יופיע תמיד כאשר משתמשים ב-data service)
כדי לייצר Operation חדש, יש ללחוץ על כפתור Add Operation.
בדף שיפתח יש לבחור את שם ה-Operation בשדה Operation Name, כאמור הוא ישפיע על מבנה ה-URL ולכן יש לשמור שם בעל משמעות.
לאחר מכן, נדרש לבחור בשדה Query ID את ה-Query אותו מעוניינים להריץ.
ה-QuerIes שיופיעו הם אלו שיצרנו בשלב הקודם.
בסיום, יש ללחוץ על Save. (בתחתית הדף)

לאחר שיצרנו את ה-Operation, יש ללחוץ על Finish.
במידה ואין בעיות, ה-Data Service החדש שיצרנו יופיע ברשימת ה-List של ה-EI. (יש לרפרש את הדף במידה ולא מופיע)
בלחיצה על Data Service קיים ניתן לערוך אותו באמצעות Wizard (כל המהלכים שצוינו לעיל) או באמצעות XML.

שימוש ב-Data Service ב-Integration Studio
להלן דוגמת קוד ל-API שמקבל ת.ז ב-Post (ממקור חיצוני) ואז מתבצעת קריאת Call ל-Data service שנקרא userData שתפקידו לשלוף מספר נתונים מה-DB ולהחזירם ב-Payload ב-Response.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/getUserDetails" name="getUserDetails" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<log level="full"/>
<property expression="json-eval($.userTZ)" name="uri.var.userTZ" scope="default" type="STRING"/>
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
<header name="Accept" scope="transport" value="application/json"/>
<call>
<endpoint>
<http method="get" uri-template="http://localhost:8280/services/usersData/getUserData/?userid={uri.var.userTZ}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property expression="json-eval($.users.entry[0].userFirstName)" name="userFirstName" scope="default" type="STRING"/>
<property expression="json-eval($.users.entry[0].userLastName)" name="userLastName" scope="default" type="STRING"/>
<property expression="json-eval($.users.entry[0].userAddress)" name="userAddress" scope="default" type="STRING"/>
<filter xpath="get-property('userFirstName') != ''">
<then>
<payloadFactory media-type="json">
<format>{"userFirstName":"$1", "userLastName":"$2", "userAddress":"$3"}</format>
<args>
<arg evaluator="xml" expression="get-property('userFirstName')"/>
<arg evaluator="xml" expression="get-property('userLastName')"/>
<arg evaluator="xml" expression="get-property('userAddress')"/>
</args>
</payloadFactory>
</then>
<else>
<payloadFactory media-type="json">
<format>{"alert_message":"לא נמצאו תוצאות", "userFirstName":"$1", "userLastName":"$2", "userAddress":"$3"}</format>
<args>
<arg value=""/>
<arg value=""/>
<arg value=""/>
</args>
</payloadFactory>
</else>
</filter>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>