Hi,
I am trying to make "common" service for my project, and i am facing problem using dynamic service name. My common service has Map parameter, and then it calls required service using values from that Map. Sample: Service definition: <service name="updateCommon" engine="simple" location="com/codes/CommonServices.xml" invoke="updateCommon" auth="true"> <description>Update entity - common</description> <attribute name="entityName" type="String" mode="IN" optional="false"/> <attribute name="data" type="Map" mode="IN" optional="false"/> </service> Service: <simple-method method-name="updateCommon" short-description="Update entity - common"> <!-- no problem --> <set-service-fields service-name="update${parameters.entityName}" map-name="parameters.data" to-map-name="serviceParams"/> <!- there is problem --> <call-service service-name="update${parameters.entityName}" in-map-name="serviceParams"> <results-to-map map-name="result"/> </call-service> </simple-method> And I want it to call service like this (let say, I pass 'GlAccount' in entity-name parameter for updateCommon service): <service name="updateGlAccount" default-entity-name="GlAccount" engine="simple" location="com/accounting/ledger/GeneralLedgerServices.xml" invoke="updateGlAccount" auth="true"> <description>Update a GlAccount record</description> <auto-attributes include="pk" mode="IN" optional="false"/> <auto-attributes include="nonpk" mode="IN" optional="true"/> </service> I test that for "<set-service-fields ...>" tag the dynamic use of service-name is working fine, and parameters for service are filled correctly, but for "call service" tag it's not working. It gives me an error saying "Cannot locate service by name (update${parameters.entityName})". I know to do that using service written in java, but this looks more simply :-) Is there some way to solve that or is there any other way to do that, except java ? Thanx for any advance, Radoslav Tomko |
I suggest you read up on the service engine
http://docs.ofbiz.org/display/OFBTECH/Service+Engine+Guide and use a xml editor that reads the xsd for services. if you have defined your xml file with the appropriate header this should show what will not work. pick any servicedef/service.xml as an example. Radoslav Tomko sent the following on 7/24/2008 12:02 AM: > Hi, > > I am trying to make "common" service for my project, and i am facing problem > using dynamic service name. > My common service has Map parameter, and then it calls required service > using values from that Map. > > Sample: > > Service definition: > > <service name="updateCommon" engine="simple" > location="com/codes/CommonServices.xml" > invoke="updateCommon" auth="true"> > <description>Update entity - common</description> > <attribute name="entityName" type="String" mode="IN" > optional="false"/> > <attribute name="data" type="Map" mode="IN" optional="false"/> > </service> > > Service: > > <simple-method method-name="updateCommon" short-description="Update > entity - common"> > <!-- no problem --> > <set-service-fields > service-name="update${parameters.entityName}" map-name="parameters.data" > to-map-name="serviceParams"/> > > <!- there is problem --> > <call-service service-name="update${parameters.entityName}" > in-map-name="serviceParams"> > <results-to-map map-name="result"/> > </call-service> > </simple-method> > > > And I want it to call service like this (let say, I pass 'GlAccount' in > entity-name parameter for updateCommon service): > > <service name="updateGlAccount" default-entity-name="GlAccount" > engine="simple" > location="com/accounting/ledger/GeneralLedgerServices.xml" > invoke="updateGlAccount" auth="true"> > <description>Update a GlAccount record</description> > <auto-attributes include="pk" mode="IN" optional="false"/> > <auto-attributes include="nonpk" mode="IN" optional="true"/> > </service> > > > I test that for "<set-service-fields ...>" tag the dynamic use of > service-name is working fine, and parameters for service > are filled correctly, but for "call service" tag it's not working. It > gives me an error saying "Cannot locate service by > name (update${parameters.entityName})". > > I know to do that using service written in java, but this looks more > simply :-) > > Is there some way to solve that or is there any other way to do that, > except java ? > > > Thanx for any advance, > > Radoslav Tomko > > > > > |
you might consider using java instead of simple for the engine
BJ Freeman sent the following on 7/24/2008 8:50 AM: > I suggest you read up on the service engine > http://docs.ofbiz.org/display/OFBTECH/Service+Engine+Guide > and use a xml editor that reads the xsd for services. > if you have defined your xml file with the appropriate header this > should show what will not work. > pick any servicedef/service.xml as an example. > > Radoslav Tomko sent the following on 7/24/2008 12:02 AM: >> Hi, >> >> I am trying to make "common" service for my project, and i am facing problem >> using dynamic service name. >> My common service has Map parameter, and then it calls required service >> using values from that Map. >> >> Sample: >> >> Service definition: >> >> <service name="updateCommon" engine="simple" >> location="com/codes/CommonServices.xml" >> invoke="updateCommon" auth="true"> >> <description>Update entity - common</description> >> <attribute name="entityName" type="String" mode="IN" >> optional="false"/> >> <attribute name="data" type="Map" mode="IN" optional="false"/> >> </service> >> >> Service: >> >> <simple-method method-name="updateCommon" short-description="Update >> entity - common"> >> <!-- no problem --> >> <set-service-fields >> service-name="update${parameters.entityName}" map-name="parameters.data" >> to-map-name="serviceParams"/> >> >> <!- there is problem --> >> <call-service service-name="update${parameters.entityName}" >> in-map-name="serviceParams"> >> <results-to-map map-name="result"/> >> </call-service> >> </simple-method> >> >> >> And I want it to call service like this (let say, I pass 'GlAccount' in >> entity-name parameter for updateCommon service): >> >> <service name="updateGlAccount" default-entity-name="GlAccount" >> engine="simple" >> location="com/accounting/ledger/GeneralLedgerServices.xml" >> invoke="updateGlAccount" auth="true"> >> <description>Update a GlAccount record</description> >> <auto-attributes include="pk" mode="IN" optional="false"/> >> <auto-attributes include="nonpk" mode="IN" optional="true"/> >> </service> >> >> >> I test that for "<set-service-fields ...>" tag the dynamic use of >> service-name is working fine, and parameters for service >> are filled correctly, but for "call service" tag it's not working. It >> gives me an error saying "Cannot locate service by >> name (update${parameters.entityName})". >> >> I know to do that using service written in java, but this looks more >> simply :-) >> >> Is there some way to solve that or is there any other way to do that, >> except java ? >> >> >> Thanx for any advance, >> >> Radoslav Tomko >> >> >> >> >> > > > > |
In reply to this post by BJ Freeman
This seems to be more of a simple-method problem than a service engine one. Basically when the call-service operation in the simple-method runs it doesn't expand the service-name attribute's value, so this doesn't work. The only way to do it would be to change the implementation of that operation (pretty simply done in the CallService.java file) so that it uses the FlexibleStringExpander on that value. -David On Jul 24, 2008, at 9:50 AM, BJ Freeman wrote: > I suggest you read up on the service engine > http://docs.ofbiz.org/display/OFBTECH/Service+Engine+Guide > and use a xml editor that reads the xsd for services. > if you have defined your xml file with the appropriate header this > should show what will not work. > pick any servicedef/service.xml as an example. > > Radoslav Tomko sent the following on 7/24/2008 12:02 AM: >> Hi, >> >> I am trying to make "common" service for my project, and i am >> facing problem >> using dynamic service name. >> My common service has Map parameter, and then it calls required >> service >> using values from that Map. >> >> Sample: >> >> Service definition: >> >> <service name="updateCommon" engine="simple" >> location="com/codes/CommonServices.xml" >> invoke="updateCommon" auth="true"> >> <description>Update entity - common</description> >> <attribute name="entityName" type="String" mode="IN" >> optional="false"/> >> <attribute name="data" type="Map" mode="IN" optional="false"/> >> </service> >> >> Service: >> >> <simple-method method-name="updateCommon" short- >> description="Update >> entity - common"> >> <!-- no problem --> >> <set-service-fields >> service-name="update${parameters.entityName}" map- >> name="parameters.data" >> to-map-name="serviceParams"/> >> >> <!- there is problem --> >> <call-service service-name="update${parameters.entityName}" >> in-map-name="serviceParams"> >> <results-to-map map-name="result"/> >> </call-service> >> </simple-method> >> >> >> And I want it to call service like this (let say, I pass >> 'GlAccount' in >> entity-name parameter for updateCommon service): >> >> <service name="updateGlAccount" default-entity-name="GlAccount" >> engine="simple" >> location="com/accounting/ledger/GeneralLedgerServices.xml" >> invoke="updateGlAccount" auth="true"> >> <description>Update a GlAccount record</description> >> <auto-attributes include="pk" mode="IN" optional="false"/> >> <auto-attributes include="nonpk" mode="IN" optional="true"/> >> </service> >> >> >> I test that for "<set-service-fields ...>" tag the dynamic use of >> service-name is working fine, and parameters for service >> are filled correctly, but for "call service" tag it's not working. It >> gives me an error saying "Cannot locate service by >> name (update${parameters.entityName})". >> >> I know to do that using service written in java, but this looks more >> simply :-) >> >> Is there some way to solve that or is there any other way to do that, >> except java ? >> >> >> Thanx for any advance, >> >> Radoslav Tomko >> >> >> >> >> > |
hmmmm.
he is trying to call all services thru one call, passing the service. so I would expect a new entity to support that and java to process calling all the services. plus the locations seems strange. David E Jones sent the following on 7/24/2008 9:43 AM: > > This seems to be more of a simple-method problem than a service engine one. > > Basically when the call-service operation in the simple-method runs it > doesn't expand the service-name attribute's value, so this doesn't work. > The only way to do it would be to change the implementation of that > operation (pretty simply done in the CallService.java file) so that it > uses the FlexibleStringExpander on that value. > > -David > > > On Jul 24, 2008, at 9:50 AM, BJ Freeman wrote: > >> I suggest you read up on the service engine >> http://docs.ofbiz.org/display/OFBTECH/Service+Engine+Guide >> and use a xml editor that reads the xsd for services. >> if you have defined your xml file with the appropriate header this >> should show what will not work. >> pick any servicedef/service.xml as an example. >> >> Radoslav Tomko sent the following on 7/24/2008 12:02 AM: >>> Hi, >>> >>> I am trying to make "common" service for my project, and i am facing >>> problem >>> using dynamic service name. >>> My common service has Map parameter, and then it calls required service >>> using values from that Map. >>> >>> Sample: >>> >>> Service definition: >>> >>> <service name="updateCommon" engine="simple" >>> location="com/codes/CommonServices.xml" >>> invoke="updateCommon" auth="true"> >>> <description>Update entity - common</description> >>> <attribute name="entityName" type="String" mode="IN" >>> optional="false"/> >>> <attribute name="data" type="Map" mode="IN" optional="false"/> >>> </service> >>> >>> Service: >>> >>> <simple-method method-name="updateCommon" short-description="Update >>> entity - common"> >>> <!-- no problem --> >>> <set-service-fields >>> service-name="update${parameters.entityName}" map-name="parameters.data" >>> to-map-name="serviceParams"/> >>> >>> <!- there is problem --> >>> <call-service service-name="update${parameters.entityName}" >>> in-map-name="serviceParams"> >>> <results-to-map map-name="result"/> >>> </call-service> >>> </simple-method> >>> >>> >>> And I want it to call service like this (let say, I pass 'GlAccount' in >>> entity-name parameter for updateCommon service): >>> >>> <service name="updateGlAccount" default-entity-name="GlAccount" >>> engine="simple" >>> location="com/accounting/ledger/GeneralLedgerServices.xml" >>> invoke="updateGlAccount" auth="true"> >>> <description>Update a GlAccount record</description> >>> <auto-attributes include="pk" mode="IN" optional="false"/> >>> <auto-attributes include="nonpk" mode="IN" optional="true"/> >>> </service> >>> >>> >>> I test that for "<set-service-fields ...>" tag the dynamic use of >>> service-name is working fine, and parameters for service >>> are filled correctly, but for "call service" tag it's not working. It >>> gives me an error saying "Cannot locate service by >>> name (update${parameters.entityName})". >>> >>> I know to do that using service written in java, but this looks more >>> simply :-) >>> >>> Is there some way to solve that or is there any other way to do that, >>> except java ? >>> >>> >>> Thanx for any advance, >>> >>> Radoslav Tomko >>> >>> >>> >>> >>> >> > > > > |
In reply to this post by David E Jones
Index: framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java
=================================================================== --- framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java (revision 679466) +++ framework/minilang/src/org/ofbiz/minilang/method/callops/CallService.java (working copy) @@ -225,7 +225,7 @@ try { if (UtilValidate.isEmpty(this.requireNewTransactionStr) && this.transactionTimeout < 0) { - result = methodContext.getDispatcher().runSync(this.serviceName, inMap); + result = methodContext.getDispatcher().runSync(serviceName, inMap); } else { ModelService modelService = methodContext.getDispatcher().getDispatchContext().getModelService(serviceName); boolean requireNewTransaction = modelService.requireNewTransaction; @@ -236,7 +236,7 @@ if (this.transactionTimeout >= 0) { timeout = this.transactionTimeout; } - result = methodContext.getDispatcher().runSync(this.serviceName, inMap, timeout, requireNewTransaction); + result = methodContext.getDispatcher().runSync(serviceName, inMap, timeout, requireNewTransaction); } } catch (GenericServiceException e) { Debug.logError(e, module); |
Ooops,
content of my previous mail was lost and only attachmnt was received. So, here is missed content: ------------------------------------------------------------ Hi, there is a bug, probably. In method 'exec' of class CallService is: 182 String serviceName = methodContext.expandString(this.serviceName); 183 String errorCode = methodContext.expandString(this.errorCode); 184 String successCode = methodContext.expandString(this.successCode); Local variables are expanded, but when next in code, when service is calling, serviceName is passed as unexpanded global variable: 228 result = methodContext.getDispatcher().runSync(this.serviceName, inMap); and 239 result = methodContext.getDispatcher().runSync(this.serviceName, inMap, timeout, requireNewTransaction); I fixed this by remove keyword 'this' in lined 228 and 239, patch is included :-) ya ------------------------------------------------------------ |
how does that effect the thread safety?
Ján Valkovič sent the following on 7/24/2008 11:04 AM: > Ooops, > content of my previous mail was lost and only attachmnt was received. > So, here is missed content: > ------------------------------------------------------------ > Hi, > there is a bug, probably. In method 'exec' of class CallService is: > > 182 String serviceName = > methodContext.expandString(this.serviceName); > 183 String errorCode = methodContext.expandString(this.errorCode); > 184 String successCode = > methodContext.expandString(this.successCode); > > Local variables are expanded, but when next in code, when service is > calling, serviceName is passed as unexpanded global variable: > > 228 result = > methodContext.getDispatcher().runSync(this.serviceName, inMap); > and > 239 result = > methodContext.getDispatcher().runSync(this.serviceName, inMap, timeout, > requireNewTransaction); > > I fixed this by remove keyword 'this' in lined 228 and 239, patch is > included :-) > > ya > ------------------------------------------------------------ > > > > |
serviceName in SetServiceFields.java is expanded same way, so, i think,
CallService.exec after this change is thread safe as well as SetServiceFields.exec. If SetServiceFields.exec is not thread safe, then, sorry, i will search for other solution :-) BJ Freeman wrote / napísal(a): > how does that effect the thread safety? > > Ján Valkovič sent the following on 7/24/2008 11:04 AM: > >> Ooops, >> content of my previous mail was lost and only attachmnt was received. >> So, here is missed content: >> ------------------------------------------------------------ >> Hi, >> there is a bug, probably. In method 'exec' of class CallService is: >> >> 182 String serviceName = >> methodContext.expandString(this.serviceName); >> 183 String errorCode = methodContext.expandString(this.errorCode); >> 184 String successCode = >> methodContext.expandString(this.successCode); >> >> Local variables are expanded, but when next in code, when service is >> calling, serviceName is passed as unexpanded global variable: >> >> 228 result = >> methodContext.getDispatcher().runSync(this.serviceName, inMap); >> and >> 239 result = >> methodContext.getDispatcher().runSync(this.serviceName, inMap, timeout, >> requireNewTransaction); >> >> I fixed this by remove keyword 'this' in lined 228 and 239, patch is >> included :-) >> >> ya >> ------------------------------------------------------------ >> >> >> >> >> > > > |
In reply to this post by Radoslav Tomko
May it work with doing <set field="serviceName" value="
update${parameters.entityName}"> first and use serviceName to pass other tags like<set-service-fields service-name="serviceName"> and <call-service service-name="serviceName"> - Vikas On Thu, Jul 24, 2008 at 12:32 PM, Radoslav Tomko <[hidden email]> wrote: > Hi, > > I am trying to make "common" service for my project, and i am facing > problem > using dynamic service name. > My common service has Map parameter, and then it calls required service > using values from that Map. > > Sample: > > Service definition: > > <service name="updateCommon" engine="simple" > location="com/codes/CommonServices.xml" > invoke="updateCommon" auth="true"> > <description>Update entity - common</description> > <attribute name="entityName" type="String" mode="IN" > optional="false"/> > <attribute name="data" type="Map" mode="IN" optional="false"/> > </service> > > Service: > > <simple-method method-name="updateCommon" short-description="Update > entity - common"> > <!-- no problem --> > <set-service-fields > service-name="update${parameters.entityName}" map-name="parameters.data" > to-map-name="serviceParams"/> > > <!- there is problem --> > <call-service service-name="update${parameters.entityName}" > in-map-name="serviceParams"> > <results-to-map map-name="result"/> > </call-service> > </simple-method> > > > And I want it to call service like this (let say, I pass 'GlAccount' in > entity-name parameter for updateCommon service): > > <service name="updateGlAccount" default-entity-name="GlAccount" > engine="simple" > location="com/accounting/ledger/GeneralLedgerServices.xml" > invoke="updateGlAccount" auth="true"> > <description>Update a GlAccount record</description> > <auto-attributes include="pk" mode="IN" optional="false"/> > <auto-attributes include="nonpk" mode="IN" optional="true"/> > </service> > > > I test that for "<set-service-fields ...>" tag the dynamic use of > service-name is working fine, and parameters for service > are filled correctly, but for "call service" tag it's not working. It > gives me an error saying "Cannot locate service by > name (update${parameters.entityName})". > > I know to do that using service written in java, but this looks more > simply :-) > > Is there some way to solve that or is there any other way to do that, > except java ? > > > Thanx for any advance, > > Radoslav Tomko > > > |
Nope because then it will try to call a service called "serviceName". You have to have the string expansion for this, because technically what you want even in that case is: service-name="${serviceName}" and not service-name="serviceName" ... and so you need string expansion anyway. -David On Jul 25, 2008, at 2:39 AM, Vikas Mayur wrote: > May it work with doing <set field="serviceName" value=" > update${parameters.entityName}"> first and use serviceName to pass > other > tags like<set-service-fields service-name="serviceName"> and <call- > service > service-name="serviceName"> > > - Vikas > > On Thu, Jul 24, 2008 at 12:32 PM, Radoslav Tomko <[hidden email]> > wrote: > >> Hi, >> >> I am trying to make "common" service for my project, and i am facing >> problem >> using dynamic service name. >> My common service has Map parameter, and then it calls required >> service >> using values from that Map. >> >> Sample: >> >> Service definition: >> >> <service name="updateCommon" engine="simple" >> location="com/codes/CommonServices.xml" >> invoke="updateCommon" auth="true"> >> <description>Update entity - common</description> >> <attribute name="entityName" type="String" mode="IN" >> optional="false"/> >> <attribute name="data" type="Map" mode="IN" optional="false"/> >> </service> >> >> Service: >> >> <simple-method method-name="updateCommon" short-description="Update >> entity - common"> >> <!-- no problem --> >> <set-service-fields >> service-name="update${parameters.entityName}" map- >> name="parameters.data" >> to-map-name="serviceParams"/> >> >> <!- there is problem --> >> <call-service service-name="update${parameters.entityName}" >> in-map-name="serviceParams"> >> <results-to-map map-name="result"/> >> </call-service> >> </simple-method> >> >> >> And I want it to call service like this (let say, I pass >> 'GlAccount' in >> entity-name parameter for updateCommon service): >> >> <service name="updateGlAccount" default-entity-name="GlAccount" >> engine="simple" >> location="com/accounting/ledger/GeneralLedgerServices.xml" >> invoke="updateGlAccount" auth="true"> >> <description>Update a GlAccount record</description> >> <auto-attributes include="pk" mode="IN" optional="false"/> >> <auto-attributes include="nonpk" mode="IN" optional="true"/> >> </service> >> >> >> I test that for "<set-service-fields ...>" tag the dynamic use of >> service-name is working fine, and parameters for service >> are filled correctly, but for "call service" tag it's not working. It >> gives me an error saying "Cannot locate service by >> name (update${parameters.entityName})". >> >> I know to do that using service written in java, but this looks more >> simply :-) >> >> Is there some way to solve that or is there any other way to do that, >> except java ? >> >> >> Thanx for any advance, >> >> Radoslav Tomko >> >> >> |
Thanks David. Yes you are right indeed. I think I did not read your recent
post correctly. - Vikas On Fri, Jul 25, 2008 at 2:16 PM, David E Jones <[hidden email]> wrote: > > Nope because then it will try to call a service called "serviceName". You > have to have the string expansion for this, because technically what you > want even in that case is: > > service-name="${serviceName}" > > and not > > service-name="serviceName" > > ... and so you need string expansion anyway. > > -David > > > > On Jul 25, 2008, at 2:39 AM, Vikas Mayur wrote: > > May it work with doing <set field="serviceName" value=" >> update${parameters.entityName}"> first and use serviceName to pass other >> tags like<set-service-fields service-name="serviceName"> and <call-service >> service-name="serviceName"> >> >> - Vikas >> >> On Thu, Jul 24, 2008 at 12:32 PM, Radoslav Tomko <[hidden email]> >> wrote: >> >> Hi, >>> >>> I am trying to make "common" service for my project, and i am facing >>> problem >>> using dynamic service name. >>> My common service has Map parameter, and then it calls required service >>> using values from that Map. >>> >>> Sample: >>> >>> Service definition: >>> >>> <service name="updateCommon" engine="simple" >>> location="com/codes/CommonServices.xml" >>> invoke="updateCommon" auth="true"> >>> <description>Update entity - common</description> >>> <attribute name="entityName" type="String" mode="IN" >>> optional="false"/> >>> <attribute name="data" type="Map" mode="IN" optional="false"/> >>> </service> >>> >>> Service: >>> >>> <simple-method method-name="updateCommon" short-description="Update >>> entity - common"> >>> <!-- no problem --> >>> <set-service-fields >>> service-name="update${parameters.entityName}" map-name="parameters.data" >>> to-map-name="serviceParams"/> >>> >>> <!- there is problem --> >>> <call-service service-name="update${parameters.entityName}" >>> in-map-name="serviceParams"> >>> <results-to-map map-name="result"/> >>> </call-service> >>> </simple-method> >>> >>> >>> And I want it to call service like this (let say, I pass 'GlAccount' in >>> entity-name parameter for updateCommon service): >>> >>> <service name="updateGlAccount" default-entity-name="GlAccount" >>> engine="simple" >>> location="com/accounting/ledger/GeneralLedgerServices.xml" >>> invoke="updateGlAccount" auth="true"> >>> <description>Update a GlAccount record</description> >>> <auto-attributes include="pk" mode="IN" optional="false"/> >>> <auto-attributes include="nonpk" mode="IN" optional="true"/> >>> </service> >>> >>> >>> I test that for "<set-service-fields ...>" tag the dynamic use of >>> service-name is working fine, and parameters for service >>> are filled correctly, but for "call service" tag it's not working. It >>> gives me an error saying "Cannot locate service by >>> name (update${parameters.entityName})". >>> >>> I know to do that using service written in java, but this looks more >>> simply :-) >>> >>> Is there some way to solve that or is there any other way to do that, >>> except java ? >>> >>> >>> Thanx for any advance, >>> >>> Radoslav Tomko >>> >>> >>> >>> > |
Free forum by Nabble | Edit this page |