We’ve used the OpenDACS Api in both JAVA & .NET. The Java version works well, however, for the .NET version we don’t see any usage data collected in the dacs.usage file like we do for other apps. Would an expert be able to take a look at the code & let me know if there is anything missing please?
using Ion.MarketView.Gui.Toolkit.Core.LoggingEx;
using Reuters.RFA.Common;
using Reuters.RFA.DACS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static RFA_DACS.DACSConfiguration;
namespace RFA_DACS
{
public class DaemonSink
{
static private ILogger logger = LogManager.GetCurrentClassLogger();
static private DaemonSink instance = null;
private Dictionary<String, uint> srcToPe = new Dictionary<string, uint>();
private DACSUser user;
private DACSDispatcher dispatcher;
private static RFA_String AUTHORIZATION_NAME = new RFA_String("DACSMC");
private List<AuthorizationSystem.AUTH_SYSTEM_OPTION_ELEMENT> options = new List<AuthorizationSystem.AUTH_SYSTEM_OPTION_ELEMENT>();
private AuthorizationSystem system = null;
private AuthorizationAgent agent = null;
private AuthorizationRequest.PerformUsageEnum usageLogging = AuthorizationRequest.PerformUsageEnum.AlwaysPerformUsageLogging;
private int serviceId = -1;
private String application = null;
private String serviceName = null;
private RFA_String serviceNameRFA = null;
// private long loginHandle = -1;
// private Boolean loginState = false;
private EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
private RuntimeConfiguration config = null;
private Site dacsConnectionParameters = null;
private bool checksDisabled = false;
public DaemonSink(RuntimeConfiguration config)
{
this.config = config;
DaemonSink.instance = this;
logger.LogKey = "DACS Audit";
}
public bool Enabled
{
get { return checksDisabled == false; }
}
/*
* Convenience method for defining DACS options.
*/
public void SetOption(String name, String value)
{
AuthorizationSystem.AUTH_SYSTEM_OPTION_ELEMENT option = new AuthorizationSystem.AUTH_SYSTEM_OPTION_ELEMENT();
option.OptionName = new RFA_String(name);
option.OptionValue = new RFA_String(value);
options.Add(option);
}
/*
* Public 'do it all' connector for DACS sink. Iterates defined sites and attempts DACS init and login until success.
* If site cannot be logged into, disables DACS entitlement checks.
*/
public void Connect(String componentName, DACSConfiguration config)
{
if (dispatcher == null)
{
dispatcher = new DACSDispatcher();
dispatcher.LoginFailed += LoginFailed;
dispatcher.LoginSucceeded += LoginSucceeded;
dispatcher.Start();
}
else
{
dispatcher.Stop();
dispatcher.Start();
}
foreach (Site site in config.Sites)
{
logger.Low().Info().Event("Attempting connection to site '" + site.Name + "'.").End();
try
{
Connect(componentName, site.Application, site.Service, int.Parse(site.Port), site.Hosts);
}
catch (System.Exception)
{
CleanUp();
}
if (user != null && user.LoginState)
{
dacsConnectionParameters = site;
logger.Low().Info().Event("Connected to site '" + dacsConnectionParameters.Name + "'.").End();
break;
}
}
if (user == null || user.LoginState == false)
{
// Couldn't login anywhere, so disable DACS checking...
checksDisabled = true;
logger.Low().Error().Event("Unable to connect to any configured DACS site, DACS checks disabled.").End();
}
}
/*
* Throws AuthorizationException on login failure
*
* 'Do it all' internal site connection and login. Initialises DACS for current user and logs in. Called by public method
* for each defined site until a successful login is completed.
*/
private void Connect(String componentName, String application, String serviceName, int port, String[] hosts, int timeout = 30)
{
int tryCount = 0;
String val = string.Join(" ", hosts);
val += ":" + port;
SetOption("hosts", val);
SetOption("forecase", "lower");
this.application = application;
this.serviceName = serviceName;
system = AuthorizationSystem.Acquire(AUTHORIZATION_NAME, options);
agent = system.CreateAuthorizationAgent(new RFA_String(componentName), true);
AuthorizationSystem.InitAuthorizationUsageLogging(new RFA_String("E:\\apps\\Ion\\env\\Test\\Workspaces\\uk280374\\LOGS"), 1024);
do
{
Thread.Sleep(1000);
tryCount++;
switch (ConnectionStatus)
{
case Reuters.RFA.DACS.AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionUp:
logger.Low().Info().Event("DACS Daemon connection is up").End();
break;
case Reuters.RFA.DACS.AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionDown:
logger.Low().Info().Event("DACS Daemon connection is down").End();
break;
case Reuters.RFA.DACS.AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionPending:
logger.Low().Info().Event("DACS Daemon connection is pending").End();
break;
default:
logger.Low().Info().Event("DACS Daemon connection is unknown").End();
break;
}
}
while (ConnectionStatus != AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionUp && tryCount < timeout);
if (ConnectionStatus != AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionUp)
{
Disconnect();
logger.Low().Error().Event("Timeout waiting to connect.").End();
throw new System.Exception("Timeout waiting to connect.");
}
serviceNameRFA = new RFA_String(serviceName);
agent.LookupServiceID(serviceNameRFA, ref serviceId);
UpdateServiceList();
try
{
Login();
}
catch (System.Exception ex)
{
logger.Low().Warn().Event("Login attempt for host(s) '" + String.Join(",", hosts) + "' on port " + port + " failed: " + ex.Message);
throw ex;
}
}
/*
* Updates global service/permission entity cache for current DACS connection parameters.
*/
private void UpdateServiceList()
{
List<AuthorizationAgent.AUTH_PE_SUBSERVICE_ELEMENT> services = new List<AuthorizationAgent.AUTH_PE_SUBSERVICE_ELEMENT>();
if (agent.GetPEToSubServiceList(serviceId, services) == AuthorizationAgent.AuthorizationServiceLookupEnum.SuccessfulLookup)
{
logger.Low().Info().Event("Mapping source to PE identifiers for Service: " + serviceName + " (" + serviceId + ")").End();
foreach (AuthorizationAgent.AUTH_PE_SUBSERVICE_ELEMENT svc in services)
{
foreach (RFA_String ss in svc.SubserviceList)
{
srcToPe[ss.ToString()] = svc.PEValue;
String msg = ss.ToString() + " --> " + svc.PEValue;
logger.Low().Info().Event(msg).End();
}
}
logger.Low().Info().Event("Done mapping source to PE identifiers").End();
}
}
public List<String> GetUserAvailableSources()
{
List<String> sources = new List<String>();
if (Enabled && user != null)
{
List<AuthorizationAgent.AUTH_USER_SUBSERVICE_ELEMENT> result = new List<AuthorizationAgent.AUTH_USER_SUBSERVICE_ELEMENT>();
if (agent.GetUserSubServiceList(user.Handle, serviceId, result) == AuthorizationAgent.AuthorizationServiceLookupEnum.SuccessfulLookup)
{
foreach (AuthorizationAgent.AUTH_USER_SUBSERVICE_ELEMENT ss in result)
{
sources.Add(ss.SubserviceName.ToString());
}
}
}
return sources;
}
private void Login()
{
if (user == null)
{
user = new DACSUser(application);
}
if (user.IsSet == false || user.LoginState == false)
{
AuthorizationRequest request = AuthorizationRequest.Create();
request.SetUsageLogging(usageLogging);
request.PrincipalIdentity = user.Identity;
long loginHandle = agent.Login(dispatcher.EventQueue, request, dispatcher, this);
waitHandle.WaitOne();
String msg = "DACS login for Principal " + request.PrincipalIdentity.AppName.ToString() + "/" + request.PrincipalIdentity.Name.ToString() + (user.LoginState ? " successful." : " failed.");
logger.Low().Info().Event(msg).End();
if (user.LoginState == false)
{
throw new System.Exception(msg);
}
}
}
private void LoginFailed(AuthorizationAgentEventStatus.StatusCodeEnum status, string text)
{
user.Set(text);
waitHandle.Set();
}
private void LoginSucceeded(long handle, string text)
{
user.Set(handle, text);
waitHandle.Set();
}
public Boolean CheckAccess(String source, String record)
{
if (config.Enabled == false)
{
return true;
}
Boolean ret = false;
if (srcToPe.ContainsKey(source))
{
try
{
uint pe = srcToPe[source];
List<uint> peList = new List<uint>();
peList.Add(pe);
AuthorizationLockStatus status = new AuthorizationLockStatus();
AuthorizationLockData lockData = new AuthorizationLockData();
AuthorizationLock dacsLock = new AuthorizationLock(serviceId, AuthorizationLock.OperatorEnum.AND, peList);
AuthorizationLockData.LockResultEnum res = dacsLock.GetLock(lockData, status);
AuthorizationAgent.AuthorizationCheckResultEnum checkResult = AuthorizationAgent.AuthorizationCheckResultEnum.AccessDenied;
if (res == AuthorizationLockData.LockResultEnum.LOCK_SUCCESS)
{
AuthorizationCheckStatus reqStatus = new AuthorizationCheckStatus();
checkResult = agent.CheckSubscription(user.Handle, usageLogging, reqStatus, serviceNameRFA);
ret = checkResult == AuthorizationAgent.AuthorizationCheckResultEnum.AccessAllowed;
if (!ret)
{
logger.Low().Warn().Event("Access check, user context [" + user.ToString() + "], source context [" + source + "], record context [" + record + "], auth context [PE=" + pe + ", SVCId=" + serviceId + ", SVCName=" + serviceName + ", Log=" + usageLogging.ToString() + "] DENIED. Site[" + dacsConnectionParameters.ToString() + "]").End();
}
else
{
logger.Low().Info().Event("Access check, user context [" + user.ToString() + "], source context [" + source + "], record context [" + record + "], auth context [PE=" + pe + ", SVCId=" + serviceId + ", SVCName=" + serviceName + ", Log=" + usageLogging.ToString() + "] ALLOWED. Site[" + dacsConnectionParameters.ToString() + "]").End();
}
}
}
catch (System.Exception ex)
{
logger.Low().Error().Event(ex.GetType().Name + " exception in audit(...): " + ex.Message).End();
}
}
return ret;
}
public AuthorizationAgent.AuthorizationConnectionEnum ConnectionStatus
{
get
{
if (agent != null) return agent.DaemonConnectionState;
return AuthorizationAgent.AuthorizationConnectionEnum.AuthorizationConnectionDown;
}
}
public void Disconnect()
{
try
{
dispatcher.Stop();
CleanUp();
}
catch (System.Exception e)
{
logger.Low().Error().Event(e.GetType().Name + " exception during Disconnect: " + e.Message).End();
}
}
private void CleanUp()
{
srcToPe.Clear();
user = null;
checksDisabled = false;
if (agent != null)
{
agent.Destroy();
agent = null;
}
if (system != null)
{
system.Release();
system = null;
}
}
}
}