Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [ice-dev] Enabling ConnectCoreAction

Hi Ram and Jay,

I noticed this too so I just created a RSCoreConnectAction class (based upon your CoreConnectAction class) that uses an EDEF template to connect to and import the ICore remote service.

To create the EDEF template, I added this code to the Core.class in the activator, *before* the ICore remote service is registered (line 257 and 258 on 2.2.1 branch):

        //Setup RSA debug output
        bundleContext.registerService(RemoteServiceAdminListener.class,new DebugRemoteServiceAdminListener(), null);

With this in place, when the ICore remote service is registered in the Core OSGi server the EDEF is output to System.out as below via the DebugRemoteServiceAdminListener. 

Once started on the host, I copied this EDEF and put it in a template file named /edef/rscore.xml inside the org.eclipse.ice.client bundle.   When the RSCoreConnectAction.run() method is invoked...see RSCoreConnectAction.run()...the /edef/rscore.xml is read, the user-provided hostname and port are substituted in the appropriate endpoint description property, and then the RemoteServiceAdmin.importService(endpointDescription) is called to connect to the ICore remote host, and create and register the ICore remote service proxy.  

When this happens (inside the RSA.importService call), the client has an ICore proxy in it's service registry and with DS it will then be automatically injected.  See the class RSCore.bindCore for an example of having the ICore remote service injected by DS.  

I'll be happy to put all this into a single patch, if that's how you would prefer.  Or if you would rather just take the appropriate snippets that would be fine.  Just let me know how you would like to handle.

Note that currently the Core class exports via the ECF generic provider (rather than r-osgi).   It's not a big deal to change both the remote service host and consumer to use either the r-osgi provider, or other providers (e.g. the Jersey Jax-RS provider).

Have a good Thanksgiving.

Scott

EDEF System.out on host when ICore is registered and exported as remote service:
<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">
    <endpoint-description>
        <property name="ecf.endpoint.id" value-type="String"
            value="ecftcp://localhost:57072/server" />
        <property name="ecf.endpoint.id.ns" value-type="String"
            value="org.eclipse.ecf.core.identity.StringID" />
        <property name="ecf.endpoint.ts" value-type="Long" value="1479948680285" />
        <property name="ecf.rsvc.id" value-type="Long" value="0" />
        <property name="endpoint.framework.uuid" value-type="String"
            value="e052c618-e0b1-0016-1552-845201c2682d" />
        <property name="endpoint.id" value-type="String"
            value="26d50b6b-bc66-4e04-91cf-dd656c8f7b56" />
        <property name="endpoint.service.id" value-type="Long" value="0" />
        <property name="objectClass" value-type="String">
            <array>
                <value>org.eclipse.ice.core.iCore.ICore</value>
            </array>
        </property>
        <property name="remote.configs.supported" value-type="String">
            <array>
                <value>ecf.generic.server</value>
            </array>
        </property>
        <property name="remote.intents.supported" value-type="String">
            <array>
                <value>passByValue</value>
                <value>exactlyOnce</value>
                <value>ordered</value>
            </array>
        </property>
        <property name="service.imported" value-type="String" value="true" />
        <property name="service.imported.configs" value-type="String">
            <array>
                <value>ecf.generic.server</value>
            </array>
        </property>
    </endpoint-description>
</endpoint-descriptions>

On 11/23/2016 8:05 AM, Ramachandran K. Narayanan wrote:
Hello Jay,

I was looking at enabling ConnectCoreAction locally, based on what we had discussed earlier. I enabled this in ClientActionBarAdvisor.makeActions. This is in turn used by ClientWorkbenchWindowAdvisor.

But this class doesn't seem to be used anywhere else. Any breakpoints within this class are also not hit when I use the product_linux.launch file. Looking in this class further, it almost seems like a separate UI that is launched. Any ideas on how I can take it further?

Thanks,
Ram


--
Ramachandran K. Narayanan
(Ram)
Software Engineer
RNET Technologies Inc.
240 W.Elmwood Drive, Suite 2010
Dayton, OH 45459-4248


_______________________________________________
ice-dev mailing list
ice-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/ice-dev


<?xml version="1.0" encoding="UTF-8"?>
<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0";>
	<endpoint-description>
		<property name="ecf.endpoint.id" value-type="String"
			value="ecftcp://localhost:57072/server" />
		<property name="ecf.endpoint.id.ns" value-type="String"
			value="org.eclipse.ecf.core.identity.StringID" />
		<property name="ecf.endpoint.ts" value-type="Long" value="1479948680285" />
		<property name="ecf.rsvc.id" value-type="Long" value="0" />
		<property name="endpoint.framework.uuid" value-type="String"
			value="e052c618-e0b1-0016-1552-845201c2682d" />
		<property name="endpoint.id" value-type="String"
			value="26d50b6b-bc66-4e04-91cf-dd656c8f7b56" />
		<property name="endpoint.service.id" value-type="Long" value="0" />
		<property name="objectClass" value-type="String">
			<array>
				<value>org.eclipse.ice.core.iCore.ICore</value>
			</array>
		</property>
		<property name="remote.configs.supported" value-type="String">
			<array>
				<value>ecf.generic.server</value>
			</array>
		</property>
		<property name="remote.intents.supported" value-type="String">
			<array>
				<value>passByValue</value>
				<value>exactlyOnce</value>
				<value>ordered</value>
			</array>
		</property>
		<property name="service.imported" value-type="String" value="true" />
		<property name="service.imported.configs" value-type="String">
			<array>
				<value>ecf.generic.server</value>
			</array>
		</property>
	</endpoint-description>
</endpoint-descriptions>
package org.eclipse.ice.client.internal;

import org.eclipse.ice.core.iCore.ICore;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;

@Component(immediate=true)
public class RSCore {

	private static RemoteServiceAdmin rsa;
	private static ICore remoteCore;
	
	@Reference
	void bindRemoteServiceAdmin(RemoteServiceAdmin r) {
		rsa = r;
	}
	
	void unbindRemoteServiceAdmin(RemoteServiceAdmin r) {
		rsa = null;
	}
	
	public static RemoteServiceAdmin getRSA() {
		return rsa;
	}
	
	@Reference(policy=ReferencePolicy.DYNAMIC,cardinality=ReferenceCardinality.MULTIPLE,target="(service.imported=*)")
	public void bindCore(ICore core) {
		remoteCore = core;
		System.out.println("Get item list returns="+remoteCore.getItemList());
	}
	
	public void unbindCore(ICore core) {
		remoteCore = null;
	}
	
	public static ICore getCore() {
		return remoteCore;
	}
}
/*******************************************************************************
 * Copyright (c) 2012, 2014 UT-Battelle, LLC, 2016 Composent, Inc..
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Initial API and implementation and/or initial documentation - Jay Jay Billings,
 *   Jordan H. Deyton, Dasha Gorin, Alexander J. McCaskey, Taylor Patterson,
 *   Claire Saunders, Matthew Wang, Anna Wojtowicz
 *   Scott Lewis - Composent, Inc.
 *******************************************************************************/
package org.eclipse.ice.client.common;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ecf.osgi.services.remoteserviceadmin.EndpointDescriptionReader;
import org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.ImportRegistration;
import org.eclipse.ice.client.internal.Client;
import org.eclipse.ice.client.internal.RSCore;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.osgi.framework.Bundle;
import org.osgi.service.remoteserviceadmin.EndpointDescription;

public class RSCoreConnectAction extends Action implements ISelectionListener, IWorkbenchAction {

	// Handle to the workbench window
	private final IWorkbenchWindow workbenchWindow;

	// Action ID - for internal use
	public static final String ID = "org.eclipse.ice.client.common.RSCoreConnectAction";

	// CoreConnectDialog that presents a login screen
	// to the user
	private CoreConnectDialog login;

	// Constructor
	public RSCoreConnectAction(IWorkbenchWindow window) {

		// Local Declarations
		Bundle bundle = null;
		Path serverPath = null;
		URL serverImageURL = null;
		ImageDescriptor serverImage = null;

		// Find the client bundle
		bundle = Platform.getBundle("org.eclipse.ice.client.widgets");

		// Create the image descriptor for the create item action
		serverPath = new Path("icons/server.gif");
		serverImageURL = FileLocator.find(bundle, serverPath, null);
		serverImage = ImageDescriptor.createFromURL(serverImageURL);

		// Set the action ID, Menu Text, and a tool tip.
		workbenchWindow = window;
		setId(ID);
		setText("&Connect to Core...");
		setToolTipText("Open connection to Core with " + "hostname and port...");
		setImageDescriptor(serverImage);

		// Add this class as a listener to the window events
		workbenchWindow.getSelectionService().addSelectionListener(this);

		return;
	}

	@Override
	public void dispose() {
		this.workbenchWindow.getSelectionService().removeSelectionListener(this);
	}

	@Override
	public void run() {
		// Create a new CoreConnectDialog to prompt for login credentials
		login = new CoreConnectDialog(new Shell(PlatformUI.getWorkbench().getDisplay()), "localhost", null);
		// Open the Dialog
		login.open();

		importViaGenericServer("/edef/rscore.xml", login.getHostname(), login.getPort());
	}

	void importViaGenericServer(String edefTemplateFile, String hostname, String port) {
		// Use completable future so that this doesn't block UI thread
		CompletableFuture.supplyAsync(new Supplier<ImportRegistration>() {
			@Override
			public ImportRegistration get() {
				ImportRegistration reg = null;
				try {
					// Get endpoint description template
					URL url = Client.getDefault().getContext().getBundle().getEntry(edefTemplateFile);
					// Read using EndpointDescriptionReader into
					// EndpointDescription instance
					EndpointDescription ed = new EndpointDescriptionReader()
							.readEndpointDescriptions(url.openStream())[0];
					// Get copy of the properties from endpoint description
					Map<String, Object> props = new HashMap<String, Object>(ed.getProperties());
					// change property
					props.put("ecf.endpoint.id", "ecftcp://" + hostname + ":" + port + "/server");
					// import using RSA. This is where all the work happens...i.e. connection,
					// creation of proxy, registration of proxy in local service registry
					reg = (ImportRegistration) RSCore.getRSA().importService(new EndpointDescription(props));
					// Check if exception occurred and if so, throw
					Throwable t = reg.getException();
					if (t != null)
						throw t;
				} catch (Throwable t) {
					throw new RuntimeException("Exception importing Core remote service", t);
				}
				return reg;
			}
		}).whenComplete((ir, e) -> {
			// when complete, if there was exception
			// then print stack trace (would normally notify user also)
			if (e != null)
				e.printStackTrace();
		});

	}

	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
	}

}

Back to the top