public void EntitiesPerUploadFileFromBindingAttribute()
        {
            // Arrange
            var binding = new Binding
            {
                Name             = "MyNestedBinding",
                SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                },
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.EntitiesPerUploadFile, AttributeValue = "31"
                                    } }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual(31, config.DatabusConfiguration.EntitiesPerUploadFile, "EntitiesPerUploadFile was not equal");
        }
        /// <summary>
        /// Transform the data from SQL to a restful API via Data Bus
        /// </summary>
        /// <param name="bindingExecution"></param>
        /// <param name="binding"></param>
        /// <param name="entity"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <long> TransformDataAsync(
            BindingExecution bindingExecution,
            Binding binding,
            Entity entity,
            CancellationToken cancellationToken)
        {
            bindingExecution.CheckWhetherArgumentIsNull(nameof(bindingExecution));
            binding.CheckWhetherArgumentIsNull(nameof(binding));
            entity.CheckWhetherArgumentIsNull(nameof(entity));

            try
            {
                SwitchLogLevel(await this.GetPluginLogLevelSystemAttributeValue() ?? LogLevel.Warning);

                this.LogDebug($"Entering HierarchicalDataTransformer.TransformDataAsync(BindingId = {binding.Id})", bindingExecution);

                HierarchicalConfiguration config = this.GetConfiguration(binding, bindingExecution, entity);
                this.LogDebug($"Plugin Configuration: {config}", bindingExecution);

                JobData jobData = await this.GetJobData(binding, bindingExecution, entity);

                this.LogDebug($"JobData: {Serialize(jobData)}", bindingExecution);

                return(await this.RunDatabusAsync(config, jobData, bindingExecution, cancellationToken));
            }
            catch (Exception e)
            {
                this.LogError($"HierarchicalDataTransformer.TransformDataAsync threw an exception: {e}", e, bindingExecution);
                throw;
            }
        }
        public void UploadToUrlFromBindingAttribute()
        {
            // Arrange
            var binding = new Binding
            {
                Name             = "MyNestedBinding",
                SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                },
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.UploadToUrl, AttributeValue = "true"
                                    } }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsTrue(config.DatabusConfiguration.UploadToUrl, "UploadToUrl was not true");
        }
        public void HttpVerbFromEntityAttribute()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection      = new Connection(),
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.HttpMethod, AttributeValue = "Put"
                                    } }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual(HttpMethod.Put, config.DatabusConfiguration.UrlMethod, "UrlMethod was not equal");
        }
        public void EmptyClientSpecificConfigurationKeyResultsInNoExtraConfiguration()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection = new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName =
                                AttributeNames
                                .ClientSpecificConfigurationKey,
                            AttributeValue = string.Empty
                        }
                    }
                }
            };                             // No ClientSpecificConfiguration attribute
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsNull(config.ClientSpecificConfiguration, "ClientSpecificConfiguration should have been null");
        }
        public void ReadConnectionStringFromSourceConnectionString()
        {
            // Arrange
            var binding = new Binding
            {
                Name             = "MyNestedBinding",
                SourceConnection = new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName  = AttributeNames.ConnectionString,
                            AttributeValue =
                                "someConnectionString;with-stuff;in-it"
                        }
                    }
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("someConnectionString;with-stuff;in-it", config.DatabusConfiguration.ConnectionString, "Connection string was not equal.");
        }
        public void InvalidClientSpecificConfigurationKey()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection = new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName =
                                AttributeNames
                                .ClientSpecificConfigurationKey,
                            AttributeValue = "UPMC.Garbage"
                        }
                    }
                }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var ex = Assert.ThrowsException <TargetInvocationException>(() => this.privateMethodRunner.Invoke("GetConfiguration", args));

            Assert.IsInstanceOfType(ex.InnerException, typeof(InvalidOperationException));
        }
        public void UnsupportedHttpVerbThrowsException()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection      = new Connection(),
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.HttpMethod, AttributeValue = "Delete"
                                    } }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var ex = Assert.ThrowsException <TargetInvocationException>(() => this.privateMethodRunner.Invoke("GetConfiguration", args));

            Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentException));
        }
        public void LocalSaveFolderFromBindingAttribute()
        {
            // Arrange
            var binding = new Binding
            {
                Name             = "MyNestedBinding",
                SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                },
                AttributeValues =
                {
                    new ObjectAttributeValue {
                        AttributeName = AttributeNames.LocalSaveFolder, AttributeValue = "D:\\MyDirectory"
                    },
                    new ObjectAttributeValue {
                        AttributeName = AttributeNames.WriteTempFilesToDisk, AttributeValue = "False"
                    }
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("D:\\MyDirectory\\MyNestedBinding_1_2", config.DatabusConfiguration.LocalSaveFolder, "LocalSaveFolder was not equal");
        }
        public void DetailedTempFilesFromBindingAttribute()
        {
            // Arrange
            var binding = new Binding
            {
                Name             = "MyNestedBinding",
                SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                },
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.DetailedTempFiles, AttributeValue = "false"
                                    } }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsFalse(config.DatabusConfiguration.WriteDetailedTemporaryFilesToDisk, "WriteDetailedTemporaryFilesToDisk was not false");
        }
        private void LogDebug(string message, BindingExecution bindingExecution = null)
        {
            Log.Logger.Debug(message);

            if (bindingExecution != null)
            {
                this.loggingRepository.LogInformation(bindingExecution, message);
            }
        }
        public bool CanHandle(BindingExecution bindingExecution, Binding binding, Entity destinationEntity)
        {
            if (binding == null)
            {
                throw new ArgumentException("Binding cannot be null.");
            }

            return(binding.BindingType == HierarchicalDataTransformer.NestedBindingTypeName);
        }
        protected override async Task <long> LoadStagingEntityAsync(
            BindingExecution bindingExecution,
            Binding binding,
            Entity entity,
            CancellationToken cancellationToken)
        {
            bindingExecution.CheckWhetherArgumentIsNull(nameof(bindingExecution));
            binding.CheckWhetherArgumentIsNull(nameof(bindingExecution));
            entity.CheckWhetherArgumentIsNull(nameof(entity));

            using (IProcessingContextWrapper processingContextWrapper =
                       this.processingContextWrapperFactory.CreateProcessingContextWrapper())
            {
                string pathToRExe = processingContextWrapper
                                    .GetSystemAttribute(AttributeName.PathToRExecutable)?.AttributeValueText;

                string pathToRModelFolder = processingContextWrapper
                                            .GetSystemAttribute(AttributeName.PathToRModelFolder)?.AttributeValueText;

                string sourceConnectionDatabase = binding.SourceConnection.Database;

                var rScriptSourceEntityInfos = new List <RScriptSourceEntityInfo>();
                foreach (int sourceEntityId in binding.SourcedByEntities.Select(e => e.SourceEntityId))
                {
                    Entity sourceEntity = await this.metadataServiceClient.GetEntityAsync(sourceEntityId);

                    rScriptSourceEntityInfos.Add(new RScriptSourceEntityInfo
                    {
                        DatabaseName = sourceEntity.DatabaseName,
                        EntityName   = sourceEntity.EntityName,
                        SchemaName   = sourceEntity.SchemaName,
                    });

                    // HACK: sourceConnectionDatabase is always set to master which doesn't work when R is trying to update the table
                    sourceConnectionDatabase = sourceEntity.DatabaseName;
                }

                var rScriptParameters = new RScriptParameters
                {
                    BindingScript             = binding.Script,
                    Script                    = binding.UserDefinedSql,
                    CompletedSuccessfullyText = CompletedSuccessfullyText,
                    DestinationDatabaseName   = entity.Connection.Database,
                    DestinationServer         = entity.Connection.Server,
                    DestinationSystemTypeCode = entity.Connection.DataSystemTypeCode,
                    PathToRModelFolder        = pathToRModelFolder,
                    SourceConnectionDatabase  = sourceConnectionDatabase,
                    SourceDataSystemTypeCode  = binding.SourceConnection.DataSystemTypeCode,
                    SourceServer              = binding.SourceConnection.Server,
                    SourceEntities            = rScriptSourceEntityInfos
                };

                var augmentedRScript = new ScriptParser().GetAugmentedRScript(rScriptParameters);

                return(await this.StartScriptR(pathToRExe, bindingExecution, augmentedRScript));
            }
        }
        private string BuildLocalSaveFolder(string baseUrl, Binding binding, BindingExecution bindingExecution)
        {
            if (baseUrl.IsNullOrWhiteSpace())
            {
                return(null);
            }

            return(Path.Combine(baseUrl, $"{binding.Name}_{bindingExecution.BindingId}_{bindingExecution.Id}"));
        }
        private void LogError(string message, Exception e, BindingExecution bindingExecution = null)
        {
            Log.Logger.Error(message, e);

            if (bindingExecution != null)
            {
                this.loggingRepository.LogError(bindingExecution, e);
            }
        }
        public override bool CanHandle(BindingExecution bindingExecution, Binding binding, Entity destinationEntity)
        {
            binding.CheckWhetherArgumentIsNull(nameof(binding));
            destinationEntity.CheckWhetherArgumentIsNull(nameof(destinationEntity));

            return(DataSystemTypeCode.AcceptableDatabaseTypes.Contains(binding.SourceConnection.DataSystemTypeCode) &&
                   destinationEntity.Connection.DataSystemTypeCode == DataSystemTypeCode.SqlServer &&
                   binding.UserDefinedSql != null &&
                   new ScriptParser().HasRCode(binding.UserDefinedSql));
        }
        public void ReadFullConfiguration()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection = new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName =
                                AttributeNames
                                .ClientSpecificConfigurationKey,
                            AttributeValue = "UPMC.PHI"
                        }
                    }
                }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("server=localhost;initial catalog=SAM;Trusted_Connection=True;", config.DatabusConfiguration.ConnectionString, "Connection string was not equal.");
            Assert.AreEqual("http://localhost/MyService/MyEndpoint", config.DatabusConfiguration.Url, "Service endpoint was not equal.");
            Assert.AreEqual(100, config.DatabusConfiguration.MaximumEntitiesToLoad, "MaximumEntitiesToLoad was not equal");
            Assert.AreEqual(10, config.DatabusConfiguration.EntitiesPerBatch, "EntitiesPerBatch was not equal");
            Assert.AreEqual(100, config.DatabusConfiguration.EntitiesPerUploadFile, "EntitiesPerUploadFile was not equal");
            Assert.AreEqual($"C:\\Catalyst\\databus\\{binding.Name}_{bindingExecution.BindingId}_{bindingExecution.Id}", config.DatabusConfiguration.LocalSaveFolder, "LocalSaveFolder was not equal");
            Assert.AreEqual(true, config.DatabusConfiguration.WriteTemporaryFilesToDisk, "WriteTemporaryFilesToDisk was not equal");
            Assert.AreEqual(true, config.DatabusConfiguration.WriteDetailedTemporaryFilesToDisk, "WriteDetailedTemporaryFilesToDisk was not equal");
            Assert.AreEqual(false, config.DatabusConfiguration.CompressFiles, "CompressFiles was not equal");
            Assert.AreEqual(false, config.DatabusConfiguration.UploadToUrl, "UploadToUrl was not equal");
            Assert.AreEqual(HttpMethod.Post, config.DatabusConfiguration.UrlMethod, "UrlMethod was not equal");

            Assert.IsTrue(config.ClientSpecificConfiguration is UpmcSpecificConfiguration, "ClientSpecificConfiguration was not of type UpmcSpecificConfiguration.");
            var upmcConfig = (UpmcSpecificConfiguration)config.ClientSpecificConfiguration;

            Assert.AreEqual("phi_name", upmcConfig.Name, "Name was not equal");
            Assert.AreEqual("phi_base", upmcConfig.BaseUrl, "BaseUrl was not equal");
            Assert.AreEqual("phi_app_id", upmcConfig.AppId, "AppId was not equal");
            Assert.AreEqual("phi_app_sec", upmcConfig.AppSecret, "AppSecret was not equal");
            Assert.AreEqual("phi_tenant_sec", upmcConfig.TenantSecret, "TenantSecret was not equal");
        }
        /// <summary>
        /// Gets configuration from config file (json) unless specified in attributes on the binding or entity
        /// </summary>
        /// <param name="binding"></param>
        /// <param name="bindingExecution"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        private HierarchicalConfiguration GetConfiguration(Binding binding, BindingExecution bindingExecution, Entity entity)
        {
            string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            if (directoryName == null)
            {
                throw new InvalidOperationException("Could not find plugin configuration file base path.");
            }

            string  fullPath             = Path.Combine(directoryName, Resources.DefaultConfigFileName);
            string  json                 = File.ReadAllText(fullPath);
            dynamic deserialized         = JsonConvert.DeserializeObject(json);
            dynamic databusConfiguration = deserialized.DatabusConfiguration;

            var queryConfig = new QueryConfig
            {
                ConnectionString = this.BuildConnectionString(binding),
                Url = this.BuildUrl(entity) ?? databusConfiguration.Url,
                MaximumEntitiesToLoad = this.GetAttributeInt(binding.AttributeValues, AttributeNames.MaxEntitiesToLoad)
                                        ?? databusConfiguration.MaximumEntitiesToLoad,
                EntitiesPerBatch = this.GetAttributeInt(binding.AttributeValues, AttributeNames.EntitiesPerBatch)
                                   ?? databusConfiguration.EntitiesPerBatch,
                EntitiesPerUploadFile = this.GetAttributeInt(binding.AttributeValues, AttributeNames.EntitiesPerUploadFile)
                                        ?? databusConfiguration.EntitiesPerUploadFile,
                LocalSaveFolder = this.BuildLocalSaveFolder(
                    binding.AttributeValues.GetAttributeTextValue(AttributeNames.LocalSaveFolder),
                    binding,
                    bindingExecution)
                                  ?? this.BuildLocalSaveFolder(Convert.ToString(databusConfiguration.LocalSaveFolder), binding, bindingExecution),
                WriteTemporaryFilesToDisk = this.GetAttributeBool(binding.AttributeValues, AttributeNames.WriteTempFilesToDisk)
                                            ?? databusConfiguration.WriteTemporaryFilesToDisk,
                WriteDetailedTemporaryFilesToDisk = this.GetAttributeBool(binding.AttributeValues, AttributeNames.DetailedTempFiles)
                                                    ?? databusConfiguration.WriteDetailedTemporaryFilesToDisk,
                CompressFiles = this.GetAttributeBool(binding.AttributeValues, AttributeNames.CompressFiles)
                                ?? databusConfiguration.CompressFiles,
                UploadToUrl = this.GetAttributeBool(binding.AttributeValues, AttributeNames.UploadToUrl)
                              ?? databusConfiguration.UploadToUrl,
                UrlMethod = this.GetHtmlMethod(entity.AttributeValues?.GetAttributeTextValue(AttributeNames.HttpMethod))
                            ?? this.GetHtmlMethod(Convert.ToString(databusConfiguration.UrlMethod))
                            ?? HttpMethod.Post
            };

            this.CreateLocalSaveFolderIfNotExists(queryConfig);

            var hierarchicalConfig = new HierarchicalConfiguration
            {
                ClientSpecificConfiguration = this.GetClientSpecificConfiguration(entity, deserialized.ClientSpecificConfigurations),
                DatabusConfiguration        = queryConfig
            };

            return(hierarchicalConfig);
        }
        /// <summary>
        /// Execute DataBus with the given configuration and job data
        /// </summary>
        /// <param name="config"></param>
        /// <param name="jobData"></param>
        /// <param name="bindingExecution"></param>
        /// <param name="cancellationToken"></param>
        private async Task <long> RunDatabusAsync(
            HierarchicalConfiguration config,
            JobData jobData,
            BindingExecution bindingExecution,
            CancellationToken cancellationToken)
        {
            var container = new UnityContainer();

            // TODO - need to eventually remove anything UPMC-specific from this plugin.
            UpmcSpecificConfiguration upmcSpecificConfiguration = (UpmcSpecificConfiguration)config.ClientSpecificConfiguration;

            if (upmcSpecificConfiguration != null)
            {
                container.RegisterInstance <IHttpRequestInterceptor>(
                    new UpmcHmacAuthorizationRequestInterceptor(upmcSpecificConfiguration.AppId, upmcSpecificConfiguration.AppSecret, upmcSpecificConfiguration.TenantSecret));
            }

            var rowCounter = new RowCounterBatchEventsLogger(this.loggingRepository, bindingExecution);

            ILogger databusLogger = CreateLogger <DatabusRunner>();

            container.RegisterInstance(databusLogger);
            container.RegisterInstance <IBatchEventsLogger>(rowCounter);

            var jobEventsLogger = new JobEventsLogger(this.loggingRepository, bindingExecution);

            container.RegisterInstance <IJobEventsLogger>(jobEventsLogger);
            container.RegisterInstance <IQuerySqlLogger>(new QuerySqlLogger(this.loggingRepository, bindingExecution));
            container.RegisterInstance <IHttpResponseLogger>(new MyHttpResponseLogger(this.loggingRepository, bindingExecution));

            var job = new Job {
                Config = config.DatabusConfiguration, Data = jobData
            };

            this.LogDebug($"Executing DatabusRunner.RunRestApiPipeline with:\n\tcontainer: {Serialize(container)}\n\tjob: {Serialize(job)}");

            try
            {
                await this.runner.RunRestApiPipelineAsync(container, job, cancellationToken);
            }
            catch (Exception e)
            {
                this.LogError($"Databus threw an error: {e}", e);
                throw;
            }

            SetupSerilogLogger(); // re-setup logger as Databus is closing it
            this.LogDebug($"Databus execution complete.  Processed { jobEventsLogger.NumberOfEntities } records.");
            return(jobEventsLogger.NumberOfEntities);
        }
        private async Task <long> StartScriptR(string pathToRExe, BindingExecution bindingExecution, string script)
        {
            script.CheckWhetherArgumentIsNullOrWhiteSpace(nameof(script));

            this.loggingRepository.LogExecutionStatement(
                this.GetType().Name,
                nameof(this.StartScriptR),
                bindingExecution.EntityExecution.BatchExecution,
                script,
                bindingExecution.EntityExecution,
                bindingExecution);

            var result = await new MyRExecutionService().ExecuteScriptAsync(pathToRExe, script, true, CompletedSuccessfullyText);

            return(this.FinishScriptR(bindingExecution, result, script));
        }
        private async Task <JobData> GetJobData(Binding binding, BindingExecution bindingExecution, Entity destinationEntity)
        {
            var jobData = new JobData();

            Binding[] allBindings = await this.GetBindingsForEntityAsync(destinationEntity);

            this.ValidateHierarchicalBinding(binding, allBindings);

            List <DataSource> dataSources = new List <DataSource>();

            await this.GenerateDataSources(binding, bindingExecution, allBindings, destinationEntity, dataSources, null, "$", isFirst : true);

            var jobDataTopLevelDataSource = dataSources.First();

            jobData.TopLevelDataSource = jobDataTopLevelDataSource as TopLevelDataSource;
            jobData.MyDataSources      = dataSources.ToList();

            return(jobData);
        }
        public void MissingConnectionStringThrowsException()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection()
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var ex = Assert.ThrowsException <TargetInvocationException>(() => this.privateMethodRunner.Invoke("GetConfiguration", args));

            Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentException));
        }
        public void ReadUpmcNonPhiSpecificValues()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection = new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName =
                                AttributeNames
                                .ClientSpecificConfigurationKey,
                            AttributeValue = "UPMC.NonPHI"
                        }
                    }
                }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsTrue(config.ClientSpecificConfiguration is UpmcSpecificConfiguration, "ClientSpecificConfiguration was not of type UpmcSpecificConfiguration.");
            var upmcConfig = (UpmcSpecificConfiguration)config.ClientSpecificConfiguration;

            Assert.AreEqual("non_phi_name", upmcConfig.Name, "Name was not equal");
            Assert.AreEqual("non_phi_base", upmcConfig.BaseUrl, "BaseUrl was not equal");
            Assert.AreEqual("non_phi_app_id", upmcConfig.AppId, "AppId was not equal");
            Assert.AreEqual("non_phi_app_sec", upmcConfig.AppSecret, "AppSecret was not equal");
            Assert.AreEqual("non_phi_tenant_sec", upmcConfig.TenantSecret, "TenantSecret was not equal");
        }
        /// <summary>
        /// <see cref="IDataTransformer.CanHandle"/>
        /// </summary>
        /// <param name="bindingExecution"></param>
        /// <param name="binding"></param>
        /// <param name="destinationEntity"></param>
        /// <returns></returns>
        public bool CanHandle(BindingExecution bindingExecution, Binding binding, Entity destinationEntity)
        {
            Binding topMost;

            try
            {
                Binding[] allBindings = this.GetBindingsForEntityAsync(destinationEntity).Result;
                topMost = this.GetTopMostBinding(allBindings);
            }
            catch (Exception e)
            {
                this.LogError(
                    $"HierarchicalDataTransformer.CanHandle threw exception for binding [{Serialize(binding)}], bindingExecution [{Serialize(bindingExecution)}",
                    e,
                    bindingExecution);
                throw;
            }

            return(binding.BindingType == NestedBindingTypeName &&
                   binding.Id == topMost.Id &&
                   binding.SourceConnection.DataSystemTypeCode == DataSystemTypeCode.SqlServer);
        }
        public void BuildConnectionStringFromSourceConnectionServerAndDatabase()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("server=localhost;initial catalog=SAM;Trusted_Connection=True;", config.DatabusConfiguration.ConnectionString, "Connection string was not equal.");
        }
        public void DefaultEntitiesPerBatchFromConfigFile()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual(10, config.DatabusConfiguration.EntitiesPerBatch, "EntitiesPerBatch was not equal");
        }
        public void DefaultLocalSaveFolderFromConfigFile()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("C:\\Catalyst\\databus\\MyNestedBinding_1_2", config.DatabusConfiguration.LocalSaveFolder, "LocalSaveFolder was not equal");
        }
        public void DefaultUploadToUrlFromConfigFile()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsFalse(config.DatabusConfiguration.UploadToUrl, "UploadToUrl was not false");
        }
        public void ReadConfigurationWithoutClientSpecificConfiguration()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity {
                Connection = new Connection()
            };                                                                    // No ClientSpecificConfiguration attribute
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.IsNull(config.ClientSpecificConfiguration, "ClientSpecificConfiguration should have been null");
        }
        public void UrlFromEntityAndConnectionAttributes()
        {
            // Arrange
            var binding = new Binding {
                Name = "MyNestedBinding", SourceConnection = new Connection {
                    Server = "localhost", Database = "SAM"
                }
            };
            var bindingExecution = new BindingExecution {
                BindingId = 1, Id = 2
            };
            var destinationEntity = new Entity
            {
                Connection =
                    new Connection
                {
                    AttributeValues =
                    {
                        new ObjectAttributeValue
                        {
                            AttributeName  = AttributeNames.ServiceUrl,
                            AttributeValue = "https://some-server/SomeService"
                        }
                    }
                },
                AttributeValues = { new ObjectAttributeValue {
                                        AttributeName = AttributeNames.ServiceEndpoint, AttributeValue = "SomeEndpoint"
                                    } }
            };
            var args = new object[] { binding, bindingExecution, destinationEntity };

            // Act
            var config = (HierarchicalConfiguration)this.privateMethodRunner.Invoke("GetConfiguration", args);

            // Assert
            Assert.AreEqual("https://some-server/SomeService/SomeEndpoint", config.DatabusConfiguration.Url, "Url was not equal");
        }