Cache基于Webservice做跨库执行M

在好些场景需要执行其他Cache库的M逻辑来实现业务功能。总不能每次有要求就部署发布个webservice,然后创建客户端代理类。这样太麻烦了,机依赖已有的webservice封装一个跨库执行M的通道。来实现跨库报告同步、跨库基础数据同步等等。

1.包装代码如下

/// 到远程数据库执行M返回数据
/// w ##class(LIS.WS.DHCLISServiceBase).RemoteGetData("http://172.26.234.12:57772/imedicallis/csp/LIS.WS.DHCLISService.cls?wsdl=1&CacheUserName=yonghu&CachePassword=mima","LIS.WS.DHCLISServiceBase","RemoteCacheActiveTestMTHD","")
/// Address:webservice地址
/// ClassName:调用类名
/// FuncName:调用方法名
/// P0-P13的参数
/// OutFormat:输出类型,不传输出JSON,否则输出xml
ClassMethod RemoteGetData(Address, ClassName, FuncName, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, OutFormat) As %String
{
	s Address=$g(Address)
	s ClassName=$g(ClassName)
	s FuncName=$g(FuncName)
	s P0=$g(P0)
	s P1=$g(P1)
	s P2=$g(P2)
	s P3=$g(P3)
	s P4=$g(P4)
	s P5=$g(P5)
	s P6=$g(P6)
	s P7=$g(P7)
	s P8=$g(P8)
	s P9=$g(P9)
	s P10=$g(P11)
	s P12=$g(P12)
	s P13=$g(P13)
	s Sessions=$g(Sessions)
	s OutFormat=$g(OutFormat)
	s RowCount=$g(RowCount)
	s soapObj=##Class(LIS.WS.DHCLISServiceSoap).%New()
	s soapObj.SSLConfiguration="hisweb" 
	s soapObj.Address=Address
	s ParaXml="<Parameter>"
	s ParaXml=ParaXml_"<P0>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P0>"
	s ParaXml=ParaXml_"<P1>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P1>"
	s ParaXml=ParaXml_"<P2>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P2>"
	s ParaXml=ParaXml_"<P3>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P3>"
	s ParaXml=ParaXml_"<P4>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P4>"
	s ParaXml=ParaXml_"<P5>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P5>"
	s ParaXml=ParaXml_"<P6>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P6>"
	s ParaXml=ParaXml_"<P7>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P7>"
	s ParaXml=ParaXml_"<P8>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P8>"
	s ParaXml=ParaXml_"<P9>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P9>"
	s ParaXml=ParaXml_"<P10>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P10>"
	s ParaXml=ParaXml_"<P11>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P11>"
	s ParaXml=ParaXml_"<P12>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P0)_"</P12>"
	s ParaXml=ParaXml_"<P13>"_##Class(LIS.WS.BLL.DHCDataJSON).DealForXML(P13)_"</P0>"
	s ParaXml=ParaXml_"</Parameter>"
	i '$l(OutFormat) d
	.s OutFormat="JSON"
	i OutFormat="JSON" d
	.s $p(Sessions,"^",7)="JSON"
	.s retxml=soapObj.GetData(ClassName,FuncName,ParaXml,Sessions)
	.s err=..GetXmlValByPath(retxml,"/Response/Error")
	.i $l(err) THROW ##class(%Exception.SystemException).%New("远程调用异常","D",,"调用远程M失败:"_err)
	.s retstr=..GetXmlValByPath(retxml)
	e  d
	.s retstr=soapObj.GetData(ClassName,FuncName,ParaXml,Sessions)
	q retstr
}

/// 通过xpath得到xml节点值
/// w ##class(LIS.WS.DHCLISServiceBase).GetXmlValByPath("<Response><RemoteCacheActiveTestMTHDResult>1</RemoteCacheActiveTestMTHDResult><RetVal>0</RetVal><Error></Error><Node>RemoteCacheActiveTestMTHD</Node><RowCount>0</RowCount><ResType>1</ResType><RetSession>^^^^^^JSON</RetSession></Response>","")
/// xml:xml串
/// xpath:不传就默认为检验csp返回格式的xpath,否则传入/Response/RemoteCacheActiveTestMTHD格式层级路径
ClassMethod GetXmlValByPath(xml, xpath)
{
	s xml=$g(xml)
	s xpath=$g(xpath)
	set sc = ##class(%XML.TextReader).ParseStream(xml, .reader)
	Set repid=$I(^CacheTemp)
	s ret=""
	k ^TMP($zn,repid,$j)
	while (reader.Read()) {
		set Type = reader.NodeType
		set Path = reader.Path
		set Value = reader.Value
		i Type="chars" d
		.s ^TMP($zn,repid,$j,Path)=Value
	}
	i '$l(xpath) d
	.s nodenamePath="/Response/Node"
	.s resNodeName=$g(^TMP($zn,repid,$j,nodenamePath))
	.s xpath="/Response/"_resNodeName_"Result"
	i $l(xpath) s ret=$g(^TMP($zn,repid,$j,xpath))
	k ^TMP($zn,repid,$j)
	q ret
}

Soap代理类

Class LIS.WS.DHCLISServiceSoap Extends %SOAP.WebClient [ ProcedureBlock ]
{

/// This is the URL used to access the web service.
Parameter LOCATION = "http://127.0.0.1:57772/imedicallis/csp/LIS.WS.DHCLISService.cls";

/// This is the namespace used by the Service
Parameter NAMESPACE = "http://tempuri.org";

/// Use xsi:type attribute for literal types.
Parameter OUTPUTTYPEATTRIBUTE = 1;

/// Determines handling of Security header.
Parameter SECURITYIN = "ALLOW";

/// This is the name of the Service
Parameter SERVICENAME = "LISService";

/// This is the SOAP version supported by the service.
Parameter SOAPVERSION = 1.1;

/// webservice地址http://127.0.0.1:57772/imedicallis/csp/LIS.WS.DHCLISService.cls?wsdl=1&amp;CacheUserName=yonghu&amp;CachePassword=mima
Property Address As %String;

Method ExcMethod(ClassName As %String, FuncName As %String, P0 As %String, P1 As %String, P2 As %String, P3 As %String, P4 As %String, P5 As %String, P6 As %String, P7 As %String, P8 As %String, P9 As %String, P10 As %String, P11 As %String, P12 As %String, P13 As %String, P14 As %String) As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("ExcMethod").Invoke($this,"http://tempuri.org/LIS.WS.DHCLISService.ExcMethod",.ClassName,.FuncName,.P0,.P1,.P2,.P3,.P4,.P5,.P6,.P7,.P8,.P9,.P10,.P11,.P12,.P13,.P14)
}

Method GetData(ClassName As %String, FuncName As %String, Param As %String(MAXLEN=99999999), Session As %String(MAXLEN=1000)) As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 s User=""
 s Pwd=""
 //判断地址是否包含密码
 i ..Address["?" d
 .s AddressNew=$REPLACE(..Address,"&amp;","&")
 .s PassInfo=$p(AddressNew,"?",2)
 .f i=1:1:$l(PassInfo,"&") d
 ..s OnePStr=$p(PassInfo,"&",i)
 ..s PCode=$p(OnePStr,"=",1)
 ..s PVal=$p(OnePStr,"=",2)
 ..i PCode="CacheUserName" d
 ...s User=PVal
 ..i PCode="CachePassword" d
 ...s Pwd=PVal
 //webservice是2016库使用
 i $l(User) d ..WSSecurityLogin(User,Pwd) 
 s $this.Location=$p(AddressNew,"?",1)
 Quit ..WebMethod("GetData").Invoke($this,"http://tempuri.org/LIS.WS.DHCLISService.GetData",.ClassName,.FuncName,.Param,.Session)
}

Method GetLabTrakData(ClassName As %String, FuncName As %String, P0 As %String, P1 As %String, P2 As %String, P3 As %String) As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("GetLabTrakData").Invoke($this,"http://tempuri.org/LIS.WS.DHCLISService.GetLabTrakData",.ClassName,.FuncName,.P0,.P1,.P2,.P3)
}

Method GetLabTrakQuery(ClassName As %String, FuncName As %String, P0 As %String, P1 As %String, P2 As %String, Output rset As %XML.DataSet) As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("GetLabTrakQuery").Invoke($this,"http://tempuri.org/LIS.WS.DHCLISService.GetLabTrakQuery",.ClassName,.FuncName,.P0,.P1,.P2,.rset)
}

Method GetSQLData(SQLText As %String(MAXLEN=100000), Param As %String(MAXLEN=100000), Session As %String(MAXLEN=100000)) As %String [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Quit ..WebMethod("GetSQLData").Invoke($this,"http://tempuri.org/LIS.WS.DHCLISService.GetSQLData",.SQLText,.Param,.Session)
}

}

这样需要跨库执行M就方便了,不需要特殊配置,测试代码示例:

Class LIS.WS.DHCRemoteCallTest Extends %RegisteredObject
{

/// 测试远程数据库是否能访问,可以访问返回1
/// w ##class(LIS.WS.DHCRemoteCallTest).CallTestMTHD("")
ClassMethod CallTestMTHD(P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, Output RowCount As %String) As %String
{
	//远程webservice地址
	s Address="http://192.168.23.234:57772/imedicallis/csp/LIS.WS.DHCLISService.cls?wsdl=1&amp;CacheUserName=yonghu&amp;CachePassword=mima"
	
	//先测试远程执行是否可用
	s dbActive=##class(LIS.WS.DHCLISServiceBase).RemoteGetData(Address,"LIS.WS.DHCLISServiceBase","RemoteCacheActiveTestMTHD","")


	//数据库可用的话调用业务M
	i dbActive="1" d
	.//查询检验仪器列表,以JSON格式返回。可以调用任意符合检验M参数的方法和Qry
	.s qcMachine=##class(LIS.WS.DHCLISServiceBase).RemoteGetData(Address,"Service.LIS.QC.DHCQCService","GetMachineList","")
	.zw qcMachine
	.s sp=""
	.zw sp
	.zw sp
	.zw sp
	.//查询检验仪器列表,以XML格式返回。可以调用任意符合检验M参数的方法和Qry
	.s qcMachine=##class(LIS.WS.DHCLISServiceBase).RemoteGetData(Address,"Service.LIS.QC.DHCQCService","GetMachineList","","","","","","","","","","","","","","","","XML")
	.zw qcMachine
	q ""
}

}

效果

DHC-LISDATA>w ##class(LIS.WS.DHCRemoteCallTest).CallTestMTHD("")
qcMachine="[{""Code"":""1"",""Name"":""0319Test"",""HospitalCode"":""DHSZHYYZY""},{""Code"":""2"",""Name"":""0508质控测试"",""HospitalCode"":""DHSZHYYZY""},{""C    ode"":""4"",""Name"":""tyu测试仪器"",""HospitalCode"":""DHSZHYYZY""},{""Code"":"    "6"",""Name"":""0906质控测试"",""HospitalCode"":""DHSZHYYZY""},{""Code"":""7"","    "Name"":""微生物仪器1"",""HospitalCode"":""DHSZHYYZY""},{""Code"":""8"",""Name""     :""西门子"",""HospitalCode"":""DHSZHYYZY""},{""Code"":""9"",""Name"":""海尔血球        仪"",""HospitalCode"":""DHSZHYYZY""}]"                                           sp=""
sp=""
sp=""
qcMachine="<Response><GetMachineListResult><s:schema id=""DefaultDataSet"" xmlns="""" attributeFormDefault=""qualified"" elementFormDefault=""qualified"" xmlns:s=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata""><s:element name=""DefaultDataSet"" msdata:IsDataSet=""true""><s:complexType><s:choice maxOccurs=""unbounded""><s:element name=""GetMachineList""><s:complexType><s:sequence><s:element name=""Code""/><s:element name=""Name""/><s:element name=""HospitalCode""/></s:sequence></s:complexType></s:element></s:choice></s:complexType></s:element></s:schema><GetMachineList><Code>1</Code><Name>0319Test</Name><HospitalCode>DHSZHYYZY</HospitalCode></GetMachineList><GetMachineList><Code>2</Code><Name>0508质控测试</Name><HospitalCode>DHSZHYYZY</HospitalCode    ></GetMachineList><GetMachineList><Code>4</Code><Name>tyu测试仪器</Name><Hospita    lCode>DHSZHYYZY</HospitalCode></GetMachineList><GetMachineList><Code>6</Code><Name>0906质控测试</Name><HospitalCode>DHSZHYYZY</HospitalCode></GetMachineList><Ge    tMachineList><Code>7</Code><Name>微生物仪器1</Name><HospitalCode>DHSZHYYZY</Hosp     italCode></GetMachineList><GetMachineList><Code>8</Code><Name>西门子</Name><Hosp   italCode>DHSZHYYZY</HospitalCode></GetMachineList><GetMachineList><Code>9</Code><Name>海尔血球仪</Name><HospitalCode>DHSZHYYZY</HospitalCode></GetMachineList></     GetMachineListResult><RetVal>0</RetVal><Error></Error><Node>GetMachineList</Node><RowCount>7</RowCount><ResType>0</ResType><RetSession></RetSession></Response>" 
DHC-LISDATA>

多备点基础方法,总有机会用到的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小乌鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值