/*-------------------------------------------------------------------------
// UNCLASSIFIED
/*-------------------------------------------------------------------------
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
COMPANY.
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Xml.Linq;
using Microsoft.Win32;
using Raytheon.Common;
using Raytheon.Communication;
using Raytheon.Communication.Rpc;
using Raytheon.Composition;
using Raytheon.Logging;
namespace Raytheon.Instruments
{
public enum Mode
{
///
/// instruments must be managed by the service (like RINSS)
///
Service,
///
/// ignore the service and initialize instruments directly
///
StandAlone,
///
/// dynamically identify if instrument service is running
///
Auto
}
///
/// hybrid implementation of the instrument manager interface
/// will check if
///
public class GeneralInstrumentManager : IInstrumentManager, IPartImportsSatisfiedNotification
{
#region Private Fields
private readonly bool _haveService;
private IUms _umsHost;
private IUmsClient _instrumentManager;
private IUmsClient _rpcInstrumentManagerHost;
private bool _partsLoaded { get; set; }
///
/// PartsLocation - where the instrument manager should get it's MEF components
///
public string _partsLocation { get; set; }
///
/// ConfigLocation - where the configuration manager stores config files
/// specifically Instruments.xml
///
public string _configLocation { get; set; }
private List _availableInstruments = new List();
private readonly Dictionary _factoryMap = new Dictionary();
private readonly Dictionary _instruments = new Dictionary();
private readonly HashSet _instrumentTypes = new HashSet();
// simulation
private readonly bool _isThereHardware;
#endregion
#region Constants
private const string NO_SERVER = "Client for communication to the server has not been setup";
private const string SECTION = "RpcClient";
private const string RegistryValue = @"ConsumerInstrumentManagerPartsDirectory";
private const string RegistryValueNoRINSS = @"InstrumentManagerPartsDirectory";
private const string RegistryKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\Raytheon";
private const string DefaultName = "Default";
private const string DefaultIP = "127.0.0.1";
private const string DefaultPort = "8006";
private const string DefaultMedia = "Tcp";
private const string DefaultSerializer = "Fusion";
#endregion
#region Imports
[ImportMany(typeof(IInstrumentFactory))]
private Lazy[] InstrumentFactories { get; set; }
[Import(typeof(IUmsFactory))]
private Lazy LazyUmsFactory { get; set; }
private IUmsFactory UmsFactory { get { return LazyUmsFactory?.Value; } }
[Import(typeof(IConfigurationManager))]
private Lazy LazyConfigManager { get; set; }
private IConfigurationManager ConfigManager { get { return LazyConfigManager?.Value; } }
[Import(typeof(IUmsClientFactory))]
private Lazy LazyUmsClientFactory { get; set; }
private IUmsClientFactory UmsClientFactory { get { return LazyUmsClientFactory?.Value; } }
[Import(typeof(ILogFactory), AllowDefault = true)]
private Lazy LazyLogFactory { get; set; }
private ILogFactory LogFactory { get { return LazyLogFactory?.Value; } }
[ImportMany(typeof(IInstrumentProxyFactory))]
private Lazy[] ProxyFactories { get; set; }
#endregion
#region Logging
private static ILogger _logger;
private static ILogger GetLogger()
{
FusionLogManager.Changed += l => _logger = l.GetLogger();
return _logger;
}
#endregion
///
/// default constructor
/// in Auto mode the Instrument Manager will use RINSS based on the service running status
/// in Service mode the Instrument Manager must have the RINSS Service running
/// in StandAlone mode the Instrument Manager will ignore RINSS
///
public GeneralInstrumentManager(Mode mode = Mode.Auto)
{
_haveService = CheckServiceRunningStatus("RINSS");
if (mode == Mode.Service && !_haveService)
{
throw new Exception("RINSS Service is not running for Service mode");
}
if (mode == Mode.StandAlone)
{
_haveService = false;
}
_logger = GetLogger();
}
///
/// constructor to be used when no RINSS available to set parts location
///
///
public GeneralInstrumentManager(string partsLocation, Mode mode = Mode.Auto)
: this(mode)
{
_partsLocation = partsLocation;
}
///
/// constructor to be used when no RINSS available to set parts location and configuration location
///
///
///
///
public GeneralInstrumentManager(string partsLocation, string configLocation, bool isThereHardware = true, Mode mode = Mode.Auto)
: this(partsLocation, mode)
{
_configLocation = configLocation;
_isThereHardware = isThereHardware;
}
///
/// Initializes this instance.
///
public void Initialize()
{
try
{
//Setup the instrument part path
if (!string.IsNullOrWhiteSpace(_partsLocation) && !Directory.Exists(_partsLocation))
{
_logger.Error($"Unable to id parts in this location: {_partsLocation}");
_partsLocation = string.Empty;
}
SetupPath();
//load the instruments
if (!_partsLoaded)
{
LoadParts();
}
if (_haveService)
{
// 1. Create the Ums Client
CreateUmsClient();
_logger.Debug("created client");
// 2. Find out what instruments are available
_availableInstruments = new List(_rpcInstrumentManagerHost.Contract.EnumRpcInstruments());
_logger.Debug("geting list of availible instruments");
// 3. Find all the instrument interfaces supported by proxy factories
InitializeFactories();
_logger.Debug("initialized all the factories");
}
else
{
//configure all the instruments found
ConfigureInstruments();
}
}
catch (CompositionException)
{
throw;
}
catch (Exception)
{
throw;
}
}
///
/// InitializeInstruments - init all the instruments
///
public void InitializeInstruments()
{
_logger.Info("Instrument initialization complete");
}
///
/// InitializeInstrument - inits a specific instrument
///
/// instrument's unique name
public void InitializeInstrument(string instName)
{
}
///
/// implementation for IPartImportsSatisfiedNotification interface
///
public void OnImportsSatisfied()
{
if (LogFactory != null && LogFactory != null)
{
FusionLogManager.Current = LogFactory;
}
}
///
/// Gets the generic instrument.
///
/// The name.
///
public IInstrument GetGenericInstrument(string name)
{
_logger.Debug("In ConsumerInstrumentManager in method GetGenericInstrument with name: {0} ", name);
return GetInstrument(name);
}
///
/// gets a specific instrument by name
/// the name should match one of the names in Instruments.xml file
///
///
///
///
public T GetInstrument(string name) where T : class
{
_logger.Debug($"Starting GetInstrument with name: {name}");
object inst = null;
if (_haveService)
{
try
{
string interfaceName = typeof(T).FullName;
if (typeof(IInstrument).FullName == interfaceName)
{
_logger.Debug($"GetInstrument with typeof(IInstrument).FullName == interfaceName: {interfaceName}");
//get the real interface behind the scenes
//first find the appropriate factory
RpcInstrumentDescriptor correctDesc = _availableInstruments.FirstOrDefault((desc) => 0 == string.Compare(name, desc.InstrumentName, true));
if (null != correctDesc)
{
_logger.Debug($"GetInstrument with correctDesc.name: {correctDesc.InstrumentName}");
string temp = correctDesc.InstrumentInterfaces.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(temp))
{
interfaceName = temp;
}
}
_logger.Debug("Requested generic instrument, found {0} to be the correct interface", interfaceName);
}
if (InstrumentIsAvailable(name) && FactoryIsAvailable(interfaceName))
{
_logger.Debug($"GetInstrument with InstrumentIsAvailable(name) && FactoryIsAvailable(interfaceName) name: {name}, interfaceName: {interfaceName}");
IInstrumentProxyFactory factory = _factoryMap.Where((t) => 0 == string.Compare(t.Key, interfaceName, true))
.Select(t => t.Value)
.FirstOrDefault();
if (null != factory)
{
inst = factory.GetInstrument(name);
_logger.Debug($"GetInstrument got an instrument (name: {name}) from factory: {factory}, interfaceName: {interfaceName}");
}
else
{
_logger.Warn($"Could not find factory for interface: {interfaceName}, instrument: {name}");
}
}
}
catch (InstrumentException ex)
{
_logger.WarnException(ex, ex.Message);
}
}
else
{
_instruments.TryGetValue(name.ToLower(), out inst);
}
_logger.Debug($"GetInstrument returning with inst: {inst}");
return inst as T;
}
///
/// returns a collection of instrument names
///
///
public ICollection GetInstrumentNames()
{
_logger.Debug("Returning instrument list");
if (_haveService)
{
return _instrumentManager.Contract.GetInstrumentNames();
}
else
{
return new ReadOnlyCollection(_instruments.Keys.ToList());
}
}
public string[] GetInstrumentNamesArray()
{
_logger.Debug("Getting Instrument Names Array");
return GetInstrumentNames().ToArray();
}
///
/// Gets instruments collection
///
///
public ICollection