You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Benson Margulies <bi...@basistech.com> on 2007/07/14 03:19:48 UTC

customizing the HTTP transport factory

I set out to replace JettyHTTPTransportFactory with a slightly modified
version. So, I wrote the code below.

The effect is an NPE when my factory object is asked for its
transportIds, of which it has none. When I don't try to set this up, the
default transport factory does not get asked for its transport ids,
apparently because other things that aren't initialized protect it from
being asked.

I think I see what the transport Id has to be for SOAP, so I can just
set it, but is this idea supposed to work without that?



       Bus bus =  BusFactory.getDefaultBus();
        DestinationFactoryManager dfm =
bus.getExtension(DestinationFactoryManager.class);
        JettyHTTPTransportFactoryForStaticContent transportFactory = new
JettyHTTPTransportFactoryForStaticContent();
        transportFactory.setBus(bus);
 
dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/co
nfiguration", transportFactory);

Re: customizing the HTTP transport factory

Posted by Willem Jiang <ni...@iona.com>.
Hi Benson,

I don't think you can replace the JettyTransportFactory just by 
extending the transport factory with a subclass.
Because you need to do some register or unregister the transport id things.

NOTE, when the bus starts up , it will look up the bus-extension.xml 
(for no spring supporting )or cxf-extension-*.xml (for spring 
supporting) in the class path to find extensions.
If your sub JettyTransportFactory want to replace the old  
JettyTransportFactory,  you not only need to add the *extension*.xml but 
also do some replacing work if you also include 
cxf-rt-transports-http-jetty-*.jar in you class path.

Here is an example of it in the CXFServlet.java's replaceDestionFactory 
method.

Cheers,

Willem.

Benson Margulies wrote:
> By the way, here's what was really surprising about this. 
>
> When I first hit the NPE, I thought, "OK, I need to set some transport
> IDs. Let's see what the standard version of the class has."
>
> So, I turned off my class and set a breakpoint at the spot that looked
> at the transport ids. It was never called.
>
> I apologize for not capturing the details, but, in general, when the
> code is setting up lazily as a result of a call to get a server for a
> service, the rest of the (un)initialization status causes the logic to
> assume that there will be no transport ids, and it makes some
> assumptions, instead. By creating and advertising a factory on the bus
> before entering that code, I'm obviating all of that.
>
> Now, ignorantly, I would suggest that I should be able to arrange the
> same convenient treatment for my subclass as the standard class gets. 
>
> Or, alternatively, your concept might be: 
>
> "As soon as you (ahem) open the jar and start customizing things, we
> recommend spring wiring, and look at the supplied files to see how it's
> done."
>
>
>
>   
>> -----Original Message-----
>> From: Dan Diephouse [mailto:dan@envoisolutions.com]
>> Sent: Saturday, July 14, 2007 1:57 PM
>> To: cxf-user@incubator.apache.org
>> Subject: Re: customizing the HTTP transport factory
>>
>> Hi Benson,
>>
>> You're very close to getting it to work :-)  If you look at the
>> cxf-extension-http-jetty.xml file you'll see that we associate several
>> transport IDs with that transport:
>>
>>     <bean class="
>> org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory"
>> lazy-init="true">
>>         <property name="bus" ref="cxf"/>
>>         <property name="transportIds">
>>             <list>
>>                 <value>http://schemas.xmlsoap.org/soap/http</value>
>>                 <value>http://schemas.xmlsoap.org/wsdl/http/</value>
>>
>>     
> <value>http://schemas.xmlsoap.org/wsdl/soap/http</value>
>   
>>                  <value>http://www.w3.org/2003/05/soap/bindings/HTTP/
>> </value>
>>
>>     
> <value>http://cxf.apache.org/transports/http/configuration
>   
>> </value>
>>                 <value>http://cxf.apache.org/bindings/xformat</value>
>>             </list>
>>         </property>
>>     </bean>
>>
>> In code form, this is equivalent to:
>>
>> Set<String> tids = new HashSet<String>();
>> tids.add("http://schemas.xmlsoap.org/soap/http");
>> ... etc for all transport ids
>>
>> httpTransport.setTransportIds(tids);
>>
>> for (String tid : tids) {
>>   dfm.registerDestinationFactory(tid, httpTransport);
>> }
>>
>> We should really write some docs on the transport layer, but hopefully
>> this
>> will get you going in the meantime.
>>
>> Thanks,
>> - Dan
>>
>>
>> On 7/13/07, Benson Margulies <bi...@basistech.com> wrote:
>>     
>>> I set out to replace JettyHTTPTransportFactory with a slightly
>>>       
> modified
>   
>>> version. So, I wrote the code below.
>>>
>>> The effect is an NPE when my factory object is asked for its
>>> transportIds, of which it has none. When I don't try to set this up,
>>>       
> the
>   
>>> default transport factory does not get asked for its transport ids,
>>> apparently because other things that aren't initialized protect it
>>>       
> from
>   
>>> being asked.
>>>
>>> I think I see what the transport Id has to be for SOAP, so I can
>>>       
> just
>   
>>> set it, but is this idea supposed to work without that?
>>>
>>>
>>>
>>>        Bus bus =  BusFactory.getDefaultBus();
>>>         DestinationFactoryManager dfm =
>>> bus.getExtension(DestinationFactoryManager.class);
>>>         JettyHTTPTransportFactoryForStaticContent transportFactory =
>>>       
> new
>   
>>> JettyHTTPTransportFactoryForStaticContent();
>>>         transportFactory.setBus(bus);
>>>
>>>
>>>       
> dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/co
>   
>>> nfiguration", transportFactory);
>>>
>>>       
>>
>> --
>> Dan Diephouse
>> Envoi Solutions
>> http://envoisolutions.com | http://netzooid.com/blog
>>     
>
>   

RE: customizing the HTTP transport factory

Posted by Benson Margulies <bi...@basistech.com>.
By the way, here's what was really surprising about this. 

When I first hit the NPE, I thought, "OK, I need to set some transport
IDs. Let's see what the standard version of the class has."

So, I turned off my class and set a breakpoint at the spot that looked
at the transport ids. It was never called.

I apologize for not capturing the details, but, in general, when the
code is setting up lazily as a result of a call to get a server for a
service, the rest of the (un)initialization status causes the logic to
assume that there will be no transport ids, and it makes some
assumptions, instead. By creating and advertising a factory on the bus
before entering that code, I'm obviating all of that.

Now, ignorantly, I would suggest that I should be able to arrange the
same convenient treatment for my subclass as the standard class gets. 

Or, alternatively, your concept might be: 

"As soon as you (ahem) open the jar and start customizing things, we
recommend spring wiring, and look at the supplied files to see how it's
done."



> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: Saturday, July 14, 2007 1:57 PM
> To: cxf-user@incubator.apache.org
> Subject: Re: customizing the HTTP transport factory
> 
> Hi Benson,
> 
> You're very close to getting it to work :-)  If you look at the
> cxf-extension-http-jetty.xml file you'll see that we associate several
> transport IDs with that transport:
> 
>     <bean class="
> org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory"
> lazy-init="true">
>         <property name="bus" ref="cxf"/>
>         <property name="transportIds">
>             <list>
>                 <value>http://schemas.xmlsoap.org/soap/http</value>
>                 <value>http://schemas.xmlsoap.org/wsdl/http/</value>
>
<value>http://schemas.xmlsoap.org/wsdl/soap/http</value>
>                  <value>http://www.w3.org/2003/05/soap/bindings/HTTP/
> </value>
>
<value>http://cxf.apache.org/transports/http/configuration
> </value>
>                 <value>http://cxf.apache.org/bindings/xformat</value>
>             </list>
>         </property>
>     </bean>
> 
> In code form, this is equivalent to:
> 
> Set<String> tids = new HashSet<String>();
> tids.add("http://schemas.xmlsoap.org/soap/http");
> ... etc for all transport ids
> 
> httpTransport.setTransportIds(tids);
> 
> for (String tid : tids) {
>   dfm.registerDestinationFactory(tid, httpTransport);
> }
> 
> We should really write some docs on the transport layer, but hopefully
> this
> will get you going in the meantime.
> 
> Thanks,
> - Dan
> 
> 
> On 7/13/07, Benson Margulies <bi...@basistech.com> wrote:
> >
> > I set out to replace JettyHTTPTransportFactory with a slightly
modified
> > version. So, I wrote the code below.
> >
> > The effect is an NPE when my factory object is asked for its
> > transportIds, of which it has none. When I don't try to set this up,
the
> > default transport factory does not get asked for its transport ids,
> > apparently because other things that aren't initialized protect it
from
> > being asked.
> >
> > I think I see what the transport Id has to be for SOAP, so I can
just
> > set it, but is this idea supposed to work without that?
> >
> >
> >
> >        Bus bus =  BusFactory.getDefaultBus();
> >         DestinationFactoryManager dfm =
> > bus.getExtension(DestinationFactoryManager.class);
> >         JettyHTTPTransportFactoryForStaticContent transportFactory =
new
> > JettyHTTPTransportFactoryForStaticContent();
> >         transportFactory.setBus(bus);
> >
> >
dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/co
> > nfiguration", transportFactory);
> >
> 
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog

Re: customizing the HTTP transport factory

Posted by Willem Jiang <ni...@iona.com>.
Hi Benson,

I think we could add some spring configuration support for the Jetty 
server.That could make you life easier.
I filled a JIRA[1] for it.
In this way, we can get the benefits of  the easy start of standalone 
server and flexible of the configuration.
[1] https://issues.apache.org/jira/browse/CXF-795

BTW, the servlet transport choice absolutely is other option.

Cheers,

Willem.

Benson Margulies wrote:
> Dan,
>
> The most interesting thing that dawned on me is that a JettyHTTPHandler
> \is a/ Jetty \Handler/. Thus, I can instantiate Jetty's standard static
> content handler and call it from a subclass of JettyHTTPHandler, since
> the same arguments that come into JettyHTTPHandler can be delegated to
> the handlers in Jetty and thus avoid the need for what you sent.
>
> To use what you sent, I'd need to fill in the suffix-to-mime-type
> department. Not the end of the world, and borrowable from Jetty, but
> still clumsy compared to just using Jetty's stuff.
>
> I appreciate your coaching on the transport factory. You presumably saw
> the JIRA I created when I tried to reduce the number of extra classes I
> had to create by registering my own subclass of the server engine
> factory as the bus extension instead of using my own transport factory
> to return my own server engine factory to return my own server engine. 
>
> Ironically, I want to get rid of the program I have that uses the
> embedded server and replace it with a spring deployment inside a WAR
> inside Jetty. However, it was going to be easier on various people if I
> got it working, instead.
>
> I have this feeling that I don't have an adequate design understanding
> of the relationship between the bus, the spring wiring, and the
> hardcoded defaults, so please excuse anything goofy I send.
>
> --benson
>
>
>
>   

RE: customizing the HTTP transport factory

Posted by Benson Margulies <bi...@basistech.com>.
Dan,

The most interesting thing that dawned on me is that a JettyHTTPHandler
\is a/ Jetty \Handler/. Thus, I can instantiate Jetty's standard static
content handler and call it from a subclass of JettyHTTPHandler, since
the same arguments that come into JettyHTTPHandler can be delegated to
the handlers in Jetty and thus avoid the need for what you sent.

To use what you sent, I'd need to fill in the suffix-to-mime-type
department. Not the end of the world, and borrowable from Jetty, but
still clumsy compared to just using Jetty's stuff.

I appreciate your coaching on the transport factory. You presumably saw
the JIRA I created when I tried to reduce the number of extra classes I
had to create by registering my own subclass of the server engine
factory as the bus extension instead of using my own transport factory
to return my own server engine factory to return my own server engine. 

Ironically, I want to get rid of the program I have that uses the
embedded server and replace it with a spring deployment inside a WAR
inside Jetty. However, it was going to be easier on various people if I
got it working, instead.

I have this feeling that I don't have an adequate design understanding
of the relationship between the bus, the spring wiring, and the
hardcoded defaults, so please excuse anything goofy I send.

--benson




Re: customizing the HTTP transport factory

Posted by Dan Diephouse <da...@envoisolutions.com>.
BTW, you may also be interested in this code that I wrote to serve out
static HTML files once upon a time:

    private static void serveHTML() throws Exception {
        Bus bus = BusFactory.getDefaultBus();
        DestinationFactoryManager dfm = bus.getExtension(
DestinationFactoryManager.class);
        DestinationFactory df = dfm.getDestinationFactory("
http://cxf.apache.org/transports/http/configuration");

        EndpointInfo ei = new EndpointInfo();
        ei.setAddress("http://localhost:8080/test.html");

        Destination d = df.getDestination(ei);
        d.setMessageObserver(new MessageObserver() {

            public void onMessage(Message message) {
                try {
                    // HTTP seems to need this right now...
                    ExchangeImpl ex = new ExchangeImpl();
                    ex.setInMessage(message);

                    Conduit backChannel = message.getDestination().
                        getBackChannel(message, null, null);

                    MessageImpl res = new MessageImpl();
                    res.put(Message.CONTENT_TYPE, "text/html");
                    backChannel.prepare(res);

                    OutputStream out = res.getContent(OutputStream.class);
                    FileInputStream is = new FileInputStream("test.html");
                    IOUtils.copy(is, out, 2048);

                    out.flush();

                    out.close();
                    is.close();

                    backChannel.close(res);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        });
    }

Ugly, but it works ;)

- Dan

On 7/14/07, Dan Diephouse <da...@envoisolutions.com> wrote:
>
> Hi Benson,
>
> You're very close to getting it to work :-)  If you look at the
> cxf-extension-http-jetty.xml file you'll see that we associate several
> transport IDs with that transport:
>
>     <bean class="
> org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory"
> lazy-init="true">
>         <property name="bus" ref="cxf"/>
>         <property name="transportIds">
>             <list>
>                 <value>http://schemas.xmlsoap.org/soap/http</value>
>                 <value> http://schemas.xmlsoap.org/wsdl/http/</value>
>                 <value>http://schemas.xmlsoap.org/wsdl/soap/http</value>
>                  <value> http://www.w3.org/2003/05/soap/bindings/HTTP/
> </value>
>                 <value>http://cxf.apache.org/transports/http/configuration
> </value>
>                 <value>http://cxf.apache.org/bindings/xformat</value>
>             </list>
>         </property>
>     </bean>
>
> In code form, this is equivalent to:
>
> Set<String> tids = new HashSet<String>();
> tids.add("http://schemas.xmlsoap.org/soap/http");
> ... etc for all transport ids
>
> httpTransport.setTransportIds(tids);
>
> for (String tid : tids) {
>   dfm.registerDestinationFactory(tid, httpTransport);
> }
>
> We should really write some docs on the transport layer, but hopefully
> this will get you going in the meantime.
>
> Thanks,
> - Dan
>
>
> On 7/13/07, Benson Margulies <bi...@basistech.com> wrote:
> >
> > I set out to replace JettyHTTPTransportFactory with a slightly modified
> > version. So, I wrote the code below.
> >
> > The effect is an NPE when my factory object is asked for its
> > transportIds, of which it has none. When I don't try to set this up, the
> >
> > default transport factory does not get asked for its transport ids,
> > apparently because other things that aren't initialized protect it from
> > being asked.
> >
> > I think I see what the transport Id has to be for SOAP, so I can just
> > set it, but is this idea supposed to work without that?
> >
> >
> >
> >        Bus bus =  BusFactory.getDefaultBus();
> >         DestinationFactoryManager dfm =
> > bus.getExtension(DestinationFactoryManager.class);
> >         JettyHTTPTransportFactoryForStaticContent transportFactory = new
> > JettyHTTPTransportFactoryForStaticContent();
> >         transportFactory.setBus(bus);
> >
> > dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/co
> > nfiguration", transportFactory);
> >
>
>
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog




-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: customizing the HTTP transport factory

Posted by Dan Diephouse <da...@envoisolutions.com>.
Hi Benson,

You're very close to getting it to work :-)  If you look at the
cxf-extension-http-jetty.xml file you'll see that we associate several
transport IDs with that transport:

    <bean class="
org.apache.cxf.transport.http_jetty.JettyHTTPTransportFactory"
lazy-init="true">
        <property name="bus" ref="cxf"/>
        <property name="transportIds">
            <list>
                <value>http://schemas.xmlsoap.org/soap/http</value>
                <value>http://schemas.xmlsoap.org/wsdl/http/</value>
                <value>http://schemas.xmlsoap.org/wsdl/soap/http</value>
                 <value>http://www.w3.org/2003/05/soap/bindings/HTTP/
</value>
                <value>http://cxf.apache.org/transports/http/configuration
</value>
                <value>http://cxf.apache.org/bindings/xformat</value>
            </list>
        </property>
    </bean>

In code form, this is equivalent to:

Set<String> tids = new HashSet<String>();
tids.add("http://schemas.xmlsoap.org/soap/http");
... etc for all transport ids

httpTransport.setTransportIds(tids);

for (String tid : tids) {
  dfm.registerDestinationFactory(tid, httpTransport);
}

We should really write some docs on the transport layer, but hopefully this
will get you going in the meantime.

Thanks,
- Dan


On 7/13/07, Benson Margulies <bi...@basistech.com> wrote:
>
> I set out to replace JettyHTTPTransportFactory with a slightly modified
> version. So, I wrote the code below.
>
> The effect is an NPE when my factory object is asked for its
> transportIds, of which it has none. When I don't try to set this up, the
> default transport factory does not get asked for its transport ids,
> apparently because other things that aren't initialized protect it from
> being asked.
>
> I think I see what the transport Id has to be for SOAP, so I can just
> set it, but is this idea supposed to work without that?
>
>
>
>        Bus bus =  BusFactory.getDefaultBus();
>         DestinationFactoryManager dfm =
> bus.getExtension(DestinationFactoryManager.class);
>         JettyHTTPTransportFactoryForStaticContent transportFactory = new
> JettyHTTPTransportFactoryForStaticContent();
>         transportFactory.setBus(bus);
>
> dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/co
> nfiguration", transportFactory);
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog