Пример #1
0
        private async Task TryInitClusterVersion()
        {
            try
            {
                ClusterVersionEntity version = default;

                try
                {
                    version = ((JObject)await this._kubeClient.GetNamespacedCustomObjectAsync(
                                   Constants.ORLEANS_GROUP,
                                   Constants.PROVIDER_MODEL_VERSION,
                                   this._namespace,
                                   ClusterVersionEntity.PLURAL,
                                   this._clusterOptions.ClusterId
                                   ))?.ToObject <ClusterVersionEntity>();
                }
                catch (HttpOperationException ex)
                {
                    if (ex.Response.StatusCode != HttpStatusCode.NotFound)
                    {
                        throw;
                    }
                }

                if (version == null)
                {
                    version = new ClusterVersionEntity
                    {
                        ClusterId      = this._clusterOptions.ClusterId,
                        ClusterVersion = 0,
                        ApiVersion     = $"{Constants.ORLEANS_GROUP}/{Constants.PROVIDER_MODEL_VERSION}",
                        Metadata       = new V1ObjectMeta {
                            Name = this._clusterOptions.ClusterId
                        }
                    };

                    var created = ((JObject)await this._kubeClient.CreateNamespacedCustomObjectAsync(
                                       version,
                                       Constants.ORLEANS_GROUP,
                                       Constants.PROVIDER_MODEL_VERSION,
                                       this._namespace,
                                       ClusterVersionEntity.PLURAL
                                       ))?.ToObject <ClusterVersionEntity>();

                    if (created != null)
                    {
                        this._logger?.Info("Created new Cluster Version entity for Cluster {clusterId}.", this._clusterOptions.ClusterId);
                    }
                }
                else
                {
                    this._logger?.Info("Cluster {clusterId} already exists. Trying to join it.", this._clusterOptions.ClusterId);
                }
            }
            catch (Exception exc)
            {
                // TODO: Handle conflicts better when the schema is already deployed
                this._logger?.LogWarning(exc, "We tried to Initialize ClusterVersion but fail. Ignoring for now...");
            }
        }
Пример #2
0
        private async Task <(ClusterVersionEntity Version, List <SiloEntity> Silos)> ReadRecords(string clusterId)
        {
            var query = this._container
                        .GetItemQueryIterator <dynamic>(
                READ_ALL_QUERY,
                requestOptions: new QueryRequestOptions
            {
                PartitionKey = new PartitionKey(clusterId)
            }
                );

            var silos = new List <SiloEntity>();
            ClusterVersionEntity clusterVersion = null;

            do
            {
                var items = await query.ReadNextAsync();

                var version = items.Where(i => i.EntityType == nameof(ClusterVersionEntity)).SingleOrDefault();
                if (version != null)
                {
                    clusterVersion = ClusterVersionEntity.FromDocument(version);
                }

                silos.AddRange(items.Where(i => i.EntityType == nameof(SiloEntity)).Select(d => (SiloEntity)SiloEntity.FromDocument(d)));
            } while (query.HasMoreResults);

            return(clusterVersion, silos);
        }
Пример #3
0
        public async Task InitializeMembershipTable(bool tryInitTableVersion)
        {
            if (this._options.Client != null)
            {
                this._cosmos = this._options.Client;
            }
            else
            {
                this._cosmos = new CosmosClient(this._options.AccountEndpoint, this._options.AccountKey,
                                                new CosmosClientOptions
                {
                    ConnectionMode = this._options.ConnectionMode
                }
                                                );
            }
            this._container = this._cosmos.GetDatabase(this._options.DB).GetContainer(this._options.Collection);

            if (this._options.CanCreateResources)
            {
                if (this._options.DropDatabaseOnInit)
                {
                    await this.TryDeleteDatabase();
                }

                await this.TryCreateCosmosDBResources();
            }

            ClusterVersionEntity versionEntity = null;

            try
            {
                versionEntity = (await this._container.ReadItemAsync <ClusterVersionEntity>(
                                     CLUSTER_VERSION_ID,
                                     new PartitionKey(this._clusterOptions.ClusterId))).Resource;
            }
            catch (CosmosException ce) when(ce.StatusCode == HttpStatusCode.NotFound)
            {
                if (versionEntity == null)
                {
                    versionEntity = new ClusterVersionEntity
                    {
                        ClusterId      = this._clusterOptions.ClusterId,
                        ClusterVersion = 0,
                        Id             = CLUSTER_VERSION_ID
                    };

                    var response = await this._container.CreateItemAsync(
                        versionEntity,
                        new PartitionKey(versionEntity.ClusterId)
                        );

                    if (response.StatusCode == HttpStatusCode.Created)
                    {
                        this._logger?.Info("Created new Cluster Version entity.");
                    }
                }
            }
        }
Пример #4
0
        public async Task <MembershipTableData> ReadRow(SiloAddress key)
        {
            var id = ConstructSiloEntityId(key);

            try
            {
                var query = this._container
                            .GetItemQueryIterator <dynamic>(
                    new QueryDefinition(READ_ENTRY_QUERY).WithParameter("@siloId", id),
                    requestOptions: new QueryRequestOptions
                {
                    PartitionKey = new PartitionKey(this._clusterOptions.ClusterId)
                }
                    );

                var docs = await query.ReadNextAsync();

                var versionDoc = docs.Where(i => i.EntityType == nameof(ClusterVersionEntity)).SingleOrDefault();
                ClusterVersionEntity clusterVersionEntity = versionDoc != null?ClusterVersionEntity.FromDocument(versionDoc) : default;

                var siloEntities = docs.Where(i => i.EntityType == nameof(SiloEntity)).Select <dynamic, SiloEntity>(d => SiloEntity.FromDocument(d));

                TableVersion version = null;
                if (clusterVersionEntity != null)
                {
                    version = new TableVersion(clusterVersionEntity.ClusterVersion, clusterVersionEntity.ETag);
                }
                else
                {
                    this._logger.LogError("Initial ClusterVersionEntity entity doesn't exist.");
                }

                var memEntries = new List <Tuple <MembershipEntry, string> >();
                foreach (var entity in siloEntities)
                {
                    try
                    {
                        MembershipEntry membershipEntry = ParseEntity(entity);
                        memEntries.Add(new Tuple <MembershipEntry, string>(membershipEntry, entity.ETag));
                    }
                    catch (Exception exc)
                    {
                        this._logger.LogError(exc, "Failure reading membership row.");
                        throw;
                    }
                }

                var data = new MembershipTableData(memEntries, version);
                return(data);
            }
            catch (Exception exc)
            {
                this._logger.LogWarning($"Failure reading silo entry {id} for cluster id {this._clusterOptions.ClusterId}: {exc}");
                throw;
            }
        }
Пример #5
0
        public async Task InitializeMembershipTable(bool tryInitTableVersion)
        {
            this._dbClient = new DocumentClient(new Uri(this._options.AccountEndpoint), this._options.AccountKey,
                                                new ConnectionPolicy
            {
                ConnectionMode     = this._options.ConnectionMode,
                ConnectionProtocol = this._options.ConnectionProtocol
            });

            await this._dbClient.OpenAsync();

            if (this._options.CanCreateResources)
            {
                if (this._options.DropDatabaseOnInit)
                {
                    await this._dbClient.DeleteDatabaseAsync(UriFactory.CreateDatabaseUri(this._options.DB));
                }

                await TryCreateCosmosDBResources();

                if (this._options.AutoUpdateStoredProcedures)
                {
                    await UpdateStoredProcedures();
                }
            }

            var versionEntity = (await this._dbClient.Query <ClusterVersionEntity>(
                                     this._options.DB, this._options.Collection, t =>
                                     t.ClusterId == this._options.ClusterId &&
                                     t.EntityType == nameof(ClusterVersionEntity))).SingleOrDefault();

            if (versionEntity == null)
            {
                versionEntity = new ClusterVersionEntity
                {
                    ClusterId      = this._options.ClusterId,
                    ClusterVersion = 0,
                    Id             = CLUSTER_VERSION_ID
                };

                var response = await this._dbClient.CreateDocumentAsync(
                    UriFactory.CreateDocumentCollectionUri(this._options.DB, this._options.Collection),
                    versionEntity,
                    new RequestOptions
                {
                    PartitionKey = new PartitionKey(versionEntity.ClusterId)
                });

                if (response.StatusCode == HttpStatusCode.Created)
                {
                    this._logger?.Info("Created new Cluster Version entity.");
                }
            }
        }
Пример #6
0
        public async Task <MembershipTableData> ReadRow(SiloAddress key)
        {
            var id = ConstructSiloEntityId(key);

            try
            {
                var spResponse = await this._dbClient.ExecuteStoredProcedureAsync <ReadResponse>(
                    UriFactory.CreateStoredProcedureUri(this._options.DB, this._options.Collection, READ_SILO_SPROC),
                    new RequestOptions { PartitionKey = new PartitionKey(this._options.ClusterId) },
                    this._options.ClusterId, id);

                ClusterVersionEntity versionEntity = spResponse.Response.ClusterVersion;
                List <SiloEntity>    entryEntities = spResponse.Response.Silos;

                TableVersion version = null;
                if (versionEntity != null)
                {
                    version = new TableVersion(versionEntity.ClusterVersion, versionEntity.ETag);
                }
                else
                {
                    this._logger.LogError("Initial ClusterVersionEntity entity doesn't exist.");
                }

                var memEntries = new List <Tuple <MembershipEntry, string> >();
                foreach (var entity in entryEntities)
                {
                    try
                    {
                        MembershipEntry membershipEntry = ParseEntity(entity);
                        memEntries.Add(new Tuple <MembershipEntry, string>(membershipEntry, entity.ETag));
                    }
                    catch (Exception exc)
                    {
                        //TODO: Log it
                        throw;
                    }
                }

                var data = new MembershipTableData(memEntries, version);
                return(data);
            }
            catch (Exception exc)
            {
                this._logger.LogWarning($"Failure reading silo entry {id} for cluster id {this._options.ClusterId}: {exc}");
                throw;
            }
        }
Пример #7
0
        public async Task <MembershipTableData> ReadAll()
        {
            try
            {
                (ClusterVersionEntity Version, List <SiloEntity> Silos)response = await this.ReadRecords(this._clusterOptions.ClusterId);

                ClusterVersionEntity versionEntity = response.Version;
                List <SiloEntity>    entryEntities = response.Silos;

                TableVersion version = null;
                if (versionEntity != null)
                {
                    version = new TableVersion(versionEntity.ClusterVersion, versionEntity.ETag);
                }
                else
                {
                    this._logger.LogError("Initial ClusterVersionEntity entity doesn't exist.");
                }

                var memEntries = new List <Tuple <MembershipEntry, string> >();
                foreach (var entity in entryEntities)
                {
                    try
                    {
                        MembershipEntry membershipEntry = ParseEntity(entity);
                        memEntries.Add(new Tuple <MembershipEntry, string>(membershipEntry, entity.ETag));
                    }
                    catch (Exception exc)
                    {
                        this._logger.LogError(exc, "Failure reading all membership records.");
                        throw;
                    }
                }

                var data = new MembershipTableData(memEntries, version);
                return(data);
            }
            catch (Exception exc)
            {
                this._logger.LogWarning($"Failure reading all silo entries for cluster id {this._clusterOptions.ClusterId}: {exc}");
                throw;
            }
        }
Пример #8
0
        private async Task TryInitClusterVersion()
        {
            try
            {
                var version = await this._kube.GetCustomObject <ClusterVersionEntity>(
                    this._siloOptions.ClusterId, PROVIDER_MODEL_VERSION, ClusterVersionEntity.PLURAL);

                if (version == null)
                {
                    version = new ClusterVersionEntity
                    {
                        ClusterId      = this._siloOptions.ClusterId,
                        ClusterVersion = 0,
                        Kind           = ClusterVersionEntity.KIND,
                        ApiVersion     = $"{this._options.Group}/{PROVIDER_MODEL_VERSION}",
                        Metadata       = new ObjectMetadata {
                            Name = this._siloOptions.ClusterId
                        }
                    };

                    var created = await this._kube.CreateCustomObject(
                        PROVIDER_MODEL_VERSION, ClusterVersionEntity.PLURAL, version);

                    if (created != null)
                    {
                        this._logger?.Info($"Created new Cluster Version entity for Cluster {this._siloOptions.ClusterId}.");
                    }
                }
                else
                {
                    this._logger?.Info($"Cluster {this._siloOptions.ClusterId} already exist. Trying to join it.");
                }
            }
            catch (Exception exc)
            {
                // TODO: Handle conflics better when the schema is already deployed
                this._logger?.LogWarning(exc, "We tried to Initialize ClusterVersion but fail. Ignoring for now...");
            }
        }