use of ch.ethz.iks.r_osgi.messages.LeaseUpdateMessage in project ecf by eclipse.
the class ChannelEndpointImpl method handleMessage.
/**
* message handler method.
*
* @param msg
* the incoming message.
* @return if reply is created, null otherwise.
* @throws RemoteOSGiException
* if something goes wrong.
*/
RemoteOSGiMessage handleMessage(final RemoteOSGiMessage msg) throws RemoteOSGiException {
trace("handleMessage(msg=" + msg + ";remoteAddress=" + networkChannel.getRemoteAddress() + ")");
switch(msg.getFuncID()) {
// requests
case RemoteOSGiMessage.LEASE:
{
final LeaseMessage lease = (LeaseMessage) msg;
processLease(lease);
populateLease(lease, RemoteOSGiServiceImpl.getServices(networkChannel.getProtocol()), RemoteOSGiServiceImpl.getTopics());
return lease;
}
case RemoteOSGiMessage.REQUEST_SERVICE:
{
final RequestServiceMessage reqSrv = (RequestServiceMessage) msg;
final String serviceID = reqSrv.getServiceID();
final RemoteServiceRegistration reg = getServiceRegistration(serviceID);
final DeliverServiceMessage m = reg.getDeliverServiceMessage();
m.setXID(reqSrv.getXID());
m.setServiceID(reqSrv.getServiceID());
return m;
}
case RemoteOSGiMessage.LEASE_UPDATE:
{
final LeaseUpdateMessage suMsg = (LeaseUpdateMessage) msg;
final String serviceID = suMsg.getServiceID();
final short stateUpdate = suMsg.getType();
final String serviceURI = getRemoteAddress().resolve("#" + serviceID).toString();
switch(stateUpdate) {
case LeaseUpdateMessage.TOPIC_UPDATE:
{
// There is an older r-OSGi version that incorrectly sends an ArrayList
// (1.0.0.RC4_v20131016-1848)
Object topicsAdded = suMsg.getPayload()[0];
if (topicsAdded instanceof List) {
topicsAdded = ((List) topicsAdded).toArray(new String[0]);
}
Object topicsRemoved = suMsg.getPayload()[1];
if (topicsRemoved instanceof List) {
topicsRemoved = ((List) topicsRemoved).toArray(new String[0]);
}
updateTopics((String[]) topicsAdded, (String[]) topicsRemoved);
return null;
}
case LeaseUpdateMessage.SERVICE_ADDED:
{
final Dictionary properties = (Dictionary) suMsg.getPayload()[1];
sanitizeServiceProperties(properties, serviceURI);
final RemoteServiceReferenceImpl ref = new RemoteServiceReferenceImpl((String[]) suMsg.getPayload()[0], serviceID, properties, this);
remoteServices.put(serviceURI, ref);
RemoteOSGiServiceImpl.notifyRemoteServiceListeners(new RemoteServiceEvent(RemoteServiceEvent.REGISTERED, ref));
return null;
}
case LeaseUpdateMessage.SERVICE_MODIFIED:
{
final Dictionary properties = (Dictionary) suMsg.getPayload()[1];
sanitizeServiceProperties(properties, serviceURI);
final ServiceRegistration reg = (ServiceRegistration) proxiedServices.get(serviceID);
if (reg != null) {
reg.setProperties(properties);
}
// $NON-NLS-1$
final RemoteServiceReferenceImpl ref = getRemoteReference(serviceURI);
// (see https://bugs.eclipse.org/420433)
if (ref == null && reg == null) {
return null;
}
ref.setProperties(properties);
RemoteOSGiServiceImpl.notifyRemoteServiceListeners(new RemoteServiceEvent(RemoteServiceEvent.MODIFIED, ref));
return null;
}
case LeaseUpdateMessage.SERVICE_REMOVED:
{
if (networkChannel == null) {
return null;
}
final RemoteServiceReference ref = (RemoteServiceReference) remoteServices.remove(serviceURI);
if (ref != null) {
RemoteOSGiServiceImpl.notifyRemoteServiceListeners(new RemoteServiceEvent(RemoteServiceEvent.UNREGISTERING, ref));
}
final Bundle bundle = (Bundle) proxyBundles.remove(serviceID);
if (bundle != null) {
try {
bundle.uninstall();
} catch (final BundleException be) {
be.printStackTrace();
}
proxiedServices.remove(serviceID);
// $NON-NLS-1$
remoteServices.remove(serviceURI);
}
return null;
}
}
return null;
}
case RemoteOSGiMessage.REMOTE_CALL:
{
final RemoteCallMessage invMsg = (RemoteCallMessage) msg;
try {
RemoteServiceRegistration serv = (RemoteServiceRegistration) localServices.get(invMsg.getServiceID());
if (serv == null) {
final RemoteServiceRegistration reg = getServiceRegistration(invMsg.getServiceID());
if (reg == null) {
throw new IllegalStateException(toString() + "Could not get " + // $NON-NLS-1$
invMsg.getServiceID() + ", known services " + // $NON-NLS-1$
localServices);
} else {
serv = reg;
}
}
// get the invocation arguments and the local method
final Object[] arguments = invMsg.getArgs();
for (int i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof InputStreamHandle) {
arguments[i] = getInputStreamProxy((InputStreamHandle) arguments[i]);
} else if (arguments[i] instanceof OutputStreamHandle) {
arguments[i] = getOutputStreamProxy((OutputStreamHandle) arguments[i]);
}
}
final Method method = serv.getMethod(invMsg.getMethodSignature());
// invoke method
try {
Object result = method.invoke(serv.getServiceObject(), arguments);
final RemoteCallResultMessage m = new RemoteCallResultMessage();
m.setXID(invMsg.getXID());
Class returnType = method.getReturnType();
if (result instanceof InputStream) {
m.setResult(getInputStreamPlaceholder((InputStream) result));
} else if (result instanceof OutputStream) {
m.setResult(getOutputStreamPlaceholder((OutputStream) result));
} else if (serv.isOSGiAsync() && AsyncReturnUtil.isAsyncType(returnType)) {
m.setResult(AsyncReturnUtil.convertAsyncToReturn(result, returnType, serv.getOSGiTimeout()));
} else
m.setResult(result);
return m;
} catch (final InvocationTargetException t) {
t.printStackTrace();
throw t.getTargetException();
}
} catch (final Throwable t) {
// TODO: send to log
t.printStackTrace();
final RemoteCallResultMessage m = new RemoteCallResultMessage();
m.setXID(invMsg.getXID());
m.setException(t);
return m;
}
}
case RemoteOSGiMessage.REMOTE_EVENT:
{
final RemoteEventMessage eventMsg = (RemoteEventMessage) msg;
final Dictionary properties = eventMsg.getProperties();
// transform the event timestamps
final Long remoteTs;
if ((remoteTs = (Long) properties.get(EventConstants.TIMESTAMP)) != null) {
properties.put(EventConstants.TIMESTAMP, getOffset().transform(remoteTs));
}
final Event event = new Event(eventMsg.getTopic(), properties);
// and deliver the event to the local framework
if (RemoteOSGiServiceImpl.eventAdminTracker.getTrackingCount() > 0) {
((EventAdmin) RemoteOSGiServiceImpl.eventAdminTracker.getService()).postEvent(event);
} else {
// TODO: to log
System.err.println(// $NON-NLS-1$
"Could not deliver received event: " + event + // $NON-NLS-1$
". No EventAdmin available.");
}
return null;
}
case RemoteOSGiMessage.TIME_OFFSET:
{
// add timestamp to the message and return the message to sender
((TimeOffsetMessage) msg).timestamp();
return msg;
}
case RemoteOSGiMessage.STREAM_REQUEST:
{
final StreamRequestMessage reqMsg = (StreamRequestMessage) msg;
try {
// fetch stream object
final Object stream = streams.get(new Integer(reqMsg.getStreamID()));
if (stream == null) {
throw new IllegalStateException(// $NON-NLS-1$
"Could not get stream with ID " + reqMsg.getStreamID());
}
// invoke operation on stream
switch(reqMsg.getOp()) {
case StreamRequestMessage.READ:
{
final int result = ((InputStream) stream).read();
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult((short) result);
return m;
}
case StreamRequestMessage.READ_ARRAY:
{
final byte[] b = new byte[reqMsg.getLenOrVal()];
final int len = ((InputStream) stream).read(b, 0, reqMsg.getLenOrVal());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_ARRAY);
m.setLen(len);
if (len > 0) {
m.setData(b);
}
return m;
}
case StreamRequestMessage.WRITE:
{
((OutputStream) stream).write(reqMsg.getLenOrVal());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_WRITE_OK);
return m;
}
case StreamRequestMessage.WRITE_ARRAY:
{
((OutputStream) stream).write(reqMsg.getData());
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_WRITE_OK);
return m;
}
default:
throw new RemoteOSGiException(// $NON-NLS-1$
"Unimplemented op code for stream request " + msg);
}
} catch (final IOException e) {
final StreamResultMessage m = new StreamResultMessage();
m.setXID(reqMsg.getXID());
m.setResult(StreamResultMessage.RESULT_EXCEPTION);
m.setException(e);
return m;
}
}
case RemoteOSGiMessage.REQUEST_BUNDLE:
final RequestBundleMessage reqB = (RequestBundleMessage) msg;
try {
final String serviceID = reqB.getServiceID();
final RemoteServiceRegistration reg = getServiceRegistration(serviceID);
final byte[] bytes = RemoteOSGiServiceImpl.getBundle(reg.getReference().getBundle());
final DeliverBundlesMessage delB = new DeliverBundlesMessage();
delB.setXID(reqB.getXID());
delB.setDependencies(new byte[][] { bytes });
return delB;
} catch (IOException ioe) {
ioe.printStackTrace();
return null;
}
case RemoteOSGiMessage.REQUEST_DEPENDENCIES:
final RequestDependenciesMessage reqDeps = (RequestDependenciesMessage) msg;
try {
final byte[][] bundleBytes = RemoteOSGiServiceImpl.getBundlesForPackages(reqDeps.getPackages());
final DeliverBundlesMessage delDeps = new DeliverBundlesMessage();
delDeps.setXID(reqDeps.getXID());
delDeps.setDependencies(bundleBytes);
return delDeps;
} catch (IOException ioe) {
ioe.printStackTrace();
return null;
}
default:
// $NON-NLS-1$
throw new RemoteOSGiException("Unimplemented message " + msg);
}
}
use of ch.ethz.iks.r_osgi.messages.LeaseUpdateMessage in project ecf by eclipse.
the class RemoteOSGiServiceImpl method setupTrackers.
private void setupTrackers(final BundleContext context) throws IOException {
// initialize service trackers
eventAdminTracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
eventAdminTracker.open();
if (eventAdminTracker.getTrackingCount() == 0 && log != null) {
log.log(LogService.LOG_WARNING, // $NON-NLS-1$
"NO EVENT ADMIN FOUND. REMOTE EVENT DELIVERY TEMPORARILY DISABLED.");
}
try {
eventHandlerTracker = new ServiceTracker(context, context.createFilter(// $NON-NLS-1$ //$NON-NLS-2$
"(&(" + Constants.OBJECTCLASS + "=" + EventHandler.class.getName() + // $NON-NLS-1$
")(|(!(" + R_OSGi_INTERNAL + // $NON-NLS-1$
"=*))" + // https://bugs.eclipse.org/418740
"(!(" + // $NON-NLS-1$
EventConstants.EVENT_TOPIC + // $NON-NLS-1$
"=org/osgi/service/remoteserviceadmin/*))))"), new ServiceTrackerCustomizer() {
public Object addingService(final ServiceReference reference) {
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326033
Collection theTopics;
Object topic = reference.getProperty(EventConstants.EVENT_TOPIC);
if (topic instanceof String)
theTopics = Arrays.asList(new String[] { (String) topic });
else
theTopics = Arrays.asList((String[]) topic);
// Remove filtered topics
theTopics = StringUtils.rightDifference(topicFilters, theTopics);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.TOPIC_UPDATE);
// $NON-NLS-1$
lu.setServiceID("");
lu.setPayload(new Object[] { theTopics.toArray(new String[theTopics.size()]), null });
updateLeases(lu);
return theTopics;
}
public void modifiedService(final ServiceReference reference, final Object oldTopics) {
final List oldTopicList = (List) oldTopics;
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=326033
Collection newTopicList;
Object topic = reference.getProperty(EventConstants.EVENT_TOPIC);
if (topic instanceof String)
newTopicList = Arrays.asList(new String[] { (String) topic });
else
newTopicList = Arrays.asList((String[]) topic);
// Remove filtered topics
newTopicList = StringUtils.rightDifference(topicFilters, newTopicList);
final Collection removed = CollectionUtils.rightDifference(newTopicList, oldTopicList);
final Collection added = CollectionUtils.leftDifference(newTopicList, oldTopicList);
final String[] addedTopics = (String[]) added.toArray(new String[removed.size()]);
final String[] removedTopics = (String[]) removed.toArray(addedTopics);
oldTopicList.removeAll(removed);
oldTopicList.addAll(added);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.TOPIC_UPDATE);
// $NON-NLS-1$
lu.setServiceID("");
lu.setPayload(new Object[] { addedTopics, removedTopics });
updateLeases(lu);
}
public void removedService(final ServiceReference reference, final Object oldTopics) {
final List oldTopicsList = (List) oldTopics;
final String[] removedTopics = (String[]) oldTopicsList.toArray(new String[oldTopicsList.size()]);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.TOPIC_UPDATE);
// $NON-NLS-1$
lu.setServiceID("");
lu.setPayload(new Object[] { null, removedTopics });
updateLeases(lu);
}
});
eventHandlerTracker.open();
if (DEBUG) {
log.log(LogService.LOG_DEBUG, // $NON-NLS-1$
"Local topic space " + Arrays.asList(getTopics()));
}
remoteServiceListenerTracker = new ServiceTracker(context, RemoteServiceListener.class.getName(), null);
remoteServiceListenerTracker.open();
serviceDiscoveryHandlerTracker = new ServiceTracker(context, ServiceDiscoveryHandler.class.getName(), new ServiceTrackerCustomizer() {
public Object addingService(final ServiceReference reference) {
// register all known services for discovery
final ServiceDiscoveryHandler handler = (ServiceDiscoveryHandler) context.getService(reference);
RemoteServiceRegistration[] regs = null;
synchronized (serviceRegistrations) {
regs = (RemoteServiceRegistration[]) serviceRegistrations.values().toArray(new RemoteServiceRegistration[serviceRegistrations.size()]);
}
for (int i = 0; i < regs.length; i++) {
handler.registerService(regs[i].getReference(), regs[i].getProperties(), URI.create(// $NON-NLS-1$
"r-osgi://" + RemoteOSGiServiceImpl.MY_ADDRESS + // $NON-NLS-1$
":" + RemoteOSGiServiceImpl.R_OSGI_PORT + // $NON-NLS-1$
"#" + regs[i].getServiceID()));
}
return handler;
}
public void modifiedService(final ServiceReference reference, final Object service) {
}
public void removedService(final ServiceReference reference, final Object service) {
}
});
serviceDiscoveryHandlerTracker.open();
remoteServiceTracker = new ServiceTracker(context, context.createFilter(// $NON-NLS-1$
"(" + RemoteOSGiService.R_OSGi_REGISTRATION + "=*)"), new // $NON-NLS-1$
ServiceTrackerCustomizer() {
public Object addingService(final ServiceReference reference) {
// FIXME: Surrogates have to be monitored
// separately!!!
final ServiceReference service = Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)).contains(SurrogateRegistration.class.getName()) ? (ServiceReference) reference.getProperty(SurrogateRegistration.SERVICE_REFERENCE) : reference;
try {
final RemoteServiceRegistration reg = new RemoteServiceRegistration(reference, service);
if (log != null) {
log.log(LogService.LOG_INFO, // $NON-NLS-1$
"REGISTERING " + reference + // $NON-NLS-1$
" AS PROXIED SERVICES");
}
synchronized (serviceRegistrations) {
serviceRegistrations.put(service, reg);
}
registerWithServiceDiscovery(reg);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.SERVICE_ADDED);
lu.setServiceID(String.valueOf(reg.getServiceID()));
lu.setPayload(new Object[] { reg.getInterfaceNames(), reg.getProperties() });
updateLeases(lu);
return service;
} catch (final ClassNotFoundException e) {
e.printStackTrace();
throw new RemoteOSGiException("Cannot find class " + service, // $NON-NLS-1$
e);
}
}
public void modifiedService(final ServiceReference reference, final Object service) {
if (reference.getProperty(R_OSGi_REGISTRATION) == null) {
removedService(reference, service);
return;
}
final RemoteServiceRegistration reg = (RemoteServiceRegistration) serviceRegistrations.get(reference);
registerWithServiceDiscovery(reg);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.SERVICE_MODIFIED);
lu.setServiceID(String.valueOf(reg.getServiceID()));
lu.setPayload(new Object[] { null, reg.getProperties() });
updateLeases(lu);
}
public void removedService(final ServiceReference reference, final Object service) {
final ServiceReference sref = Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)).contains(SurrogateRegistration.class.getName()) ? (ServiceReference) reference.getProperty(SurrogateRegistration.SERVICE_REFERENCE) : reference;
final RemoteServiceRegistration reg = (RemoteServiceRegistration) serviceRegistrations.remove(sref);
unregisterFromServiceDiscovery(reg);
final LeaseUpdateMessage lu = new LeaseUpdateMessage();
lu.setType(LeaseUpdateMessage.SERVICE_REMOVED);
lu.setServiceID(String.valueOf(reg.getServiceID()));
lu.setPayload(new Object[] { null, null });
updateLeases(lu);
}
});
remoteServiceTracker.open(true);
networkChannelFactoryTracker = new ServiceTracker(context, context.createFilter(// $NON-NLS-1$ //$NON-NLS-2$
"(" + Constants.OBJECTCLASS + "=" + NetworkChannelFactory.class.getName() + ")"), new // $NON-NLS-1$
ServiceTrackerCustomizer() {
public Object addingService(final ServiceReference reference) {
final NetworkChannelFactory factory = (NetworkChannelFactory) context.getService(reference);
try {
factory.activate(RemoteOSGiServiceImpl.this);
} catch (final IOException ioe) {
if (log != null) {
log.log(LogService.LOG_ERROR, ioe.getMessage(), ioe);
}
}
return factory;
}
public void modifiedService(final ServiceReference reference, final Object factory) {
}
public void removedService(final ServiceReference reference, final Object factory) {
}
});
networkChannelFactoryTracker.open();
} catch (final InvalidSyntaxException ise) {
ise.printStackTrace();
}
}
Aggregations