Example #1
0
        /// <summary>
        /// Loads the configuration.
        /// </summary>
        /// <param name="path">Path to the directory containing configuration information.</param>
        /// <param name="sections">Collection of keyed ConfigurationSections.</param>
        /// <remarks>Loads the configuration with the same name as the service type (e.g. [ServiceTypeName].XML. This
        /// method was constructed this way to enable some level of unit testing. ConfigurationSection cannot be created or mocked.</remarks>
        internal void LoadConfiguration(string path, KeyedCollection <string, ConfigurationSection> sections)
        {
            Guard.ArgumentNotNullOrWhitespace(path, nameof(path));
            Guard.ArgumentNotNull(sections, nameof(sections));

            _eventSource?.ServicePartitionConfigurationChanged(_serviceName, _partitionId, _replicaOrInstanceId);

            try
            {
                // Create an MD5 to hash the values to determine if they have changed.
                using (MD5 md5 = MD5.Create())
                {
                    // First load the configuration section for this service type.
                    if (sections.Contains(_serviceNameUri.AbsoluteUri))
                    {
                        // Get the section and calculate the hash.
                        ConfigurationSection section = sections[_serviceNameUri.AbsoluteUri];
                        string sectionContent        = string.Join("|", section.Parameters.Select(p => $"{p.Name}~{p.Value}"));
                        byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(sectionContent));

                        if (false == CompareHashes(hash, _configSectionHash))
                        {
                            // Set the provider values.
                            _configSection     = section;
                            _configSectionHash = hash;

                            // If necessary, call the property changed event.
                            OnConfigurationPropertyChangedEvent?.Invoke(this, EventArgs.Empty);
                        }
                    }

                    // Second, attempt to load a file of the format <service name>.json. Use the last segment of the service name Uri for the file name.
                    string filepath = Path.Combine(path, $"{_serviceName}.json");

                    // Stream the file while calculating the MD5 hash of the contents.
                    using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
                        using (CryptoStream cs = new CryptoStream(fs, md5, CryptoStreamMode.Read))
                            using (StreamReader reader = new StreamReader(cs))
                            {
                                string json = reader.ReadToEnd();
                                JsonSerializerSettings settings = new JsonSerializerSettings();
                                settings.Converters.Add(new IsoDateTimeConverter());
                                TConfiguration result   = JsonConvert.DeserializeObject <TConfiguration>(json, settings);
                                byte[]         fileHash = md5.Hash;
                                if (false == CompareHashes(fileHash, _configFileHash))
                                {
                                    // If necessary, call the class changed event.
                                    OnConfigurationClassChangedEvent?.Invoke(this, new ConfigurationClassChangedEventArgs <TConfiguration>(_serviceName, _configFile, result));

                                    // Set the provider values.
                                    _configFileHash = fileHash;
                                    _configFile     = result;
                                }
                            }
                }
            }
            catch (FileNotFoundException) { }
        }
Example #2
0
        /// <summary>
        /// QueueService constructor.
        /// </summary>
        /// <param name="context">StatefulServiceContext instance.</param>
        /// <param name="eventSource">IStatefulServiceEventSource instance for diagnostic logging.</param>
        public GenericInt64PartitionService(StatefulServiceContext context, IServiceEventSource eventSource)
            : base(context)
        {
            // Check passed parameters.
            Guard.ArgumentNotNull(context, nameof(context));
            Guard.ArgumentNotNull(eventSource, nameof(eventSource));

            _eventSource = eventSource;

            TokenSource = new CancellationTokenSource();

            // Parse the service name into an application name.
            string appName = (Context.ServiceName.Segments.Length > 2) ? Context.ServiceName.Segments[1].Replace("/", "") : "";

            Application = new Uri($"fabric:/{appName}");

            ConfigurationProvider = new ConfigurationProvider <TConfiguration>(context.ServiceName, context.CodePackageActivationContext, eventSource, Context.PartitionId, Context.ReplicaOrInstanceId);
            _eventSource?.ServicePartitionConfigurationChanged(Context.ServiceTypeName, Context.PartitionId, Context.ReplicaOrInstanceId);
        }