package org.societies.api.internal.servicelifecycle; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; import org.eclipse.osgi.internal.signedcontent.Base64; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import org.societies.api.comm.xmpp.interfaces.ICommManager; import org.societies.api.identity.IIdentity; import org.societies.api.identity.InvalidFormatException; import org.societies.api.internal.servicelifecycle.IServiceDiscovery; import org.societies.api.osgi.event.EMSException; import org.societies.api.osgi.event.EventTypes; import org.societies.api.osgi.event.IEventMgr; import org.societies.api.osgi.event.InternalEvent; import org.societies.api.schema.servicelifecycle.model.Service; import org.societies.api.schema.servicelifecycle.model.ServiceImplementation; import org.societies.api.schema.servicelifecycle.model.ServiceInstance; import org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier; import org.societies.api.schema.servicelifecycle.model.ServiceType; import org.societies.api.services.ServiceMgmtEventType; /** * Collection of utility methods. * * @author <a href="mailto:sanchocsa@gmail.com">Sancho RĂªgo</a> (PTIN) * */ public class ServiceModelUtils extends org.societies.api.services.ServiceUtils{ private ServiceModelUtils() { super(); } /** * This method generates a Service object that can be used as a filter for the Service Discovery search methods. * * @return The Service filter object */ public static Service generateEmptyFilter(){ Service filter = new Service(); // Preparing the search filter filter.setAuthorSignature(null); filter.setServiceDescription(null); filter.setServiceEndpoint(null); filter.setServiceName(null); filter.setServiceStatus(null); filter.setServiceType(null); filter.setPrivacyPolicy(null); ServiceResourceIdentifier filterIdentifier = new ServiceResourceIdentifier(); filterIdentifier.setIdentifier(null); filterIdentifier.setServiceInstanceIdentifier(null); filter.setServiceIdentifier(filterIdentifier); ServiceInstance filterInstance = new ServiceInstance(); filterInstance.setFullJid(null); filterInstance.setXMPPNode(null); filterInstance.setCssJid(null); ServiceImplementation filterImplementation = new ServiceImplementation(); filterImplementation.setServiceVersion(null); filterImplementation.setServiceNameSpace(null); filterImplementation.setServiceProvider(null); filterImplementation.setServiceClient(null); filterInstance.setServiceImpl(filterImplementation); filter.setServiceInstance(filterInstance); return filter; } /** * This method is used to obtain the Bundle Id that corresponds to a given a Service * * @param The Service object whose bundle we wish to find * @param The bundleContext * @return The Bundle that exposes this service */ public static Bundle getBundleFromService(Service service, BundleContext bundleContext) { //Long bundleId = getBundleIdFromServiceIdentifier(service.getServiceIdentifier()); return bundleContext.getBundle(service.getServiceLocation()); } /** * This method is used to obtain the Service that is exposed by given Bundle * * @param The Bundle that exposes this service * @param A reference to IServiceDiscovery * @return The Service object whose bundle we wish to find */ public static Service getServiceFromBundle(Bundle bundle, IServiceDiscovery serviceDiscovery) { // Preparing the search filter Service filter = generateEmptyFilter(); filter.getServiceIdentifier().setServiceInstanceIdentifier(bundle.getSymbolicName()); filter.setServiceLocation(bundle.getLocation()); //filter.getServiceInstance().getServiceImpl().setServiceVersion(bundle.getVersion().toString()); List<Service> listServices = null; try { Future<List<Service>> asyncListServices = serviceDiscovery.searchServices(filter); listServices = asyncListServices.get(); } catch (Exception e) { e.printStackTrace(); } if(listServices == null || listServices.isEmpty()) return null; Service result = null; for(Service service: listServices){ String bundleSymbolic = service.getServiceIdentifier().getServiceInstanceIdentifier(); if(bundleSymbolic.equals(bundle.getSymbolicName())){ result = service; break; } } return result; } /** * This method is used to obtain the Service that is exposed by given Bundle * * @param The ServiceInstance of this service * @param A reference to IServiceDiscovery * @return The Service object */ public static Service getServiceFromServiceInstance(String serviceInstance, IServiceDiscovery serviceDiscovery) { // Preparing the search filter Service filter = generateEmptyFilter(); filter.getServiceIdentifier().setServiceInstanceIdentifier(serviceInstance); //filter.getServiceInstance().getServiceImpl().setServiceVersion(bundle.getVersion().toString()); List<Service> listServices = null; try { Future<List<Service>> asyncListServices = serviceDiscovery.searchServices(filter); listServices = asyncListServices.get(); } catch (Exception e) { e.printStackTrace(); } if(listServices == null || listServices.isEmpty()) return null; Service result = null; for(Service service: listServices){ if(service.getServiceIdentifier().getServiceInstanceIdentifier().equals(serviceInstance)){ result = service; break; } } return result; } /** * This method takes a Service Resource Identifier and returns the id of the bundle * * @param serviceId * @return the bundle Id public static Long getBundleIdFromServiceIdentifier(ServiceResourceIdentifier serviceId){ return Long.parseLong(serviceId.getServiceInstanceIdentifier()); } */ /** * This method returns the textual description of a Bundle state * * @param the state of the service * @return The textual description of the bundle's state */ public static String getBundleStateName(int state){ switch(state){ case Bundle.ACTIVE: return "ACTIVE"; case Bundle.INSTALLED: return "INSTALLED"; case Bundle.RESOLVED: return "RESOLVED"; case Bundle.STARTING: return "STARTING"; case Bundle.STOPPING: return "STOPPING"; case Bundle.UNINSTALLED: return "UNINSTALLED"; default: return null; } } /** * This method generates a Service Resource Identifier; it is meant to be used by third-party services * in order to determine their own SRI. * * @param identity The IIdentity of the node where this service is running * @param callingClass The service class * @return The SRI of the associated service */ public static ServiceResourceIdentifier generateServiceResourceIdentifier(IIdentity identity, java.lang.Class<?> callingClass){ // First we get the calling Bundle Bundle serviceBundle = FrameworkUtil.getBundle(callingClass); ServiceReference[] registeredService = serviceBundle.getRegisteredServices(); Service ourService = null; for(int i = 0; i < registeredService.length; i++){ ServiceReference regiServ = registeredService[i]; String property = (String) regiServ.getProperty("TargetPlatform"); if(property != null && property.equals("SOCIETIES")){ ourService = (Service) regiServ.getProperty("ServiceMetaModel"); break; } } ServiceResourceIdentifier result = new ServiceResourceIdentifier(); try { result.setIdentifier(new URI(identity.getJid()+'/'+ourService.getServiceName().replace(' ', '_'))); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } result.setServiceInstanceIdentifier(serviceBundle.getSymbolicName()); //result.setServiceInstanceIdentifier(value); return result; } /** * This method generates a ServiceResourceIdentifier given the ServiceBundle and the Service Model object * * @param service * @param serBndl * @return the ServiceResourceIdentifier */ public static ServiceResourceIdentifier generateServiceResourceIdentifier(Service service, Bundle serBndl){ // ***** To do ******** // some logic to map available meta data and xmpp service identity // and construct serviceResourceIdentity object // then pass return this object ServiceResourceIdentifier serResId=new ServiceResourceIdentifier(); try { serResId.setIdentifier(new URI(service.getServiceInstance().getFullJid()+'/'+ service.getServiceName().replace(' ', '_'))); //This next line is for solving https://redmine.ict-societies.eu/issues/619 serResId.setServiceInstanceIdentifier(serBndl.getSymbolicName()); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return serResId; } /** * This method determines if a service belongs to the current node * * @param service * @param commManager * @return true or false */ public static boolean isServiceOurs(Service service, ICommManager commManager){ try{ IIdentity ourNode = commManager.getIdManager().getThisNetworkNode(); IIdentity serviceNode = commManager.getIdManager().fromFullJid(getJidFromServiceIdentifier(service.getServiceIdentifier())); return ourNode.equals(serviceNode); } catch(Exception ex){ return false; } } public static ServiceResourceIdentifier generateServiceResourceIdentifierForDevice( Service service, String deviceId) { ServiceResourceIdentifier serResId=new ServiceResourceIdentifier(); try { serResId.setIdentifier(new URI(service.getServiceInstance().getFullJid()+"/"+ service.getServiceName().replace(' ', '_'))); //This next line is for solving https://redmine.ict-societies.eu/issues/619 serResId.setServiceInstanceIdentifier(deviceId); } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return serResId; } public static boolean hasClient(ServiceResourceIdentifier serviceId, IServiceDiscovery serviceDiscovery){ return !getClients(serviceId,serviceDiscovery).isEmpty(); } public static List<Service> getClients(ServiceResourceIdentifier service, IServiceDiscovery serviceDiscovery){ List<Service> clients = new ArrayList<Service>(); Service filter = generateEmptyFilter(); ServiceInstance serviceInstance = filter.getServiceInstance(); serviceInstance.setParentIdentifier(service); filter.setServiceInstance(serviceInstance); filter.setServiceType(ServiceType.THIRD_PARTY_CLIENT); try { Future<List<Service>> clientAsync = serviceDiscovery.searchServices(filter); clients = clientAsync.get(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return clients; } /** * This method converts a Service Resource Identifier into a Base64 encoded string. * * @param serviceId * @return */ public static String getServiceId64Encode(ServiceResourceIdentifier serviceId){ return new String(Base64.encode(serviceResourceIdentifierToString(serviceId).getBytes())); } /** * This method takes a Base64 Encoded string and converts it to a Service Resource Identifier * @param encoded64 * @return */ public static ServiceResourceIdentifier getServiceId64Decode(String encoded64){ return generateServiceResourceIdentifierFromString(new String(Base64.decode(encoded64.getBytes()))); } public static void sendServiceMgmtEvent(ServiceMgmtEventType eventType, Service service,IIdentity node, Bundle bundle, IEventMgr eventManager){ ServiceMgmtInternalEvent serviceEvent = new ServiceMgmtInternalEvent(); serviceEvent.setEventType(eventType); serviceEvent.setSharedNode(node); if(service != null){ serviceEvent.setServiceType(service.getServiceType()); serviceEvent.setServiceId(service.getServiceIdentifier()); serviceEvent.setServiceName(service.getServiceName()); if(!service.getServiceType().equals(ServiceType.DEVICE)){ serviceEvent.setBundleId(bundle.getBundleId()); serviceEvent.setBundleSymbolName(bundle.getSymbolicName()); } else{ serviceEvent.setBundleId(-1); serviceEvent.setBundleSymbolName(null); } } InternalEvent internalEvent = new InternalEvent(EventTypes.SERVICE_LIFECYCLE_EVENT, eventType.toString(), "org/societies/servicelifecycle", serviceEvent); try { eventManager.publishInternalEvent(internalEvent); } catch (EMSException e) { e.printStackTrace(); } } }