O gRPC é um sistema de chamada de procedimento remoto (RPC) de código aberto desenvolvido inicialmente no Google. Ele usa HTTP 2.0 para transporte e fornece métodos de configuração e gerenciamento de dispositivos de rede compatíveis com várias linguagens de programação.
A Tabela 1 descreve as camadas da pilha de protocolos gRPC.
Tabela 1 Camadas da pilha de protocolos gRPC
Camada | Descrição |
Camada de conteúdo | Define os dados do módulo de serviço. Dois pares devem notificar um ao outro sobre os modelos de dados que estão usando. |
Camada de codificação de buffer de protocolo | Codifica dados usando o formato de código de buffer de protocolo. |
Camada gRPC | Define o formato de interação do protocolo para chamadas de procedimento remoto. |
Camada HTTP 2.0 | Carrega o gRPC. |
Camada TCP | Fornece links de dados confiáveis orientados por conexão. |
Conforme mostrado na Figura 1, a rede gRPC usa o modelo cliente/servidor. Ela usa HTTP 2.0 para o transporte de pacotes.
Figura 1 Arquitetura da rede gRPC
A rede gRPC usa o seguinte mecanismo:
A telemetria é uma tecnologia de coleta remota de dados para monitorar o desempenho e o status operacional do dispositivo. A tecnologia de telemetria da Intelbras usa o gRPC para enviar dados do dispositivo para os coletores nos NMSs. Conforme mostrado na Figura 2, depois que uma conexão gRPC é estabelecida entre o dispositivo e os NMSs, os NMSs podem se inscrever para obter dados de módulos no dispositivo.
Figura 2 Tecnologia de telemetria baseada em gRPC
O dispositivo é compatível com os seguintes modos de telemetria:
O modo de discagem se aplica a redes pequenas em que os coletores precisam implementar configurações nos dispositivos.
O modo de discagem se aplica a redes maiores em que os dispositivos precisam enviar os dados do dispositivo para os coletores.
RFC 7540, Protocolo de transferência de hipertexto versão 2 (HTTP/2)
O dispositivo é compatível com o modo FIPS que atende aos requisitos do NIST FIPS 140-2. O suporte a recursos, comandos e parâmetros pode ser diferente no modo FIPS e no modo não-FIPS. Para obter mais informações sobre o modo FIPS, consulte o Guia de configuração de segurança.
O gRPC não é compatível com o modo FIPS.
Antes de configurar o gRPC, você deve instalar uma imagem de software do recurso gRPC compatível com a versão do software do dispositivo. Para obter informações sobre o procedimento de instalação, consulte atualização de software no Fundamentals Configuration Guide.
Para configurar o modo de discagem gRPC, execute as seguintes tarefas:
Se o serviço gRPC não for ativado, use o comando display tcp ou display ipv6 tcp para verificar se o número da porta do serviço gRPC foi usado por outro recurso. Em caso afirmativo, especifique uma porta livre como o número da porta do serviço gRPC e tente ativar o serviço gRPC novamente. Para obter mais informações sobre os comandos display tcp e display ipv6 tcp, consulte Referência do comando Layer 3-IP Services.
system-view
grpc port port-number
Por padrão, o número da porta do serviço gRPC é 50051.
A alteração do número da porta do serviço gRPC quando o serviço gRPC está ativado reinicia o serviço gRPC e fecha as conexões gRPC com os clientes gRPC. Os clientes gRPC devem reiniciar as conexões.
grpc enable
Por padrão, o serviço gRPC está desativado.
grpc idle-timeout minutes
Por padrão, o cronômetro de tempo limite de inatividade da sessão gRPC é de 5 minutos.
Para que os clientes gRPC estabeleçam sessões gRPC com o dispositivo, é necessário configurar usuários locais para os clientes gRPC.
system-view
local-user user-name [ class manage ]
password [ { hash | simple } password ]
Por padrão, nenhuma senha é configurada para um usuário local. Um usuário não protegido por senha pode passar na autenticação depois de fornecer o nome de usuário correto e passar nas verificações de atributos.
service-type https
Por padrão, nenhum tipo de serviço é autorizado a um usuário local.
Para obter mais informações sobre local-user, password, authorization-attribute e
comandos de tipo de serviço, consulte Configuração AAA na Referência de comandos de segurança.
Para configurar o modo de discagem gRPC, execute as seguintes tarefas:
system-view
grpc enable
Por padrão, o serviço gRPC está desativado.
O dispositivo usa sensores para coletar dados. Um caminho de sensor indica uma fonte de dados. Os tipos de amostragem de dados suportados incluem:
ocorrer. Para conhecer os caminhos do sensor desse tipo de amostragem de dados, consulte Referência de eventos da API NETCONF XML
para o módulo.
system-view
telemetry
sensor-group group-name
sensor path path
Para especificar vários caminhos de sensores, execute esse comando várias vezes.
Os coletores são usados para receber dados de amostragem dos dispositivos de rede. Para que o dispositivo se comunique com os coletores, você deve criar um grupo de destino e adicionar coletores ao grupo de destino.
Você pode adicionar coletores a um grupo de destino por seus endereços IP. A partir da versão 6343P08, também é possível adicionar coletores a um grupo de destino por seus nomes de domínio. Ao especificar os coletores por seus nomes de domínio, use as restrições e diretrizes a seguir:
Como prática recomendada, configure um máximo de cinco grupos de destino. Se você configurar muitos grupos de destino , o desempenho do sistema poderá ser prejudicado.
system-view
telemetry
destination-group group-name
ipv4-address ipv4-address [ port port-number ]
IPv6:
ipv6-address ipv6-address [ port port-number ]
Para adicionar vários coletores, repita esse comando. Um coletor é identificado exclusivamente por uma tripla de endereço IP, número de porta e nome da instância da VPN. Um coletor deve ter um endereço IP, número de porta ou nome de instância de VPN diferente dos outros coletores do grupo de destino .
domain-name domain-name [ port port-number ] [ vpn-instance vpn-instance-name ]
Esse comando é compatível apenas com a versão 6343P08 e posteriores. IPv6:
ipv6 domain-name domain-name [ port port-number ] [ vpn-instance vpn-instance-name ]
Esse comando é compatível apenas com a versão 6343P08 e posteriores.
Para adicionar vários coletores, repita esse comando. Um coletor é identificado exclusivamente por um
três tuplas de nome de domínio, número da porta e nome da instância da VPN. Um coletor deve ter um nome de domínio, número de porta ou nome de instância de VPN diferente dos outros coletores no grupo de destino.
Uma assinatura vincula grupos de sensores a grupos de destino. Em seguida, o dispositivo envia os dados dos sensores especificados para os coletores.
system-view
telemetry
subscription subscription-name
source-address { ipv4-address | interface interface-type interface-number | ipv6 ipv6-address }
Por padrão, o dispositivo usa o endereço IPv4 primário da interface de saída da rota para os coletores como endereço de origem.
A alteração do endereço IP de origem dos pacotes enviados aos coletores faz com que o dispositivo restabeleça a conexão com o servidor gRPC.
sensor-group group-name [ sample-interval interval ]
Especifique a opção de intervalo de intervalo de amostragem para caminhos de sensores periódicos e somente para caminhos de sensores periódicos.
destination-group group-name
Executar comandos de exibição em qualquer visualização.
Tarefa | Comando |
Exibir informações sobre gRPC. | display grpc [ verbose ] A palavra-chave verbose é compatível apenas com a versão 6343P08 e posteriores. |
Esses exemplos de configuração descrevem apenas as tarefas de configuração da CLI no dispositivo. Os coletores precisam executar um aplicativo adicional. Para obter informações sobre o desenvolvimento do aplicativo no lado do coletor, consulte "Desenvolvimento do aplicativo no lado do coletor".
Conforme mostrado na Figura 3, configure o modo de discagem gRPC no dispositivo para que o dispositivo atue como servidor gRPC e o cliente gRPC possa se inscrever em eventos LLDP no dispositivo.
Figura 3 Diagrama de rede
Antes de poder configurar o gRPC, você deve instalar uma imagem de software do recurso gRPC compatível com a versão do software do dispositivo. Para obter mais informações sobre o procedimento de instalação, consulte a configuração de atualização de software no Guia de Configuração dos Fundamentos.
Para instalar uma imagem de software do recurso gRPC:
<Device> install activate feature flash:/grpc-01.bin slot 1
Verifying the file flash:/grpc-01.bin on slot 1....Done.
Identifying the upgrade methods....Done.
Upgrade summary according to following table:
flash:/grpc-01.bin
Running Version New Version
None Demo 01
Slot Upgrade Way
1 Service Upgrade
Upgrading software images to compatible versions. Continue? [Y/N]:y
This operation might take several minutes, please wait....................Done.
<Device> install commit
This operation will take several minutes, please wait.......................Done.
Essa operação levará vários minutos, aguarde Concluído.
<Device> system-view
[Device] grpc enable
# Crie um usuário local chamado test. Defina a senha como teste e atribua a função de usuário network-admin e o serviço HTTPS ao usuário.
[Device] local-user test
[Device-luser-manage-test] password simple test
[Device-luser-manage-test] authorization-attribute user-role network-admin
[Device-luser-manage-test] service-type https
[Device-luser-manage-test] quit
Quando ocorrer um evento LLDP no servidor gRPC, verifique se o cliente gRPC recebe o evento.
Conforme mostrado na Figura 4, o dispositivo está conectado a um coletor. O coletor usa a porta 50050.
Configure o modo de discagem gRPC no dispositivo para que ele envie as informações de capacidade do dispositivo de seu módulo de interface para o coletor em intervalos de 10 segundos.
Figura 4 Diagrama de rede
Antes de poder configurar o gRPC, você deve instalar uma imagem de software do recurso gRPC compatível com a versão do software do dispositivo. Para obter mais informações sobre o procedimento de instalação, consulte a configuração de atualização de software no Fundamentals Configuration Guide.
Para instalar uma imagem de software do recurso gRPC:
<Device> install activate feature flash:/grpc-01.bin slot 1
Verifying the file flash:/grpc-01.bin on slot 1....Done.
Identifying the upgrade methods....Done.
Upgrade summary according to following table:
flash:/grpc-01.bin
Running Version New Version
None Demo 01
Slot Upgrade Way
1 Service Upgrade
Upgrading software images to compatible versions. Continue? [Y/N]:y
This operation might take several minutes, please wait....................Done.
<Device> install commit
This operation will take several minutes, please wait.......................Done.
# Configure os endereços IP conforme necessário para que o dispositivo e o coletor possam se comunicar. (Detalhes não mostrados.)
# Habilite o serviço gRPC.
<Device> system-view
[Device] grpc enable
# Crie um grupo de sensores chamado test e adicione o caminho do sensor ifmgr/devicecapabilities/.
[Device] telemetry
[Device-telemetry] sensor-group test
[Device-telemetry-sensor-group-test] sensor path ifmgr/devicecapabilities/
[Device-telemetry-sensor-group-test] quit
# Crie um grupo de destino chamado collector1. Especifique um coletor que use o endereço IPv4 192.168. 2.1 e o número de porta 50050.
[Device-telemetry] destination-group collector1
[Device-telemetry-destination-group-collector1] ipv4-address 192.168.2.1 port 50050
[Device-telemetry-destination-group-collector1] quit
# Configure uma assinatura chamada A para vincular o teste do grupo de sensores ao grupo de destino collector1. Defina o intervalo de amostragem como 10 segundos.
[Device-telemetry] subscription A
[Device-telemetry-subscription-A] sensor-group test sample-interval 10
[Device-telemetry-subscription-A] destination-group collector1
[Device-telemetry-subscription-A] quit
# Verifique se o coletor recebe as informações de capacidade do dispositivo do módulo de interface do dispositivo em intervalos de 10 segundos. (Detalhes não mostrados).
Os buffers de protocolo do Google oferecem um mecanismo flexível para serializar dados estruturados. Diferentemente do código XML e do código JSON, o código do buffer de protocolo é binário e oferece maior desempenho.
A Tabela 2 compara um exemplo de formato de código de buffer de protocolo e o formato de código JSON correspondente exemplo.
Tabela 2 Exemplos de buffer de protocolo e formato de código JSON
Exemplo de formato de código de buffer de protocolo | Exemplo de formato de código JSON correspondente |
{ | |
{ | "producerName": "Intelbras", |
1: "Intelbras" | "deviceName": "Intelbras", |
2: "Intelbras" | "deviceModel": "Intelbras Simware", |
3: "Intelbras Simware" | "sensorPath": "Syslog/LogBuffer", |
4: "Syslog/LogBuffer" | "jsonData": { |
5: "notification": { | "notification": { |
"Syslog": { | "Syslog": { |
"LogBuffer": { | "LogBuffer": { |
"BufferSize": 512, | "BufferSize": 512, |
"BufferSizeLimit": 1024, | "BufferSizeLimit": 1024, |
"DroppedLogsCount": 0, | "DroppedLogsCount": 0, |
"LogsCount": 100, | "LogsCount": 100, |
"LogsCountPerSeverity": { | "LogsCountPerSeverity": { |
"Alert": 0, | "Alert": 0, |
"Crítico": 1, | "Crítico": 1, |
"Debug": 0, | "Debug": 0, |
"Emergência": 0, | "Emergência": 0, |
"Erro": 3, | "Erro": 3, |
"Informativo": 80, | "Informativo": 80, |
"Aviso": 15, | "Aviso": 15, |
"Advertência": 1 | "Advertência": 1 |
}, | }, |
"OverwrittenLogsCount": 0, | "OverwrittenLogsCount": 0, |
"Estado": "enable" | "Estado": "enable" |
} | } |
}, | }, |
"Timestamp": "1527206160022" | "Timestamp": "1527206160022" |
} | } |
} | } |
} |
É possível definir estruturas de dados em um arquivo de definição proto. Em seguida, você pode compilar o arquivo com o utilitário protoc para gerar código em uma linguagem de programação, como Java e C++. Usando o código gerado, você pode desenvolver um aplicativo para que um coletor se comunique com o dispositivo.
A Intelbras fornece arquivos de definição de proto para os modos dial-in e dial-out.
O arquivo grpc_service.proto define os métodos RPC públicos no modo de discagem, por exemplo, o método de login e o método de logout.
A seguir, o conteúdo do arquivo grpc_service.proto:
syntax = "proto2";
package grpc_service;
message GetJsonReply { // Reply to the Get method
required string result = 1;
}
message SubscribeReply { // Subscription result
required string result = 1;
}
message ConfigReply { // Configuration result
required string result = 1;
}
message ReportEvent { // Subscribed event
required string token_id = 1; // Login token_id
required string stream_name = 2; // Event stream name
required string event_name = 3; // Event name
required string json_text = 4; // Subscription result, a JSON string
}
message GetReportRequest{ // Obtains the event subscription result
required string token_id = 1; // Returns the token_id upon a successful login
}
message LoginRequest { // Login request parameters
required string user_name = 1; // Username
required string password = 2; // Password
}
message LoginReply { // Reply to a login request
required string token_id = 1; // Returns the token_id upon a successful login
}
message LogoutRequest { // Logout parameter
required string token_id = 1; // token_id
}
message LogoutReply { // Reply to a logout request
required string result = 1; // Logout result
}
message SubscribeRequest { // Event stream name
required string stream_name = 1;
}
service GrpcService { // gRPC methods
rpc Login (LoginRequest) returns (LoginReply) {} // Login method
rpc Logout (LogoutRequest) returns (LogoutReply) {} // Logout method
rpc SubscribeByStreamName (SubscribeRequest) returns (SubscribeReply) {} // Event subscription method
rpc GetEventReport (GetReportRequest) returns (stream ReportEvent) {} // Method for obtaining the subscribed event
}
O arquivo grpc_dialout.proto define os métodos RPC públicos no modo dial-out. O conteúdo do arquivo é o seguinte:
syntax = "proto2";
package grpc_dialout;
message DeviceInfo{ // Pushed device information
required string producerName = 1; // Vendor name
required string deviceName = 2; // Device name
required string deviceModel = 3; // Device model
optional string deviceIpAddr = 4; // Device IP
optional string eventType = 5; // Type of the sensor path
optional string deviceSerialNumber = 6; // Serial number of the device
optional string deviceMac= 7; // Bridge MAC address of the device
}
message DialoutMsg{ // Format of the pushed data
required DeviceInfo deviceMsg = 1; // Device information described by DeviceInfo
required string sensorPath = 2; // Sensor path, which corresponds to xpath in NETCONF
required string jsonData = 3; // Sampled data, a JSON string
}
message DialoutResponse{ // Response from the collector. Reserved. The value is not
processed.
required string response = 1;
}
service gRPCDialout { // Data push method
rpc Dialout(stream DialoutMsg) returns (DialoutResponse);
}
Entre em contato com o suporte técnico.
Use uma linguagem (por exemplo, C++) para desenvolver um aplicativo do lado do coletor gRPC no Linux para permitir que um coletor colete dados do dispositivo.
# Copie os arquivos de definição de proto necessários para o diretório atual, por exemplo, grpc_service.proto e BufferMonitor.proto.
$protoc --plugin=./grpc_cpp_plugin --grpc_out=. --cpp_out=. *.proto
# Copiar o arquivo de definição de proto grpc_dialout.proto para o diretório atual.
$ protoc --plugin=./grpc_cpp_plugin --grpc_out=. --cpp_out=. *.proto
No modo dial-in, o aplicativo precisa fornecer o código a ser executado no cliente gRPC.
O código C++ gerado a partir dos arquivos de definição de proto já encapsula as classes de serviço, que são GrpcService e BufferMonitorService neste exemplo. Para que o cliente gRPC inicie solicitações RPC, basta chamar o método RPC no aplicativo.
O aplicativo executa as seguintes operações:
Para desenvolver o aplicativo do lado do coletor no modo dial-in:
# Na classe, use a classe GrpcService::Stub gerada em grpc_service.proto. Implemente o login e o logout com os métodos Login e Logout gerados em grpc_service.proto.
class GrpcServiceTest
{
public:
/* Constructor functions */
GrpcServiceTest(std::shared_ptr<Channel> channel):
GrpcServiceStub(GrpcService::NewStub(channel)) {}
/* Member functions */
int Login(const std::string& username, const std::string& password);
void Logout();
void listen();
/* Member variable */
std::string token;
private:
std::unique_ptr<GrpcService::Stub> GrpcServiceStub; // Use the
GrpcService::Stub class generated from grpc_service.proto.
};
# Chame o método Login da classe GrpcService::Stub para permitir que um usuário que forneça o nome de usuário e a senha corretos faça login.
int GrpcServiceTest::Login(const std::string& username, const std::string& password)
{
LoginRequest request; // Username and password.
request.set_user_name(username);
request.set_password(password);
LoginReply reply;
ClientContext context;
// Call the Login method.
Status status = GrpcServiceStub->Login(&context, request, &reply);
if (status.ok())
{
std::cout << "login ok!" << std::endl;
std::cout << "token id is :" << reply.token_id() << std::endl;
token = reply.token_id(); // The login succeeds. The token is obtained.
return 0;
}
else
{
std::cout << status.error_code() << ": " << status.error_message()
<< ". Login failed!" << std::endl;
return -1;
}
}
rpc SubscribePortQueDropEvent(PortQueDropEvent) retorna (grpc_service.SubscribeReply) {}
# Use a classe BufferMonitorService::Stub gerada a partir de BufferMonitor.proto para chamar o método RPC.
class BufMon_GrpcClient
{
public:
BufMon_GrpcClient(std::shared_ptr<Channel> channel):
mStub(BufferMonitorService::NewStub(channel))
{
}
std::string BufMon_Sub_AllEvent(std::string token);
std::string BufMon_Sub_BoardEvent(std::string token);
std::string BufMon_Sub_PortOverrunEvent(std::string token);
std::string BufMon_Sub_PortDropEvent(std::string token);
/* Get entries */
std::string BufMon_Sub_GetStatistics(std::string token);
std::string BufMon_Sub_GetGlobalCfg(std::string token);
std::string BufMon_Sub_GetBoardCfg(std::string token);
std::string BufMon_Sub_GetNodeQueCfg(std::string token);
std::string BufMon_Sub_GetPortQueCfg(std::string token);
private:
std::unique_ptr<BufferMonitorService::Stub> mStub; // Use the class generated
from BufferMonitor.proto.
};
class BufMon_GrpcClient
{
public:
BufMon_GrpcClient(std::shared_ptr<Channel> channel):
mStub(BufferMonitorService::NewStub(channel))
{
}
std::string BufMon_Sub_AllEvent(std::string token);
std::string BufMon_Sub_BoardEvent(std::string token);
std::string BufMon_Sub_PortOverrunEvent(std::string token);
std::string BufMon_Sub_PortDropEvent(std::string token);
/* Get entries */
std::string BufMon_Sub_GetStatistics(std::string token);
std::string BufMon_Sub_GetGlobalCfg(std::string token);
std::string BufMon_Sub_GetBoardCfg(std::string token);
std::string BufMon_Sub_GetNodeQueCfg(std::string token);
std::string BufMon_Sub_GetPortQueCfg(std::string token);
private:
std::unique_ptr<BufferMonitorService::Stub> mStub; // Use the class generated
from BufferMonitor.proto.
};
# Implemente esse método na classe GrpcServiceTest.
void GrpcServiceTest::listen()
{
GetReportRequest reportRequest;
ClientContext context;
ReportEvent reportedEvent;
/* Add the token to the request */
reportRequest.set_token_id(token);
std::unique_ptr<ClientReader<ReportEvent>>
reader(GrpcServiceStub->GetEventReport(&context, reportRequest)); // Use
GetEventReport (which is generated from grpc_service.proto) to obtain event
information.
std::string streamName;
std::string eventName;
std::string jsonText;
std::string token;
JsonFormatTool jsonTool;
std::cout << "Listen to server for Event" << std::endl;
while(reader->Read(&reportedEvent)) // Read the received event report.
{
streamName = reportedEvent.stream_name();
eventName = reportedEvent.event_name();
jsonText = reportedEvent.json_text();
token = reportedEvent.token_id();
std::cout << "/**********************EVENT COME************************/" <<
std::endl;
std::cout << "TOKEN: " << token << std::endl;
std::cout << "StreamName: "<< streamName << std::endl;
std::cout << "EventName: " << eventName << std::endl;
std::cout << "JsonText without format: " << std::endl << jsonText << std::endl;
std::cout << std::endl;
std::cout << "JsonText Formated: " << jsonTool.formatJson(jsonText) <<
std::endl;
std::cout << std::endl;
}
Status status = reader->Finish();
std::cout << "Status Message:" << status.error_message() << "ERROR code :" <<
status.error_code();
} // Login and RPC request finished
No modo dial-out, o aplicativo precisa fornecer o código do servidor gRPC para que o coletor possa receber e resolver os dados obtidos do dispositivo.
O aplicativo realiza as seguintes operações:
# Criar a classe DialoutTest e herdar GRPCDialout::Service.
class DialoutTest final : public GRPCDialout::Service { // Sobrecarrega a classe abstrata gerada automaticamente.
Status Dialout(ServerContext* context, ServerReader<DialoutMsg>* reader, DialoutResponse* response) override; // Implementar o método RPC Dialout.
};
using grpc::Server;
using grpc::ServerBuilder;
std::string server_address("0.0.0.0:60057"); // Specify the address and port to
listen to.
DialoutTest dialout_test; // Define the object declared in step 1.
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());// Add
the listening port.
builder.RegisterService(&dialout_test); // Register the service.
std::unique_ptr
<<Server << server(builder.BuildAndStart()); // Start the service.
server->Wait();
Status DialoutTest::Dialout(ServerContext* context, ServerReader<DialoutMsg>* reader, DialoutResponse* response)
{
DialoutMsg msg;
while(reader->Read(&msg))
{
const DeviceInfo &device_msg = msg.devicemsg();
std::cout<< "Producer-Name: " << device_msg.producername() << std::endl;
std::cout<< "Device-Name: " << device_msg.devicename() << std::endl;
std::cout<< "Device-Model: " << device_msg.devicemodel() << std::endl;
std::cout<<"Sensor-Path: " << msg.sensorpath()<<std::endl;
std::cout<<"Json-Data: " << msg.jsondata()<<std::endl;
std::cout<<std::endl;
}
response->set_response("test");
return Status::OK;
}