package scs.instrumentation.servant;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import scs.container.servant.ContainerServant;
import scs.core.AlreadyConnected;
import scs.core.ExceededConnectionLimit;
import scs.core.IComponent;
import scs.core.IReceptacles;
import scs.core.IReceptaclesHelper;
import scs.core.InvalidConnection;
import scs.core.NoConnection;
import scs.core.StartupFailed;
import scs.event_service.ChannelCollection;
import scs.event_service.ChannelCollectionHelper;
import scs.event_service.ChannelFactory;
import scs.event_service.ChannelFactoryHelper;
import scs.event_service.ChannelManagement;
import scs.event_service.ChannelManagementHelper;
import scs.event_service.EventSink;
import scs.event_service.NameAlreadyInUse;
import scs.instrumentation.InterfaceStats;
import scs.instrumentation.ContainerStats;
import scs.instrumentation.ContainerStatsHelper;
import scs.instrumentation.MethodStats;
import scs.instrumentation.StatsCollectionPOA;
import scs.instrumentation.app.LogSender;
import scs.instrumentation.ComponentStatsNotAvailable;
import scs.instrumentation.InterfaceStatsNotAvailable;
import scs.instrumentation.IOStatsNotAvailable;
import scs.instrumentation.NetworkStatsNotAvailable;
import scs.instrumentation.SystemIOStats;
import scs.instrumentation.SystemIOStatsHelper;
import scs.instrumentation.SystemNetworkStats;
import scs.instrumentation.SystemNetworkStatsHelper;
import system.SystemInformation;
import system.SystemInformation.IOStats;
import system.SystemInformation.NetworkStats;
/**
* Classe que implementa o servant da interface scs::instrumentation::StatsCollection.
* Funciona como um repositorio de estatisticas do container em que este classe �
* executada.
*
* Implementa o padrao singleton, pois pode ser usada do Interceptor.
*
* @author Eduardo Fonseca/Luiz Marques
*/
public class StatsCollectionServant extends StatsCollectionPOA {
private static StatsCollectionServant _instance = null;
IComponent eventMgr = null;
ChannelManagement chManagement = null;
/**
* Hash para controlar as conexoes de notificacao de chamadas de metodos
* Chave = nome da interface + metodo
* Valor = Connection ID
*/
HashMap<String, Integer> hashConnections = null;
public static StatsCollectionServant getInstance()
{
if(_instance == null)
{
_instance = new StatsCollectionServant();
}
return _instance;
}
ArrayList<InterfaceStats> componentsStats = new ArrayList<InterfaceStats>();
private ContainerStats containerStats;
private SystemIOStats systemIOStats;
private SystemNetworkStats systemNetworkStats;
private StatsCollectionServant()
{
containerStats = new ContainerStats();
systemIOStats = new SystemIOStats();
systemNetworkStats = new SystemNetworkStats();
containerStats.containerName = "";
hashConnections = new HashMap<String, Integer> ();
}
/**
* Monta o nome do canal, concatenando o nome do container, o nome da interface
* e o nome do metodo (separados por |).
*/
private String getChannelName( String iface, String method ) {
return( ContainerServant.getInstance().getName()
+ "|" + iface
+ "|" + method );
}
/**
* Monta o nome do canal usando o nome do container
*/
private String getChannelName(){
return( ContainerServant.getInstance().getName());
}
/**
* Retorna a estrutura contendo a estat�sticaso nome do canal, concatenando o nome do container, o nome da interface
* e o nome do metodo (separados por |).
*/
private MethodStats find(String interfaceName , String methodName )
{
MethodStats[] msArray =this.findByInterface(interfaceName);
if(msArray == null)
{
InterfaceStats cs = new InterfaceStats();
cs.interfaceName = interfaceName;
cs.methodStatsCollection = new MethodStats[1];
MethodStats newMs = new MethodStats();
newMs.callsCount = 0;
newMs.cpuTime = 0;
newMs.elapsedTime = 0;
newMs.methodName = methodName;
cs.methodStatsCollection[0] = newMs;
componentsStats.add(cs);
return newMs;
}
MethodStats ms = findByMetod(msArray, methodName);
if(ms == null)
{
msArray = insertIntoArray(msArray, methodName);
for (Iterator iter = componentsStats.iterator(); iter.hasNext();) {
InterfaceStats element = (InterfaceStats) iter.next();
if(element.interfaceName.equalsIgnoreCase(interfaceName))
{
element.methodStatsCollection = msArray;
}
}
return msArray[msArray.length -1];
}
return ms;
}
private MethodStats[] insertIntoArray(MethodStats[] msArray, String methodName)
{
MethodStats[] newMs = new MethodStats[msArray.length + 1];
System.arraycopy(msArray, 0, newMs, 0, msArray.length);
MethodStats ms = new MethodStats();
ms.callsCount = 0;
ms.cpuTime = 0;
ms.elapsedTime = 0;
ms.methodName = methodName;
newMs[newMs.length - 1] = ms;
return newMs;
}
private MethodStats[] findByInterface(String interfaceName)
{
for (Iterator iter = componentsStats.iterator(); iter.hasNext();) {
InterfaceStats element = (InterfaceStats) iter.next();
if(element.interfaceName == null ) {
System.err.println("StatsCollectionServant: if(element.interfaceName == null ");
}
if(element.interfaceName.equalsIgnoreCase(interfaceName))
{
return element.methodStatsCollection;
}
}
return null;
}
private MethodStats findByMetod(MethodStats[] stats, String methodName)
{
for (int i = 0; i < stats.length; i++) {
if(((MethodStats)stats[i]).methodName.equals(methodName))
{
return stats[i];
}
}
return null;
}
private String getHost(){
String host = "";
try {
InetAddress hostAddr = Inet4Address.getLocalHost();
host = hostAddr.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return host;
}
private void notifyMethodCall(String interfaceName, String methodName) {
String chName = this.getChannelName(interfaceName, methodName);
String s = this.getHost()
+ "|" + ContainerServant.getInstance().getName()
+ "|"+ interfaceName
+ "|"+ methodName;
String logMessage = "statsCollection: methodNotification";
Any eventAny = ORB.init().create_any();
eventAny.insert_string(s);
notifyEvent(chName,eventAny,logMessage);
}
private void notifyContainerStats(){
String chName = this.getChannelName();
String logMessage = "statsCollection: containerNotification";
Any eventAny = ORB.init().create_any();
ContainerStatsHelper.insert(eventAny, containerStats);
notifyEvent(chName,eventAny,logMessage);
}
private void notifyEvent(String channelName, Any event, String logMessage){
LogSender ls = new LogSender(logMessage,"localhost",514);
if( this.chManagement == null )
return;
this.chManagement.notifyChannel(channelName, event);
}
private boolean subscribeEvent(String clientName, String channelName, EventSink sink){
boolean ret = false;
if( this.chManagement == null ) {
this.eventMgr = ContainerServant.getInstance().getEventMgr();
if (this.eventMgr == null){
System.err.println("StatsCollectionServant: Erro ao retornar eventMgr");
return ret;
}
this.chManagement = ChannelManagementHelper.narrow(this.eventMgr.getFacet("scs::event_service::ChannelManagement"));
if( this.chManagement== null ) {
System.err.println("StatsCollectionServant: Erro ao retornar ChannelManagement !");
return ret;
}
}
return this.chManagement.subscribeChannel(clientName, channelName, sink);
}
private void cancelEvent(String clientName , String channelName){
if( this.chManagement== null )
return;
this.chManagement.cancelChannel(clientName, channelName);
}
public InterfaceStats[] getComponentsStats() throws ComponentStatsNotAvailable {
if (componentsStats.size() == 0)
throw new ComponentStatsNotAvailable ();
return componentsStats.toArray(new InterfaceStats[componentsStats.size()]);
}
public MethodStats[] getInterfaceStats(String interfaceName) throws InterfaceStatsNotAvailable {
for (Iterator iter = componentsStats.iterator(); iter.hasNext();) {
InterfaceStats element = (InterfaceStats) iter.next();
if(element.interfaceName.equalsIgnoreCase(interfaceName))
{
return element.methodStatsCollection;
}
}
throw new InterfaceStatsNotAvailable ();
}
public SystemIOStats getIOStats() throws IOStatsNotAvailable{
IOStats iostats = SystemInformation.getIOUsage();
if (iostats == null)
throw new IOStatsNotAvailable ();
systemIOStats.sectorsRead = iostats.sectors_read;
systemIOStats.timeReading = iostats.time_spent_in_readings;
systemIOStats.sectorsWriten = iostats.sectors_writen;
systemIOStats.timeWriting = iostats.time_spent_in_writings;
systemIOStats.nfsSectorsRead = iostats.sectors_read_in_nfs;
systemIOStats.nfsSectorsWriten = iostats.sectors_writen_in_nfs;
return systemIOStats;
}
public SystemNetworkStats getNetworkStats() throws NetworkStatsNotAvailable{
NetworkStats netstats = SystemInformation.getNetworkUsage();
if (netstats == null)
throw new NetworkStatsNotAvailable ();
systemNetworkStats.bytesReceived = netstats.bytes_received;
systemNetworkStats.bytesTransmitted = netstats.bytes_transmitted;
return systemNetworkStats;
}
public void setContainerName( String name ) {
this.containerStats.containerName = name;
}
public boolean insertStatsCalls(String interfaceName , String methodName)
{
//System.out.println ("Dentro de StatsCall: " + interfaceName + " " + methodName);
MethodStats ms = find(interfaceName , methodName);
ms.callsCount++;
notifyMethodCall( interfaceName, methodName );
return true;
}
public boolean insertStatsCPU(String interfaceName , String methodName, long cpuUsage)
{
MethodStats ms = find(interfaceName , methodName);
ms.cpuTime += cpuUsage;
return true;
}
public boolean insertStatsElapsedTime(String interfaceName , String methodName, long elapsedTime)
{
MethodStats ms = find(interfaceName , methodName);
ms.elapsedTime += elapsedTime;
return true;
}
public boolean setContainerStatsCPUTime(long cpuTime)
{
this.containerStats.cpuTime = cpuTime;
return true;
}
public boolean setContainerStatsCPUUsage(double cpuUsage)
{
this.containerStats.cpuUsage = cpuUsage;
return true;
}
public void setContainerStatsAvgCPUUsage(double cpuUsage) {
this.containerStats.avgCpuUsage = cpuUsage;
}
public boolean setContainerStatsElapsedTime(long elapsedTime)
{
this.containerStats.elapsedTime = elapsedTime;
return true;
}
public void setContainerStatsMemoryUsage(long memoryUsage) {
this.containerStats.memoryUsage = memoryUsage;
notifyContainerStats();
}
public ContainerStats getContainerStats() {
return this.containerStats;
}
public boolean subscribeMethodNotification(String clientName, String ifname, String method, EventSink sink) {
String chName = this.getChannelName(ifname, method);
return this.subscribeEvent(clientName, chName, sink);
}
public boolean subscribeContainerNotification(String clientName, EventSink sink) {
String chName = this.getChannelName();
return this.subscribeEvent(clientName, chName, sink);
}
public void cancelMethodNotification(String clientName,String ifname, String method) {
String chName = this.getChannelName(ifname, method);
this.cancelEvent(clientName, chName);
}
public void cancelContainerNotification(String clientName) {
String chName = this.getChannelName();
this.cancelEvent(clientName, chName);
}
}