public GitDatabaseClient(IApiConnection apiConnection) : base(apiConnection) { Blob = new BlobsClient(apiConnection); Tree = new TreesClient(apiConnection); Tag = new TagsClient(apiConnection); Commit = new CommitsClient(apiConnection); Reference = new ReferencesClient(apiConnection); }
public async Task RequestsCorrectUrlWithRepositoryId() { var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); await client.GetRecursive(1, "123456ABCD"); connection.Received().Get <TreeResponse>(Arg.Is <Uri>(u => u.ToString() == "repositories/1/git/trees/123456ABCD?recursive=1")); }
public async Task RequestsCorrectUrlWithRepositoryId() { var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); await client.GetRecursive(1, "123456ABCD"); connection.Received().Get<TreeResponse>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/git/trees/123456ABCD?recursive=1")); }
public void RequestsCorrectUrl() { var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); client.GetRecursive("fake", "repo", "123456ABCD"); connection.Received().Get<TreeResponse>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/git/trees/123456ABCD?recursive=1")); }
public async Task RequestsCorrectUrl() { var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); await client.Get("fake", "repo", "123456ABCD"); connection.Received().Get <TreeResponse>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/git/trees/123456ABCD")); }
/// <summary> /// Instantiates a new GitHub Git API client. /// </summary> /// <param name="apiConnection">An API connection</param> public GitDatabaseClient(IApiConnection apiConnection) : base(apiConnection) { Blob = new BlobsClient(apiConnection); Tree = new TreesClient(apiConnection); Tag = new TagsClient(apiConnection); Commit = new CommitsClient(apiConnection); Reference = new ReferencesClient(apiConnection); }
public void RequestsCorrectUrl() { var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); client.GetRecursive("fake", "repo", "123456ABCD"); connection.Received().Get <TreeResponse>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/git/trees/123456ABCD?recursive=1"), null); }
public async Task EnsuresArgumentsNotNull() { var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); await Assert.ThrowsAsync<ArgumentNullException>(() => client.Create(null, "name", new NewTree())); await Assert.ThrowsAsync<ArgumentException>(() => client.Create("", "name", new NewTree())); await Assert.ThrowsAsync<ArgumentNullException>(() => client.Create("owner", null, new NewTree())); await Assert.ThrowsAsync<ArgumentException>(() => client.Create("owner", "", new NewTree())); }
public void PostsToCorrectUrlWithRepositoryId() { var newTree = new NewTree(); var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); client.Create(1, newTree); connection.Received().Post <TreeResponse>(Arg.Is <Uri>(u => u.ToString() == "repositories/1/git/trees"), newTree); }
public void PostsToCorrectUrl() { var newTree = new NewTree(); var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); client.Create("fake", "repo", newTree); connection.Received().Post <TreeResponse>(Arg.Is <Uri>(u => u.ToString() == "repos/fake/repo/git/trees"), newTree); }
public void PostsToCorrectUrl() { var newTree = new NewTree(); var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); client.Create("fake", "repo", newTree); connection.Received().Post<TreeResponse>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/git/trees"), newTree); }
public async Task EnsuresNonNullArguments() { var client = new TreesClient(Substitute.For<IApiConnection>()); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetRecursive(null, "name", "123456ABCD")); await Assert.ThrowsAsync<ArgumentException>(() => client.GetRecursive("", "name", "123456ABCD")); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetRecursive("owner", null, "123456ABCD")); await Assert.ThrowsAsync<ArgumentException>(() => client.GetRecursive("owner", "", "123456ABCD")); await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetRecursive("owner", "name", null)); await Assert.ThrowsAsync<ArgumentException>(() => client.GetRecursive("owner", "name", "")); }
public async Task EnsureExceptionIsThrownWhenModeIsNotProvided() { var newTree = new NewTree(); newTree.Tree.Add(new NewTreeItem { Path = "README.md", Type = TreeType.Blob, Sha = "2e1a73d60f004fd842d4bad28aa42392d4f35d28" }); var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); await AssertEx.Throws<ArgumentException>( async () => await client.Create("fake", "repo", newTree)); }
public async Task EnsuresArgumentsNotNull() { var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); await AssertEx.Throws <ArgumentNullException>(async() => await client.Create(null, "name", new NewTree())); await AssertEx.Throws <ArgumentException>(async() => await client.Create("", "name", new NewTree())); await AssertEx.Throws <ArgumentNullException>(async() => await client.Create("owner", null, new NewTree())); await AssertEx.Throws <ArgumentException>(async() => await client.Create("owner", "", new NewTree())); }
public async Task EnsureExceptionIsThrownWhenModeIsNotProvidedWithRepositoryId() { var newTree = new NewTree(); newTree.Tree.Add(new NewTreeItem { Path = "README.md", Type = TreeType.Blob, Sha = "2e1a73d60f004fd842d4bad28aa42392d4f35d28" }); var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); await Assert.ThrowsAsync <ArgumentException>( () => client.Create(1, newTree)); }
public async Task EnsuresNonNullArguments() { var client = new TreesClient(Substitute.For <IApiConnection>()); await AssertEx.Throws <ArgumentNullException>(async() => await client.GetRecursive(null, "name", "123456ABCD")); await AssertEx.Throws <ArgumentException>(async() => await client.GetRecursive("", "name", "123456ABCD")); await AssertEx.Throws <ArgumentNullException>(async() => await client.GetRecursive("owner", null, "123456ABCD")); await AssertEx.Throws <ArgumentException>(async() => await client.GetRecursive("owner", "", "123456ABCD")); await AssertEx.Throws <ArgumentNullException>(async() => await client.GetRecursive("owner", "name", null)); await AssertEx.Throws <ArgumentException>(async() => await client.GetRecursive("owner", "name", "")); }
public async Task EnsuresNonNullArguments() { var connection = Substitute.For <IApiConnection>(); var client = new TreesClient(connection); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Create(null, "name", new NewTree())); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Create("owner", null, new NewTree())); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Create("owner", "name", null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Create(1, null)); await Assert.ThrowsAsync <ArgumentException>(() => client.Create("", "name", new NewTree())); await Assert.ThrowsAsync <ArgumentException>(() => client.Create("owner", "", new NewTree())); }
public async Task EnsuresNonNullArguments() { var client = new TreesClient(Substitute.For <IApiConnection>()); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Get(null, "name", "123456ABCD")); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Get("owner", null, "123456ABCD")); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Get("owner", "name", null)); await Assert.ThrowsAsync <ArgumentNullException>(() => client.Get(1, null)); await Assert.ThrowsAsync <ArgumentException>(() => client.Get("owner", "", "123456ABCD")); await Assert.ThrowsAsync <ArgumentException>(() => client.Get("", "name", "123456ABCD")); await Assert.ThrowsAsync <ArgumentException>(() => client.Get("owner", "name", "")); await Assert.ThrowsAsync <ArgumentException>(() => client.Get(1, "")); }
public void PostsToCorrectUrlWithRepositoryId() { var newTree = new NewTree(); var connection = Substitute.For<IApiConnection>(); var client = new TreesClient(connection); client.Create(1, newTree); connection.Received().Post<TreeResponse>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/git/trees"), newTree); }
public static void RegisterServices(IServiceCollection services, IConfiguration configuration, IHostingEnvironment env, Dependencies dependencies, Caching caching) { // Put caching config in container //var caching = configuration.GetSection("Caching").Get<InternalModel.AppSettings.Caching>(); services.AddSingleton(typeof(InternalModel.AppSettings.Caching), caching); // Load config data //var dependencies = configuration.GetSection("Dependencies").Get<InternalModel.AppSettings.Dependencies>(); services.AddSingleton(typeof(InternalModel.AppSettings.Dependencies), dependencies); // --------------------------------- // -- Configure GitHub API access -- // --------------------------------- // Read in the github api token value (either from local secrets or from environment variables) var gitHubTokenSecretName = $"GithubAccessToken"; var gitHubAccessToken = configuration[gitHubTokenSecretName]; if (string.IsNullOrWhiteSpace(gitHubAccessToken)) { throw new ArgumentException($"No GitHub API token variable named '{gitHubTokenSecretName}' found in local secrets or enviornment variables"); } // Setup GitHub V3 Api clients var gitHubV3ApiCredentials = new Credentials(gitHubAccessToken); var gitHubClient = new GitHubClient(new ProductHeaderValue("RepositoryAnalyticsApi"), new Uri(dependencies.GitHub.V3ApiUrl)); gitHubClient.Credentials = gitHubV3ApiCredentials; var gitHubTreesClient = new TreesClient(new ApiConnection(new Connection(new ProductHeaderValue("RepositoryAnalyticsApi"), new Uri(dependencies.GitHub.V3ApiUrl)) { Credentials = gitHubV3ApiCredentials })); // Setup GitHub GraphQL client var requestHeaders = new NameValueCollection(); requestHeaders.Add("Authorization", $"Bearer {gitHubAccessToken}"); requestHeaders.Add("User-Agent", "RepositoryAnalyticsApi"); var graphQLClient = new GraphQLClient(new HttpClient(), dependencies.GitHub.GraphQlApiUrl, requestHeaders); // ---------------------------- // -- Configure the Database -- // ---------------------------- var dbConnectionStringBuilder = new DbConnectionStringBuilder(); dbConnectionStringBuilder.ConnectionString = dependencies.Database.ConnectionString; // It's possible to use things like windows auth when running outside of a container so check for the User Id // value in the connection string before trying to look for a local secret pwd if (dbConnectionStringBuilder.ConnectionString.Contains("User Id", StringComparison.OrdinalIgnoreCase)) { Log.Logger.Debug("User Id found in connection string, attempting to integrate password into connection string"); var dbPasswordSecretName = $"DatabasePassword"; var dbPassword = configuration[dbPasswordSecretName]; if (string.IsNullOrWhiteSpace(dbPassword)) { throw new ArgumentException($"No DB password token variable named '{dbPasswordSecretName}' found in local secrets or enviornment variables"); } else { Log.Logger.Debug("Password found in configuration, adding it to connection string"); } dbConnectionStringBuilder["Password"] = dbPassword; } else { Log.Logger.Debug("No User Id found in connection string, assuming passowrd less (E.G. Windows Auth) authentication is in use"); } var connestionString = dbConnectionStringBuilder.ConnectionString; // Figure out which DB type needs to be loaded var formattedDbType = dependencies.Database.Type.ToLower().Replace(" ", string.Empty); if (formattedDbType == "sqlserver") { services.AddDbContext <RepositoryAnalysisContext>(options => { options.UseSqlServer(connestionString); }); } else if (formattedDbType == "postgresql") { services.AddDbContext <RepositoryAnalysisContext>(options => { options.UseNpgsql(connestionString); }); } else { throw new ArgumentException("Unsupported DB Type, only PostgreSQL and SQL Server are supported"); } // Now setup all the mapping between the Entity Framework objects var config = new MapperConfiguration(cfg => { var versionManager = new VersionManager(); cfg.AddCollectionMappers(); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryCurrentState, ServiceModel.RepositoryDevOpsIntegrations>(); cfg.CreateMap <ServiceModel.RepositoryDevOpsIntegrations, Repositories.Model.EntityFramework.RepositoryCurrentState>(); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryCurrentState, ServiceModel.RepositoryCurrentState>() .ForMember(dest => dest.Id, opt => opt.MapFrom(source => source.RepositoryId)) .ForMember(dest => dest.DevOpsIntegrations, opt => opt.MapFrom(source => source)); cfg.CreateMap <ServiceModel.RepositoryCurrentState, Repositories.Model.EntityFramework.RepositoryCurrentState>() .ForMember(dest => dest.RepositoryId, opt => opt.MapFrom(source => source.Id)) .ForMember(dest => dest.ContinuousDelivery, opt => opt.MapFrom(source => source.DevOpsIntegrations.ContinuousDelivery)) .ForMember(dest => dest.ContinuousIntegration, opt => opt.MapFrom(source => source.DevOpsIntegrations.ContinuousIntegration)) .ForMember(dest => dest.ContinuousDeployment, opt => opt.MapFrom(source => source.DevOpsIntegrations.ContinuousDeployment)); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryDependency, ServiceModel.RepositoryDependency>(); cfg.CreateMap <ServiceModel.RepositoryDependency, Repositories.Model.EntityFramework.RepositoryDependency>() .ForMember(dest => dest.PaddedVersion, opt => opt.MapFrom(source => versionManager.GetPaddedVersion(source.Version))) .ForMember(dest => dest.MinorVerison, opt => opt.MapFrom(source => versionManager.GetMinorVersion(source.Version))) .ForMember(dest => dest.PreReleaseSemanticVersion, opt => opt.MapFrom(source => versionManager.GetPreReleaseVersion(source.Version))) .EqualityComparison((source, dest) => $"{source.Name}|{source.Version}|{source.RepoPath}" == $"{dest.Name}|{dest.Version}|{dest.RepoPath}"); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryFile, ServiceModel.RepositoryFile>(); cfg.CreateMap <ServiceModel.RepositoryFile, Repositories.Model.EntityFramework.RepositoryFile>() .EqualityComparison((source, dest) => source.FullPath == dest.FullPath); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryImplementation, ServiceModel.RepositoryImplementation>(); cfg.CreateMap <ServiceModel.RepositoryImplementation, Repositories.Model.EntityFramework.RepositoryImplementation>() .EqualityComparison((source, dest) => source.Name == dest.Name); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryTeam, ServiceModel.RepositoryTeam>(); cfg.CreateMap <ServiceModel.RepositoryTeam, Repositories.Model.EntityFramework.RepositoryTeam>() .EqualityComparison((source, dest) => source.Name == dest.Name); cfg.CreateMap <Repositories.Model.EntityFramework.Topic, ServiceModel.RepositoryTopic>(); cfg.CreateMap <ServiceModel.RepositoryTopic, Repositories.Model.EntityFramework.Topic>() .EqualityComparison((source, dest) => source.Name == dest.Name); cfg.CreateMap <Repositories.Model.EntityFramework.RepositoryTypeAndImplementations, ServiceModel.RepositoryTypeAndImplementations>(); cfg.CreateMap <ServiceModel.RepositoryTypeAndImplementations, Repositories.Model.EntityFramework.RepositoryTypeAndImplementations>() .EqualityComparison((source, dest) => source.TypeName == dest.TypeName); cfg.CreateMap <Repositories.Model.EntityFramework.RepositorySnapshot, ServiceModel.RepositorySnapshot>(); cfg.CreateMap <ServiceModel.RepositorySnapshot, Repositories.Model.EntityFramework.RepositorySnapshot>() .EqualityComparison((source, dest) => source.WindowStartCommitId == dest.WindowStartCommitId); }); services.AddSingleton(config.CreateMapper()); // ------------------------- // Configure DI container -- // ------------------------- services.AddTransient <IRepositoryManager, RepositoryManager>(); services.AddTransient <IDependencyRepository, RelationalDependencyRepository>(); services.AddTransient <IRepositorySourceManager, RepositorySourceManager>(); services.AddTransient <IRepositoryAnalysisManager, RepositoryAnalysisManager>(); services.AddTransient <IDependencyManager, DependencyManager>(); services.AddTransient <IRepositorySourceRepository>(serviceProvider => new GitHubApiRepositorySourceRepository( gitHubClient, gitHubTreesClient, graphQLClient, serviceProvider.GetService <ILogger <GitHubApiRepositorySourceRepository> >() )); services.AddTransient <IRepositoryImplementationsManager, RepositoryImplementationsManager>(); //services.AddTransient<IRepositoryImplementationsRepository, MongoRepositoryImplementationsRepository>(); services.AddTransient <IRepositoriesTypeNamesManager, RepositoriesTypeNamesManager>(); //services.AddTransient<IRepositoriesTypeNamesRepository, MongoRepositoriesTypeNamesRepository>(); //services.AddTransient<IRepositorySearchRepository, MongoRepositorySearchRepository>(); services.AddTransient <IVersionManager, VersionManager>(); services.AddTransient <IRepositoryCurrentStateRepository, RelationalRepositoryCurrentStateRepository>(); services.AddTransient <IRepositorySnapshotRepository, RelationalRepositorySnapshotRepository>(); services.AddTransient <IRepositoryRepository, RelationalRepositoryRepository>(); services.AddTransient <IEnumerable <IDependencyScraperManager> >((serviceProvider) => new List <IDependencyScraperManager> { new BowerDependencyScraperManager(serviceProvider.GetService <IRepositorySourceManager>()), new DotNetProjectFileDependencyScraperManager(serviceProvider.GetService <IRepositorySourceManager>()), new NpmDependencyScraperManager(serviceProvider.GetService <IRepositorySourceManager>()), new NuGetDependencyScraperManager(serviceProvider.GetService <IRepositorySourceManager>()) }); }