package platform.context; import model.interfaces.control.IControlUnit; import platform.servicesregister.ServiceClosedException; import platform.servicesregister.ServiceInUseException; import platform.servicesregister.ServicesRegisterManager; import platform.context.hostsurveillance.HostLoadWatcher; import network.platform.PlatformMessagesEmitter; import network.platform.PlatformMessagesReceptor; import network.NetworkEmitterContainer; import network.NetworkReceptorContainer; import util.NetworkAddress; import network.platform.NetworkPlatformMessage; import java.util.Timer; import util.Parameters; import platform.context.status.HostStatus; /** * Manages all context information of the platform. * For the moment only sends alarm to a referent PF (deplyment/reconfiguration module). * @author Dalmau */ public class ContextManager extends Thread { private HostLoadWatcher mesureCharge; // processus lance par timer // a intervalles reguliers pour mesurer l'etat de l'hote // memoire libre, charge CPU et niveau de batterie private Timer surveillance; // timer utilise pour surveiller la charge de l'hote private NetworkAddress referent; // adresse de la PF a laquelle signaler les evenements // on prendra la derniere PF qui a cree un composant ou un connecteur sur cet hote // sauf pour les commandes de creation d'extremite de connecteur // car elles ont transmise par l'hote qui a recu la demande de creation // et non par une PF. private int portReferent; // numero de port par lequel envoyer a la PF referente private NetworkAddress relaisReferent; // adresse de l'hote auquel signaler les evenements // dans le cas ou l'on n'a pas de PF redferente private int portRelaisReferent; // numero de port par lequel envoyer a cette PF private PlatformMessagesEmitter emetteurDeMessages; private PlatformMessagesReceptor receptionMessages; private NetworkEmitterContainer networkEmitterContainer; private NetworkReceptorContainer networkReceptorContainer; private boolean enMarche; /** * Collects all context information comming from: * connectors * BCs * Host surveillance * Network */ public ContextManager() { try { // enregistrer le service de gestion du contexte ServicesRegisterManager.registerService(Parameters.CONTEXT_MANAGER, this); } catch (ServiceInUseException mbiue) { System.err.println("Context Manager service created twice"); } } /** * Used to indicate the platform to send context information to * @param expediteur address of the platform to send context information to * @param portEnvoi port number used to send this context information */ public void setReferentPlatform(String expediteur, int portEnvoi) { // Pour le moment on n'accepte comme PF de reference que le module de deploiement/reconfiguration if (portEnvoi == 1098) { referent = new NetworkAddress(expediteur); // la PF a laquelle signaler les evenements portReferent = portEnvoi; // le port sur lequel les envoyer } else setRelayReferentPlatform(expediteur, portEnvoi); } /** * Used to indicate a platform that can relays context information * @param expediteur address of the platform that can relays context information * @param portEnvoi port numbber to sent this context information to the relay platform */ public void setRelayReferentPlatform(String expediteur, int portEnvoi) { relaisReferent = new NetworkAddress(expediteur); portRelaisReferent = portEnvoi; // le port sur lequel les envoyer } /** * Performs context information. * For the moment this information is sent to a referent platform (deployment/reconfiguration module) * On ly to be displayed. * In later versions this information must be performed in order to decide reconfigurations. * * @param alarme alarm message to be sent */ public synchronized void signalEvent(ContextInformation alarme) { performEvent(alarme); } /** * Returns the QoS indicated by a BC (application or connector BC) * @param nom name of the component or connector * @return the QoS indicated by the component or connector */ public float getComponentQdS(String nom) { // recuperation de la valeur de QdS retournee par un CM (osagaia) // ou par un CM de transfert de flux (Korrontea) try { IControlUnit uc = (IControlUnit)(ServicesRegisterManager.lookForService(nom)); float rep=uc.sendBCQoSLevel(); // acces au service de l'UC return rep; // reponse obtenue } catch (ServiceClosedException sce) { //System.err.println("Lecture QdS "+nom+" : composant inconnu"); return -2f; } } /** * Returns the actual network traffic average for a given connector (in KB/s) * @param nom name of the connector * @return the actual network traffic average for this connector (in KB/s) */ public int getConnectorTrafficAverage(String nom) { try { IControlUnit uc = (IControlUnit)(ServicesRegisterManager.lookForService(nom)); if (uc instanceof model.korrontea.ControlUnit) { return (int)(((model.korrontea.ControlUnit)uc).getDebitMoyen())/Parameters.LOAD_MEASURE_RATE; } else return 0; } catch (ServiceClosedException sce) { //System.err.println("Lecture QdS "+nom+" : composant inconnu"); return 0; } } /** * Returns the actual CPU load (in %) * @return the actual CPU load (in %) */ public int getCpuLoad() { return mesureCharge.getCPULoad(); } /** * Returns the actual amount of free memory (in %) * @return the actual amount of free memory (in %) */ public int getMemoryLoad() { return mesureCharge.getFreeMemory(); } /** * Returns the actual battery level (in %) * @return the actual battery level (in %) */ public int getBatteryLevel() { return mesureCharge.getBatteryLevel(); } /** * Returns the actual number of running threads * @return the actual number of running threads */ public int getNumberOfThreads() { return mesureCharge.getThreadsActifs(); } /** * Gets the network input trafic for the platform (in KB/s) * @return the network input trafic for the platform (in KB/s) */ public int getPFInputTrafic() { return mesureCharge.getNetworkPlatformReceptions(); } /** * Gets the network output trafic for the platform (in KB/s) * @return the network output trafic for the platform (in KB/s) */ public int getPFOutputTrafic() { return mesureCharge.getNetworkPlatformEmissions(); } /** * GEts the network output trafic for the application ie all connectors (in KB/s) * @return the network output trafic for the application ie all connectors (in KB/s) */ public int getApplicationOutputTrafic() { return mesureCharge.getNetworkConnectorsEmissions(); } /** * Gets the network input trafic for the application ie all connectors (in KB/s) * @return the network input trafic for the application ie all connectors (in KB/s) */ public int getApplicationInputTrafic() { return mesureCharge.getNetworkConnectorsReceptions(); } /** * Gets the actual complete host status (see HostStatus for details) * @return the actual complete host status */ public HostStatus getHostStatus() { return new HostStatus(); } /** * Returns the actual host state (CPU, memory, battery, threads) * @return the actual host state (CPU, memory, battery, threads) */ public String getHostState() { return new HostStatus().toMessage(); } /** * Starts the contaext manager: start listening to events (internal and network received) */ public void startThread() { // Recherche du service d'envoi de messages de la PF networkEmitterContainer = (NetworkEmitterContainer)ServicesRegisterManager.platformWaitForService(Parameters.NETWORK_EMISSIONS_CONTAINER); emetteurDeMessages = networkEmitterContainer.getPlatformMessagesEmitter(); networkReceptorContainer = (NetworkReceptorContainer)ServicesRegisterManager.platformWaitForService(Parameters.NETWORK_RECEPTIONS_CONTAINER); receptionMessages = networkReceptorContainer.getPlatformMessagesReceptor(); receptionMessages.inscription(Parameters.CONTEXT_MANAGER); // Lancer la surveillance de l'hote mesureCharge = new HostLoadWatcher(this, networkEmitterContainer, networkReceptorContainer); surveillance = new Timer(); surveillance.scheduleAtFixedRate(mesureCharge, Parameters.LOAD_MEASURE_RATE, Parameters.LOAD_MEASURE_RATE); start(); } /** * Stops the context manager */ public void stopThread() { surveillance.cancel(); mesureCharge.cancel(); enMarche = false; receptionMessages.desinscription(Parameters.CONTEXT_MANAGER); } /** * Waiting for context information comming from networks * This information is performed like local one */ @Override public void run() { enMarche = true; while (enMarche) { // La PF peut etre arretee par stopThread // traitement des alarmes recues par reseau String infoDeContexte = null; NetworkPlatformMessage recu=null; // Attendre une commande sur le reseau recu = receptionMessages.retirerMessage(Parameters.CONTEXT_MANAGER); if ((recu != null) && (enMarche)) { infoDeContexte = recu.getContent(); // recuperer la chaine de cars contenant l'alarme recue if (infoDeContexte != null) { // si on a recu une info de contexte signalEvent(new ContextInformation(infoDeContexte+" from: "+recu.getExpeditorAddress())); } } } } private void performEvent(ContextInformation alarme) { if (enMarche) { System.out.println("ContextManager performing event :"+alarme.getInformation()); if (referent!=null) { // envoyer le message par reseau a la PF referente NetworkPlatformMessage envoi = new NetworkPlatformMessage(Parameters.CONTEXT_MANAGER, referent.getNormalizedAddress()); envoi.setPortNumber(portReferent); envoi.addContent(alarme.getInformation()); emetteurDeMessages.postDirectMessage(envoi); System.out.println("ContextManager event :"+alarme.getInformation()+" sended to: "+referent.getNormalizedAddress()+":"+portReferent); } else { // si on n'a pas de PF referente // envoyer le message par reseau un hote qui fera relais si on en a un if (relaisReferent!=null) { NetworkPlatformMessage reponse = new NetworkPlatformMessage(Parameters.CONTEXT_MANAGER, relaisReferent.getNormalizedAddress()); reponse.setPortNumber(portRelaisReferent); reponse.addContent(alarme.getInformation()); emetteurDeMessages.postDirectMessage(reponse); System.out.println("ContextManager event :"+alarme.getInformation()+" sended to: "+relaisReferent.getNormalizedAddress()+":"+portRelaisReferent); } } } } }