/*
*
* Copyright (c) 1999 - 2011 my-Channels Ltd
* Copyright (c) 2012 - 2019 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors.
*
* Use, reproduction, transfer, publication or disclosure is prohibited except as specifically provided for in your License Agreement with Software AG.
*
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using com.pcbsys.nirvana.client;
using com.pcbsys.nirvana.nAdminAPI;
namespace com.pcbsys.nirvana.nAdminAPI.apps
{
///
/// * This class demonstrates how to watch for connections to a realm and be notified of
/// * new connections, or connections closing
///
public class connectionwatch : IObserver
{
private string realmUrl = null;
///
/// * Constructor takes a realm URL
///
public connectionwatch(string[] args)
{
try
{
processArgs(args);
Console.WriteLine("Connecting to " + realmUrl);
// construct the session attributes for the realm
nSessionAttributes attr = new nSessionAttributes(realmUrl);
// construct the real node
for (int x = 0; x < 1000; x++)
{
try
{
nRealmNode node = new nRealmNode(attr);
node.waitForEntireNameSpace(5000);
nRealmNode master = getMaster(node);
if (master != null)
{
Console.WriteLine("Found master realm " + master.Name + " Connected "+master.isConnected());
master.getCluster().close();
Thread.Sleep(5000);
}
else
{
Console.WriteLine("Master realm not found using " + node.Name);
Thread.Sleep(5000);
}
} catch (Exception ex)
{
Console.WriteLine("Exception " + ex.Message);
Console.WriteLine(ex.StackTrace);
Thread.Sleep(5000);
}
}
// add a new Realm watch instance as a watcher for connections to this root realm
// call the method to add listeners to the channel and queue nodes
//register(node);
Console.WriteLine("Press any key to quit !");
try
{
Console.ReadLine();
}
catch (Exception ) //Ignore this
{
}
//node.close();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
public nRealmNode getMaster(nRealmNode initialRealm)
{
// wait for the entire node namespace to be constructed if
// the operation is recursive
nClusterNode cnode = initialRealm.getCluster();
while (cnode == null) Thread.Sleep(1000);
Console.WriteLine("Cluster is " +
((cnode != null) ? ("OK - has quorum: " + cnode.hasquorum()) : "NULL"));
if (cnode != null)
{
if (cnode.hasquorum())
{
nRealmNode master;
try
{
master = cnode.getMaster(5000);
return master;
} catch(Exception )
{
return null;
}
}
}
return null;
}
static void Main(string[] args)
{
connectionwatch dump = new connectionwatch(args);
}
private void processArgs(string[] args)
{
switch (args.Length)
{
case 0:
Usage();
break;
case 1:
if (args[0].Equals("-?"))
{
Usage();
break;
}
getOptions(args);
break;
default:
getOptions(args);
break;
}
}
///
/// * Set the program variables and flags based on command line args
///
public virtual void getOptions(string[] args)
{
realmUrl = args[0];
if (realmUrl == null)
{
Usage();
System.Environment.Exit(1);
}
}
///
/// * Search the enumeration of child nodes, and add realm watchers to all child realms,
/// * and watchers to all channel and queue nodes
///
private void register(System.Collections.IEnumerator enum1)
{
while (enum1.MoveNext())
{
object obj = enum1.Current;
if (obj is nLeafNode)
{
((nLeafNode)obj).addListener(new nChannelWatch((nLeafNode)obj, this));
}
else if (obj is nContainer)
{
register(((nContainer)obj).getNodes());
}
else if (obj is nRealmNode)
{
// add a new realm watch instance as a watcher for connections to this realm
register((nRealmNode)obj);
}
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
private void newConnection(string target, nConnectionDetails cd)
{
if (cd.getSubject().Length == 1)
{
Console.WriteLine(DateTime.Now + " User [" + cd.getSubject()[0] + "] " + target + ": New Connection : " + cd.getId() + " Subject:" + cd.getSubject()[0]);
}
else
{
Console.WriteLine(DateTime.Now + " User [" + cd.getSubject()[0] + "] " + target + ": New Connection :" + cd.getId());
for (int x = 0; x < cd.getSubject().Length; x++)
{
Console.WriteLine(DateTime.Now + " Subject[" + x + "] " + cd.getSubject()[x]);
}
}
}
private void delConnection(string target, nConnectionDetails cd)
{
Console.WriteLine(DateTime.Now + " User [" + cd.getSubject()[0] + "] " + target + ": Del Connection : " + cd.getId());
}
private void register(nRealmNode node)
{
nRealmNode rNode = (nRealmNode)node;
rNode.addObserver(this);
rNode.addConnectionListener(new nRealmWatch(this));
register(rNode.getNodes());
}
public virtual void update(Observable obs)
{
update(obs, null);
}
public virtual void update(Observable obs, object obj)
{
try
{
if (obj is nLeafNode)
{
((nLeafNode)obj).addListener(new nChannelWatch((nLeafNode)obj, this));
}
else if (obj is nContainer)
{
register(((nContainer)obj).getNodes());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
///
/// * Class that implements the connection lister interface.
/// * This internal class will Receive notifications when a sesison is added to
/// * or removed from a channel
///
public class nChannelWatch : nConnectionListener
{
internal nLeafNode myChannel;
private connectionwatch myWatcher;
///
/// * Construct the channel watch with the channel leaf node
///
public nChannelWatch(nLeafNode chan, connectionwatch watch)
{
myChannel = chan;
myWatcher = watch;
}
///
/// * Notification of a new channel connection
///
public virtual void add(nConnectionDetails cd)
{
if (cd is nChannelConnectionDetails)
{
nChannelConnectionDetails ccd = (nChannelConnectionDetails)cd;
myWatcher.newConnection("Chan: " + myChannel.getAbsolutePath() + " with name [" + ccd.getNamedSubscriber() + "]", ccd);
}
}
///
/// * Notification of a channel connection being removed
///
public virtual void del(nConnectionDetails cd)
{
myWatcher.delConnection("Chan: " + myChannel.getAbsolutePath(), cd);
}
}
///
/// * Class that implements the connection lister interface.
/// * This internal class will Receive notifications when a subject connection
/// * is added or removed from the realm
///
public class nRealmWatch : nConnectionListener
{
private connectionwatch myWatcher;
public nRealmWatch(connectionwatch watch)
{
myWatcher = watch;
}
///
/// * Notification of a new session connection to the realm
///
public virtual void add(nConnectionDetails cd)
{
myWatcher.newConnection("Realm: New Connection : ", cd);
}
///
/// * Notification of a session connection being removed from the realm
///
public virtual void del(nConnectionDetails cd)
{
myWatcher.delConnection("Realm: Del Connection : ", cd);
}
}
///
/// * Prints the usage message for this class
///
private static void Usage()
{
Console.WriteLine("Usage ...\n");
Console.WriteLine("nconnectionwatch \n");
Console.WriteLine(" - the rname of the server to connect to");
}
}
}