You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@karaf.apache.org by Ranx0r0x <re...@bradleejohnson.com> on 2019/11/27 15:08:49 UTC

CXF Controllers...

I'm not sure if this is of interest but I took JB's examples of CXF in DS and
created some fluent wrappers around them. There are probably more delegate
methods that could be added. In any case, the controllers simplify the set
up and tear down and adding new interceptors, providers, features and
properties. 

I've used a similar mechanism in the past for standing up webservices in
unit tests with mock back ends. The impl class implements an interface and
that interface has annotations for both REST and SOAP services on it. 

Separately I have a DS class that bootstraps new Bus instances based on cfg
files (akin to the PAX JDBC mechanism) and currently specifies logging
behavior, sets properties and will use a JAAS realm name to attach to Bus if
desired. The Bus configuration mechanism uses plugins so is easily expanded
to add new properties/interceptors/providers/features. 

CXF sans Blueprint.

@Activate
public void activate() throws Exception {
	Foo fooServiceImpl=new Foo();
		

wsController.setAddress("/ws/foo").setBus(bus).setServiceBean(fooServiceImpl).start();

rsController.setAddress("/rs/foo").setBus(bus).setServiceBean(fooServiceImpl).start();

}
@Deactivate
public void deactivate() {
	rsController.stop();
	wsController.stop();
}

}
@Reference(target="(id=standard)")
public void setBus(Bus bus) {
	this.bus = bus;
}
<snip>
public class WSController {
	private JaxWsServerFactoryBean serverFactory = new
JaxWsServerFactoryBean();
	private Server server;
	
	public WSController setAddress(String url) {
		serverFactory.setAddress(url);
		return this;
	}
	
	public WSController setServiceInterface(Class clazz) {
		 serverFactory.setServiceClass(clazz);
		 return this;
		 
	}
	
	public WSController setServiceBean(Object serviceBean) {
		serverFactory.setServiceBean(serviceBean);
		return this;
	}
	public WSController setBus(Bus bus) {
		serverFactory.setBus(bus);
		return this;
	}
	
	public WSController start() {
		server = serverFactory.create();
		return this;
	}
	
	public WSController stop() {
		server.destroy();
		return this;
	}
	public WSController addOutFaultInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getOutFaultInterceptors().add(interceptor);
		return this;
	}
	public WSController addOutInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getOutInterceptors().add(interceptor);
		return this;
	}
	public WSController addInInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getInInterceptors().add(interceptor);
		return this;
	}
	public WSController addInFaultInterceptors(Interceptor<? extends Message>
interceptor) {
		serverFactory.getInFaultInterceptors().add(interceptor);
		return this;
	}
	public WSController addFeature(Feature feature) {
		serverFactory.getFeatures().add(feature);
		return this;
	}
	
	public WSController addProperties(Map<String,Object> properties) {
		serverFactory.getProperties().putAll(properties);
		return this;
	}
}


public class RSController {
	private JAXRSServerFactoryBean serverFactory = new
JAXRSServerFactoryBean();
	private Server server;

	public RSController setAddress(String url) {
		serverFactory.setAddress(url);
		return this;
	}
	
	public RSController setServiceBean(Object serviceBean) {
		serverFactory.setServiceBean(serviceBean);
		return this;
	}
	public RSController setBus(Bus bus) {
		serverFactory.setBus(bus);
		return this;
	}
	
	public RSController start() {
		server = serverFactory.create();
		return this;
	}
	
	public RSController stop() {
		server.destroy();
		return this;
	}
	public RSController addOutFaultInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getOutFaultInterceptors().add(interceptor);
		return this;
	}
	public RSController addOutInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getOutInterceptors().add(interceptor);
		return this;
	}
	public RSController addInInterceptor(Interceptor<? extends Message>
interceptor) {
		serverFactory.getInInterceptors().add(interceptor);
		return this;
	}
	public RSController addInFaultInterceptors(Interceptor<? extends Message>
interceptor) {
		serverFactory.getInFaultInterceptors().add(interceptor);
		return this;
	}
	public RSController addFeature(Feature feature) {
		serverFactory.getFeatures().add(feature);
		return this;
	}
	
	public RSController addProperties(Map<String,Object> properties) {
		serverFactory.getProperties().putAll(properties);
		return this;
	}
}



--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Ranx0r0x <re...@bradleejohnson.com>.
I have most of the tests in place. Obviously these will get more robust as
we move along. There are also questions I've noted in my TODO comments that
I haven't fully resolved. For example, the last plugin in the chain is the
PropertiesPlugin which simply sets the key/value pairs it receives on the
bus. However, there are a number of key/values like jaasRealm, in/out
logging, that are in the cfg which aren't really appropriate bus properties.
They may not hurt anything either. It may be that fields that are actually
to be used as properties be specified by property.xxxx=foo and the bean
associated with the plugin would parse out the property. part of any keys
and add it to new Map before setting it in the bus while ignoring all that
don't have such property. prepended. Initially I'd thought of having the
other plugins remove entries that are associated with them but think that
may create more problems than it helps. 

public class LoggingBusConfiguratorPluginTest {

	BusConfiguratorPlugin plugin;
	Bus bus;
	Map<String,Object> properties;

	@Before
	public void init() {
		bus = mock(Bus.class);
		plugin = new LoggingBusConfiguratorPlugin();

	
		when(bus.getInInterceptors()).thenReturn(new ArrayList<Interceptor&lt;?
extends Message>>());
		when(bus.getInFaultInterceptors()).thenReturn(new
ArrayList<Interceptor&lt;? extends Message>>());
		when(bus.getOutInterceptors()).thenReturn(new ArrayList<Interceptor&lt;?
extends Message>>());
		when(bus.getOutFaultInterceptors()).thenReturn(new
ArrayList<Interceptor&lt;? extends Message>>());

		
		properties = new HashMap<String,Object>();
		properties.put("errorLogIn", "true");
		properties.put("errorLogOut", "true");
		properties.put("logOut", "true");
		properties.put("logIn", "true");

	}
	@Test
	public void testAllLoggingSet() {
		
		plugin.init(bus, properties);
		assertEquals(1,bus.getInFaultInterceptors().size());
		assertEquals(1,bus.getInInterceptors().size());
		assertEquals(1,bus.getOutFaultInterceptors().size());
		assertEquals(1,bus.getOutInterceptors().size());
		
	
assertEquals(bus.getInFaultInterceptors().get(0).getClass(),LoggingInInterceptor.class);
	
assertEquals(bus.getInInterceptors().get(0).getClass(),LoggingInInterceptor.class);		
	
assertEquals(bus.getOutFaultInterceptors().get(0).getClass(),LoggingOutInterceptor.class);
	
assertEquals(bus.getOutInterceptors().get(0).getClass(),LoggingOutInterceptor.class);

	}
	
	@Test
	public void testNoLoggingSet() {
		properties.clear();
		plugin.init(bus, properties);
		assertEquals(0,bus.getInFaultInterceptors().size());
		assertEquals(0,bus.getInInterceptors().size());
		assertEquals(0,bus.getOutFaultInterceptors().size());
		assertEquals(0,bus.getOutInterceptors().size());
		
				
	}
	
//Necessary as Jackson will set null on Boolean of the LoggingBean so the
LoggingBean has internal check in its setters.
	@Test
	public void testEmptyAndNull() {
		properties = new HashMap<String,Object>();
		properties.put("errorLogIn", "");
		properties.put("errorLogOut", null);
		properties.put("logOut", "");
		properties.put("logIn", null);
		plugin.init(bus, properties);
		
		assertEquals(0,bus.getInFaultInterceptors().size());
		assertEquals(0,bus.getInInterceptors().size());
		assertEquals(0,bus.getOutFaultInterceptors().size());
		assertEquals(0,bus.getOutInterceptors().size());
		
				
	}

}




--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Ranx0r0x <re...@bradleejohnson.com>.
Sounds like  a plan.

I'm working on plugin tests right now and I'll obviously have to revamp the
POM structure as I'm using a third party BOM for the dependency management.





--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by stefang <st...@me.com>.
Hi,

any Github-Link or bundle we can look at this?

Regards
Stefan




--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi,

You can already do it: you can take a look on the provided example.

Brad and I started a more generic implementation based on the current
examples.

Regards
JB

On 11/12/2019 10:20, stefang wrote:
> Hi,
> 
> we are very interested in this implementation.
> 
> JAX-RS-Whiteboard is unusable in combination with CXF because auf
> ClassCastExpections at the moment.
> 
> http://karaf.922171.n3.nabble.com/Problem-in-using-CXF-together-with-JAX-RS-Whiteboard-due-ClassCastException-td4057148.html
> 
> We must throw it out of our distribution and searching now a better solution
> with DS/scr with pure CXF
> 
> Stefan 
> 
>  
> 
> 
> 
> --
> Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html
> 

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Re: CXF Controllers...

Posted by stefang <st...@me.com>.
Hi,

we are very interested in this implementation.

JAX-RS-Whiteboard is unusable in combination with CXF because auf
ClassCastExpections at the moment.

http://karaf.922171.n3.nabble.com/Problem-in-using-CXF-together-with-JAX-RS-Whiteboard-due-ClassCastException-td4057148.html

We must throw it out of our distribution and searching now a better solution
with DS/scr with pure CXF

Stefan 

 



--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Ranx0r0x <re...@bradleejohnson.com>.
I've created a self-contained bundle with unit tests, JavaDoc and can share
that with you. I'm not sure  how that will tie into a parent POM or if it
might use BOM at some point but the bus-configurator-ds bundle is currently
such that you can simply import it into the IDE and run it self-contained.

There are question we can hammer out as we go forward.



--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
It sounds great !

What about sharing a git repository (fork of CXF) to work together on it ?

I can create on my github and add you as contributor on it. Then we will
create the PR with both authors.

Thoughts ?

Regards
JB

On 27/11/2019 17:55, Ranx0r0x wrote:
> I'd be very interested in seeing what you did. Obviously if a new standard
> way of doing DS is coming out then I wouldn't want to reinvent that.
> 
> For the Bus setup I now have a separate bundle that does this. When a cfg
> starting with org.apache.cxf.bus is added or changed, it triggers this and a
> Bus is added to the registry based on properties in the cfg. The plugins
> each have a configuration bean associated with them and Jackson is used to
> set values so that a lot of tedious null/empty string checking isn't
> required and defaults are set. For example, the logging is all set to False
> by default so if it isn't actually specified the logging simply isnt' set.
> 
> My cfg looks like this and in the endpoint set up I use an
> @Reference(target="(id=standard)") to inject it. I've verified that multiple
> busses can be created this way and that changing the values in the cfg
> trigger reinitialization that the endpoints pick up. For example, by putting
> a # before the jaasRealm it turns the security on and off.
> 
> Between the JAXRSConfiguration/JAXWSConfiguration factory with DS
> annotations mechanics that you provided and the CXF Bus configurator it's
> now possible to set all this up with Blueprint using simple DS.
> 
> I can share that project/bundle with you if you have any interest in it.
> 
> id=standard
> logIn=true
> logOut=true
> errorLogIn=true
> errorLogOut=true
> jaasRealm=karaf
> 
> @Component(
> 		service = Bus.class,
> 		configurationPid = "org.apache.cxf.bus",
> 		immediate=true
> )
> public class StandardBus extends ExtensionManagerBus implements Bus{
> 
> 	public StandardBus() {
> 		super(null, null, StandardBus.class.getClassLoader());
>     } 
> 
>     private List<BusConfiguratorPlugin> plugins = new
> ArrayList<BusConfiguratorPlugin>();
> 
>     private void initPlugins() {
> 		plugins.add(new BusIdentifierPlugin());
> 		plugins.add(new LoggingBusConfiguratorPlugin());
> 		plugins.add(new JAASAuthenticationBusConfiguratorPlugin());
> 		plugins.add(new PropertiesConfiguratorPlugin());
> 	}
> 	
> 
> 
> 	@Activate
> 	public void init(Map<String, Object> properties) {
> 		System.out.println("Activate Bus");
> 		initPlugins();
> 		init(this,properties);
> 	}
> 	@Modified
>     public void modified(Map<String, Object> properties) {
> 		System.out.println("Modified Bus");
> 		reset();
>         init(this,properties);
>     }
>  
>     @Deactivate
>     public void deactivate() {
>     	System.out.println("Deactivate Bus");
>     	
>     }
>     private void reset() {
> 		super.getInFaultInterceptors().clear();
> 		super.getInInterceptors().clear();
> 		super.getFeatures().clear();
> 		super.getOutFaultInterceptors().clear();
> 		super.getOutInterceptors().clear();
> 		super.getProperties().clear();
>     }
>     
>     private void init(Bus bus,Map<String, Object> properties) {
>     	plugins.forEach((plugin) -> plugin.init(bus, properties));
>     }
>     
> 
>    
> }
> 
> 
> 
> --
> Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html
> 

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Re: CXF Controllers...

Posted by Ranx0r0x <re...@bradleejohnson.com>.
I'd be very interested in seeing what you did. Obviously if a new standard
way of doing DS is coming out then I wouldn't want to reinvent that.

For the Bus setup I now have a separate bundle that does this. When a cfg
starting with org.apache.cxf.bus is added or changed, it triggers this and a
Bus is added to the registry based on properties in the cfg. The plugins
each have a configuration bean associated with them and Jackson is used to
set values so that a lot of tedious null/empty string checking isn't
required and defaults are set. For example, the logging is all set to False
by default so if it isn't actually specified the logging simply isnt' set.

My cfg looks like this and in the endpoint set up I use an
@Reference(target="(id=standard)") to inject it. I've verified that multiple
busses can be created this way and that changing the values in the cfg
trigger reinitialization that the endpoints pick up. For example, by putting
a # before the jaasRealm it turns the security on and off.

Between the JAXRSConfiguration/JAXWSConfiguration factory with DS
annotations mechanics that you provided and the CXF Bus configurator it's
now possible to set all this up with Blueprint using simple DS.

I can share that project/bundle with you if you have any interest in it.

id=standard
logIn=true
logOut=true
errorLogIn=true
errorLogOut=true
jaasRealm=karaf

@Component(
		service = Bus.class,
		configurationPid = "org.apache.cxf.bus",
		immediate=true
)
public class StandardBus extends ExtensionManagerBus implements Bus{

	public StandardBus() {
		super(null, null, StandardBus.class.getClassLoader());
    } 

    private List<BusConfiguratorPlugin> plugins = new
ArrayList<BusConfiguratorPlugin>();

    private void initPlugins() {
		plugins.add(new BusIdentifierPlugin());
		plugins.add(new LoggingBusConfiguratorPlugin());
		plugins.add(new JAASAuthenticationBusConfiguratorPlugin());
		plugins.add(new PropertiesConfiguratorPlugin());
	}
	


	@Activate
	public void init(Map<String, Object> properties) {
		System.out.println("Activate Bus");
		initPlugins();
		init(this,properties);
	}
	@Modified
    public void modified(Map<String, Object> properties) {
		System.out.println("Modified Bus");
		reset();
        init(this,properties);
    }
 
    @Deactivate
    public void deactivate() {
    	System.out.println("Deactivate Bus");
    	
    }
    private void reset() {
		super.getInFaultInterceptors().clear();
		super.getInInterceptors().clear();
		super.getFeatures().clear();
		super.getOutFaultInterceptors().clear();
		super.getOutInterceptors().clear();
		super.getProperties().clear();
    }
    
    private void init(Bus bus,Map<String, Object> properties) {
    	plugins.forEach((plugin) -> plugin.init(bus, properties));
    }
    

   
}



--
Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html

Re: CXF Controllers...

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi,

Actually, it's pretty close to a CXF branch that I started.

What I did is a CxfRsTemplate and CxfWsTemplate wrapper that "wrap/hide"
basically the code I did in the examples.

I removed blueprint dependency in CXF thanks for those templates and I'm
about proposing this change to the CXF community.

I can share what I did with you.

Regards
JB

On 27/11/2019 16:08, Ranx0r0x wrote:
> I'm not sure if this is of interest but I took JB's examples of CXF in DS and
> created some fluent wrappers around them. There are probably more delegate
> methods that could be added. In any case, the controllers simplify the set
> up and tear down and adding new interceptors, providers, features and
> properties. 
> 
> I've used a similar mechanism in the past for standing up webservices in
> unit tests with mock back ends. The impl class implements an interface and
> that interface has annotations for both REST and SOAP services on it. 
> 
> Separately I have a DS class that bootstraps new Bus instances based on cfg
> files (akin to the PAX JDBC mechanism) and currently specifies logging
> behavior, sets properties and will use a JAAS realm name to attach to Bus if
> desired. The Bus configuration mechanism uses plugins so is easily expanded
> to add new properties/interceptors/providers/features. 
> 
> CXF sans Blueprint.
> 
> @Activate
> public void activate() throws Exception {
> 	Foo fooServiceImpl=new Foo();
> 		
> 
> wsController.setAddress("/ws/foo").setBus(bus).setServiceBean(fooServiceImpl).start();
> 
> rsController.setAddress("/rs/foo").setBus(bus).setServiceBean(fooServiceImpl).start();
> 
> }
> @Deactivate
> public void deactivate() {
> 	rsController.stop();
> 	wsController.stop();
> }
> 
> }
> @Reference(target="(id=standard)")
> public void setBus(Bus bus) {
> 	this.bus = bus;
> }
> <snip>
> public class WSController {
> 	private JaxWsServerFactoryBean serverFactory = new
> JaxWsServerFactoryBean();
> 	private Server server;
> 	
> 	public WSController setAddress(String url) {
> 		serverFactory.setAddress(url);
> 		return this;
> 	}
> 	
> 	public WSController setServiceInterface(Class clazz) {
> 		 serverFactory.setServiceClass(clazz);
> 		 return this;
> 		 
> 	}
> 	
> 	public WSController setServiceBean(Object serviceBean) {
> 		serverFactory.setServiceBean(serviceBean);
> 		return this;
> 	}
> 	public WSController setBus(Bus bus) {
> 		serverFactory.setBus(bus);
> 		return this;
> 	}
> 	
> 	public WSController start() {
> 		server = serverFactory.create();
> 		return this;
> 	}
> 	
> 	public WSController stop() {
> 		server.destroy();
> 		return this;
> 	}
> 	public WSController addOutFaultInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getOutFaultInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public WSController addOutInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getOutInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public WSController addInInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getInInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public WSController addInFaultInterceptors(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getInFaultInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public WSController addFeature(Feature feature) {
> 		serverFactory.getFeatures().add(feature);
> 		return this;
> 	}
> 	
> 	public WSController addProperties(Map<String,Object> properties) {
> 		serverFactory.getProperties().putAll(properties);
> 		return this;
> 	}
> }
> 
> 
> public class RSController {
> 	private JAXRSServerFactoryBean serverFactory = new
> JAXRSServerFactoryBean();
> 	private Server server;
> 
> 	public RSController setAddress(String url) {
> 		serverFactory.setAddress(url);
> 		return this;
> 	}
> 	
> 	public RSController setServiceBean(Object serviceBean) {
> 		serverFactory.setServiceBean(serviceBean);
> 		return this;
> 	}
> 	public RSController setBus(Bus bus) {
> 		serverFactory.setBus(bus);
> 		return this;
> 	}
> 	
> 	public RSController start() {
> 		server = serverFactory.create();
> 		return this;
> 	}
> 	
> 	public RSController stop() {
> 		server.destroy();
> 		return this;
> 	}
> 	public RSController addOutFaultInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getOutFaultInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public RSController addOutInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getOutInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public RSController addInInterceptor(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getInInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public RSController addInFaultInterceptors(Interceptor<? extends Message>
> interceptor) {
> 		serverFactory.getInFaultInterceptors().add(interceptor);
> 		return this;
> 	}
> 	public RSController addFeature(Feature feature) {
> 		serverFactory.getFeatures().add(feature);
> 		return this;
> 	}
> 	
> 	public RSController addProperties(Map<String,Object> properties) {
> 		serverFactory.getProperties().putAll(properties);
> 		return this;
> 	}
> }
> 
> 
> 
> --
> Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html
> 

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com