feat: delete pom

This commit is contained in:
dawnwinterLiu 2023-11-13 17:55:38 +08:00
parent 0854ce5de8
commit a0b30e6533
52 changed files with 0 additions and 3395 deletions

View File

@ -1,15 +0,0 @@
FROM tomcat:10.0.5
RUN wget https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zip \
&& unzip -q apache-maven-3.6.3-bin.zip \
&& mv apache-maven-3.6.3 /opt/apache-maven-3.6.3/ \
&& ln -s /opt/apache-maven-3.6.3/ /opt/maven
ENV M2_HOME=/opt/maven
ENV M2=$M2_HOME/bin
ENV PATH=$M2:$PATH
COPY ./web-server /code
WORKDIR /code
RUN mvn package -Dmaven.skip.test=true
RUN mv ./target/emqx-web-0.0.1.war /usr/local/tomcat/webapps/emqx-web.war
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]

View File

@ -1,65 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>emqx-web</groupId>
<artifactId>emqx-web</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/reousrce</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,54 +0,0 @@
package com.emqx.dao;
import java.io.IOException;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.emqx.util.EmqxDatabaseUtil;
public class AuthDAO {
public String getUserName(String userName) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select password from http_user where username='"+userName+"'";
String password =runner.query(sql, new ScalarHandler<String>());
return password;
}
public String getClient(String clientid) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select password from http_user where clientid='"+clientid+"'";
String password =runner.query(sql, new ScalarHandler<String>());
return password;
}
public String getUserAccess(String userName) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select access from http_acl where username='"+userName+"'";
String access =runner.query(sql, new ScalarHandler<String>());
return access;
}
public String getUserTopic(String userName) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select topic from http_acl where username='"+userName+"'";
String topic =runner.query(sql, new ScalarHandler<String>());
return topic;
}
public String getClientAccess(String clientid) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select access from http_acl where clientid='"+clientid+"'";
String access =runner.query(sql, new ScalarHandler<String>());
return access;
}
public String getClientTopic(String clientid) throws IOException, SQLException {
QueryRunner runner = new QueryRunner(EmqxDatabaseUtil.getDataSource());
String sql = "select topic from http_acl where clientid='"+clientid+"'";
String topic =runner.query(sql, new ScalarHandler<String>());
return topic;
}
}

View File

@ -1,45 +0,0 @@
package com.emqx.dao;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.commons.dbutils.handlers.columns.StringColumnHandler;
public class DBUtilsTest {
public static void main(String args[]) throws FileNotFoundException, IOException, SQLException {
Properties property = new Properties();//流文件
property.load(DBUtilsTest.class.getClassLoader().getResourceAsStream("database.properties"));
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(property.getProperty("jdbc.driver"));
dataSource.setUrl(property.getProperty("jdbc.url"));
dataSource.setUsername(property.getProperty("jdbc.username"));
dataSource.setPassword(property.getProperty("jdbc.password"));
// 初始化连接数 if(initialSize!=null)
//dataSource.setInitialSize(Integer.parseInt(initialSize));
// 最小空闲连接 if(minIdle!=null)
//dataSource.setMinIdle(Integer.parseInt(minIdle));
// 最大空闲连接 if(maxIdle!=null)
//dataSource.setMaxIdle(Integer.parseInt(maxIdle));
QueryRunner runner = new QueryRunner(dataSource);
String sql="select username from mqtt_user where id=1";
String result = runner.query(sql, new ScalarHandler<String>());
System.out.println(result);
}
}

View File

@ -1,103 +0,0 @@
package com.emqx.servlet;
import java.io.IOException;
import java.sql.SQLException;
import com.emqx.dao.AuthDAO;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class AclServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String clientid = req.getParameter("clientid");
String username = req.getParameter("username");
String access = req.getParameter("access");
String topic = req.getParameter("topic");
//String password = req.getParameter("password");
//step0: password is not null, or not pass.
AuthDAO dao = new AuthDAO();
try {
//step1: check username access&topic
if(username != null) {
String access_1 = dao.getUserAccess(username);
String topic_1 = dao.getUserTopic(username);
if(access.equals(access_1)) {
if(topic.equals(topic_1)) {
resp.setStatus(200);
}
else {
if(clientid != null){
String access_2 = dao.getClientAccess(clientid);
String topic_2 = dao.getClientTopic(clientid);
if(access.equals(access_2)) {
if(topic.equals(topic_2)) {
resp.setStatus(200);
}
else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}
}else {//step2.1: username password is not match, then check clientid password
if(clientid != null){
String access_3 = dao.getClientAccess(clientid);
String topic_3 = dao.getClientTopic(clientid);
if(access.equals(access_3)) {
if(topic.equals(topic_3)) {
resp.setStatus(200);
}
else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}
}else {//step2.2: username is null, then check clientid password
if(clientid != null){
String access_4 = dao.getClientAccess(clientid);
String topic_4 = dao.getClientTopic(clientid);
if(access.equals(access_4)) {
if(topic.equals(topic_4)) {
resp.setStatus(200);
}
else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -1,72 +0,0 @@
package com.emqx.servlet;
import java.io.IOException;
import java.sql.SQLException;
import com.emqx.dao.AuthDAO;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class AuthServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String clientid = req.getParameter("clientid");
String username =req.getParameter("username");
String password = req.getParameter("password");
//step0: password is not null, or not pass.
if(password == null) {
resp.setStatus(400);
return;
}
AuthDAO dao = new AuthDAO();
try {
//step1: check username password
if(username != null) {
String password_d = dao.getUserName(username);
if(password.equals(password_d)) {
resp.setStatus(200);
//200
}else {//step2.1: username password is not match, then check clientid password
if(clientid != null){
String password_c = dao.getClient(clientid);
if(password.equals(password_c)) {
resp.setStatus(200);
}else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}
}else {//step2.2: username is null, then check clientid password
if(clientid != null){
String password_c = dao.getClient(clientid);
if(password.equals(password_c)) {
resp.setStatus(200);
}else {
resp.setStatus(400);
}
}else {
resp.setStatus(400);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@ -1,27 +0,0 @@
package com.emqx.util;
import java.io.IOException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import com.emqx.dao.DBUtilsTest;
public class EmqxDatabaseUtil {
public static DataSource getDataSource() throws IOException {
Properties property = new Properties();// 流文件
property.load(EmqxDatabaseUtil.class.getClassLoader().getResourceAsStream("database.properties"));
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(property.getProperty("jdbc.driver"));
dataSource.setUrl(property.getProperty("jdbc.url"));
dataSource.setUsername(property.getProperty("jdbc.username"));
dataSource.setPassword(property.getProperty("jdbc.password"));
return dataSource;
}
}

View File

@ -1,4 +0,0 @@
jdbc.driver= com.mysql.jdbc.Driver
jdbc.url= jdbc:mysql://mysql_server:3306/mqtt
jdbc.username= root
jdbc.password= public

View File

@ -1,3 +0,0 @@
Manifest-Version: 1.0
Class-Path:

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://JAVA.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>emqx-web</display-name>
<servlet>
<servlet-name>Auth</servlet-name>
<servlet-class>com.emqx.servlet.AuthServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Acl</servlet-name>
<servlet-class>com.emqx.servlet.AclServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Auth</servlet-name>
<url-pattern>/auth</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Acl</servlet-name>
<url-pattern>/acl</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>love</title>
</head>
<body>
It's lucky, jiabanxiang.
</body>
</html>

View File

@ -1,34 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlink", "Dlink\Dlink.csproj", "{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DlinkClient", "DlinkClient\DlinkClient.csproj", "{B754FB02-D501-4308-8B89-33AB7119C80D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DlinkServer", "DlinkServer\DlinkServer.csproj", "{DDBFF994-E076-43AD-B18D-049DFC1B670C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.Build.0 = Release|Any CPU
{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.Build.0 = Release|Any CPU
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="dlink.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.12.2" />
<PackageReference Include="Grpc.Core" Version="2.29.0" />
<PackageReference Include="Grpc.HealthCheck" Version="2.29.0" />
<PackageReference Include="Grpc.Reflection" Version="2.29.0" />
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Grpc.Tools" Version="2.29.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="dlink.proto" />
</ItemGroup>
</Project>

View File

@ -1,30 +0,0 @@
// copy from: https://grpc.io/docs/what-is-grpc/introduction/
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.dgiot.dlink";
option java_outer_classname = "DlinkProto";
option objc_class_prefix = "dlink";
package dgiot;
// The dlink service definition.
service Dlink {
rpc Payload (PayloadRequest) returns (PayloadResponse) {}
}
// The request message containing PayloadRequest.
message PayloadRequest {
optional string product = 1;
string cmd = 2;
string data = 3;
}
// The response message containing PayloadResponse
message PayloadResponse {
optional string topic = 1;
optional string payload = 2;
optional string ack = 3;
}

View File

@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Dlink\Dlink.csproj" />
</ItemGroup>
</Project>

View File

@ -1,50 +0,0 @@
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using Grpc.Core;
using CommandLine;
namespace DlinkClient
{
class Program
{
private class Options
{
[Option("server", Default = "localhost:30051", HelpText = "The address of the server")]
public string Server { get; set; }
}
public static void Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args)
.WithParsed<Options>(options => RunClient(options));
}
private static void RunClient(Options options)
{
Channel channel = new Channel(options.Server, ChannelCredentials.Insecure);
var client = new Dlink.DlinkClient(channel);
String user = "you";
var reply = client.Payload(new PayloadRequest { Name = user });
Console.WriteLine("Dlink client received: " + reply.Message);
channel.ShutdownAsync().Wait();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}

View File

@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Dlink\Dlink.csproj" />
</ItemGroup>
</Project>

View File

@ -1,92 +0,0 @@
// Copyright 2020 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.Net;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.HealthCheck;
using Dgiot;
using Grpc.Health.V1;
using Grpc.Reflection;
using Grpc.Reflection.V1Alpha;
using CommandLine;
namespace DlinkServer
{
class DlinkImpl : Dlink.DlinkBase
{
private string hostname;
public DlinkImpl(string hostname)
{
this.hostname = hostname;
}
// Server side handler of the SayHello RPC
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply { Message = $"Hello {request.Name} from {hostname}!"});
}
}
class Program
{
class Options
{
[Option("port", Default = 30051, HelpText = "The port to listen on.")]
public int Port { get; set; }
[Option("hostname", Required = false, HelpText = "The name clients will see in responses. If not specified, machine's hostname will obtain automatically.")]
public string Hostname { get; set; }
}
public static void Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args)
.WithParsed<Options>(options => RunServer(options));
}
private static void RunServer(Options options)
{
var hostName = options.Hostname ?? Dns.GetHostName();
var serviceDescriptors = new [] { Dlink.Descriptor, Health.Descriptor, ServerReflection.Descriptor};
var greeterImpl = new DlinkImpl(hostName);
var healthServiceImpl = new HealthServiceImpl();
var reflectionImpl = new ReflectionServiceImpl(serviceDescriptors);
Server server = new Server
{
Services = { Dlink.BindService(greeterImpl), Health.BindService(healthServiceImpl), ServerReflection.BindService(reflectionImpl) },
Ports = { new ServerPort("[::]", options.Port, ServerCredentials.Insecure) }
};
server.Start();
// Mark all services as healthy.
foreach (var serviceDescriptor in serviceDescriptors)
{
healthServiceImpl.SetStatus(serviceDescriptor.FullName, HealthCheckResponse.Types.ServingStatus.Serving);
}
// Mark overall server status as healthy.
healthServiceImpl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
Console.WriteLine("Dlink server listening on port " + options.Port);
Console.WriteLine("Press any key to stop the server...");
Console.ReadKey();
server.ShutdownAsync().Wait();
}
}
}

View File

@ -1,99 +0,0 @@
gRPC Hostname example (C#)
========================
BACKGROUND
-------------
This is a version of the dlink example with a server whose response includes its hostname. It also supports health and reflection services. This makes it a good server to test infrastructure, such as XDS load balancing.
PREREQUISITES
-------------
- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core)
You can also build the solution `Dlink.sln` using Visual Studio 2019,
but it's not a requirement.
RUN THE EXAMPLE
-------------
First, build and run the server, then verify the server is running and
check the server is behaving as expected (more on that below).
```
cd DlinkServer
dotnet run
```
After configuring your dlink server to track the gRPC server we just started,
create a bootstrap file as desribed in [gRFC A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md):
```
{
dlink_servers": [
{
"server_uri": <string containing URI of xds server>,
"channel_creds": [
{
"type": <string containing channel cred type>,
"config": <JSON object containing config for the type>
}
]
}
],
"node": <JSON form of Node proto>
}
```
Then point the `GRPC_DLINK_BOOTSTRAP` environment variable at the bootstrap file:
```
export GRPC_DLINK_BOOTSTRAP=/etc/dlink-bootstrap.json
```
Finally, run your client:
```
cd DlinkClient
dotnet run --server dlink-experimental:///my-backend
```
VERIFYING THE SERVER
-------------
`grpcurl` can be used to test your server. If you don't have it,
install [`grpcurl`](https://github.com/fullstorydev/grpcurl/releases). This will allow
you to manually test the service.
Exercise your server's application-layer service:
```sh
> grpcurl --plaintext -d '{"name": "you"}' localhost:30051
{
"message": "Hello you from jtatt.muc.corp.google.com!"
}
```
Make sure that all of your server's services are available via reflection:
```sh
> grpcurl --plaintext localhost:30051 list
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
```
Make sure that your services are reporting healthy:
```sh
> grpcurl --plaintext -d '{"service": "helloworld.Dlink"}' localhost:30051
grpc.health.v1.Health/Check
{
"status": "SERVING"
}
> grpcurl --plaintext -d '{"service": ""}' localhost:30051
grpc.health.v1.Health/Check
{
"status": "SERVING"
}
```

View File

@ -1,23 +0,0 @@
.rebar3
_*
.eunit
*.o
*.beam
*.plt
*.swp
*.swo
.erlang.cookie
ebin
log
erl_crash.dump
.rebar
logs
_build
.idea
*.iml
rebar3.crashdump
*~
rebar.lock
src/route_guide_pb.erl
src/routeguide_route_guide_bhvr.erl
src/routeguide_route_guide_client.erl

View File

@ -1,191 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2021, JianBo He <heeejianbo@gmail.com>.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,53 +0,0 @@
# route_guide
The example application for grpc
## Build
```
rebar3 compile
```
## Usage
1. Start the rebar3 shell
```
rebar3 shell
```
2. Start the `route_guide` services in the rebar3 shell
```erl
1> route_guide:start_services().
Start service route_guide on 10000 successfully!
```
3. Start the client channel
```erl
2> route_guide:start_client_channel().
Start client channel channel1 for http://127.0.0.1:10000 successfully!
```
4. Call the `get_feature` method of route_guide services
```erl
3> routeguide_route_guide_client:get_feature(#{latitude => 1, longitude => 1}, #{channel => channel1}).
{ok,#{name => <<>>},
[{<<"grpc-message">>,<<>>},{<<"grpc-status">>,<<"0">>}]}
```
## Project Structure
```
├── priv
│   └── route_guide.proto %% The grpc services defined file
└── src
├── route_guide.app.src
├── route_guide.erl %% mainly example codes
├── route_guide_pb.erl %% generated by gpb
├── route_guide_svr.erl %% the route_guide service implementation
├── routeguide_route_guide_bhvr.erl %% generated by grpc-plugin
└── routeguide_route_guide_client.erl %% generated by grpc-plugin
```

View File

@ -1,125 +0,0 @@
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.routeguide";
option java_outer_classname = "RouteGuideProto";
package routeguide;
// Interface exported by the server.
service RouteGuide {
// A simple RPC.
//
// Obtains the feature at a given position.
//
// A feature with an empty name is returned if there's no feature at the given
// position.
rpc GetFeature(Point) returns (Feature) {}
// A server-to-client streaming RPC.
//
// Obtains the Features available within the given Rectangle. Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field), as the rectangle may cover a large area and contain a
// huge number of features.
rpc ListFeatures(Rectangle) returns (stream Feature) {}
// A client-to-server streaming RPC.
//
// Accepts a stream of Points on a route being traversed, returning a
// RouteSummary when traversal is completed.
rpc RecordRoute(stream Point) returns (RouteSummary) {}
// A Bidirectional streaming RPC.
//
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {
// One corner of the rectangle.
Point lo = 1;
// The other corner of the rectangle.
Point hi = 2;
}
// A feature names something at a given point.
//
// If a feature could not be named, the name is empty.
message Feature {
// The name of the feature.
string name = 1;
// The point where the feature is detected.
Point location = 2;
}
// A RouteNote is a message sent while at a given point.
message RouteNote {
// The location from which the message is sent.
Point location = 1;
// The message to be sent.
string message = 2;
}
// A RouteSummary is received in response to a RecordRoute rpc.
//
// It contains the number of individual points received, the number of
// detected features, and the total distance covered as the cumulative sum of
// the distance between each point.
message RouteSummary {
// The number of points received.
int32 point_count = 1;
// The number of known features passed while traversing the route.
int32 feature_count = 2;
// The distance covered in metres.
int32 distance = 3;
// The duration of the traversal in seconds.
int32 elapsed_time = 4;
}

View File

@ -1,22 +0,0 @@
{erl_opts, [debug_info]}.
{plugins,
[rebar3_proper,
{grpc_plugin, {git, "https://gitee.com/fastdgiot/grpc_plugin.git", {tag, "v0.10.3"}}}
]}.
{deps,
[{grpc, {git, "https://gitee.com/fastdgiot/grpc-erl", {tag, "0.6.8"}}}
]}.
{grpc,
[ {type, all}
, {protos, ["priv/"]}
, {out_dir, "src/"}
, {gpb_opts, [{module_name_suffix, "_pb"}]}
]}.
{provider_hooks,
[{pre, [{compile, {grpc, gen}},
{clean, {grpc, clean}}]}
]}.

View File

@ -1,11 +0,0 @@
{application, route_guide,
[{description, "An OTP application"},
{vsn, "0.1.0"},
{registered, []},
{mod, {route_guide, []}},
{applications, [kernel,stdlib,grpc]},
{env,[]},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.

View File

@ -1,64 +0,0 @@
-module(route_guide).
-behaviour(supervisor).
-behaviour(application).
-export([start/2, stop/1]).
-export([init/1]).
-export([start_services/0, start_client_channel/0,
stop_services/0, stop_client_channel/0]).
%%--------------------------------------------------------------------
%% APIs
-define(SERVER_NAME, route_guide).
-define(CHANN_NAME, channel1).
start_services() ->
Services = #{protos => [route_guide_pb],
services => #{'routeguide.RouteGuide' => route_guide_svr}
},
Options = [],
{ok, _} = grpc:start_server(?SERVER_NAME, 10000, Services, Options),
io:format("Start service ~s on 10000 successfully!~n", [?SERVER_NAME]).
start_client_channel() ->
ClientOps = #{},
SvrAddr = "http://127.0.0.1:10000",
{ok, _} = grpc_client_sup:create_channel_pool(
?CHANN_NAME,
SvrAddr,
ClientOps
),
io:format("Start client channel ~s for ~s successfully!~n~n"
"Call the 'routeguide_route_guide_client' module exported functions "
"to use it. e.g:~n"
" routeguide_route_guide_client:get_feature(#{latitude => 1"
", longitude => 1}, #{channel => channel1}).~n",
[?CHANN_NAME, SvrAddr]).
stop_services() ->
grpc:stop_server(?SERVER_NAME).
stop_client_channel() ->
grpc_client_sup:stop_channel_pool(?CHANN_NAME).
%%--------------------------------------------------------------------
%% APIs for application
start(_StartType, _StartArgs) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
stop(_State) ->
ok.
%%--------------------------------------------------------------------
%% callbacks for supervisor
init([]) ->
SupFlags = #{strategy => one_for_all,
intensity => 0,
period => 1},
ChildSpecs = [],
{ok, {SupFlags, ChildSpecs}}.

View File

@ -1,56 +0,0 @@
-module(route_guide_svr).
-behavior(routeguide_route_guide_bhvr).
-compile(export_all).
-compile(nowarn_export_all).
-define(LOG(Fmt, Args), io:format(standard_error, "[Svr] " ++ Fmt, Args)).
%%--------------------------------------------------------------------
%% Callbacks
get_feature(Request, _Md) ->
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Request]),
{ok, #{}, _Md}.
list_features(Stream, _Md) ->
{eos, [Request], NStream} = grpc_stream:recv(Stream),
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Request]),
grpc_stream:reply(Stream, [#{name => "City1", location => #{latitude => 1, longitude => 1}}]),
grpc_stream:reply(Stream, [#{name => "City2", location => #{latitude => 2, longitude => 2}}]),
grpc_stream:reply(Stream, [#{name => "City3", location => #{latitude => 3, longitude => 3}}]),
{ok, NStream}.
record_route(Stream, _Md) ->
LoopRecv = fun _Lp(St, Acc) ->
case grpc_stream:recv(St) of
{more, Reqs, NSt} ->
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Reqs]),
_Lp(NSt, Acc ++ Reqs);
{eos, Reqs, NSt} ->
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Reqs]),
{NSt, Acc ++ Reqs}
end
end,
{NStream, Points} = LoopRecv(Stream, []),
grpc_stream:reply(NStream, #{point_count => length(Points)}),
{ok, NStream}.
route_chat(Stream, _Md) ->
grpc_stream:reply(Stream, [#{name => "City1", location => #{latitude => 1, longitude => 1}}]),
grpc_stream:reply(Stream, [#{name => "City2", location => #{latitude => 2, longitude => 2}}]),
LoopRecv = fun _Lp(St) ->
case grpc_stream:recv(St) of
{more, Reqs, NSt} ->
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Reqs]),
_Lp(NSt);
{eos, Reqs, NSt} ->
?LOG("~p: ~0p~n", [?FUNCTION_NAME, Reqs]),
NSt
end
end,
NStream = LoopRecv(Stream),
grpc_stream:reply(NStream, [#{name => "City3", location => #{latitude => 3, longitude => 3}}]),
{ok, NStream}.

View File

@ -1,64 +0,0 @@
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
proto_library(
name = "dlink_proto",
srcs = ["src/main/proto/dlink.proto"],
)
java_proto_library(
name = "dlink_java_proto",
deps = [":dlink_proto"],
)
java_grpc_library(
name = "dlink_java_grpc",
srcs = [":dlink_proto"],
deps = [":dlink_java_proto"],
)
java_library(
name = "examples",
testonly = 1,
srcs = glob(
["src/main/java/**/*.java"],
),
resources = glob(
["src/main/resources/**"],
),
runtime_deps = [
"@io_grpc_grpc_java//netty",
],
deps = [
":helloworld_java_grpc",
":helloworld_java_proto",
"@com_google_protobuf//:protobuf_java",
"@com_google_protobuf//:protobuf_java_util",
"@io_grpc_grpc_java//api",
"@io_grpc_grpc_java//protobuf",
"@io_grpc_grpc_java//stub",
"@maven//:com_google_api_grpc_proto_google_common_protos",
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_code_gson_gson",
"@maven//:com_google_guava_guava",
],
)
java_binary(
name = "dlinkclient",
testonly = 1,
main_class = "io.grpc.examples.dlink.DlinkClient",
runtime_deps = [
":examples",
],
)
java_binary(
name = "dlinkserver",
testonly = 1,
main_class = "io.grpc.examples.dlink.DlinkServer",
runtime_deps = [
":examples",
],
)

View File

@ -1,232 +0,0 @@
gRPC Examples
==============================================
The examples require `grpc-java` to already be built. You are strongly encouraged
to check out a git release tag, since there will already be a build of gRPC
available. Otherwise you must follow [COMPILING](../COMPILING.md).
You may want to read through the
[Quick Start](https://grpc.io/docs/languages/java/quickstart)
before trying out the examples.
## Basic examples
- [Hello world](src/main/java/io/grpc/dgiot/dlink)
- [Route guide](src/main/java/io/grpc/dgiot/routeguide)
- [Metadata](src/main/java/io/grpc/dgiot/header)
- [Error handling](src/main/java/io/grpc/dgiot/errorhandling)
- [Compression](src/main/java/io/grpc/dgiot/experimental)
- [Flow control](src/main/java/io/grpc/dgiot/manualflowcontrol)
- [Json serialization](src/main/java/io/grpc/dgiot/advanced)
- <details>
<summary>Hedging</summary>
The [hedging example](src/main/java/io/grpc/dgiot/hedging) demonstrates that enabling hedging
can reduce tail latency. (Users should note that enabling hedging may introduce other overhead;
and in some scenarios, such as when some server resource gets exhausted for a period of time and
almost every RPC during that time has high latency or fails, hedging may make things worse.
Setting a throttle in the service config is recommended to protect the server from too many
inappropriate retry or hedging requests.)
The server and the client in the example are basically the same as those in the
[hello world](src/main/java/io/grpc/dgiot/dlink) example, except that the server mimics a
long tail of latency, and the client sends 2000 requests and can turn on and off hedging.
To mimic the latency, the server randomly delays the RPC handling by 2 seconds at 10% chance, 5
seconds at 5% chance, and 10 seconds at 1% chance.
When running the client enabling the following hedging policy
```json
"hedgingPolicy": {
"maxAttempts": 3,
"hedgingDelay": "1s"
}
```
Then the latency summary in the client log is like the following
```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging enabled]
========================
50% latency: 0ms
90% latency: 6ms
95% latency: 1,003ms
99% latency: 2,002ms
99.9% latency: 2,011ms
Max latency: 5,272ms
========================
```
See [the section below](#to-build-the-examples) for how to build and run the example. The
executables for the server and the client are `hedging-hello-world-server` and
`hedging-hello-world-client`.
To disable hedging, set environment variable `DISABLE_HEDGING_IN_HEDGING_EXAMPLE=true` before
running the client. That produces a latency summary in the client log like the following
```text
Total RPCs sent: 2,000. Total RPCs failed: 0
[Hedging disabled]
========================
50% latency: 0ms
90% latency: 2,002ms
95% latency: 5,002ms
99% latency: 10,004ms
99.9% latency: 10,007ms
Max latency: 10,007ms
========================
```
</details>
- <details>
<summary>Retrying</summary>
The [retrying example](src/main/java/io/grpc/dgiot/retrying) provides a HelloWorld gRPC client &
server which demos the effect of client retry policy configured on the [ManagedChannel](
../api/src/main/java/io/grpc/ManagedChannel.java) via [gRPC ServiceConfig](
https://github.com/grpc/grpc/blob/master/doc/service_config.md). Retry policy implementation &
configuration details are outlined in the [proposal](https://github.com/grpc/proposal/blob/master/A6-client-retries.md).
This retrying example is very similar to the [hedging example](src/main/java/io/grpc/dgiot/hedging) in its setup.
The [RetryingHelloWorldServer](src/main/java/io/grpc/dgiot/retrying/RetryingHelloWorldServer.java) responds with
a status UNAVAILABLE error response to a specified percentage of requests to simulate server resource exhaustion and
general flakiness. The [RetryingHelloWorldClient](src/main/java/io/grpc/dgiot/retrying/RetryingHelloWorldClient.java) makes
a number of sequential requests to the server, several of which will be retried depending on the configured policy in
[retrying_service_config.json](src/main/resources/io/grpc/examples/retrying/retrying_service_config.json). Although
the requests are blocking unary calls for simplicity, these could easily be changed to future unary calls in order to
test the result of request concurrency with retry policy enabled.
One can experiment with the [RetryingHelloWorldServer](src/main/java/io/grpc/dgiot/retrying/RetryingHelloWorldServer.java)
failure conditions to simulate server throttling, as well as alter policy values in the [retrying_service_config.json](
src/main/resources/io/grpc/examples/retrying/retrying_service_config.json) to see their effects. To disable retrying
entirely, set environment variable `DISABLE_RETRYING_IN_RETRYING_EXAMPLE=true` before running the client.
Disabling the retry policy should produce many more failed gRPC calls as seen in the output log.
See [the section below](#to-build-the-examples) for how to build and run the example. The
executables for the server and the client are `retrying-hello-world-server` and
`retrying-hello-world-client`.
</details>
### <a name="to-build-the-examples"></a> To build the examples
1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**
2. From grpc-java/examples directory:
```
$ ./gradlew installDist
```
This creates the scripts `dlinkserver`, `dlinkclient`,
`route-guide-server`, `route-guide-client`, etc. in the
`build/install/dgiot/bin/` directory that run the examples. Each
example requires the server to be running before starting the client.
For example, to try the hello world example first run:
```
$ ./build/install/dgiot/bin/dlinkserver
```
And in a different terminal window run:
```
$ ./build/install/dgiot/bin/dlinkclient
```
That's it!
For more information, refer to gRPC Java's [README](../README.md) and
[tutorial](https://grpc.io/docs/languages/java/basics).
### Maven
If you prefer to use Maven:
1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).**
2. Run in this directory:
```
$ mvn verify
$ # Run the server
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.dlink.DlinkServer
$ # In another terminal run the client
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.dlink.DlinkClient
```
### Bazel
If you prefer to use Bazel:
```
$ bazel build :hello-world-server :hello-world-client
$ # Run the server
$ bazel-bin/hello-world-server
$ # In another terminal run the client
$ bazel-bin/hello-world-client
```
## Other examples
- [Android examples](android)
- Secure channel examples
+ [TLS examples](example-tls)
+ [ALTS examples](example-alts)
- [Google Authentication](example-gauth)
- [JWT-based Authentication](example-jwt-auth)
## Unit test examples
Examples for unit testing gRPC clients and servers are located in [examples/src/test](src/test).
In general, we DO NOT allow overriding the client stub and we DO NOT support mocking final methods
in gRPC-Java library. Users should be cautious that using tools like PowerMock or
[mockito-inline](https://search.maven.org/search?q=g:org.mockito%20a:mockito-inline) can easily
break this rule of thumb. We encourage users to leverage `InProcessTransport` as demonstrated in the
examples to write unit tests. `InProcessTransport` is light-weight and runs the server
and client in the same process without any socket/TCP connection.
Mocking the client stub provides a false sense of security when writing tests. Mocking stubs and responses
allows for tests that don't map to reality, causing the tests to pass, but the system-under-test to fail.
The gRPC client library is complicated, and accurately reproducing that complexity with mocks is very hard.
You will be better off and write less code by using `InProcessTransport` instead.
Example bugs not caught by mocked stub tests include:
* Calling the stub with a `null` message
* Not calling `close()`
* Sending invalid headers
* Ignoring deadlines
* Ignoring cancellation
For testing a gRPC client, create the client with a real stub
using an
[InProcessChannel](../core/src/main/java/io/grpc/inprocess/InProcessChannelBuilder.java),
and test it against an
[InProcessServer](../core/src/main/java/io/grpc/inprocess/InProcessServerBuilder.java)
with a mock/fake service implementation.
For testing a gRPC server, create the server as an InProcessServer,
and test it against a real client stub with an InProcessChannel.
The gRPC-java library also provides a JUnit rule,
[GrpcCleanupRule](../testing/src/main/java/io/grpc/testing/GrpcCleanupRule.java), to do the graceful
shutdown boilerplate for you.
## Even more examples
A wide variety of third-party examples can be found [here](https://github.com/saturnism/grpc-java-by-example).

View File

@ -1,50 +0,0 @@
workspace(name = "examples")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# For released versions, use release tag:
# http_archive(
# name = "io_grpc_grpc_java",
# sha256 = "<SHA>",
# strip_prefix = "grpc-java-<TAG>",
# url = "https://github.com/grpc/grpc-java/archive/<TAG>.zip",
# )
local_repository(
name = "io_grpc_grpc_java",
path = "..",
)
http_archive(
name = "rules_jvm_external",
sha256 = "c21ce8b8c4ccac87c809c317def87644cdc3a9dd650c74f41698d761c95175f3",
strip_prefix = "rules_jvm_external-1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a",
url = "https://github.com/bazelbuild/rules_jvm_external/archive/1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a.zip",
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
load("@io_grpc_grpc_java//:repositories.bzl", "IO_GRPC_GRPC_JAVA_ARTIFACTS")
load("@io_grpc_grpc_java//:repositories.bzl", "IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS")
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
grpc_java_repositories()
load("@com_google_protobuf//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS")
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
maven_install(
artifacts = [
"com.google.api.grpc:grpc-google-cloud-pubsub-v1:0.1.24",
"com.google.api.grpc:proto-google-cloud-pubsub-v1:0.1.24",
] + IO_GRPC_GRPC_JAVA_ARTIFACTS + PROTOBUF_MAVEN_ARTIFACTS,
generate_compat_repositories = True,
override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS,
repositories = [
"https://repo.maven.apache.org/maven2/",
],
)
load("@maven//:compat.bzl", "compat_repositories")
compat_repositories()

View File

@ -1,83 +0,0 @@
plugins {
// Provide convenience executables for trying out the examples.
id 'application'
id 'com.google.protobuf' version '0.9.1'
// Generate IntelliJ IDEA's .idea & .iml project files
id 'idea'
}
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/maven2/" }
mavenCentral()
mavenLocal()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
// IMPORTANT: You probably want the non-SNAPSHOT version of gRPC. Make sure you
// are looking at a tagged version of the example and not "master"!
// Feel free to delete the comment at the next line. It is just for safely
// updating the version in our release process.
def grpcVersion = '1.54.0' // CURRENT_GRPC_VERSION
def protobufVersion = '3.21.7'
def protocVersion = protobufVersion
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
compileOnly "org.apache.tomcat:annotations-api:6.0.53"
// examples/advanced need this for JsonFormat
implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
testImplementation "io.grpc:grpc-testing:${grpcVersion}"
testImplementation "junit:junit:4.13.2"
testImplementation "org.mockito:mockito-core:3.4.0"
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
}
generateProtoTasks {
all()*.plugins { grpc {} }
}
}
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
startScripts.enabled = false
task dlinkServer(type: CreateStartScripts) {
mainClass = 'io.grpc.dgiot.dlink.DlinkServer'
applicationName = 'dlinkserver'
outputDir = new File(project.buildDir, 'tmp/scripts/' + name)
classpath = startScripts.classpath
}
task dlinkClient(type: CreateStartScripts) {
mainClass = 'io.grpc.dgiot.dlink.DlinkClient'
applicationName = 'dlinkclient'
outputDir = new File(project.buildDir, 'tmp/scripts/' + name)
classpath = startScripts.classpath
}
applicationDistribution.into('bin') {
from(dlinkServer)
from(dlinkClient)
fileMode = 0755
}

View File

@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,234 +0,0 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@ -1,89 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,131 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.grpc</groupId>
<artifactId>examples</artifactId>
<packaging>jar</packaging>
<!-- Feel free to delete the comment at the end of these lines. It is just
for safely updating the version in our release process. -->
<version>1.54.0</version><!-- CURRENT_GRPC_VERSION -->
<name>examples</name>
<url>https://github.com/grpc/grpc-java</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<grpc.version>1.54.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
<protobuf.version>3.21.7</protobuf.version>
<protoc.version>3.21.7</protoc.version>
<!-- required for JDK 8 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-bom</artifactId>
<version>${grpc.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version> <!-- prevent downgrade via protobuf-java-util -->
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope> <!-- not needed at runtime -->
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireUpperBoundDeps/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,167 +0,0 @@
# [Protobuf 之 proto 基础语法](https://www.cnblogs.com/sherlock-lin/p/16522652.html)
目录
* [1、说明](https://www.cnblogs.com/sherlock-lin/p/16522652.html#1%E8%AF%B4%E6%98%8E)
* [2、字段类型](https://www.cnblogs.com/sherlock-lin/p/16522652.html#2%E5%AD%97%E6%AE%B5%E7%B1%BB%E5%9E%8B)
* [3、字段规则](https://www.cnblogs.com/sherlock-lin/p/16522652.html#3%E5%AD%97%E6%AE%B5%E8%A7%84%E5%88%99)
* [4、字段编号](https://www.cnblogs.com/sherlock-lin/p/16522652.html#4%E5%AD%97%E6%AE%B5%E7%BC%96%E5%8F%B7)
* [5、注释](https://www.cnblogs.com/sherlock-lin/p/16522652.html#5%E6%B3%A8%E9%87%8A)
* [6、类型](https://www.cnblogs.com/sherlock-lin/p/16522652.html#6%E7%B1%BB%E5%9E%8B)
* [6.1、message](https://www.cnblogs.com/sherlock-lin/p/16522652.html#61message)
* [6.2、service](https://www.cnblogs.com/sherlock-lin/p/16522652.html#62service)
* [7、枚举 enum](https://www.cnblogs.com/sherlock-lin/p/16522652.html#7%E6%9E%9A%E4%B8%BEenum)
* [8、保留字段](https://www.cnblogs.com/sherlock-lin/p/16522652.html#8%E4%BF%9D%E7%95%99%E5%AD%97%E6%AE%B5)
* [9、import](https://www.cnblogs.com/sherlock-lin/p/16522652.html#9import)
* [9.1、protoc 指令](https://www.cnblogs.com/sherlock-lin/p/16522652.html#91protoc%E6%8C%87%E4%BB%A4)
# 1、说明
示例中的 proto 文件描述了一个数据结构,遵循 Protobuf 语法
示例:
```protobuf
message TestOne {
required string name = 1;
optional int32 age = 2;
}
```
# 2、字段类型
| type | C++ type | Java Type | Python Type | description |
| -------- | -------- | ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| double | double | double | float | |
| float | float | float | float | |
| int32 | int | int | int | |
| uint32 | uint32 | int | int/long | |
| int64 | int64 | long | int/long | |
| uint64 | uint64 | long | int/long | |
| sint32 | int32 | int | int | 存数据时引入 zigzag 编码``Zigzag(n) = (n << 1) ^ (n >> 31)``解决负数太占空间的问题``**正负数最多占用 5 个字节,内存高效** |
| sint64 | int64 | long | int/long | |
| fixed32 | uint32 | int | int/long | 4 byte``抛弃了可变长存储策略``适用与存储数值较大数据 |
| fixed64 | uint64 | long | int/long | |
| sfixed32 | int32 | int | int | |
| sfixed64 | int64 | long | int/long | |
| bool | bool | boolean | bool | |
| string | string | String | unicode | |
| bytes | string | ByteString | bytes | |
1. 负数使用 **sint**
2. 数值较大,使用 **fixed**
# 3、字段规则
示例中的 required 和 optional 都是字段规则,规则有以下几个:
| 字段规则 | 说明 |
| -------- | ------------------------------------------------------------------------------------- |
| required | 格式良好的 message 必须包含该字段一次 |
| optional | 格式良好的 message 可以包含该字段零次或一次(不超过一次) |
| repeated | 该字段可以在格式良好的消息中重复任意多次(包括零)``其中重复值的顺序会被保留。 |
**optional** 字段是可选字段,如果不设定数据,则需要有一个默认值以避免出错,指定方式:
```protobuf
message TestOne {
required string name = 1;
optional int32 age = 2 [default = 100];
}
```
# 4、字段编号
如示例中,每个字段都有一个编号,这些编号是 **唯一的**
* 编号 1-15 会占用一个字节16-2047 占用两个字节,因此尽可能使用 1-15
* 字段编号在 message 被使用后,就不能再更改;
# 5、注释
支持使用 C/C++ 风格的注释
# 6、类型
## 6.1、message
* **message** 表示一个类型,后面的名称将会是类名;
* 一个 proto 文件可以定义多种 message 类型,但尽可能减少一个 proto 多类型的情况;
> 组合 messages 会导致膨胀虽然可以在单个 .proto 文件中定义多种 messages 类型(例如 messageenum 和 service但是当在单个文件中定义了大量具有不同依赖关系的 messages 时,它也会导致依赖性膨胀。建议每个 .proto 文件包含尽可能少的 message 类型。
## 6.2、service
一般在和 RPC 系统一起使用,示例:
```protobuf
service TestService {
rpc Test (TestRequest) returns (TestResponse);
}
```
# 7、枚举 enum
枚举定在 **message** 内部
示例:
```protobuf
message TestOne {
required string name = 1;
optional int32 age = 2 [default = 100];
enum Country {
China = 0;
USA = 1;
}
optional Country country = 3 [default = China]
}
```
# 8、保留字段
示例:
下面例子,字段编号 2/15/9/11 曾经使用过,保留;字段名 foo/bar 曾经使用过,保留
```protobuf
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
```
如果一个字段不再需要,如果删除或者注释掉,则其他人在修改时会再次使用这些字段编号,那么旧的引用程序就可能出现一些错误,所以使用保留字段,保留已弃用的字段编号或字段名 ,可解决该问题
# 9、import
如果一个 proto 文件需要使用另一个 proto 文件中的定义(message/service),就需要使用 **import** 引入其他的 proto 文件
**import** 使用 **public** 属性,控制依赖是否可以传递,被 **public** 修饰的可以传递
示例:
```protobuf
//second.proto
import "message/aaa.proto";
import public "message/bbb.proto";
```
```protobuf
//test_one.proto
import "message/second.proto";
message TestOne {
required string name = 1;
optional int32 age = 2 [default = 100];
}
```
如上示例中test_one.proto 中可以使用 bbb.proto 的类型,但不能使用 aaa.proto 中的类型
## 9.1、protoc 指令
protoc 的参数 **-I** 和 **--proto_path** 用于传递 **import** 的路径
当不同的 proto 文件位于不同的路径时import 可以不传递相对路径,而使用 -I 或者 --proto_path 传递 import 的查找路径

View File

@ -1,10 +0,0 @@
pluginManagement {
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/maven2/"
}
gradlePluginPortal()
}
}
rootProject.name = 'dgiot'

View File

@ -1,105 +0,0 @@
/*
* Copyright 2015 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.dgiot.dlink;
import io.grpc.Channel;
import io.grpc.Grpc;
import io.grpc.InsecureChannelCredentials;
import io.grpc.ManagedChannel;
import io.grpc.StatusRuntimeException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A simple client that requests a greeting from the {@link DlinkServer}.
*/
public class DlinkClient {
private static final Logger logger = Logger.getLogger(DlinkClient.class.getName());
private final DlinkGrpc.DlinkBlockingStub blockingStub;
/** Construct client for accessing HelloWorld server using the existing channel. */
public DlinkClient(Channel channel) {
// 'channel' here is a Channel, not a ManagedChannel, so it is not this code's responsibility to
// shut it down.
// Passing Channels to code makes code easier to test and makes it easier to reuse Channels.
blockingStub = DlinkGrpc.newBlockingStub(channel);
}
/** Say hello to server. */
public void payload(String data) {
logger.info("Will try to login " + data + " ...");
PayloadRequest request = PayloadRequest.newBuilder()
.setData(data)
.setCmd("cmd")
.setProduct("product")
.build();
PayloadResponse response;
try {
response = blockingStub.payload(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Greeting: " + response.getPayload());
}
/**
* Greet server. If provided, the first element of {@code args} is the name to use in the
* greeting. The second argument is the target server.
*/
public static void main(String[] args) throws Exception {
String data = "world";
// Access a service running on the local machine on port 50051
String target = "localhost:30051";
// Allow passing in the user and target strings as command line arguments
if (args.length > 0) {
if ("--help".equals(args[0])) {
System.err.println("Usage: [name [target]]");
System.err.println("");
System.err.println(" name The name you wish to be greeted by. Defaults to " + data);
System.err.println(" target The server to connect to. Defaults to " + target);
System.exit(1);
}
data = args[0];
}
if (args.length > 1) {
target = args[1];
}
// Create a communication channel to the server, known as a Channel. Channels are thread-safe
// and reusable. It is common to create channels at the beginning of your application and reuse
// them until the application shuts down.
//
// For the example we use plaintext insecure credentials to avoid needing TLS certificates. To
// use TLS, use TlsChannelCredentials instead.
ManagedChannel channel = Grpc.newChannelBuilder(target, InsecureChannelCredentials.create())
.build();
try {
DlinkClient client = new DlinkClient(channel);
client.payload(data);
} finally {
// ManagedChannels use resources like threads and TCP connections. To prevent leaking these
// resources the channel should be shut down when it will no longer be used. If it may be used
// again leave it running.
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);
}
}
}

View File

@ -1,96 +0,0 @@
/*
* Copyright 2015 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.dgiot.dlink;
import io.grpc.Grpc;
import io.grpc.InsecureServerCredentials;
import io.grpc.Server;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
/**
* Server that manages startup/shutdown of a {@code Dlink} server.
*/
public class DlinkServer {
private static final Logger logger = Logger.getLogger(DlinkServer.class.getName());
private Server server;
private void start() throws IOException {
/* The port on which the server should run */
int port = 30051;
server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
.addService(new DlinkImpl())
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
try {
DlinkServer.this.stop();
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
System.err.println("*** server shut down");
}
});
}
private void stop() throws InterruptedException {
if (server != null) {
server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
}
}
/**
* Await termination on the main thread since the grpc library uses daemon threads.
*/
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
/**
* Main launches the server from the command line.
*/
public static void main(String[] args) throws IOException, InterruptedException {
final DlinkServer server = new DlinkServer();
server.start();
server.blockUntilShutdown();
}
static class DlinkImpl extends DlinkGrpc.DlinkImplBase {
@Override public void payload(PayloadRequest req, StreamObserver<PayloadResponse> responseObserver) {
//System.err.println("" + req.getMessage());
System.err.println("data from: " + req.getData());
System.err.println("cmd from: " + req.getCmd());
System.err.println("product from: " + req.getProduct());
PayloadResponse reply = PayloadResponse.newBuilder()
.setAck("Hello " + req.getData())
.setTopic("topic ")
.setPayload("payload ")
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}

View File

@ -1,30 +0,0 @@
// copy from: https://grpc.io/docs/what-is-grpc/introduction/
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.dgiot.dlink";
option java_outer_classname = "DlinkProto";
option objc_class_prefix = "dlink";
package dgiot;
// The dlink service definition.
service Dlink {
rpc Payload (PayloadRequest) returns (PayloadResponse) {}
}
// The request message containing PayloadRequest.
message PayloadRequest {
optional string product = 1;
string cmd = 2;
string data = 3;
}
// The response message containing PayloadResponse
message PayloadResponse {
optional string topic = 1;
optional string payload = 2;
optional string ack = 3;
}

View File

@ -1,22 +0,0 @@
{
"methodConfig": [
{
"name": [
{
"service": "helloworld.Dlink",
"method": "SayHello"
}
],
"hedgingPolicy": {
"maxAttempts": 3,
"hedgingDelay": "1s"
}
}
],
"retryThrottling": {
"maxTokens": 10,
"tokenRatio": 0.1
}
}

View File

@ -1,22 +0,0 @@
{
"methodConfig": [
{
"name": [
{
"service": "helloworld.Dlink",
"method": "SayHello"
}
],
"retryPolicy": {
"maxAttempts": 5,
"initialBackoff": "0.5s",
"maxBackoff": "30s",
"backoffMultiplier": 2,
"retryableStatusCodes": [
"UNAVAILABLE"
]
}
}
]
}

View File

@ -1,50 +0,0 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace dlink;
/**
* The greeting service definition.
*/
class GreeterClient extends \Grpc\BaseStub {
/**
* @param string $hostname hostname
* @param array $opts channel options
* @param \Grpc\Channel $channel (optional) re-use channel object
*/
public function __construct($hostname, $opts, $channel = null) {
parent::__construct($hostname, $opts, $channel);
}
/**
* Sends a greeting
* @param \dlink\HelloRequest $argument input argument
* @param array $metadata metadata
* @param array $options call options
* @return \Grpc\UnaryCall
*/
public function SayHello(\dlink\HelloRequest $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/dlink.Greeter/SayHello',
$argument,
['\dlink\HelloReply', 'decode'],
$metadata, $options);
}
}

View File

@ -1,58 +0,0 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace dlink;
/**
* The greeting service definition.
*/
class GreeterStub {
/**
* Sends a greeting
* @param \Helloworld\HelloRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Helloworld\HelloReply for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SayHello(
\dlink\HelloRequest $request,
\Grpc\ServerContext $context
): ?\dlink\HelloReply {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* Get the method descriptors of the service for server registration
*
* @return array of \Grpc\MethodDescriptor for the service methods
*/
public final function getMethodDescriptors(): array
{
return [
'/dlink.Greeter/SayHello' => new \Grpc\MethodDescriptor(
$this,
'SayHello',
'\dlink\HelloRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

View File

@ -1,60 +0,0 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: dlink.proto
namespace Helloworld;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* The response message containing the greetings
*
* Generated from protobuf message <code>dlink.HelloReply</code>
*/
class HelloReply extends \Google\Protobuf\Internal\Message
{
/**
* Generated from protobuf field <code>string message = 1;</code>
*/
protected $message = '';
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type string $message
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\Helloworld::initOnce();
parent::__construct($data);
}
/**
* Generated from protobuf field <code>string message = 1;</code>
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Generated from protobuf field <code>string message = 1;</code>
* @param string $var
* @return $this
*/
public function setMessage($var)
{
GPBUtil::checkString($var, True);
$this->message = $var;
return $this;
}
}

View File

@ -1,60 +0,0 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
namespace Helloworld;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* The request message containing the user's name.
*
* Generated from protobuf message <code>helloworld.HelloRequest</code>
*/
class HelloRequest extends \Google\Protobuf\Internal\Message
{
/**
* Generated from protobuf field <code>string name = 1;</code>
*/
protected $name = '';
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type string $name
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\Helloworld::initOnce();
parent::__construct($data);
}
/**
* Generated from protobuf field <code>string name = 1;</code>
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Generated from protobuf field <code>string name = 1;</code>
* @param string $var
* @return $this
*/
public function setName($var)
{
GPBUtil::checkString($var, True);
$this->name = $var;
return $this;
}
}

View File

@ -1,275 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: dlink.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='dlink.proto',
package='dgiot',
syntax='proto3',
serialized_options=b'\n\026io.grpc.examples.dlinkB\nDlinkProtoP\001\242\002\005dlink',
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x0b\x64link.proto\x12\x05\x64giot\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t\"%\n\x12HealthCheckRequest\x12\x0f\n\x07service\x18\x01 \x01(\t\"\xa0\x01\n\x13HealthCheckResponse\x12\x38\n\x06status\x18\x01 \x01(\x0e\x32(.dgiot.HealthCheckResponse.ServingStatus\"O\n\rServingStatus\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07SERVING\x10\x01\x12\x0f\n\x0bNOT_SERVING\x10\x02\x12\x13\n\x0fSERVICE_UNKNOWN\x10\x03\x32\xbf\x01\n\x05\x44link\x12\x34\n\x08SayHello\x12\x13.dgiot.HelloRequest\x1a\x11.dgiot.HelloReply\"\x00\x12>\n\x05\x43heck\x12\x19.dgiot.HealthCheckRequest\x1a\x1a.dgiot.HealthCheckResponse\x12@\n\x05Watch\x12\x19.dgiot.HealthCheckRequest\x1a\x1a.dgiot.HealthCheckResponse0\x01\x42.\n\x16io.grpc.examples.dlinkB\nDlinkProtoP\x01\xa2\x02\x05\x64linkb\x06proto3'
)
_HEALTHCHECKRESPONSE_SERVINGSTATUS = _descriptor.EnumDescriptor(
name='ServingStatus',
full_name='dgiot.HealthCheckResponse.ServingStatus',
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name='UNKNOWN', index=0, number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='SERVING', index=1, number=1,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='NOT_SERVING', index=2, number=2,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='SERVICE_UNKNOWN', index=3, number=3,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
],
containing_type=None,
serialized_options=None,
serialized_start=204,
serialized_end=283,
)
_sym_db.RegisterEnumDescriptor(_HEALTHCHECKRESPONSE_SERVINGSTATUS)
_HELLOREQUEST = _descriptor.Descriptor(
name='HelloRequest',
full_name='dgiot.HelloRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='dgiot.HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=22,
serialized_end=50,
)
_HELLOREPLY = _descriptor.Descriptor(
name='HelloReply',
full_name='dgiot.HelloReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='dgiot.HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=52,
serialized_end=81,
)
_HEALTHCHECKREQUEST = _descriptor.Descriptor(
name='HealthCheckRequest',
full_name='dgiot.HealthCheckRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='service', full_name='dgiot.HealthCheckRequest.service', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=83,
serialized_end=120,
)
_HEALTHCHECKRESPONSE = _descriptor.Descriptor(
name='HealthCheckResponse',
full_name='dgiot.HealthCheckResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='status', full_name='dgiot.HealthCheckResponse.status', index=0,
number=1, type=14, cpp_type=8, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
_HEALTHCHECKRESPONSE_SERVINGSTATUS,
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=123,
serialized_end=283,
)
_HEALTHCHECKRESPONSE.fields_by_name['status'].enum_type = _HEALTHCHECKRESPONSE_SERVINGSTATUS
_HEALTHCHECKRESPONSE_SERVINGSTATUS.containing_type = _HEALTHCHECKRESPONSE
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
DESCRIPTOR.message_types_by_name['HealthCheckRequest'] = _HEALTHCHECKREQUEST
DESCRIPTOR.message_types_by_name['HealthCheckResponse'] = _HEALTHCHECKRESPONSE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), {
'DESCRIPTOR' : _HELLOREQUEST,
'__module__' : 'dlink_pb2'
# @@protoc_insertion_point(class_scope:dgiot.HelloRequest)
})
_sym_db.RegisterMessage(HelloRequest)
HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), {
'DESCRIPTOR' : _HELLOREPLY,
'__module__' : 'dlink_pb2'
# @@protoc_insertion_point(class_scope:dgiot.HelloReply)
})
_sym_db.RegisterMessage(HelloReply)
HealthCheckRequest = _reflection.GeneratedProtocolMessageType('HealthCheckRequest', (_message.Message,), {
'DESCRIPTOR' : _HEALTHCHECKREQUEST,
'__module__' : 'dlink_pb2'
# @@protoc_insertion_point(class_scope:dgiot.HealthCheckRequest)
})
_sym_db.RegisterMessage(HealthCheckRequest)
HealthCheckResponse = _reflection.GeneratedProtocolMessageType('HealthCheckResponse', (_message.Message,), {
'DESCRIPTOR' : _HEALTHCHECKRESPONSE,
'__module__' : 'dlink_pb2'
# @@protoc_insertion_point(class_scope:dgiot.HealthCheckResponse)
})
_sym_db.RegisterMessage(HealthCheckResponse)
DESCRIPTOR._options = None
_DLINK = _descriptor.ServiceDescriptor(
name='Dlink',
full_name='dgiot.Dlink',
file=DESCRIPTOR,
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=286,
serialized_end=477,
methods=[
_descriptor.MethodDescriptor(
name='SayHello',
full_name='dgiot.Dlink.SayHello',
index=0,
containing_service=None,
input_type=_HELLOREQUEST,
output_type=_HELLOREPLY,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.MethodDescriptor(
name='Check',
full_name='dgiot.Dlink.Check',
index=1,
containing_service=None,
input_type=_HEALTHCHECKREQUEST,
output_type=_HEALTHCHECKRESPONSE,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.MethodDescriptor(
name='Watch',
full_name='dgiot.Dlink.Watch',
index=2,
containing_service=None,
input_type=_HEALTHCHECKREQUEST,
output_type=_HEALTHCHECKRESPONSE,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
])
_sym_db.RegisterServiceDescriptor(_DLINK)
DESCRIPTOR.services_by_name['Dlink'] = _DLINK
# @@protoc_insertion_point(module_scope)

View File

@ -1,153 +0,0 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import dlink_pb2 as dlink__pb2
class DlinkStub(object):
"""The dlink service definition.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.SayHello = channel.unary_unary(
'/dgiot.Dlink/SayHello',
request_serializer=dlink__pb2.HelloRequest.SerializeToString,
response_deserializer=dlink__pb2.HelloReply.FromString,
)
self.Check = channel.unary_unary(
'/dgiot.Dlink/Check',
request_serializer=dlink__pb2.HealthCheckRequest.SerializeToString,
response_deserializer=dlink__pb2.HealthCheckResponse.FromString,
)
self.Watch = channel.unary_stream(
'/dgiot.Dlink/Watch',
request_serializer=dlink__pb2.HealthCheckRequest.SerializeToString,
response_deserializer=dlink__pb2.HealthCheckResponse.FromString,
)
class DlinkServicer(object):
"""The dlink service definition.
"""
def SayHello(self, request, context):
"""Sends a greeting
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Check(self, request, context):
"""If the requested service is unknown, the call will fail with status
NOT_FOUND.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Watch(self, request, context):
"""Performs a watch for the serving status of the requested service.
The server will immediately send back a message indicating the current
serving status. It will then subsequently send a new message whenever
the service's serving status changes.
If the requested service is unknown when the call is received, the
server will send a message setting the serving status to
SERVICE_UNKNOWN but will *not* terminate the call. If at some
future point, the serving status of the service becomes known, the
server will send a new message with the service's serving status.
If the call terminates with status UNIMPLEMENTED, then clients
should assume this method is not supported and should not retry the
call. If the call terminates with any other status (including OK),
clients should retry the call with appropriate exponential backoff.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_DlinkServicer_to_server(servicer, server):
rpc_method_handlers = {
'SayHello': grpc.unary_unary_rpc_method_handler(
servicer.SayHello,
request_deserializer=dlink__pb2.HelloRequest.FromString,
response_serializer=dlink__pb2.HelloReply.SerializeToString,
),
'Check': grpc.unary_unary_rpc_method_handler(
servicer.Check,
request_deserializer=dlink__pb2.HealthCheckRequest.FromString,
response_serializer=dlink__pb2.HealthCheckResponse.SerializeToString,
),
'Watch': grpc.unary_stream_rpc_method_handler(
servicer.Watch,
request_deserializer=dlink__pb2.HealthCheckRequest.FromString,
response_serializer=dlink__pb2.HealthCheckResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'dgiot.Dlink', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class Dlink(object):
"""The dlink service definition.
"""
@staticmethod
def SayHello(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/dgiot.Dlink/SayHello',
dlink__pb2.HelloRequest.SerializeToString,
dlink__pb2.HelloReply.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Check(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/dgiot.Dlink/Check',
dlink__pb2.HealthCheckRequest.SerializeToString,
dlink__pb2.HealthCheckResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Watch(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/dgiot.Dlink/Watch',
dlink__pb2.HealthCheckRequest.SerializeToString,
dlink__pb2.HealthCheckResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

View File

@ -1,47 +0,0 @@
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter server."""
import json
from concurrent import futures
import logging
import grpc
import dlink_pb2
import dlink_pb2_grpc
import base64
import datetime
class Dlink(dlink_pb2_grpc.DlinkServicer):
def SayHello(self, request, context):
print(datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
print( request.name)
print( context)
json_request = json.loads(base64.b64decode(request.name).decode("utf-8"))
print(json_request)
return dlink_pb2.HelloReply(message="parameter received")
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
dlink_pb2_grpc.add_DlinkServicer_to_server(Dlink(), server)
server.add_insecure_port('[::]:30051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()

View File

@ -1,25 +0,0 @@
// copy from: https://grpc.io/docs/what-is-grpc/introduction/
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.dlink";
option java_outer_classname = "DlinkProto";
option objc_class_prefix = "dlink";
package dgiot;
service {{Productid}} {
rpc {{Api}} ({{Request}}) returns ({{Response}}) {}
}
// The request message containing the user's name.
message {{Request}} {
{{DataType}} {{Key}} = {{Value}};
}
// The response message containing the greetings
message {{Response}} {
{{DataType}} {{Key}} = {{Value}};
}