[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ecf-dev] Using a container multiple times

Found the problem.
I was listening for a ContainerConnectedEvent to trigger a lookup of
the service on the IRemoteServiceContainerAdapter

The trouble was that the IRemoteServiceContainerAdapter of course
listens for a ContainerConnectedEvent before initialising with the
remote server.

So when if my handler was being handled first, then there was nothing
on the IRemoteServiceContainerAdapter to find yet.

Solved by using a IRemoteServiceListener on the IRemoteServiceContainerAdapter:

container = manager.getContainerFactory().createContainer("ecf.generic.client");
ID id = IDFactory.getDefault().createID(container.getConnectNamespace(),
uri.toString());
final IRemoteServiceContainerAdapter rsc =
(IRemoteServiceContainerAdapter) ((IAdaptable)
container).getAdapter(IRemoteServiceContainerAdapter.class);
rsc.addRemoteServiceListener(new IRemoteServiceListener() {

	@Override
	public void handleServiceEvent(IRemoteServiceEvent event) {
	String[] clazzes = event.getClazzes();
	boolean quit = false;
	for (int i = 0; quit = false && i < clazzes.length; i++)
		quit = clazzes[i].equals(StateProvider.class.getName());
	if (quit){
	IRemoteServiceReference ref = event.getReference();
	StateProvider provider = (StateProvider) rsc.getRemoteService(ref);
	Map<String, Object> state = provider.provideState();
	syncBundles(state);
												}
});

final ISharedObjectContainer soc = (ISharedObjectContainer)
((IAdaptable) container).getAdapter(ISharedObjectContainer.class);
soc.addListener(new IContainerListener() {

	@Override
	public void handleEvent(IContainerEvent event) {
	if (event instanceof IContainerConnectedEvent)
	try {
		ISharedObjectManager manager = soc.getSharedObjectManager();
		EventAdmin admin = new DistributedEventAdmin(context);
		ID id1 = IDFactory.getDefault().createStringID("uk.co.xlegal.xbundle3.remote");
		Properties props = new Properties();
		props.put(EventConstants.EVENT_TOPIC, "uk_co_xlegal_xbundle3_remote");
		manager.addSharedObject(id1, (ISharedObject) admin, props);
		((DistributedEventAdmin) admin).start();
		} catch (Exception e) {
														Log.log(Log.ERROR, e.getMessage());
		}
container.connect(id, null);

...

Thus I have got a SharedObject and a Remote Service off the same container.

Thanks, Scott. And hope this helps other ECF newbies.

Robert

On Thu, Nov 4, 2010 at 9:48 PM, Scott Lewis <slewis@xxxxxxxxxxxxx> wrote:
> Hi Robert,
>
> On 11/4/2010 2:35 PM, Robert Onslow wrote:
>>
>> Scott
>> I have decided to go with the ECF method at the moment, because it
>> gives me more control over discovery etc. and I can also like to
>> retain responsibility for creating the container
>>
>> So on the client side, I will wait for the container connection, then
>> pick up the shared object, then pick up the remote service:
>>
>> container =
>> manager.getContainerFactory().createContainer("ecf.generic.client");
>> container.addListener(new IContainerListener() {
>>
>> @Override
>> public void handleEvent(IContainerEvent event) {
>>        if (event instanceof IContainerConnectedEvent)
>>        try {
>> ID id = IDFactory.getDefault().createID(container.getConnectNamespace(),
>> uri.toString());
>> //pick up the shared object
>>
>> ISharedObjectContainer soc =
>> (ISharedObjectContainer) ((IAdaptable)
>> container).getAdapter(ISharedObjectContainer.class);
>>
>>
>>
>>                              ISharedObjectManager manager =
>> soc.getSharedObjectManager();
>> EventAdmin admin = new DistributedEventAdmin(context);
>> ID id1 =
>> IDFactory.getDefault().createStringID("uk.co.xlegal.xbundle3.remote");
>> Properties props = new Properties();
>> props.put(EventConstants.EVENT_TOPIC, "uk_co_xlegal_xbundle3_remote");
>> manager.addSharedObject(id1, (ISharedObject) admin, props);
>> ((DistributedEventAdmin) admin).start();
>>
>> //now pick up the remote service
>>
>> IRemoteServiceContainerAdapter rsc = (IRemoteServiceContainerAdapter)
>> ((IAdaptable) container).getAdapter(IRemoteServiceContainerAdapter.class);
>>
>>                                      IRemoteServiceReference[] refs =
>> rsc.getRemoteServiceReferences(((IContainerConnectedEvent)
>> event).getTargetID(), StateProvider.class.getName(), null);
>> StateProvider provider = (StateProvider) rsc.getRemoteService(refs[0]);
>> Map<String, Object>  state = provider.provideState();
>> syncBundles(state);
>>
>>
>> } catch (Exception e) {
>>
>>                                      Log.log(Log.ERROR, e.getMessage());
>> }
>> }
>> });
>> container.connect(id, null);
>>
>> I'm finding that refs is null. Looking inside rsc, I see that the
>> remoteRegistry array is empty.
>> Have I missed a step in initialising the
>> IRemoteServiceContainerAdapter on the client side?
>
> I don't think so...I think probably the issue is that you should use this
> lookup method (note the ID[] first param, rather than ID):
>
> IRemoteServiceReference[] refs =
> rsc.getRemoteServiceReferences(new ID[] { ((IContainerConnectedEvent)
> event).getTargetID() }, StateProvider.class.getName(), null);
>
> I have other commitments right now so can't explain at the moment, but I
> suspect that this will deal with this situation.
>
> Scott
>
>
> _______________________________________________
> ecf-dev mailing list
> ecf-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/ecf-dev
>



-- 
Robert Onslow
XLegal Limited