HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Auke
Hello,

I want to connect to a SOAP service in my Hippo site. I want to leverage the spring framework for this, however I'm a little bit confused on how to retrieve the services that I want to use. So far I explored the following:

I can use the SpringBridgeHstComponent in which case I can sort of use the spring-web-mvc way of displaying/retrieving data. I'm not sure if I want to use this yet. I think I can figure out how the spring context can be (auto) injected / configured.

Other then that there already is a context which is - correct me if I'm wrong - loaded via the org.hippoecm.hst.site.container.HstSiteConfigServlet. I can add configuration via META-INF/hst-assembly/overrides/*.xml and retrieve this via HstServices.getComponentManager(). I've seen this work for my case.

However there is also a ComponentManager that I can configure via the org.hippoecm.hst.container.HstFilter and that I can retrieve via HstFilter.getClientComponentManager(servletContext). I haven't seen this work yet, but I'm sure it does.

Now that I'm browsing through some code I also see a reference to ModuleInstance which I hadn't seen yet, but apparently it can have it's own context as well.

I think the main question I have is why I would use the componentmanager from the org.hippoecm.hst.container.HstFilter instead of the one from the org.hippoecm.hst.site.container.HstSiteConfigServlet for example? Or is there an even cleaner way of integrating with Spring (main concern here would be to allow me to access my own spring-services).

Auke
Ard
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Ard
Hello Auke,

first of all, excellent questions, and apologies that not everything
is clear from the documentation : continuous work in progress to get
it better. See my comments below

On Wed, Feb 6, 2013 at 8:27 AM, Auke <[hidden email]> wrote:

> Hello,
>
> I want to connect to a SOAP service in my Hippo site. I want to leverage the
> spring framework for this, however I'm a little bit confused on how to
> retrieve the services that I want to use. So far I explored the following:
>
> I can use the SpringBridgeHstComponent in which case I can sort of use the
> spring-web-mvc way of displaying/retrieving data. I'm not sure if I want to
> use this yet. I think I can figure out how the spring context can be (auto)
> injected / configured.

I don't think you need this. You do not need to delegate spring mvc
for what you need. The  SpringBridgeHstComponent was meant as example
for spring framework-based developers to use full Spring DI techniques

>
> Other then that there already is a context which is - correct me if I'm
> wrong - loaded via the org.hippoecm.hst.site.container.HstSiteConfigServlet.
> I can add configuration via META-INF/hst-assembly/overrides/*.xml and
> retrieve this via HstServices.getComponentManager(). I've seen this work for
> my case.
>
> However there is also a ComponentManager that I can configure via the
> org.hippoecm.hst.container.HstFilter and that I can retrieve via
> HstFilter.getClientComponentManager(servletContext). I haven't seen this
> work yet, but I'm sure it does.

Yes, correct. There is a HstComponentManager (core) and a
ClientComponentManager (client, duh... ). The ClientComponentManager
is not by default enabled, you need to switch it on through the
web.xml, see [1]. In your case, I don't think it really matter which
component manager you use. In general, the use-cases for the
ClientComponentManager have blurred a little with those from the core
HstComponentManager : This has historical reasons: When the HST
started, you could switch a flag, to run the website with components
seamlessly as a portal (the hst components becoming portlets). Since
portals typically involve multi-webapp and multiple classloaders,
there really was a need for a ClientComponentManager : The
ClientComponentManager was tied to a webapp that did not contain the
core HstComponentManager at all: The hst core would be part of a
different webapp. However, portal support has been faded out a little,
but HstComponentManager / ClientComponentManager remained. However,
from a stylistic pov, I think it is still cleaner to add your custom
spring components, for example the SOAP component, into the
ClientComponentManager

>
> Now that I'm browsing through some code I also see a reference to
> ModuleInstance which I hadn't seen yet, but apparently it can have it's own
> context as well.

The ModuleInstance support has been added since about a year. It used
to be a bit annoying that if you have some reusable subproject that
would ship with some Spring Component configurations, you still had to
include in your overrides a xml file that would refer to that spring
configuration. This reduced the easy to reuse part. Therefor,
ModuleInstance support has been added. I see there is no documentation
about it in the onehippo.org. The jira issue that was used contains a
nice explanation and example though, see [2]. I have created a hst
task to document  ModuleInstance support as well, see [3]

>
> I think the main question I have is why I would use the componentmanager
> from the org.hippoecm.hst.container.HstFilter instead of the one from the
> org.hippoecm.hst.site.container.HstSiteConfigServlet for example? Or is
> there an even cleaner way of integrating with Spring (main concern here
> would be to allow me to access my own spring-services).

As explained, you can either HstComponentManager or
ClientComponentManager. If you want a reusable jar that auto-wires the
spring component configuration, you should go for ModuleInstance
support

Hope this helps,

Regards Ard

[1] http://www.onehippo.org/7_8/library/concepts/component-development/using-the-spring-clientcomponent.html
[2] https://issues.onehippo.com/browse/HSTTWO-2038
[3] https://issues.onehippo.com/browse/HSTTWO-2457

>
> Auke
>
>
>
> --
> View this message in context: http://hippo.2275632.n2.nabble.com/HstServices-getComponentManager-vs-HstFilter-getClientComponentManager-tp7580345.html
> Sent from the Hippo CMS 7 mailing list archive at Nabble.com.
> _______________________________________________
> Hippo-cms7-user mailing list and forums
> http://www.onehippo.org/cms7/support/forums.html



--
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
Boston - 1 Broadway, Cambridge, MA 02142

US +1 877 414 4776 (toll free)
Europe +31(0)20 522 4466
www.onehippo.com
_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Auke
Hello Ard,

thanks for the clear explanation. I can work it out from here I guess.

One more remark though: it seemed strange to me that I will have to retrieve components by name and not (as I usually would do in Spring) by type. Now I either have to define constants specifically for my component names or use string literals.

I see there is a org.hippoecm.hst.core.container.ComponentManager.getComponentsOfType(Class<T>), but this is kind of overkill to extract the unique component (which is often the case) that I'm looking for.

---
so instead of:

UserService userService = componentManager.getComponent("userService");
or
UserService userService = componentManager.getComponent(UserService.COMPONENT_NAME);

I would rather write:

UserService userService = componentManager.getComponent(UserService.class);
---

Which may result in some runtime exception if there are multiple beans defined. This would be default spring behaviour as well I suppose. I realize that the componentmanager is an abstraction - and not spring bound - but it seems behaviour that a lot of people are familiar with if they are using some kind of component manager.
Ard
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Ard
On Wed, Feb 6, 2013 at 11:26 AM, Auke <[hidden email]> wrote:

> Hello Ard,
>
> thanks for the clear explanation. I can work it out from here I guess.
>
> One more remark though: it seemed strange to me that I will have to retrieve
> components by name and not (as I usually would do in Spring) by type. Now I
> either have to define constants specifically for my component names or use
> string literals.
>
> I see there is a
> org.hippoecm.hst.core.container.ComponentManager.getComponentsOfType(Class<T>),
> but this is kind of overkill to extract the unique component (which is often
> the case) that I'm looking for.
>
> ---
> so instead of:
>
> UserService userService = componentManager.getComponent("userService");
> or
> UserService userService =
> componentManager.getComponent(UserService.COMPONENT_NAME);
>
> I would rather write:
>
> UserService userService = componentManager.getComponent(UserService.class);

What we normally do is use in the spring xml config as id the value of
UserService.class.getName() and then fetch the component in code with

UserService userService =
componentManager.getComponent(UserService.class.getName());

We typically have more than one component for one and the same class
(interface). Also realize that as 'id' we normally use the API
interface class name. In the original setup with multi-webapp, the
SpringComponentManager would 'live' in the shared lib, just like the
hst-api. A client webapp might need to be able to fetch a
SpringComponent but did not have the UserService impl class in its
webapp.

Also, I assume that if you would use

componentManager.getComponent(UserService.class);

then UserService would be an implementation class. Fetching components
by implementation class makes the DI of Spring less powerful. Also, in
the HST, most implementation classes are located in the hst-core
module, which by default pom setup, a project does not have compile
dependency against: And thus, by default fetching a component by impl
class would not even compile

Regards Ard


> ---
>
> Which may result in some runtime exception if there are multiple beans
> defined. This would be default spring behaviour as well I suppose. I realize
> that the componentmanager is an abstraction - and not spring bound - but it
> seems behaviour that a lot of people are familiar with if they are using
> some kind of component manager.
>
>
>
> --
> View this message in context: http://hippo.2275632.n2.nabble.com/HstServices-getComponentManager-vs-HstFilter-getClientComponentManager-tp7580345p7580347.html
> Sent from the Hippo CMS 7 mailing list archive at Nabble.com.
> _______________________________________________
> Hippo-cms7-user mailing list and forums
> http://www.onehippo.org/cms7/support/forums.html



--
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
Boston - 1 Broadway, Cambridge, MA 02142

US +1 877 414 4776 (toll free)
Europe +31(0)20 522 4466
www.onehippo.com
_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Auke
> What we normally do is use in the spring xml config as id the value of
> UserService.class.getName() and then fetch the component in code with
>
> UserService userService =
> componentManager.getComponent(UserService.class.getName());

I typically use component scanning insted of xml config, so I don't necessarily set the ids in that way. But I could do it that way of course.

> We typically have more than one component for one and the same class
> (interface). Also realize that as 'id' we normally use the API
> interface class name. In the original setup with multi-webapp, the
> SpringComponentManager would 'live' in the shared lib, just like the
> hst-api. A client webapp might need to be able to fetch a
> SpringComponent but did not have the UserService impl class in its
> webapp.
>
> Also, I assume that if you would use
>
> componentManager.getComponent(UserService.class);
>
> then UserService would be an implementation class. Fetching components
> by implementation class makes the DI of Spring less powerful. Also, in
> the HST, most implementation classes are located in the hst-core
> module, which by default pom setup, a project does not have compile
> dependency against: And thus, by default fetching a component by impl
> class would not even compile

First of all in my case the UserService *is* an interface (not that that was apparent) and Spring will give me the (single) corresponding implementation class that is defined in the context. I agree with you that fetching by implementation class is not an option in case the implementation class is only run-time available.

What I don't get though is that you also say that you "typically have more than one component for one and the same class (interface)". If you then use the interface name/id to retrieve an implementation for it which one do you get? Doesn't that imply that you either
1) use some kind of id to get the implementation class directly
2) or overwrite the implementation because they now have the same id in the (spring-)context?

I guess it will be point 2? In which case you can still retrieve it by context.getBean(Interface.class)?

Auke
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Woonsan Ko-3

Hi Auke / Ard,

I think it will be useful to add #getComponentOfType(Class<T>) or #getComponent(Class<T>) in ComponentManager. It can throw exception when there are multiple beans. This seems necessary especially when using auto annotation scanner feature of spring anyway.
Feel free to create a jira issue for this improvement.

Regards,

Woonsan
(Sent from my mobile phone. Apologies for any typos.)

On Feb 6, 2013 7:22 AM, "Auke" <[hidden email]> wrote:
> What we normally do is use in the spring xml config as id the value of
> UserService.class.getName() and then fetch the component in code with
>
> UserService userService =
> componentManager.getComponent(UserService.class.getName());

I typically use component scanning insted of xml config, so I don't
necessarily set the ids in that way. But I could do it that way of course.

> We typically have more than one component for one and the same class
> (interface). Also realize that as 'id' we normally use the API
> interface class name. In the original setup with multi-webapp, the
> SpringComponentManager would 'live' in the shared lib, just like the
> hst-api. A client webapp might need to be able to fetch a
> SpringComponent but did not have the UserService impl class in its
> webapp.
>
> Also, I assume that if you would use
>
> componentManager.getComponent(UserService.class);
>
> then UserService would be an implementation class. Fetching components
> by implementation class makes the DI of Spring less powerful. Also, in
> the HST, most implementation classes are located in the hst-core
> module, which by default pom setup, a project does not have compile
> dependency against: And thus, by default fetching a component by impl
> class would not even compile

First of all in my case the UserService *is* an interface (not that that was
apparent) and Spring will give me the (single) corresponding implementation
class that is defined in the context. I agree with you that fetching by
implementation class is not an option in case the implementation class is
only run-time available.

What I don't get though is that you also say that you "typically have more
than one component for one and the same class (interface)". If you then use
the interface name/id to retrieve an implementation for it which one do you
get? Doesn't that imply that you either
1) use some kind of id to get the implementation class directly
2) or overwrite the implementation because they now have the same id in the
(spring-)context?

I guess it will be point 2? In which case you can still retrieve it by
context.getBean(Interface.class)?

Auke




--
View this message in context: http://hippo.2275632.n2.nabble.com/HstServices-getComponentManager-vs-HstFilter-getClientComponentManager-tp7580345p7580350.html
Sent from the Hippo CMS 7 mailing list archive at Nabble.com.
_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html

_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Woonsan Ko-3

Hi Auke / Ard,

I think it will be useful to add #getComponentOfType(Class<T>) or #getComponent(Class<T>) in ComponentManager. It can throw exception when there are multiple beans. This seems necessary especially when using auto annotation scanner feature of spring anyway.
Feel free to create a jira issue for this improvement.

Regards,

Woonsan
(Sent from my mobile phone. Apologies for any typos.)

On Feb 6, 2013 7:22 AM, "Auke" <[hidden email]> wrote:

_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html
Ard
Reply | Threaded
Open this post in threaded view
|

Re: HstServices.getComponentManager() vs HstFilter.getClientComponentManager(...)

Ard
In reply to this post by Auke
On Wed, Feb 6, 2013 at 1:22 PM, Auke <[hidden email]> wrote:

>> What we normally do is use in the spring xml config as id the value of
>> UserService.class.getName() and then fetch the component in code with
>>
>> UserService userService =
>> componentManager.getComponent(UserService.class.getName());
>
> I typically use component scanning insted of xml config, so I don't
> necessarily set the ids in that way. But I could do it that way of course.
>
>> We typically have more than one component for one and the same class
>> (interface). Also realize that as 'id' we normally use the API
>> interface class name. In the original setup with multi-webapp, the
>> SpringComponentManager would 'live' in the shared lib, just like the
>> hst-api. A client webapp might need to be able to fetch a
>> SpringComponent but did not have the UserService impl class in its
>> webapp.
>>
>> Also, I assume that if you would use
>>
>> componentManager.getComponent(UserService.class);
>>
>> then UserService would be an implementation class. Fetching components
>> by implementation class makes the DI of Spring less powerful. Also, in
>> the HST, most implementation classes are located in the hst-core
>> module, which by default pom setup, a project does not have compile
>> dependency against: And thus, by default fetching a component by impl
>> class would not even compile
>
> First of all in my case the UserService *is* an interface (not that that was
> apparent) and Spring will give me the (single) corresponding implementation
> class that is defined in the context. I agree with you that fetching by
> implementation class is not an option in case the implementation class is
> only run-time available.
>
> What I don't get though is that you also say that you "typically have more
> than one component for one and the same class (interface)". If you then use
> the interface name/id to retrieve an implementation for it which one do you
> get? Doesn't that imply that you either
> 1) use some kind of id to get the implementation class directly
> 2) or overwrite the implementation because they now have the same id in the
> (spring-)context?

For example, if you look at the SpringComponentManager-jcr.xml config
in the hst-core. There you see

<bean id="javax.jcr.Credentials.default" class="javax.jcr.SimpleCredentials">
    <constructor-arg
value="${default.repository.user.name}${repository.pool.user.name.separator}${default.repository.pool.name}"/>
    <constructor-arg value="${default.repository.password}"/>
  </bean>

  <bean id="javax.jcr.Credentials.preview" class="javax.jcr.SimpleCredentials">
    <constructor-arg
value="${preview.repository.user.name}${repository.pool.user.name.separator}${preview.repository.pool.name}"/>
    <constructor-arg value="${preview.repository.password}"/>
  </bean>

  <bean id="javax.jcr.Credentials.writable" class="javax.jcr.SimpleCredentials">
    <constructor-arg
value="${writable.repository.user.name}${repository.pool.user.name.separator}${writable.repository.pool.name}"/>
    <constructor-arg value="${writable.repository.password}"/>
  </bean>

now fetching the, say preview credentials works through:

componentManager.getComponent(Credentials.class.getName() +".preview");

Obviously, above there are already three Credentials interface impls.

Either way, in many other cases, what you want should just be possible
as replied by Woonsan already.

Would you mind creating a hst improvement request for this at
https://issues.onehippo.com/browse/HSTTWO

Regards Ard

>
> I guess it will be point 2? In which case you can still retrieve it by
> context.getBean(Interface.class)?
>
> Auke
>
>
>
>
> --
> View this message in context: http://hippo.2275632.n2.nabble.com/HstServices-getComponentManager-vs-HstFilter-getClientComponentManager-tp7580345p7580350.html
> Sent from the Hippo CMS 7 mailing list archive at Nabble.com.
> _______________________________________________
> Hippo-cms7-user mailing list and forums
> http://www.onehippo.org/cms7/support/forums.html



--
Amsterdam - Oosteinde 11, 1017 WT Amsterdam
Boston - 1 Broadway, Cambridge, MA 02142

US +1 877 414 4776 (toll free)
Europe +31(0)20 522 4466
www.onehippo.com
_______________________________________________
Hippo-cms7-user mailing list and forums
http://www.onehippo.org/cms7/support/forums.html