/**
* pSHIELD
* Service Composition
*
* @authors Davide Migliacci, Vincenzo Suraci
* Department of System and Computer Science (DIS)
* University of Rome "Sapienza"
* Via Ariosto, 25
* 00184, Rome, IT
*
* Updated on 19-May-2011
* Version 1.0
*
*/
package eu.artemis.shield.composition.compositionmanager.impl;
/**
*
* The present class shows how a pSHIELD OSGi component
* could use the potentiality offered by the pSHIELD
* Service Discovery Framework. It interfaces with the
* Generic Discovery Manager to discover the services
* available in the (pSHIELD) network.
*/
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import eu.artemis.shield.composition.compositionmanager.ICompositionManager;
import eu.artemis.shield.discovery.gdm.interfaces.IGenericDiscovery;
import eu.artemis.shield.discovery.pdm.IService;
import eu.artemis.shield.discovery.pdm.IServiceList;
import eu.artemis.shield.discovery.pdm.IServiceProperty;
import eu.artemis.shield.discovery.pdm.IServicePropertyList;
public class CM implements ICompositionManager
{
private BundleContext bc;
private CMGUI gui = null;
private final int API_TYPE = 1;
private final int IMPL_TYPE = 2;
int SPD_lvl;
private Vector impl_bundles_to_start = new Vector();
private IGenericDiscovery gd = null;
public CM(BundleContext bc)
{
this.bc = bc;
gui = new CMGUI(bc,this);
gui.setVisible(true);
}
/**
* This function takes an Api Bundle symbolic name and create its Impl Bundle symbolic name.
* @param bundleApiName Symbolic API name
* @return Symbolic IMPL name
*/
private String getBundleImplName(String bundleApiName)
{
int indexStart = bundleApiName.lastIndexOf(".");
int indexEnd = bundleApiName.lastIndexOf("-");
if (indexEnd > 0){
String bundleImplName = bundleApiName.substring(indexStart+1, indexEnd) + "-IMPL";
return bundleImplName;
}
else
// SLP Bundle
return bundleApiName.substring(1, bundleApiName.length()-1)+"-IMPL";
}
private Bundle installApi( Hashtable ht, String bundle_type, HashMap security ) {
Vector implBundleNames = new Vector();
String initial_impl_bundle = ((String) ( (Vector) ht.get("Project Name")).elementAt(0))+"-IMPL";
// Display counter
int j = 1;
// Get the imported api
Vector imp_packages = ( Vector ) ht.get( "Import" );
gui.append("\n");
gui.appendts("Installing Import Api of " + initial_impl_bundle);
boolean found = false;
Iterator it = imp_packages.iterator();
// For each import bundle
while ( it.hasNext() ){
found = false;
String imp_package = ( String ) it.next();
gui.append("\n");
gui.appendts ("API : " + j++ + "/" + imp_packages.size() + " - looking for : " + imp_package );
// Get all installed bundles in the framework
Bundle[] installed_bundles = bc.getBundles();
if ( installed_bundles != null ) {
// For each installed bundle
for ( int i = 0; i < installed_bundles.length; i++ ) {
Bundle temp = ( Bundle ) installed_bundles[i];
Dictionary bundle_manifest = temp.getHeaders();
// Check the exported bundles of the only API Bundles
if ( bundle_manifest.get( "Bundle-Category" ) != null && bundle_manifest.get( "Bundle-Category" ).equals( "API" ) ) {
String imported_packages = ( String ) bundle_manifest.get( "Export-Package" );
// If there is an installed bundle that export the requested package, we can procede whit the other requested packages
if ( imported_packages.contains( imp_package ) ) {
gui.appendts("The installed bundle [" + bundle_manifest.get( "Bundle-Name" ) +"] exports the requested package.");
String name_bundle_found = getBundleImplName( ( String ) bundle_manifest.get( "Bundle-Symbolicname" ) );
if( !name_bundle_found.equals( initial_impl_bundle ) ){
// Add the IMPL bundle Symbolic Name into the vector if security level is satisfied
implBundleNames.add( name_bundle_found );
}
found = true;
break;
}
}
}
// If there aren't installed bundle that export the requested package, we need to search one in the SLP
if ( !found ) {
gui.appendts("There aren't installed bundles that export the requested package : " + imp_package);
gui.appendts("Trying to search the package into the SLP...");
Vector bundles = getBundleByExportedPackage( imp_package, bundle_type, API_TYPE );
if( bundles != null && !bundles.isEmpty()) {
Iterator it2 = bundles.iterator();
// Use the first package founded
if ( it2.hasNext() ){
Hashtable ht_tmp = (Hashtable) it2.next();
gui.appendts ( "Found : " + ht_tmp.get( "Service Name" ).toString() );
gui.appendts ( "> It exports : " + ht_tmp.get( "Export" ).toString() + "\n");
Bundle tmp = installBundle( ht_tmp );
if ( tmp != null ){
gui.appendts ( tmp.getSymbolicName() + " : Installation completed." );
String name_bundle_found = getBundleImplName( ht_tmp.get( "Project Name" ).toString() );
String service_name = ht_tmp.get("Project Name").toString().substring(1,ht_tmp.get("Project Name").toString().length()-1 );
if( !name_bundle_found.equals( initial_impl_bundle ) ){
// Add the IMPL bundle Symbolic Name into the vector
if (security.containsKey(service_name)){
gui.appendts("Security Level" + security.get("Cryptography") + " " + security.get("Accounting") + "\n" );
gui.appendts("Security Level" + (Integer)ht_tmp.get("SPD Level"));
}
implBundleNames.add( name_bundle_found );
}
} else {
gui.appendts ( "ERR: Installation aborted !!!" );
}
}
} else {
gui.appendts ( "ERR: There aren't available bundles in SLP that export the " + imp_package + " package" );
}
}
}
}
if ( installImpl( implBundleNames, bundle_type, security ) ){
gui.appendts ( initial_impl_bundle + " import installation completed.\n" );
}
else{
gui.appendts ( initial_impl_bundle + " import installation aborted.\n" );
return null;
}
Bundle bundle_inst = installBundle( ht );
if ( bundle_inst != null ){
gui.appendts ( "IMPL installed : " + ht.get( "Service Name" ) );
} else {
gui.appendts ( "IMPL installation ABORTED : " + ht.get( "Service Name" ) );
return null;
}
return bundle_inst;
}
/**
* This function installs
* @param bundles_name
* @param bundle_type
* @return
*/
private boolean installImpl( Vector bundles_name, String bundle_type, HashMap parameter ){
Bundle tmp = null;
Iterator it = bundles_name.iterator();
int y = 1;
// For each import bundle
while ( it.hasNext() ){
boolean found = false;
String impl_bundle = ( String ) it.next();
gui.appendts ("IMPL : " + y++ + "/" + bundles_name.size() + " - looking for : " + impl_bundle );
// Get all installed bundles in the framework
Bundle[] installed_bundles = bc.getBundles();
if ( installed_bundles != null ) {
// For each installed bundle
for ( int i = 0; i < installed_bundles.length; i++ ) {
tmp = ( Bundle ) installed_bundles[i];
Dictionary bundle_manifest = tmp.getHeaders();
// Check the IMPL bundles
if ( bundle_manifest.get( "Bundle-Category" ) == null ) {
String imp_bundles = ( String ) bundle_manifest.get( "Bundle-Symbolicname" );
// If there is an installed bundle that export the requested package, we can procede whit the other requested packages
if ( imp_bundles != null && imp_bundles.contains( impl_bundle ) ) {
gui.appendts ( "The installed bundle [" + bundle_manifest.get( "Bundle-Name" ) +"] implements the requested bundle." );
impl_bundles_to_start.add( tmp );
}
else found = false;
}
}
}
// If there aren't installed bundle that implements the requested package, we need to search one in the SLP
if ( !found ) {
gui.appendts ( "There aren't installed bundles that implements the requested package : " + impl_bundle );
gui.appendts ( "Trying to search the package into the SLP...\n" );
Vector bundles = getBundleByExportedPackage( impl_bundle, bundle_type, IMPL_TYPE );
if( bundles != null && !bundles.isEmpty()) {
Iterator it2 = bundles.iterator();
// Use the first package founded
if ( it2.hasNext() ){
Hashtable ht = (Hashtable) it2.next();
gui.appendts ( "Found : " + ht.get( "Service Name" ).toString() );
gui.appendts ( "> It implements : " + impl_bundle + "\n");
tmp = installApi( ht, bundle_type, parameter );
if ( tmp != null ){
gui.appendts ( "Installation completed." );
impl_bundles_to_start.add( tmp );
} else {
gui.appendts ( "ERR: Installation aborted !!!" );
return false;
}
}
} else {
gui.appendts ( "ERR: There aren't available bundles in SLP that implement the " + impl_bundle );
return false;
}
}
}
return true;
}
/**
* This function try to install and run a bundle from its jar url
*/
public void runBundle ( Hashtable bundle_properties, int level, HashMap bundles){
String bundle_name = ( String ) ( ( Vector ) bundle_properties.get( "Service Name" ) ).elementAt(0) ;
String bundle_jar_url = ( String ) ( ( Vector ) bundle_properties.get( "Jar Url" ) ).elementAt(0) ;
String bundle_type = ( String ) ( ( Vector ) bundle_properties.get( "Type" ) ).elementAt(0);
Integer bundle_security = (Integer)((Vector) bundle_properties.get("SPD Level")).elementAt(0);
Bundle initial_bundle = installApi ( bundle_properties, bundle_type, bundles );
Iterator it = impl_bundles_to_start.iterator();
int y = 1;
while ( it.hasNext() ){
Bundle tmp = ( Bundle ) it.next();
gui.append( "[" + y++ + "]" );
try{
tmp.start();
} catch (Exception e){
gui.appendts ( "ERR: Run command aborted !!!" );
System.out.println ( e.getMessage() );
}
}
if ( initial_bundle != null ){
Dictionary bundle_manifest = initial_bundle.getHeaders();
Integer parameter = (Integer) ( ( Vector ) bundle_properties.get( "SPD Level" ) ).elementAt(0);
String s = (String) bundle_manifest.get("Bundle-Name");
gui.appendts ( "Initial bundle installed." );
gui.appendts ( "Running : " + bundle_properties.get( "Service Name" ) );
try
{
initial_bundle.start();
} catch (Exception e){
gui.appendts ( "ERR: Run command aborted !!!" );
System.out.println ( e.getMessage() );
}
} else {
gui.appendts ( "ERR: Run command aborted !!!" );
}
}
/**
* This function install the bundle using its JAR URL
* @param hashtable of the bundle to be installed
* @return the bundle if the installation is completed, null if the installation crashed
*/
private Bundle installBundle ( Hashtable bundle ){
// Try to install the selected bundle from its jar url
try{
gui.appendts("Trying to install "+ bundle.get( "Service Name" ) +" from its JAR URL...");
Bundle b = bc.installBundle( ( ( String ) ( (Vector) bundle.get( "Jar Url" ) ).elementAt(0) ) );
return b;
}catch (Exception e){
System.out.println( e.getCause() );
return null;
}
}
/**
* @authors Davide Migliacci, Vincenzo Suraci
*
* This function try to discover a bundle that exports the requested package
*
* @param package_name : The name of the requested package
* @param service_type : The service type
* @param bundle_type : The bundle type ( API or IMPL ) to find
* @return : A vector of Hashtables. One Hashtable for each founded bundle that exports the requested package. Return null if there are not bundles
*/
private Vector getBundleByExportedPackage (String package_name, String service_type, int bundle_type)
{
Vector services = serviceDiscovery(service_type, null, false);
Vector services_discovered = new Vector();
if ( services != null && !services.isEmpty() ) {
Iterator it = services.iterator();
// For each API bundles available into the SLP
while ( it.hasNext() ){
Hashtable ht = ( Hashtable ) it.next();
switch ( bundle_type ) {
case API_TYPE :
if ( ht.containsKey( "Export" ) && ht.containsKey( "Api" ) && ht.containsKey( "Impl" )
// Search only into the simple API Bundles and the API&IMPL Bundles
&& ( ( Boolean ) ( (Vector) ht.get( "Api" ) ).elementAt(0) ).booleanValue()
){
String exported_packages = ( String ) ( ( Vector ) ht.get( "Export" ) ).elementAt(0) ;
if ( exported_packages.contains( package_name ) ) {
services_discovered.add( ht );
}
}
break;
case IMPL_TYPE :
if ( ht.containsKey( "Export" ) && ht.containsKey( "Api" ) && ht.containsKey( "Impl" )
// Search only into the simple API Bundles and the API&IMPL Bundles
&& ( ( Boolean ) ( (Vector) ht.get( "Impl" ) ).elementAt(0) ).booleanValue()
){
if ( ht.get( "Project Name" ) != null ){
String implement_packages = ( String ) ( ( Vector ) ht.get( "Project Name" ) ).elementAt(0) ;
if ( implement_packages.equals( package_name.substring(0, package_name.length()-5 ) ) ) {
services_discovered.add( ht );
}
}
}
break;
}
}
}
return services_discovered;
}
/**
* This function find the service available for a specified service type and an array of keywords to do a better filter
* @param type : the service type to search
* @param kw : an array of keywords to search
* @param filter_api : set false if you need all the available bundles, true if you want only the API bundles
* @return a vector of found services ( with no API bundles )
*/
private Vector serviceDiscovery(String type, String[] kw, boolean filter_api)
{
Vector discovered_services = new Vector();
try
{
gui.append("- Service discovery with a specified service type\n");
ServiceReference[] gdmList = findGenericDiscoveryModuleImplementations();
if (gdmList != null)
{
/*
* We ignore the possbility to have more than one GDM implementation.
* JUST USE THE FIRST ONE...
*/
gd = (IGenericDiscovery) bc.getService(gdmList[0]);
/*
* We are ready to start the discovery process!
*/
/*
* Set an array of keywords, useful to better filter
* the services
*/
if ( kw == null )
kw = new String[0];
//kw[0]="gui=false";
for(int i = 0; i<kw.length; i++)
{
gui.append("KEYWORDS " + i + "--> " + kw[i].toString() + "\n");
}
/*
* LET pSHIELD DISCOVER THE SERVICES
*/
gui.append("- Looking for Services ...");
// LinkedList ll = gd.findServices(vid, type, kw);
String CDQL =
"SELECT default" +
"FROM default" +
"SERVICETYPE " + type +
"LANGUAGE en_gb" +
"WHERE " +
"USING slp";
String SPARQL = "";
LinkedList query_output = null;
IServiceList sl = gd.findServices(CDQL, SPARQL, query_output);
if ( sl != null )
{
if ( sl.isEmpty() )
{
// NO SERVICES HAVE BEEN DISCOVERED
gui.append("- No services found !");
}
else
{
//Iterator it = sl.iterator();
//while (it.hasNext())
for (int i = 0; i < sl.size(); i++)
{
try
{
IService s = sl.getService(i);
String url = s.getOWLSURL();
System.out.println("service URL #" + i + " = " + url);
IServicePropertyList spl = s.getProperties();
Hashtable ht = new Hashtable();
for (int j=0; j<spl.size(); j++)
{
try
{
IServiceProperty sp = spl.getServiceProperty(j);
System.out.print("> attribute #" + j + " --> " + sp.getName() + "=");
Vector values = sp.getValues();
if (values != null)
{
for (int k=0; k<values.size(); k++)
{
Object obj = values.get(k);
if (obj != null)
{
if (k > 0) System.out.print(",");
System.out.print(obj.toString());
}
}
}
ht.put(sp.getName(), values);
System.out.println("");
}
catch (IndexOutOfBoundsException ioobe)
{
ioobe.printStackTrace();
}
}
if (ht.containsKey("Impl") && ht.containsKey("Api"))
{
if (filter_api)
{
boolean has_impl = ((Boolean)((Vector)ht.get("Impl")).elementAt(0)).booleanValue();
if (has_impl) discovered_services.add(ht);
}
else
{
// Insert an HashTable for each discovered service
discovered_services.add( ht );
}
}
}
catch (IndexOutOfBoundsException ioobe)
{
ioobe.printStackTrace();
}
}
}
}
else
{
//NO SERVICES HAVE BEEN DISCOVERED
gui.append("NO SERVICE FOUND!");
}
}
else
{
/*
* It was not possible to find a suitable implementation of IGenericDiscovery
*/
gui.append("No Bundles implement the IGenericDiscovery interface!\n");
}
}
catch (Exception e)
{
/*
* Something went wrong!
* It was not possible to find a suitable implementation of IGenericDiscovery
*/
gui.append(e.getMessage());
e.printStackTrace();
}
return discovered_services;
}
/**
* @author Vincenzo Suraci
*
* This function uses the internal OSGi service discovery to find a suitable implementation
* of the IGenericDiscovery interface.
*/
private ServiceReference[] findGenericDiscoveryModuleImplementations() throws Exception
{
ServiceReference[] gdmi = null;
try
{
gdmi = bc.getServiceReferences("eu.artemis.shield.discovery.gdm.interfaces.IGenericDiscovery", null);
}
catch (Exception e)
{
throw e;
}
return gdmi;
}
public void exit()
{
/*
* Close GUI
*/
gui.setVisible(false);
gui.dispose();
}
}
|