Пример #1
0
 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);
 }
Пример #2
0
            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"));
            }
Пример #3
0
            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"));
            }
Пример #4
0
            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"));
            }
Пример #5
0
            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"));
            }
Пример #6
0
 /// <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);
 }
Пример #7
0
            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);
            }
Пример #8
0
            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()));
            }
Пример #9
0
            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);
            }
Пример #10
0
            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);
            }
Пример #11
0
            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);
            }
Пример #12
0
            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", ""));
            }
Пример #13
0
            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));
            }
Пример #14
0
            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()));
            }
Пример #15
0
            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));
            }
Пример #16
0
            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", ""));
            }
Пример #17
0
            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()));
            }
Пример #18
0
            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, ""));
            }
Пример #19
0
            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>())
            });
        }