blob: 8434dc9afac088e33f7d053ce91560270c7403d7 [file] [log] [blame]
/****************************************************************************
* Copyright (c) 2009 Composent, Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*****************************************************************************/
package org.eclipse.ecf.internal.examples.loadbalancing.servicehost;
import java.util.Properties;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.IContainerManager;
import org.eclipse.ecf.examples.loadbalancing.IDataProcessor;
import org.eclipse.ecf.remoteservice.Constants;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainerAdapter;
import org.eclipse.ecf.remoteservice.IRemoteServiceRegistration;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
public class DataProcessorServiceHostApplication implements IApplication {
private static final String LB_SVCHOST_CONTAINER_TYPE = "ecf.jms.activemq.tcp.manager.lb.svchost";
public static final String DEFAULT_QUEUE_ID = "tcp://localhost:61616/exampleQueue";
private static final String DEFAULT_TOPIC_ID = "tcp://localhost:61616/exampleTopic";
private BundleContext bundleContext;
private ServiceTracker containerManagerServiceTracker;
private String containerType = LB_SVCHOST_CONTAINER_TYPE;
// JMS Queue URI that we will attach to as queue message producer (to issue
// actual remote method/invocation
// requests to server consumers). Note that this queueId can be changed by
// using the -queueId launch parameter...e.g.:
// -queueId tcp://myjmdnsbrokerdnsname:61616/myQueueName
private String queueId = DEFAULT_QUEUE_ID;
// JMS topic URI that we will register remote service registrations on...
// so that service consumers can lookup/get/use remote services. Note that
// this
// topicId can be changed by using the -topicId launch parameter...e.g.
// -topicId tcp://myjmdnsbrokerdnsname:61616/myTopicName
private String topicId = DEFAULT_TOPIC_ID;
// Container instance that connects us with the ActiveMQ queue as a message
// producer and publishes the service on the topicId
private IContainer container;
// The service host remote service registration. This is used simply to
// unregister the service when this application is stopped
private IRemoteServiceRegistration dataProcessorServiceHostRegistration;
public Object start(IApplicationContext appContext) throws Exception {
bundleContext = Activator.getContext();
// Process Arguments...i.e. set queueId and topicId if specified, otherwise use defaults
processArgs(appContext);
// Create container of appropriate type, and with the topicId and
// queueId set
// upon construction
container = getContainerManagerService().getContainerFactory()
.createContainer(containerType,
new Object[] { topicId, queueId });
// Get IRemoteServiceContainerAdapter
IRemoteServiceContainerAdapter remoteServiceAdapter = (IRemoteServiceContainerAdapter) container
.getAdapter(IRemoteServiceContainerAdapter.class);
Properties properties = new Properties();
// This is setting (currently) magical service property that indicates
// that
// this service registration is a load balancing service host
properties.put(Constants.SERVICE_REGISTER_PROXY, "true");
// Register the remote service with the IDataProcessor interface as it's
// service registration.
// Note that the Constants.SERVICE_REGISTER_PROXY allows null to be specified
// as the registered remote service implementation.
// This object does not implement the IDataProcessor service interface,
// but it is not actually used. Rather,
// the LOAD_BALANCING_SERVICE_PROPERTY set to "true" specifies that for
// this container the remote service
// requests are proxied and forwarded to the JMS queue (where they are
// load balanced among the n servers
// that are consumers from that queue)
dataProcessorServiceHostRegistration = remoteServiceAdapter
.registerRemoteService(new String[] { IDataProcessor.class
.getName() }, null, properties);
System.out.println("LB Service Host: DataProcessor Registered via ECF Remote Services topic="+topicId);
// wait for remote service requests until stopped
waitForDone();
return IApplication.EXIT_OK;
}
public void stop() {
if (dataProcessorServiceHostRegistration != null) {
dataProcessorServiceHostRegistration.unregister();
dataProcessorServiceHostRegistration = null;
}
if (container != null) {
container.dispose();
container = null;
getContainerManagerService().removeAllContainers();
}
if (containerManagerServiceTracker != null) {
containerManagerServiceTracker.close();
containerManagerServiceTracker = null;
}
bundleContext = null;
synchronized (appLock) {
done = true;
appLock.notifyAll();
}
}
private void processArgs(IApplicationContext appContext) {
String[] originalArgs = (String[]) appContext.getArguments().get(
"application.args");
if (originalArgs == null)
return;
for (int i = 0; i < originalArgs.length; i++) {
if (originalArgs[i].equals("-queueId")) {
queueId = originalArgs[i + 1];
i++;
} else if (originalArgs[i].equals("-topicId")) {
topicId = originalArgs[i + 1];
i++;
} else if (originalArgs[i].equals("-containerType")) {
containerType = originalArgs[i + 1];
i++;
}
}
}
private IContainerManager getContainerManagerService() {
if (containerManagerServiceTracker == null) {
containerManagerServiceTracker = new ServiceTracker(bundleContext,
IContainerManager.class.getName(), null);
containerManagerServiceTracker.open();
}
return (IContainerManager) containerManagerServiceTracker.getService();
}
private final Object appLock = new Object();
private boolean done = false;
private void waitForDone() {
// then just wait here
synchronized (appLock) {
while (!done) {
try {
appLock.wait();
} catch (InterruptedException e) {
// do nothing
}
}
}
}
}