예제 #1
0
        /// <summary>
        /// Performs a lookup for the givern security id if recursiveLookup is true.
        /// </summary>
        /// <param name="securityIdDetails">The details of the security id for which to perform lookup.</param>
        /// <param name="lookupService">The lookup service to use</param>
        /// <returns>the security data.</returns>
        ///
        /// <exception cref="UnknownSecurityIdTypeException">
        /// if the type of the given security id is unknown.
        /// </exception>
        /// <exception cref="InvalidSecurityIdFormatException">if the format of security id is invalid.</exception>
        /// <exception cref="SecurityIdParsingException">if any other error occurs in parsing the id.</exception>
        /// <exception cref="ServiceNotAvailableException">if the lookup service is not available.</exception>
        /// <exception cref="SecurityLookupException">if any error occurs when looking up the security data.</exception>
        /// <exception cref="SecurityDataCombiningException">if fail to combine the security data.</exception>
        private SecurityData PerformRecursiveLookup(SecurityIdDetails securityIdDetails,
                                                    ISecurityLookupService lookupService)
        {
            // check cache to get the securityDataRecord
            SecurityDataRecord securityDataRecord = securityDataCache[securityIdDetails.Id] as SecurityDataRecord;

            if (securityDataRecord != null)
            {
                return(securityDataRecord.SecurityData);
            }
            else
            {
                //Get the security data for lookupService
                SecurityData securityData = lookupService.Lookup(securityIdDetails);

                //Add current id to cache. This prevents from infinite recursion due to cyclic references.
                securityDataCache[securityIdDetails.Id] = new SecurityDataRecord(securityData, true);

                //Create all possible cross-references and store in combinedData
                SecurityData combinedData = securityData;
                foreach (string refId in securityData.ReferenceIds)
                {
                    //Check the reference id in cache
                    SecurityDataRecord refRecord = securityDataCache[refId] as SecurityDataRecord;

                    SecurityData refData;
                    //if not present in cache, the load from lookup
                    if (refRecord == null)
                    {
                        //Get details of the reference id
                        SecurityIdDetails refDetails = securityIdParser.Parse(refId);

                        //get lookup service for the refId
                        ISecurityLookupService refLookupService = null;
                        securityLookupServices.TryGetValue(refDetails.Type, out refLookupService);

                        //No lookup service found for current type.
                        if (refLookupService == null)
                        {
                            throw new NoSuchSecurityLookupServiceException(
                                      "No lookup service exists for the security type: " + refDetails.Type);
                        }

                        refData = PerformRecursiveLookup(securityIdParser.Parse(refId), refLookupService);
                    }
                    else
                    {
                        refData = refRecord.SecurityData;
                    }

                    //Combine the current combined data with
                    combinedData = securityDataCombiner.Combine(combinedData, refData);
                }

                //All cross-refernced ids must now point to the same combinedData instance
                AddUpdateCache(combinedData);

                return(combinedData);
            }
        }
예제 #2
0
        /// <summary>
        /// Performs a lookup for the givern security id if recursiveLookup is false and referenceLookup is true.
        /// </summary>
        /// <param name="securityIdDetails">The details of the security id for which to perform lookup.</param>
        /// <param name="lookupService">The lookup service to use</param>
        /// <returns>the security data.</returns>
        ///
        /// <exception cref="ServiceNotAvailableException">if the lookup service is not available.</exception>
        /// <exception cref="SecurityLookupException">if any error occurs when looking up the security data.</exception>
        /// <exception cref="SecurityDataCombiningException">if fail to combine the security data.</exception>
        private SecurityData PerformReferenceLookup(SecurityIdDetails securityIdDetails,
                                                    ISecurityLookupService lookupService)
        {
            // check cache to get the securityDataRecord
            SecurityDataRecord securityDataRecord = securityDataCache[securityIdDetails.Id] as SecurityDataRecord;

            if (securityDataRecord != null && securityDataRecord.IsLookedUp)
            {
                return(securityDataRecord.SecurityData);
            }
            else if (securityDataRecord == null)
            {
                return(PerformSimpleLookup(securityIdDetails, lookupService));
            }
            else
            {
                //Get the security data for lookupService
                SecurityData securityData = lookupService.Lookup(securityIdDetails);

                //Combine the record in cache with the one returned.
                securityData = securityDataCombiner.Combine(securityData, securityDataRecord.SecurityData);

                //Add or update cache with the cross-referenced security data
                AddUpdateCache(securityData);

                return(securityData);
            }
        }
예제 #3
0
        /// <summary>
        /// <para>Lookup the security data by the given security id details.</para>
        /// </summary>
        ///
        /// <param name="securityIdDetails">the security id details used to lookup security data.</param>
        /// <returns>the security data.</returns>
        ///
        /// <exception cref="SelfDocumentingException">Wraps ArgumentNullException is argument is null.</exception>
        /// <exception cref="UnknownSecurityIdTypeException">if type of the given security id is unknown.</exception>
        /// <exception cref="InvalidSecurityIdFormatException">if the format of security id is invalid.</exception>
        /// <exception cref="SecurityIdParsingException">if any other error occurs in parsing the id.</exception>
        /// <exception cref="NoSuchSecurityLookupServiceException">if there is no corresponding ISecurityLookupService
        /// defined for the specific security identifier type.</exception>
        /// <exception cref="ServiceNotAvailableException">if the lookup service is not available.</exception>
        /// <exception cref="SecurityLookupException">if any error occurs when looking up the security data.</exception>
        public SecurityData Lookup(SecurityIdDetails securityIdDetails)
        {
            ISecurityLookupService lookupService = null;

            try
            {
                Helper.ValidateNotNull(securityIdDetails, "securityIdDetails");

                // get corresponding lookup service. Use TryGetValue so that KeyNotFoundException is not encountered.
                securityLookupServices.TryGetValue(securityIdDetails.Type, out lookupService);

                //No lookup service found for current type.
                if (lookupService == null)
                {
                    throw new NoSuchSecurityLookupServiceException(
                              "No lookup service exists for the security type: " + securityIdDetails.Type);
                }

                //Since cache is checked and updated many times in the same function,
                //there needs to control against race conditions.
                lock (securityDataCache)
                {
                    if (recursiveLookup)
                    {
                        return(PerformRecursiveLookup(securityIdDetails, lookupService));
                    }
                    else if (referenceLookup)
                    {
                        return(PerformReferenceLookup(securityIdDetails, lookupService));
                    }
                    else
                    {
                        return(PerformSimpleLookup(securityIdDetails, lookupService));
                    }
                }
            }
            catch (Exception e)
            {
                throw Helper.GetSelfDocumentingException(e, "Unable to perform lookup.",
                                                         "TopCoder.FinancialService.Utility.FinancialSecurityManager.Lookup(SecurityIdDetails)",
                                                         new string[] { "securityIdParser", "securityLookupServices", "recursiveLookup",
                                                                        "referenceLookup", "securityDataCache", "securityDataCombiner" },
                                                         new object[] { securityIdParser, securityLookupServices, recursiveLookup, referenceLookup,
                                                                        securityDataCache, securityDataCombiner },
                                                         new string[] { "securityIdDetails" }, new object[] { securityIdDetails },
                                                         new string[] { "lookupService" }, new object[] { lookupService });
            }
        }
예제 #4
0
        /// <summary>
        /// Performs a lookup for the givern security id if recursiveLookup and referenceLookup are both false.
        /// </summary>
        /// <param name="securityIdDetails">The details of the security id for which to perform lookup.</param>
        /// <param name="lookupService">The lookup service to use</param>
        /// <returns>the security data.</returns>
        ///
        /// <exception cref="ServiceNotAvailableException">if the lookup service is not available.</exception>
        /// <exception cref="SecurityLookupException">if any error occurs when looking up the security data.</exception>
        /// <exception cref="SecurityDataCombiningException">if fail to combine the security data.</exception>
        private SecurityData PerformSimpleLookup(SecurityIdDetails securityIdDetails,
                                                 ISecurityLookupService lookupService)
        {
            // check cache to get the securityDataRecord
            SecurityDataRecord securityDataRecord = securityDataCache[securityIdDetails.Id] as SecurityDataRecord;

            if (securityDataRecord != null)
            {
                return(securityDataRecord.SecurityData);
            }
            else
            {
                //If not in cache then perform lookup
                SecurityData securityData = lookupService.Lookup(securityIdDetails);

                //Combine with itself. Combining a securityData instance with itself has the effect of
                //adding the securityID to the referenceIds
                SecurityData combinedData = securityDataCombiner.Combine(securityData, securityData);

                //Create all possible cross references
                foreach (string refId in securityData.ReferenceIds)
                {
                    //Check the reference id in cache
                    SecurityDataRecord refSecurityData = securityDataCache[refId] as SecurityDataRecord;

                    if (refSecurityData != null)
                    {
                        combinedData = securityDataCombiner.Combine(securityData, refSecurityData.SecurityData);
                    }
                }

                //Add or update cache with the cross-referenced security data
                AddUpdateCache(combinedData);

                return(combinedData);
            }
        }
        /// <summary>
        /// <para>Build the FinancialSecurityManager object using the given IConfiguration object.</para>
        /// </summary>
        ///
        /// <param name="configuration">the IConfiguration to load configuration.</param>
        /// <returns>the created FinancialSecurityManager object.</returns>
        ///
        /// <exception cref="SelfDocumentingException">
        /// Wraps ArgumentNullException if the given argument is null.
        /// Wraps ConfigurationErrorsException if the configured value is invalid, or any required
        /// property is missing.
        /// </exception>
        public static FinancialSecurityManager BuildFinancialSecurityManager(IConfiguration configuration)
        {
            //Declare local variables
            ISecurityIdParser             securityIdParser = null;
            ConfigurationAPIObjectFactory of = null;
            string ofDefinitionsKey          = null;
            string securityIdParserKey       = null;

            string[] securityIdTypes           = null;
            string[] securityLookupServiceKeys = null;
            IDictionary <string, ISecurityLookupService> securityLookupServices = null;
            bool   recursiveLookup = false, referenceLookup = false;
            ICache cache = null;
            string securityDataCacheKey = null;
            ISecurityDataCombiner combiner = null;
            string securityDataCombinerKey = null;

            try
            {
                Helper.ValidateNotNull(configuration, "configuration");

                //Get the key of the nested object definition to use
                ofDefinitionsKey = GetConfigValue(configuration, "objectfactory_key", true, false);

                try
                {
                    //Create the Obejct Factory instance using the nested definition to use.
                    of = new ConfigurationAPIObjectFactory(configuration[ofDefinitionsKey]);
                }
                catch (Exception e)
                {
                    throw new ConfigurationErrorsException(
                              "Unable to create ConfigurationAPIObjectFactory instance from object factory", e);
                }

                //Create ISecurityIdParser instance if needed.
                securityIdParserKey = GetConfigValue(configuration, "security_id_parser_key", false, false);
                if (securityIdParserKey != null)
                {
                    try
                    {
                        securityIdParser = (ISecurityIdParser)of.CreateDefinedObject(securityIdParserKey);
                    }
                    catch (Exception e)
                    {
                        throw new ConfigurationErrorsException(
                                  "Unable to create ISecurityIdParser instance from object factory", e);
                    }
                }

                //Get the security types and the keys for creating their respective ISecurityLookupService instances
                securityIdTypes = GetConfigArrayValue(
                    configuration, "security_id_types", true, false);
                securityLookupServiceKeys = GetConfigArrayValue(
                    configuration, "security_lookup_service_keys", true, false);

                //Length of both must be same
                if (securityIdTypes.Length != securityLookupServiceKeys.Length)
                {
                    throw new ConfigurationErrorsException(
                              "Arrays for security_id_types and security_lookup_service_keys must be of same length.");
                }

                //Generate dictionary of security types to lookup service mappings.
                securityLookupServices = new Dictionary <string, ISecurityLookupService>();
                for (int i = 0; i < securityIdTypes.Length; i++)
                {
                    //If any keys are empty, throw exception
                    if (securityIdTypes[i].Trim().Equals(String.Empty) ||
                        securityLookupServiceKeys[i].Trim().Equals(String.Empty))
                    {
                        throw new ConfigurationErrorsException("Arrays for security_id_types and " +
                                                               "security_lookup_service_keys must not contain empty elements");
                    }
                    else
                    {
                        try
                        {
                            //Create the lookup service instance from ObjectFactory
                            ISecurityLookupService lookupService = (ISecurityLookupService)
                                                                   of.CreateDefinedObject(securityLookupServiceKeys[i]);

                            //Add type to lookup mapping to dictionary
                            securityLookupServices[securityIdTypes[i]] = lookupService;
                        }
                        catch (Exception e)
                        {
                            throw new ConfigurationErrorsException(
                                      "Unable to create ISecurityLookupService instance from object factory", e);
                        }
                    }
                }

                //Set recursive_lookup and referenceLookup
                try
                {
                    recursiveLookup = bool.Parse(GetConfigValue(configuration, "recursive_lookup", true, false));
                    referenceLookup = bool.Parse(GetConfigValue(configuration, "reference_lookup", true, false));
                }
                catch (FormatException fe)
                {
                    throw new ConfigurationErrorsException("Unable to parse value to boolean.", fe);
                }

                //Load cache
                securityDataCacheKey = GetConfigValue(configuration, "security_data_cache_key", true, false);
                try
                {
                    cache = (ICache)of.CreateDefinedObject(securityDataCacheKey);
                }
                catch (Exception e)
                {
                    throw new ConfigurationErrorsException(
                              "Unable to create ICache instance from object factory", e);
                }

                //Load data combiner
                securityDataCombinerKey = GetConfigValue(configuration, "security_data_combiner_key", true, false);
                try
                {
                    combiner = (ISecurityDataCombiner)of.CreateDefinedObject(securityDataCombinerKey);
                }
                catch (Exception e)
                {
                    throw new ConfigurationErrorsException(
                              "Unable to create ISecurityDataCombiner instance from object factory", e);
                }

                //Create and return FinancialSecurityManager instance
                if (securityIdParser == null)
                {
                    return(new FinancialSecurityManager(
                               securityLookupServices, combiner, recursiveLookup, referenceLookup, cache));
                }
                else
                {
                    return(new FinancialSecurityManager(
                               securityIdParser, securityLookupServices, combiner, recursiveLookup, referenceLookup, cache));
                }
            }
            catch (Exception e)
            {
                throw Helper.GetSelfDocumentingException(e,
                                                         "Unable to build FinancialSecurityManager instance from configuration.",
                                                         "TopCoder.FinancialService.Utility.FinancialSecurityManagerBuilder.BuildFinancialSecurityManager",
                                                         new string[0], new object[0],
                                                         new string[] { "configuration" }, new object[] { configuration },
                                                         new string[] { "securityIdParser", "of", "of_definitions_key", "security_id_parser_key",
                                                                        "security_id_types", "security_lookup_service_keys", "securityLookupServices",
                                                                        "recursiveLookup", "referenceLookup", "cache", "securityDataCacheKey",
                                                                        "combiner", "securityDataCombinerKey" },
                                                         new object[] { securityIdParser, of, ofDefinitionsKey, securityIdParserKey, securityIdTypes,
                                                                        securityLookupServiceKeys, securityLookupServices, recursiveLookup, referenceLookup, cache,
                                                                        securityDataCacheKey, combiner, securityDataCombinerKey });
            }
        }