Exemplo: aplicativo "Hello World" em C#

Esta amostra de código é um aplicativo "hello world" escrito em C#. Ela mostra como concluir as seguintes tarefas:

  • conectar-se a uma instância do Cloud Bigtable;
  • criar uma nova tabela;
  • gravar dados na tabela;
  • ler os dados de volta;
  • excluir a tabela.

Executar o exemplo

Esse código se comunica com o Cloud Bigtable por meio das bibliotecas da API de C# Admin e da API C# Data nas bibliotecas de cliente do Google Cloud para .NET.

Para executar este programa de amostra, siga as instruções do .NET Cloud Bigtable Samples no GitHub (em inglês). Conclua as etapas Criar e executar e Início rápido para criar recursos que podem ser usados no aplicativo Hello World. Certifique-se de editar o arquivo HelloWorld.cs para adicionar os nomes dos recursos criados.

Como usar a biblioteca de clientes do Cloud com o Cloud Bigtable

O aplicativo de amostra conecta-se ao Cloud Bigtable e demonstra algumas operações simples.

Como se conectar ao Cloud Bigtable

Para começar, crie dois objetos de cliente para se conectar ao Cloud Bigtable. O BigtableTableAdminClient da API C# Admin ajuda você a criar e excluir instâncias e tabelas. O BigtableClient da API C# Data ajuda você a ler e gravar dados da tabela.

// BigtableTableAdminClient API lets us create, manage and delete tables.
BigtableTableAdminClient bigtableTableAdminClient = BigtableTableAdminClient.Create();

// BigtableClient API lets us read and write to a table.
BigtableClient bigtableClient = BigtableClient.Create();

Como criar uma tabela

Chame o método CreateTable() de administrador do cliente para gerar um objeto Table que armazene as saudações "hello world". A tabela tem um única grupo de colunas que retém uma versão de cada valor.

// Create a table with a single column family.
Console.WriteLine($"Create new table: {tableId} with column family: {columnFamily}, instance: {instanceId}");

// Check whether a table with given TableName already exists.
if (!TableExist(bigtableTableAdminClient))
{
    bigtableTableAdminClient.CreateTable(
        new InstanceName(projectId, instanceId),
        tableId,
        new Table
        {
            Granularity = Table.Types.TimestampGranularity.Millis,
            ColumnFamilies =
            {
                {
                    columnFamily, new ColumnFamily
                    {
                        GcRule = new GcRule
                        {
                            MaxNumVersions = 1
                        }
                    }
                }
            }
        });
    // Confirm that table was created successfully.
    Console.WriteLine(TableExist(bigtableTableAdminClient)
        ? $"Table {tableId} created successfully\n"
        : $"There was a problem creating a table {tableId}");
}
else
{
    Console.WriteLine($"Table: {tableId} already exists");
}

Como gravar linhas em uma tabela

Use o s_greetings[] da matriz de string, que contém três saudações simples, como uma fonte de dados para gravar na tabela. Primeiro, grave uma única linha na tabela com o MutateRow(). Em seguida, percorra o restante da matriz para criar um objeto MutateRowsRequest que contenha uma entrada para cada saudação. Faça a solicitação para gravar todas as entradas de uma só vez com o MutateRows(). Por fim, percorra a resposta retornada para verificar o código de status de cada entrada para garantir que foi gravado com êxito.

// Initialize Google.Cloud.Bigtable.V2.TableName object.
Google.Cloud.Bigtable.Common.V2.TableName tableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId);

// Write some rows
/* Each row has a unique row key.

       Note: This example uses sequential numeric IDs for simplicity, but
       this can result in poor performance in a production application.
       Since rows are stored in sorted order by key, sequential keys can
       result in poor distribution of operations across nodes.

       For more information about how to design a Bigtable schema for the
       best performance, see the documentation:

       https://cloud.google.com/bigtable/docs/schema-design */

Console.WriteLine($"Write some greetings to the table {tableId}");

// Insert 1 row using MutateRow()
s_greetingIndex = 0;
try
{
    bigtableClient.MutateRow(tableName, rowKeyPrefix + s_greetingIndex, MutationBuilder());
    Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
}
catch (Exception ex)
{
    Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
    Console.WriteLine(ex.Message);
    throw;
}

// Insert multiple rows using MutateRows()
// Build a MutateRowsRequest (contains table name and a collection of entries).
MutateRowsRequest request = new MutateRowsRequest
{
    TableNameAsTableName = tableName
};

s_mapToOriginalGreetingIndex = new List<int>();
while (++s_greetingIndex < s_greetings.Length)
{
    s_mapToOriginalGreetingIndex.Add(s_greetingIndex);
    // Build an entry for every greeting (consists of rowkey and a collection of mutations).
    string rowKey = rowKeyPrefix + s_greetingIndex;
    request.Entries.Add(Mutations.CreateEntry(rowKey, MutationBuilder()));
}

// Make the request to write multiple rows.
MutateRowsResponse response = bigtableClient.MutateRows(request);

// Check the status code of each entry to ensure that it was written successfully.
foreach (MutateRowsResponse.Types.Entry entry in response.Entries)
{
    s_greetingIndex = s_mapToOriginalGreetingIndex[(int)entry.Index];
    if (entry.Status.Code == 0)
    {
        Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
    }
    else
    {
        Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
        Console.WriteLine(entry.Status.Message);
    }
}

Mutation MutationBuilder() =>
    Mutations.SetCell(columnFamily, columnName, s_greetings[s_greetingIndex], new BigtableVersion(DateTime.UtcNow));

Como criar um filtro

Antes de ler os dados que você gravou, crie um filtro para limitar os dados que o Cloud Bigtable retorna. Com esse filtro, o Cloud Bigtable retornará apenas a versão mais recente de cada valor, mesmo que a tabela contenha versões mais antigas que não tenham sido coletadas como lixo.

RowFilter filter = RowFilters.CellsPerRowLimit(1);

Como ler uma linha pela respectiva chave

Use o método ReadRow(), com o filtro que você acabou de criar, para receber uma versão de cada valor dessa linha.

// Read from the table.
Console.WriteLine("Read the first row");

int rowIndex = 0;

// Read a specific row. Apply a filter to return latest only cell value accross entire row.
Row rowRead = bigtableClient.ReadRow(
    tableName, rowKey: rowKeyPrefix + rowIndex, filter: filter);
Console.WriteLine(
    $"\tRow key: {rowRead.Key.ToStringUtf8()} " +
    $"  -- Value: {rowRead.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
    $"  -- Time Stamp: {rowRead.Families[0].Columns[0].Cells[0].TimestampMicros}");

Como verificar todas as linhas da tabela

Chame o método ReadRows(), com o filtro, para receber todas as linhas da tabela. Como você transmitiu no filtro, o Cloud Bigtable retorna apenas uma versão de cada valor.

Console.WriteLine("Read all rows using streaming");
// stream the content of the whole table. Apply a filter to return latest only cell values accross all rows.
ReadRowsStream responseRead = bigtableClient.ReadRows(tableName, filter: filter);

Task printRead = PrintReadRowsAsync();
printRead.Wait();

async Task PrintReadRowsAsync()
{
    await responseRead.ForEachAsync(row =>
    {
        Console.WriteLine($"\tRow key: {row.Key.ToStringUtf8()} " +
                          $"  -- Value: {row.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
                          $"  -- Time Stamp: {row.Families[0].Columns[0].Cells[0].TimestampMicros}");
    });
}

Como excluir tabelas

Exclua a tabela com o método DeleteTable().

// Clean up. Delete the table.
Console.WriteLine($"Delete table: {tableId}");

bigtableTableAdminClient.DeleteTable(name: tableName);
if (!TableExist(bigtableTableAdminClient))
{
    Console.WriteLine($"Table: {tableId} deleted successfully");
}

Funcionamento em conjunto

Veja o exemplo de código completo sem comentários.

// Copyright 2018 Google Inc.

using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Google.Cloud.Bigtable.V2;
using Google.Cloud.Bigtable.Admin.V2;
using Grpc.Core;

namespace GoogleCloudSamples.Bigtable
{
    public class HelloWorld
    {
        private const string projectId = "YOUR-PROJECT-ID";

        private const string instanceId = "YOUR-INSTANCE-ID";

        private const string tableId = "Hello-Bigtable";
        private const string columnFamily = "cf";
        private const string columnName = "greeting";
        private static readonly string[] s_greetings = { "Hello World!", "Hello Bigtable!", "Hello C#!" };
        private static List<int> s_mapToOriginalGreetingIndex;
        private const string rowKeyPrefix = "greeting";
        private static int s_greetingIndex;

        private static void DoHelloWorld()
        {
            try
            {
                BigtableTableAdminClient bigtableTableAdminClient = BigtableTableAdminClient.Create();

                BigtableClient bigtableClient = BigtableClient.Create();

                Console.WriteLine($"Create new table: {tableId} with column family: {columnFamily}, instance: {instanceId}");

                if (!TableExist(bigtableTableAdminClient))
                {
                    bigtableTableAdminClient.CreateTable(
                        new InstanceName(projectId, instanceId),
                        tableId,
                        new Table
                        {
                            Granularity = Table.Types.TimestampGranularity.Millis,
                            ColumnFamilies =
                            {
                                {
                                    columnFamily, new ColumnFamily
                                    {
                                        GcRule = new GcRule
                                        {
                                            MaxNumVersions = 1
                                        }
                                    }
                                }
                            }
                        });
                    Console.WriteLine(TableExist(bigtableTableAdminClient)
                        ? $"Table {tableId} created successfully\n"
                        : $"There was a problem creating a table {tableId}");
                }
                else
                {
                    Console.WriteLine($"Table: {tableId} already exists");
                }

                Google.Cloud.Bigtable.Common.V2.TableName tableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId);

                       Note: This example uses sequential numeric IDs for simplicity, but
                       this can result in poor performance in a production application.
                       Since rows are stored in sorted order by key, sequential keys can
                       result in poor distribution of operations across nodes.

                       For more information about how to design a Bigtable schema for the
                       best performance, see the documentation:

                       https://cloud.google.com/bigtable/docs/schema-design */

                Console.WriteLine($"Write some greetings to the table {tableId}");

                s_greetingIndex = 0;
                try
                {
                    bigtableClient.MutateRow(tableName, rowKeyPrefix + s_greetingIndex, MutationBuilder());
                    Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
                    Console.WriteLine(ex.Message);
                    throw;
                }

                MutateRowsRequest request = new MutateRowsRequest
                {
                    TableNameAsTableName = tableName
                };

                s_mapToOriginalGreetingIndex = new List<int>();
                while (++s_greetingIndex < s_greetings.Length)
                {
                    s_mapToOriginalGreetingIndex.Add(s_greetingIndex);
                    string rowKey = rowKeyPrefix + s_greetingIndex;
                    request.Entries.Add(Mutations.CreateEntry(rowKey, MutationBuilder()));
                }

                MutateRowsResponse response = bigtableClient.MutateRows(request);

                foreach (MutateRowsResponse.Types.Entry entry in response.Entries)
                {
                    s_greetingIndex = s_mapToOriginalGreetingIndex[(int)entry.Index];
                    if (entry.Status.Code == 0)
                    {
                        Console.WriteLine($"\tGreeting:   -- {s_greetings[s_greetingIndex],-18}-- written successfully");
                    }
                    else
                    {
                        Console.WriteLine($"\tFailed to write greeting: --{s_greetings[s_greetingIndex]}");
                        Console.WriteLine(entry.Status.Message);
                    }
                }

                Mutation MutationBuilder() =>
                    Mutations.SetCell(columnFamily, columnName, s_greetings[s_greetingIndex], new BigtableVersion(DateTime.UtcNow));

                RowFilter filter = RowFilters.CellsPerRowLimit(1);

                Console.WriteLine("Read the first row");

                int rowIndex = 0;

                Row rowRead = bigtableClient.ReadRow(
                    tableName, rowKey: rowKeyPrefix + rowIndex, filter: filter);
                Console.WriteLine(
                    $"\tRow key: {rowRead.Key.ToStringUtf8()} " +
                    $"  -- Value: {rowRead.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
                    $"  -- Time Stamp: {rowRead.Families[0].Columns[0].Cells[0].TimestampMicros}");

                Console.WriteLine("Read all rows using streaming");
                ReadRowsStream responseRead = bigtableClient.ReadRows(tableName, filter: filter);

                Task printRead = PrintReadRowsAsync();
                printRead.Wait();

                async Task PrintReadRowsAsync()
                {
                    await responseRead.ForEachAsync(row =>
                    {
                        Console.WriteLine($"\tRow key: {row.Key.ToStringUtf8()} " +
                                          $"  -- Value: {row.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " +
                                          $"  -- Time Stamp: {row.Families[0].Columns[0].Cells[0].TimestampMicros}");
                    });
                }

                Console.WriteLine($"Delete table: {tableId}");

                bigtableTableAdminClient.DeleteTable(name: tableName);
                if (!TableExist(bigtableTableAdminClient))
                {
                    Console.WriteLine($"Table: {tableId} deleted successfully");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception while running HelloWorld: {ex.Message}");
            }
        }

        private static bool TableExist(BigtableTableAdminClient bigtableTableAdminClient)
        {
            GetTableRequest request = new GetTableRequest
            {
                TableName = new Google.Cloud.Bigtable.Common.V2.TableName(projectId, instanceId, tableId),
                View = Table.Types.View.NameOnly
            };
            try
            {
                var tables = bigtableTableAdminClient.GetTable(request);
                return true;
            }
            catch (RpcException ex)
            {
                if (ex.StatusCode == StatusCode.NotFound)
                {
                    return false;
                }

                throw;
            }
        }

        public static int Main(string[] args)
        {
            if (projectId == "YOUR-PROJECT" + "-ID")
            {
                Console.WriteLine("Edit HelloWorld.cs and replace YOUR-PROJECT-ID with your project ID.");
                return -1;
            }
            if (instanceId == "YOUR-INSTANCE" + "-ID")
            {
                Console.WriteLine("Edit HelloWorld.cs and replace YOUR-INSTANCE-ID with your instance ID.");
                return -1;
            }

            DoHelloWorld();
            return 0;
        }
    }
}
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Cloud Bigtable