שלום חברים,
היום אני אתחיל בפרק הראשון בסדרת
המאמרים הקרובה שתעסוק בקישוריות בין SharePoint לבין מערכות חיצוניות כמו Oracle וכו'
.
לאחד הלקוחות הגדולים שלי יש מגוון
מערכות במגוון טכנולוגיות שאחת מהן היא SharePoint. ע"ב הפלטפורמה הלקוח והארגון אליו הוא
שייך מנהלים ידע ומנהלים תהליכים עסקיים כגון תהליכי רכש, תהליכי תיעוד וכו' .
אני אספר על תהליך עסקי אחד ועל
הפתרון המוצע שמנסה להיות כמה שיותר קרוב לשימוש בכלים ש-SharePoint נותן לנו.
התהליך העסקי שעליו אספר הוא תהליך
ביצוע רכש/הזמנה מאגף הרכש בחברה. החברה מאפשרת למשתמש הקצה למלא טופס מקוון דרך
פורטל SharePoint,
בו המשתמש מזין את פרטי המוצר שברצונו להזמין ועוד מס' פרטי מעטפת. לאחר שהלקוח
סיים את מילוי הטופס ושולח אותו לאישור הנתונים נשמרים ברשימת SharePoint ייעודית.
כאן
מסתיים החלק של SharePoint
ומתחיל החלק של מערכות Oracle שכוללים כלי אגירת נתונים – מסדי נתונים (Databases) כלי עיבוד נתונים
וכלי אחזור לדוחות BI ו-Dashboards .
עד
לנקודה זו הלקוח היה מייצא לאקסל את נתוני הרשימה של SharePoint ומכניס אותם בצורה
ידנית/חצי אוטומטית לבסיסי הנתונים של Oracle ומשם ממשיך בתהליך עיבוד המידע והעברת מידע
לשאר המערכות בחברה.
לא
קשה לזהות את הבעיה בתהליך כזה ואת הסיכונים שכרוכים בהעברת מידע ותוכן באופן זה,
למשל איבוד תוכן, אי תאימות בקונבנציות ותבניות , כל לקוח יכול להזין מה שהוא רוצה
ומצד המערכות האחרות שאינן SharePoint החבר'ה שעובדים על המערכות האלו יכולים
לרשום דברים אחרים , כלומר אין שפה משותפת מקצה לקצה.
בנקודה
זו נכנסתי לעניין וחשבתי על מס' פתרונות אוטומטים שייתנו מענה מקצה לקצה, אחת
הדרישות הייתה שסנכרון הנתונים יהיה דו-כיווני כלומר, מה-SharePoint ל- Oracle ולהפך. להלן הפתרונות עליהם חשבתי :
1.
פיתוח Web
Service שימשוך את הנתונים
מה-SharePoint
וידחוף אותם ל-Oracle.
2.
פיתוח Timer
Job שאוסף את הנתונים
מרשימת SharePoint
פעם ביום ודוחף אותם ל-Oracle
3.
עבודה מול SharePoint
BCS.
אני בחרתי באפשרות השלישית בגלל היבטי
שימוש בכלים ומתודות קיימות ב SharePoint והן ביעילות וביצועים על-סמך דרישת הלקוח של
סנכרון דו-כיווני ומידי.
הפתרון בצורה סכמתית :
בפרק זה אפרט על השלב הראשון – בניית WCF Service שיודע לבצע את
הפעולות הבאות :
1.
לשלוף מידע מ-Oracle
2.
לעדכן מידע ב-Oracle
3.
להכניס מידע ל-Oracle
4.
למחוק מידע מה-Oracle.
כדי להמחיש את התהליך בחרתי לתת דוגמא
על ישות של Employees,
יש ליצור טבלה ב-Oracle של Employees עם השדות הבאים :
1.
מספר עובד - int
2.
שם פרטי של העובד - VChar
3.
שם משפחה של העובד - VChar
4.
מס' מחלקה – int
נמשיך בבניית WCF Service :
1.
פתח פרויקט חדש של WCF
ב-Visual
Studio (Framework 3.5 – 2010/ Framework 4.5 - 2013)
2.
שלב 1: יצירת חוזה שירות (Service Contract)
a.
כדי ליצור חוזה שירות:
i.
שנה את שם השירות לשם שונה מ-Service.svc" ".
ii.
שנה את שם השירות לשם שונה מ-
IService.cs" ".
iii.
פתח את הקובץ (IService) והוסף את המתודות הבאות :
using System;
using System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace EmployeeDemo
{
[ServiceContract]
public interface IService
{
[OperationContract]
int InsertEmployee(Employee obj);
[OperationContract]
List<Employee> GetEmployees();
[OperationContract]
Employee GetEmployeeByEmpNo(int EmpNo);
[OperationContract]
void UpdateEmployeeByEmpNo(Employee obj);
[OperationContract]
void DeleteEmployeeByEmpNo(int EmpNo);
}
// Use a data contract as illustrated in the sample below
to add composite types to service operations.
[DataContract]
public class Employee
{
[DataMember]
public int EmpNo { get; set; }
[DataMember]
public string EmpFName { get; set; }
[DataMember]
public string EmpLName { get; set; }
[DataMember]
public string EmpRole { get; set; }
}
}
3.
שלב 2 : מימוש ה-Interface
a.
פתח את קובץ ה- Service.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace EmployeeDemo
{
// NOTE: You can use the "Rename" command on the
"Refactor" menu to change the class name "Service1" in
code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing
this service, please select Service1.svc or Service1.svc.cs at the Solution
Explorer and start debugging.
public class Service : IService
{
private Service()
{
string oradb = "Data Source=OracleDB;User
Id=dwh;Password=pls_dwh";
}
public int InsertEmployee(Employee obj)
{
string oradb = "Data Source= OracleDB;User
Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Insert into xxd_sp_test
(EMPLOYEE_NUMBER,FIRST_NAME,LAST_NAME,JOB_ROLL)
Values(:EmpNo,:EmpNo,:EmpLName,:EmpRole)";
Cmd.Parameters.Add(new OracleParameter(":EmpNo", obj.EmpNo));
Cmd.Parameters.Add(new OracleParameter(":EmpFName",
obj.EmpFName));
Cmd.Parameters.Add(new OracleParameter(":EmpLName",
obj.EmpLName));
Cmd.Parameters.Add(new OracleParameter(":EmpRole",
obj.EmpRole));
Cmd.ExecuteNonQuery();
Conn.Close();
return 0;
}
public List<Employee> GetEmployees()
{
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from xxd_sp_test";
OracleDataReader Reader = Cmd.ExecuteReader();
List<Employee> lstEmp = new List<Employee>();
while (Reader.Read())
{
lstEmp.Add(new Employee() { EmpNo = Convert.ToInt32(Reader[0]), EmpFName = Reader[1].ToString(),
EmpLName = Reader[2].ToString(), EmpRole = Reader[3].ToString() });
}
Reader.Close();
Conn.Close();
return lstEmp;
}
public void UpdateEmployeeByEmpNo(Employee obj)
{
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "update xxd_sp_test set
FIRST_NAME=:EmpFName,LAST_NAME=:EmpLName,JOB_ROLL=:EmpRole where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpFName", obj.EmpFName);
Cmd.Parameters.Add(":EmpLName", obj.EmpLName);
Cmd.Parameters.Add(":EmpRole", obj.EmpRole);
Cmd.Parameters.Add(":EmpNo", obj.EmpNo);
Cmd.ExecuteNonQuery();
Conn.Close();
return;
}
public void DeleteEmployeeByEmpNo(int EmpNo)
{
string oradb = "Data Source=BIDV.;User
Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "delete from xxd_sp_test where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpNo", EmpNo);
Cmd.ExecuteNonQuery();
Conn.Close();
}
//DeleteEmployeeByEmpNo(int EmpNo);
public Employee GetEmployeeByEmpNo(int EmpNo)
{
Employee Emp = new Employee();
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from xxd_sp_test where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpNo", EmpNo);
OracleDataReader Reader = Cmd.ExecuteReader();
while (Reader.Read())
{
Emp.EmpNo = EmpNo;
Emp.EmpFName =
Reader[1].ToString();
Emp.EmpLName =
Reader[2].ToString();
Emp.EmpRole =
Reader[3].ToString();
}
Reader.Close();
Conn.Close();
return Emp;
}
}
}
4.
שלב 3 : פתיחת הקובץ Service.svc כ-Markup ע"י לחיצה ימנית על הקובץ ובחירה
באפשרות View Markup
, לאחר מכן יש לשנות את המאפיינים כמו שמוצג כאן :
<%@ ServiceHost Language="C#" Debug="true" Service="EmployeeDemo.Service" CodeBehind="Service.svc.cs" %>
5.
שלב 4 : הגדרת WebConfig –
<?xml version="1.0"?>
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<services>
<service name="EmployeeService.Service">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7741"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="EmployeeService.IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata
information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults
for debugging purposes, set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root
directory during debugging, set the value below to true.
Set to false before
deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
</configuration>
6.
שלב 5: פרסום השירות ל-IIS
a.
בצע Compile לפרויקט וודא שאין שגיאות
b.
בצע פרסום ע"י ביצוע הצעדים הבאים :
i.
לחץ קליק ימני על הפרוייקט ובחר ב-Publish
ii.
צור פרופיל חדש ותן לו שם אינטואיטיבי לפרויקט
iii.
בשדה -Publish
Methods מסוג File System
iv.
בשדה –Target
location בחר/ צור תיקייה
תחת הנתיב הבא : C:\inetpub\wwwroot\wss\VirtualDirectories למשל WCFService אז הנתיב יהיה, C:\inetpub\wwwroot\wss\VirtualDirectories\WCFService
v.
לחץ על Publish.
c.
פתח את ה-IIS וצור Site חדש ב- Port 7741 : שם ה-Site – WCFService
d.
שנה את ה-Application
Pool ל-Framework 4.0
7.
שלב 6: גלוש לאתר ובדוק שה-Service עובד.
בהצלחה,
רון נס.
============================================================================================================================================================================================================================================================
Hello
friends,
Today
I will start the first chapter in a series of upcoming articles will deal with
connectivity between SharePoint and external systems such as Oracle and so on.
One
of my biggest clients have a variety of systems in a variety of technologies,
one of which is SharePoint. The customer use SharePoint platform to executives
and managers knowledge of business processes such as procurement processes,
process documentation etc..
I'll
tell you about one business process and the proposed solution tries to be as
close as possible to use the tools that SharePoint gives us.
The
business process is a process which will tell Execution Procurement /
Purchasing Division Invitation Company. The company allows the end user to fill
out an online form via SharePoint portal, where the user enters the product
information and more. After the client finished filling out the form and send
it for approval the Content are stored in a dedicated SharePoint list.
Here
is the ends of the SharePoint part and beginning of the Oracle part. The Oracle
systems include data storage tool - database (Databases) and data processing
tool retrieve TO BI tools and dashboards.
Up
to this point the customer was exporting the SharePoint List to Excel and
insert them manually / semi-automatic to Oracle database and then continues
processing the data and information transfer systems in the rest.
It
is Not difficult to identify the problem in such a process and the risks
involved in the transfer of information and content in this way, for example,
loss of content, non-compliant conventions and formats, each customer can enter
which content and the other side of the process guys who work on these systems
can record other things, that is, There is no common language across.
At
this point I went into the matter and thought on automatic solutions that will give
end-to-end Solution. One of the requirements was that the data synchronization
would be a two-way i.e., from SharePoint to Oracle and vice versa. I suggested
them below:
1. Developing Web Service to pull the data from
SharePoint and push them to Oracle.
2. Development Timer Job that collects the data from SharePoint once a
day and pushes them to Oracle
3. Working
with SharePoint BCS.
I
chose the third option because aspects of the use of tools and methods that
exist in SharePoint and effectiveness and performance based on customer's
requirement of a two-way synchronization and hands.
Solution
schematically:
In
This Post I will detail the first phase - the construction of WCF Service knows
how to do the following:
1. extract
information from Oracle
2. update
information in Oracle
3. Insert
information into Oracle
4. Delete
information from Oracle.
To
illustrate the process, I chose to give an example of an entity's Employees,
create a table in Oracle Employees with the following fields:
1. Employee
Number – int
2. First
Name of the employee – VChar
3. Last
Name of Employee – VChar
4. No
Department - int
We
will continue building the WCF Service:
1. Open
a new WCF project in Visual Studio (Framework 3.5 - 2010 / Framework 4.5 -
2013)
2. Step
1: Create a service contract (Service Contract)
a. To
create a service contract:
i. Change
the name of the service for other than Service.svc "".
ii. Change
the name of the service for other than IService.cs "".
iii. Open
the file (IService) and add the following methods:
using System;
using System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace EmployeeDemo
{
[ServiceContract]
public interface IService
{
[OperationContract]
int InsertEmployee(Employee obj);
[OperationContract]
List<Employee> GetEmployees();
[OperationContract]
Employee GetEmployeeByEmpNo(int EmpNo);
[OperationContract]
void UpdateEmployeeByEmpNo(Employee obj);
[OperationContract]
void DeleteEmployeeByEmpNo(int EmpNo);
}
// Use a data contract as illustrated in the sample below
to add composite types to service operations.
[DataContract]
public class Employee
{
[DataMember]
public int EmpNo { get; set; }
[DataMember]
public string EmpFName { get; set; }
[DataMember]
public string EmpLName { get; set; }
[DataMember]
public string EmpRole { get; set; }
}
}
3.
Step 2: Implement the Interface
a. Open the file Service.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace EmployeeDemo
{
// NOTE: You can use the "Rename" command on the
"Refactor" menu to change the class name "Service1" in
code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing
this service, please select Service1.svc or Service1.svc.cs at the Solution
Explorer and start debugging.
public class Service : IService
{
private Service()
{
string oradb = "Data
Source=OracleDB;User Id=dwh;Password=pls_dwh";
}
public int InsertEmployee(Employee obj)
{
string oradb = "Data Source= OracleDB;User
Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Insert into xxd_sp_test
(EMPLOYEE_NUMBER,FIRST_NAME,LAST_NAME,JOB_ROLL)
Values(:EmpNo,:EmpNo,:EmpLName,:EmpRole)";
Cmd.Parameters.Add(new OracleParameter(":EmpNo", obj.EmpNo));
Cmd.Parameters.Add(new OracleParameter(":EmpFName",
obj.EmpFName));
Cmd.Parameters.Add(new OracleParameter(":EmpLName",
obj.EmpLName));
Cmd.Parameters.Add(new OracleParameter(":EmpRole",
obj.EmpRole));
Cmd.ExecuteNonQuery();
Conn.Close();
return 0;
}
public List<Employee> GetEmployees()
{
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from xxd_sp_test";
OracleDataReader Reader = Cmd.ExecuteReader();
List<Employee> lstEmp = new List<Employee>();
while (Reader.Read())
{
lstEmp.Add(new Employee() { EmpNo = Convert.ToInt32(Reader[0]), EmpFName = Reader[1].ToString(),
EmpLName = Reader[2].ToString(), EmpRole = Reader[3].ToString() });
}
Reader.Close();
Conn.Close();
return lstEmp;
}
public void UpdateEmployeeByEmpNo(Employee obj)
{
string oradb = "Data Source=BIDV.;User
Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
Cmd.Connection = Conn;
Cmd.CommandText = "update xxd_sp_test set
FIRST_NAME=:EmpFName,LAST_NAME=:EmpLName,JOB_ROLL=:EmpRole where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpFName", obj.EmpFName);
Cmd.Parameters.Add(":EmpLName", obj.EmpLName);
Cmd.Parameters.Add(":EmpRole", obj.EmpRole);
Cmd.Parameters.Add(":EmpNo", obj.EmpNo);
Cmd.ExecuteNonQuery();
Conn.Close();
return;
}
public void DeleteEmployeeByEmpNo(int EmpNo)
{
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "delete from xxd_sp_test where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpNo", EmpNo);
Cmd.ExecuteNonQuery();
Conn.Close();
}
//DeleteEmployeeByEmpNo(int EmpNo);
public Employee GetEmployeeByEmpNo(int EmpNo)
{
Employee Emp = new Employee();
string oradb = "Data
Source=BIDV.;User Id=dwh;Password=pls_dwh";
OracleConnection Conn = new OracleConnection(oradb);
OracleCommand Cmd = new OracleCommand();
Conn.Open();
//Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from xxd_sp_test where
employee_number = :EmpNo";
Cmd.Parameters.Add(":EmpNo", EmpNo);
OracleDataReader Reader = Cmd.ExecuteReader();
while (Reader.Read())
{
Emp.EmpNo = EmpNo;
Emp.EmpFName =
Reader[1].ToString();
Emp.EmpLName =
Reader[2].ToString();
Emp.EmpRole =
Reader[3].ToString();
}
Reader.Close();
Conn.Close();
return Emp;
}
}
}
5. Step
3: Open a file Service.svc about Markup by right-clicking on the file and
select View Markup, then have to change the properties as shown here:
<%@ ServiceHost Language="C#" Debug="true" Service="EmployeeDemo.Service" CodeBehind="Service.svc.cs" %>
6. Step
4: Set WebConfig -
<?xml version="1.0"?>
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<services>
<service name="EmployeeService.Service">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7741"/>
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="EmployeeService.IService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata
information, set the valuesbelow to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults
for debugging purposes, set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root
directory during debugging, set the value below to true.
Set to false before deployment
to avoid disclosing web appfolder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
</configuration>
6.
5: Publish the service to IIS
a. Follow Compile the project and make
sure there are no mistakes
b. Follow the publication by following
these steps:
i. Right-click the
project and select Publish
ii. Create a new
profile and give it an intuitive name for the project
iii. Methods
-Publish field type File System
iv. Choose a
location field -Target / Create a folder under the following path: C: \ inetpub
\ wwwroot \ wss \ VirtualDirectories example WCFService then the path will be,
C: \ inetpub \ wwwroot \ wss \ VirtualDirectories \ WCFService
v. Click on Publish.
c. Open IIS and create a new Site in
Port 7741: The Site Name - WCFService
d. Change the Application Pool to
Framework 4.0
7.
Step 6: Go to the site and check that the service works.
In
the next Post I will explain How to create External Content Type that actually
connects to the WCF we have created this section to SharePoint.
Good
luck,
Ron
Ness.
No comments:
Post a Comment