cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Huang <Alex.Hu...@citrix.com>
Subject RE: what's rule for using @Component and xml bean file
Date Thu, 14 Feb 2013 04:16:33 GMT
Agreed on turning off auto-scanning and removing @Component.  We should never have used those
in the first place.

However, I disagree on using only XML.  The fact is that we are here to put in a convention
for everyone to use.  I had to make this decision before for componentlocator and putting
managers in a java config library and adapters in xml and the xml overrides the java config
library is a very good compromise.  We have never seen any confusion simply because there's
two places to do it.  People just follow what was there before.

What's really needed is the idea that each plugin library gives you a list of components to
inject for them.  We really need to put that in or else everything is tightly coupled by the
config files.  And especially here it's much nicer to have it in a java file rather than another
xml people have to track down because the likelihood of a library having changeable components
is very low.  Imagine a xml for nicira and one for midokura and one for big switch and one
for netapps and one for....  It's just wrong.

--Alex

> -----Original Message-----
> From: Kelven Yang [mailto:kelven.yang@citrix.com]
> Sent: Wednesday, February 13, 2013 2:12 PM
> To: Frank Zhang; Edison Su; Darren Shepherd
> Cc: cloudstack-dev@incubator.apache.org
> Subject: Re: what's rule for using @Component and xml bean file
>
> Okay, I was sold by XML now, since it is more important to reduce
> confusion from developers than taking advantage of some IDE's code
> refactoring convenience. I wrote the code this morning which will generate
> an initial XML bean definition. Here is the deal.
>
> 1) Turn-off component auto-scanning
> 2) Define all components in XML, after this developers should always have
> one way to declare their components which can greatly reduce the confusion
> here. Things can become more explicit and it is easier to maintain it from
> here.
>
> Kelven
>
> On 2/12/13 4:57 PM, "Frank Zhang" <Frank.Zhang@citrix.com> wrote:
>
> >>
> >> On 2/12/13 11:49 AM, "Frank Zhang" <Frank.Zhang@citrix.com> wrote:
> >>
> >> >The issue here is about convention, no technical reason.
> >> >To construct a big project, especially a project contributed by
> >> >community,  a clear and well-understood convention is the key to make
> >> >the project maintainable.
> >> >In my opinion(I may be wrong), the core of convention is
> >> >
> >> >    "There should be one-- and preferably only one --obvious way to do
> >> it"
> >> >(from Zen of Python, ironically, I thought Python totally breaks this
> >> >rule)
> >>
> >> +1
> >>
> >> >
> >> >If we have multiple ways for one goal(again, I disagree with this), it
> >> >will absolutely confuse people new to CloudStack: which way should I
> >> >follow? What's the difference?
> >> >if we donĀ¹t have clear words on this, then people will choose by their
> >> >preference and finally leads to a unmaintainable project. This is why I
> >> >am strongly against having hibernate and DAO in CloudStack, we should
> >> only
> >> >have one persistence framework.
> >> >
> >> >               " Special cases aren't special enough to break the
> >>rules."
> >> >(Zen of Python again, I really like these rules though I think python
> >> >is not following it well)
> >> >
> >> >Now the question comes to which convention to choose? To our topic is
> >> >bean XML vs @Component.
> >> >I totally understand the reason people like @Component, it's all about
> >> >handy, especially when you write up your first Spring application.
> >> >Except handy, @Component has no advantage comparing to bean XML,
> >> >unfortunately, you have to read verbose and frustrating Spring
> document
> >> >again and again to grasp its power (I read it three times, it's really
> >> >depressing at beginning because  too much puzzling information come to
> >> >you without example).
> >> >People may argue that I don't need this power, but I believe you will,
> >> >as you are constructing a big project,  there must be one day you run
> >> >in the situation where these power is for.
> >> >
> >> >However, if our convention is leading to a steep learning curve, it
> >> >will turn developers away from CloudStack as well. The solution is
> >>EXAMPLE.
> >> >Simple and clear example is good enough to tell people how to load
> >> >their components without knowing Spring much, if advanced feature is
> >> >needed, they should go Spring documentation anyway.
> >> >
> >> >There is another advantage of bean XML is it enables Declarative
> >> >Programming which is a key for extendibility and flexibility, comparing
> >> >to Imperative Programming we use in our daily job. This is another long
> >> >story, I don't want to make this long thread even longer here.  Thanks
> >> >Darren cited an great example recently how declarative REST api
> >> >liberates people from SDK development.
> >> >
> >> >I want to cite an example at last, when I use Vim first time I can
> >> >never imagine an editor so hard to use. But after I was familiar with
> >> >it(I did read the 600+ pages official manual), I will never switch to
> >> >another editor anymore.
> >>
> >>
> >> I think to reduce confusion is very important. Removing @Component all
> >> together sounds good to me. After we used it the last time to generate
> >>the
> >> necessary bean definition (either java or XML), we can remove them all.
> >>
> >> However, whether to use pure XML or follow up the similar way of mixing
> >> java/XML that we used before, any more opinions? I know some
> developers
> >> like the power of having Eclipse to do some smart editing work when you
> >>are
> >> refactoring the java code. Either ways, we will get rid of
> >>auto-scanning and
> >> only load components based on explicit configuration, this is to solve
> >>the
> >> slow bootstrap issue.
> >
> >I didn't notice JavaConfig feature which is new in Spring 3 before,  after
> >reading documents about it, I would suggest XML again.
> >
> >The main reason is it loses lots of power of XML,  though it's more handy
> >in some
> >way (to me it's unit test which I think we could adopt  javaConfig in
> >some extent).
> >
> >Anther strong reason is avoiding re-compiling when we make some change
> in
> >Spring configuration. Actually I would suggest us adopting the idea that
> >"allow to change
> >functionality without changing code" in any design, this would make our
> >project stronger
> >, more flexible, and more modular. For example, to disable a component in
> >customer
> >environment  for debug purpose, with XML file it's a single line change,
> >with JavaConfig you
> >have to re-compile and deliver some jar file, and binary jar file would
> >not tell you how configuration
> >looks like where XML text does tell
> >
> >
> >
> >
> >>
> >> -Kelven
> >>
> >> >
> >> >> -----Original Message-----
> >> >> From: Edison Su
> >> >> Sent: Tuesday, February 12, 2013 9:44 AM
> >> >> To: Kelven Yang; Frank Zhang; Darren Shepherd
> >> >> Cc: cloudstack-dev@incubator.apache.org
> >> >> Subject: RE: what's rule for using @Component and xml bean file
> >> >>
> >> >> IMHO, if you want configuration(your class needed to be configured
by
> >> >>admin, such as all the existing adaptors/manager), use xml, otherwise,
> >> >>use  @Component or @named. Switch everything into one style over
> >> >>anther, is  really a good idea? For example, I want to my class  to
be
> >> >>a singleton, and I  know for sure, no other body wants to replace and
> >> >>configure it,  @Component is just so handy, I don't need to blow up
> >> >>the xml file.
> >> >>
> >> >> > -----Original Message-----
> >> >> > From: Kelven Yang [mailto:kelven.yang@citrix.com]
> >> >> > Sent: Monday, February 11, 2013 2:24 PM
> >> >> > To: Frank Zhang; Darren Shepherd
> >> >> > Cc: cloudstack-dev@incubator.apache.org
> >> >> > Subject: Re: what's rule for using @Component and xml bean file
> >> >> >
> >> >> >
> >> >> >
> >> >> > On 2/11/13 11:39 AM, "Frank Zhang" <Frank.Zhang@citrix.com>
> wrote:
> >> >> >
> >> >> > >Ok. now I understood the story. I will go XML for my components.
> >> >> > >I can understand the pain Kelven suffered, CloudStack has
some
> >> >> > >many components that are hard to convert to XML files at one
time,
> >> >> > >given the tight schedule we faced on javelin.
> >> >> > >So using @Component to make Spring onboard is understandable.
> >> >> > >
> >> >> > >However, I agree with Darren that we should not use @Component
> >> and
> >> >> > >should use JSR annotations instead of Spring specific like
> >> >>@Autowired.
> >> >> > >@Component is easy, but not feasible and unreadable. By not
> >> >> > >feasible I mean you could not use amazing spring
> >> >> > >constructor/setter injection, you may argue that you don't
need it
> >> >> > >but if someday you are, then you have to go XML way which
breaks
> >> >> > >your code convention as you have had @Component mess
> >> everywhere.
> >> >> > >By unreadable I mean you are not able
> >> >> to
> >> >> > >tell what's skeleton of project if you are new to CloudStack.
 The
> >> >> > >skeleton are usually made up of Spring beans, listing these
beans
> >> >> > >in XML file gives people a chance to grab a global picture
> >> >> > >quickly, for they don't have to loss in huge java files for
> >>@Component.
> >> >> > >
> >> >> > >And Spring has some other plus on XML file, it has an extensible
> >> >> > >framework that you can add your namespace in bean definition,
a
> >> >> > >beast tool!
> >> >> > >
> >> >> > >>> Option 3, Using @Configuration)
> >> >> > >Please don't approach to this. @Configuration is not for this.
Its
> >> >> > >main purpose is using byte-weaver(Aspectj) to do dependency
> >> >> > >injection on domain object. A domain object is produced by
your
> >> >> > >code but not Spring IOC, which means the object generated
by java
> >> *new* keyword.
> >> >> > >So @Configuration is largely for prototype bean, not singleton,
> >> >> > >this is usually not you want.
> >> >> > >
> >> >> > >However, I don't think using Spring specific utilities is
a big
> >>deal.
> >> >> > >I agree that POJO is good, and Spring also encourages people
not
> >> >> > >to lock in Spring as much as possible. But to a large enterprise
> >> >> > >project, it would unlikely switch to another container if
current
> >> >> > >container is stable and flexible(I mean Spring here you know).
> >> >> > >Pursuing pure POJO will introduce boilerplate glue code and
make
> >> >> > >things over-abstract/over-wrapping sometime.  Five years ago
I was
> >> >> > >writing a C framework in Linux, to be pure, I added a layer
of
> >> >> > >wrapper for some glib component. I told my architect that
I don't
> >> >> > >want to lock in to glib,  he asked back that why you want
to
> >> >> > >switch to another library as glib has been proved itself for
a
> >>long time?
> >> >> > >
> >> >> > >so, I agree we should be POJO, but just avoid being purist
if the
> >> >> > >gain is small.
> >> >> >
> >> >> >
> >> >> > Yes, we've paid extra caution not to have tight-binding with Spring
> >> >> > except about the usage of @Component annotation at meta level.
> >> >> > Since we use it only at meta level, it is now actually easy to
> >> >> > generate a bean definition XML file to switch to full XML way,
> >> >> > however, I prefer to do it a in later time and would like to hear
> >> >> > more developers to
> >> >>comment
> >> >> about it.
> >> >> >
> >> >> > -Kelven
> >> >> >
> >> >> >
> >> >> > >
> >> >> > >> -----Original Message-----
> >> >> > >> From: Kelven Yang
> >> >> > >> Sent: Monday, February 11, 2013 10:48 AM
> >> >> > >> To: Darren Shepherd
> >> >> > >> Cc: Frank Zhang; cloudstack-dev@incubator.apache.org
> >> >> > >> Subject: Re: what's rule for using @Component and xml
bean file
> >> >> > >>
> >> >> > >>
> >> >> > >>
> >> >> > >> On 2/9/13 6:54 AM, "Darren Shepherd" <darren@godaddy.com>
> >> wrote:
> >> >> > >>
> >> >> > >> >Sorry, technical error in sending the last email...
> >> >> > >> >
> >> >> > >> >
> >> >> > >> >Please, please, please do note use spring packages.
Spring
> >> >> > >> >should be a runtime and not compile time dependency.
If you
> >> >> > >> >leave spring as a compile time dependency you'll
see overtime
> >> >> > >> >that developers start leveraging handy spring utilities
and
> >> components.
> >> >> > >> >Architecturally it does make sense to have dependencies
on
> such
> >> >> > >> >a large component as spring for utility style functionality,
> >> >> > >> >that is what apache commons is
> >> >> > >>for.
> >> >> > >> >
> >> >> > >> >So my two cents.
> >> >> > >> >
> >> >> > >> >Option 1, Using coding convention to reduce the auto-scan
> >> >> > >> >scope,)
> >> >> > >> >
> >> >> > >> >
> >> >> > >> >Not feasible in a realistic time frame
> >> >> > >> >
> >> >> > >> >Option 2, Using build-time XML auto-generation)
> >> >> > >> >
> >> >> > >> >Too much of a one off solution.  This is just another
thing
> >> >> > >> >people have to understand that is different from
how the
> >> >> > >> >majority of people use spring.  And its uses a spring
specific
> >> annotation.
> >> >> > >> >
> >> >> > >> >Option 3, Using @Configuration)
> >> >> > >> >
> >> >> > >> >Yeah people don't like XML.  But the eclipse support
and
> >> >> > >> >specifically the Spring IDE support for the XML configuration
> >> >> > >> >is awesome.  The new p namespace also makes the XML
less
> >> verbose.
> >> >> > >> >So, oh well, write some XML it won't kill you.  If
you use
> >> >> > >> >autowiring you'll find that mostly you are just registering
the
> >> >> > >> >bean and the XML is quite small.  Again, for simplest
learning
> >> >> > >> >curve to developing and understanding CloudStack
just stick
> >> >> > >> >with
> >> >>the
> >> >> XML.
> >> >> > >> >
> >> >> > >> >
> >> >> > >> >So again, I'm going to strongly assert that CloudStack
should
> >> >> > >> >
> >> >> > >> >1) Use JSR250, JSR330 annotations (@Inject, @PostConstruct,
> >> >> > >> >@PreDestroy)
> >> >> > >> >2) Register all beans in XML
> >> >> > >> >3) Use autowiring
> >> >> > >>
> >> >> > >>
> >> >> > >> We have hundreds of Bean components in CloudStack, it
is quite
> >> >> > >>annoying to  register all of them in XML and to maintain
it when
> >> >> > >>code-refactoring is still  going on. So we are taking
some
> >> >> > >>compromises here, for your points, we are  definitely
using auto
> >> >> > >>wiring, but for
> >> >> > >>1) and 2), we used one more Spring  defined annotation
> >> >> > >>(@Component), which may not sound elegant that it has
 Spring
> >> >> > >>dependency, but the dependency is only at meta(annotation)
> level,
> >> >> > >>we have very limited places that require a direct reference
to
> >>Spring
> >> at code  level.
> >> >> > >>
> >> >> > >> Having some meta level annotations and combining with
the
> >> >> > >>flexibility of  XML is pretty much the census I've got
from local
> >> >> > >>CloudStack developers  around me, this may not the final
> approach
> >> >> > >>either, let's give it some time to  evolve based on broader
> >> >> > >>feedbacks from the community
> >> >> > >>
> >> >> > >> -kelven
> >> >> > >>
> >> >> > >>
> >> >> > >>
> >> >> > >> >
> >> >> > >> >Darren
> >> >> > >> >
> >> >> > >> >On Feb 9, 2013, at 12:05 AM, Kelven Yang
> >> >> > >> ><kelven.yang@citrix.com>
> >> >> > >>wrote:
> >> >> > >> >
> >> >> > >> >>
> >> >> > >> >> Apologize for such a long email first, if you
are interested,
> >> >> > >> >>please read  on...
> >> >> > >> >>
> >> >> > >> >>
> >> >> > >> >> Auto-scan globally is never a good idea and
we are currently
> >> >> > >> >>doing it just  for the reason of getting existing
code quickly
> >> >>converted.
> >> >> > >> >>I'm currently  profiling some details on how
much time Spring
> >> >> > >> >>has spent for scanning the  component and how
much time it
> >> >> > >> >>spends to resolve dependency and performs  auto-wiring.
> >> >> > >> >>
> >> >> > >> >> There are both "pros and cons" for in doing
in annotation way
> >> >> > >> >>or in XML  way. Historically in CloudStack we
are doing
> >> >> > >> >>code-refactoring quite often,  this makes using
annotation
> >> >> > >> >>attractive to CloudStack developers.
> >> >> > >> >>However,
> >> >> > >> >> we also need flexibility provided by XML for
people to
> >> >> > >> >>customize CloudStack after deployment, so historically,
> >> >> > >> >>CloudStack prefers to take  advantages of both
annotation way
> >> >> > >> >>and XML way. For built-in or other basic  components
like
> >> >> > >> >>DAOs, using annotations can save developers a
lot of  typing
> >> >> > >> >>work. For pluggable components like Adapters,
Network
> >> >> > >> >>Elements,  having them in XML
> >> >> makes more sense.
> >> >> > >> >>
> >> >> > >> >> As a general guideline, we should keep component
as
> >> >> > >> >>independent of others  as possible, as loosely
coupled with
> >> >> > >> >>other as possible. The motivation of  adopting
Spring is for
> >> >> > >> >>that purpose, to enforce a consistent way of
 developing
> >> >> > >> >>pluggable,
> >> >>unit-testable
> >> >> components.
> >> >> > >> >>
> >> >> > >> >> However, there is never a perfect solution that
can satisfy
> >> >> > >> >>everyone's  needs, I would prefer to just using
auto-wiring
> >> >> > >> >>and leaving component  definitions all in XML,
in this way,
> >> >> > >> >>component and a particular container  are not
tightly coupled
> >> >> > >> >>(does not necessarily to be Spring), however,
in  reality,
> >> >> > >> >>using @Component with caution can give developers
decent
> >> >> > >> >>freedom  to write component independently
> >> >> > >> (they
> >> >> > >> >>don't need to remember to edit Java  and XML
at multiple
> >> >> > >> >>places and not everyone likes XML soup).
> >> >> > >> >>
> >> >> > >> >> A possible solution to combine both the advantages
of using
> >> >> > >> >>@Component and  XML <bean> definitions
could be
> >> >> > >> >>
> >> >> > >> >> Option 1, Using coding convention to reduce
the auto-scan
> >> >> > >> >> scope, for example,
> >> >> > >> >>
> >> >> > >> >> All components (Spring component specifically)
have to share
> >> >> > >> >>with the same  java package namespace, for example,
> >> >> > >> >>org.apache.cloudstack.component.
> >> >> > >> >> overall module/java package structure would
look like,
> >> >> > >> >>Cloud-engine
> >> >> > >> >>(module)  org.apache.cloudstack.component.XyzMgr
> >> >> > >> >> org.apache.cloudstack.component.AbcAdapter
> >> >> > >> >>
> >> >> > >> >> Cloud-cool-plugin (module)
> >> >> > >> >> org.apache.cloudstack.component.CoolMgr
> >> >> > >> >> org.apache.cloudstack.component.CoolAdapter
> >> >> > >> >>
> >> >> > >> >>
> >> >> > >> >>
> >> >> > >> >> And we only scan org.apache.cloudstack.component.
> >> >> > >> >>
> >> >> > >> >> We didn't use this approach for the reason that
this involves
> >> >> > >> >> with a lot of directory refactoring work, and
this is too bad
> >> >> > >> >> for branch
> >> >> > >>merges.
> >> >> > >> >>
> >> >> > >> >> Option 2, Using build-time XML auto-generation
> >> >> > >> >>
> >> >> > >> >> With this option, developers can continue to
use
> @Component
> >> >> > >> >> for meta-programming, we can add a step in build-process
that
> >> >> > >> >> we can automatically generate the Spring XML
file for
> >> >> > >> >> components that have been annotated by @Component.
> >> >> > >> >>
> >> >> > >> >> However, our maven build is already slow now,
what we saved
> >> >> > >> >>in bootstrapping will have to be paid at build
time, so for
> >> >> > >> >>developers, this  option may still looks slow
> >> >> > >> >>
> >> >> > >> >> Option 3, Using @Configuration (one more Spring
annotation!)
> >> >> > >> >> Cloud-server and pluggable module, each can
have a per-
> module
> >> >> > >> >> Spring component configuration class (annotated
by
> >> >> > >> >> @Configuration) and we only scan configuration
components
> at
> >> >> bootstrap.
> >> >> > >> >>
> >> >> > >> >> Option 3 does not need us to refactor existing
directory
> >> >> > >> >> structure, and have the flexibility for developers
to do
> >> >> > >> >> module development independently, as I mentioned
early, I'm
> >> >> > >> >> profiling the Spring bootstrap process, if it
is confirmed
> >> >> > >> >> that majority of time is spent in scanning instead
of
> >> >> > >> >> auto-wiring, I'm actually leaning towards
> >> >> > >>this option.
> >> >> > >> >>
> >> >> > >> >> As of whether or not to strictly limit the usage
of Spring
> >> >> > >> >>specific stuff,
> >> >> > >> >> **never** or **ever** to use @Component, I'm
not a
> >> >> > >> >>perfect-ist but a more  practical one, so using
@Component
> >> >> > >> >>only for meta programming looks fine to  me.
And In this
> >> >> > >> >>option, @Component is actually not necessarily
to be  defined
> >> >> > >> >>by Spring, we just happen to borrow it and that's
it. I'm kind
> >> >> > >> >>of  buying the point that with such a powerful
editor like
> >> >> > >> >>Eclipse, it seems  to be much easier for code-refactoring
if
> >>things
> >> are written in "java"
> >> >> > >> >> instead of XML.
> >> >> > >> >>
> >> >> > >> >> Kelven
> >> >> > >> >>
> >> >> > >> >>
> >> >> > >> >>
> >> >> > >> >> On 2/8/13 9:38 PM, "Darren Shepherd"
> <darren@godaddy.com>
> >> >> > wrote:
> >> >> > >> >>
> >> >> > >> >>> Frank,
> >> >> > >> >>>
> >> >> > >> >>> This is probably not the answer you looking
for, but I have
> >> >> > >> >>>to just throw in my two cents. When should
you use
> >> @Component?
> >> >> > Never.
> >> >> > >> >>>The cleanest way to use the Spring container
is to *never*
> >> >> > >> >>>"import org.springframework". Only bootstrap
and obviously
> >> >> > >> >>>spring specific code  should import spring
packages. JSR250
> >> >> > >> >>>and
> >> >> > >> >>>JSR330 provide standards  compliant annotations
that can be
> >> >> > >> >>>used in place of the Spring one's that  give
most of all the
> >> >> > >> >>>functionality. Refer to
> >> >> > >> >>>
> >> >> > >> >>>http://static.springsource.org/spring/docs/3.2.x/spring-frame
> >> >> > >> >>>wor
> >> >> > >> >>>k-
> >> >> > >> >>>ref
> >> >> > >> >>>ere
> >> >> > >> >>>nc
> >> >> > >> >>> e/html/beans.html#beans-standard-annotations.
> >> >> > >> >>> The standard compliant annotation of @Component
would
> be
> >> >> > @Named
> >> >> > >> from
> >> >> > >> >>> JSR250 (which is included in the JDK at
this point).
> >> >> > >> >>>
> >> >> > >> >>> Regarding when to use @Named and when to
register the
> bean
> >> >> > >> >>> in
> >> >> > XML.
> >> >> > >> >>>You  should never use @Named. I'm sure many
will disagree
> >> >> > >> >>>with me but past  experiences have over and
over again
> shown
> >> >> > >> >>>to me that
> >> >> > >> component
> >> >> > >> >>>scanning  on large scale projects is a bad
idea. Ignoring bad
> >> >> > >> >>>initialization  performance, component scanning
ends up
> >> >> > >> >>>introducing weird difficult to  debug issues
when some does
> >> >> > >> >>>something dumb. It is better to have a  clear
and definitive
> >> >> > >> >>>source regarding what is registered in your
 context.
> >> >> > >> >>>
> >> >> > >> >>> Additionally if you get into context hierarchies
(which I
> >> >> > >> >>> hope you do, but that is a different topic
altogether),
> >> >> > >> >>> component scanning
> >> >> > >>blows
> >> >> > >> up.
> >> >> > >> >>>
> >> >> > >> >>> Darren
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>> -------- Original Message --------
> >> >> > >> >>> Subject: what's rule for using @Component
and xml bean file
> >> >> > >> >>> From: Frank Zhang <Frank.Zhang@citrix.com>
> >> >> > >> >>> Date: Fri, February 08, 2013 6:39 pm
> >> >> > >> >>> To: "cloudstack-dev@incubator.apache.org"
> >> >> > >> >>> <cloudstack-dev@incubator.apache.org>
> >> >> > >> >>>
> >> >> > >> >>>
> >> >> > >> >>> I see client/tomcatconf/componentContext.xml.in
defining
> >> >> > >> >>> lots of beans while I also see many beans
use @Component
> Is
> >> >> > >> >>> there any guideline here?
> >> >> > >> >>
> >> >> > >
> >> >
> >


Mime
View raw message