Initial commit for Ads Service. (#21)

* Initial commit for Ads Service.

* update comments for AdsService and AdsServiceClient

* Refactor Ads to Ad
Move building AdService to Docker
Use default setting for Stackdriver Exporter.
Add license text.

* Revert the projectId

- also remove commented code from frontend/rpc.go

* Add adservie to skaffold.yaml

* Remove skaffold-adservice.yaml

* Replace personal projectId with demo projectId.

* Fix the crash in adservice when ran in locally.

* Ignore .skaffold*yaml file and .kubernetes-manifests-*/ dir for easy ProjectID switch.

* Fixed review comments.
1. Changed Ad redirect urls to products.
2. Removed leftovers from Dockerfile/kub*manifests*yaml
3. Added retry for StackDriver.
4. Added log for Ad request.
5. Added comment for gradle caching.
6. Added README.md to src/adservice.

* Added GRPC Health service to Ad Service
Also added
1. timeout to getAd RPC call in frontend.
2. Async thread for stackdriver init.
This commit is contained in:
rghetia 2018-08-22 20:02:46 -04:00 committed by Ahmet Alp Balkan
parent 1d266bfdcf
commit f35fdbcac3
19 changed files with 1455 additions and 270 deletions

3
.gitignore vendored
View file

@ -7,3 +7,6 @@ pkg/
.vscode/
.vs/slnx.sqlite
.vs/microservices-demo/v15/.suo
.idea
.skaffold-*.yaml
.kubernetes-manifests-*/

View file

@ -0,0 +1,63 @@
# Copyright 2018 Google LLC
#
# 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.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: adservice
spec:
template:
metadata:
labels:
app: adservice
spec:
terminationGracePeriodSeconds: 5
containers:
- name: server
image: gcr.io/microservices-demo-app/adservice
ports:
- containerPort: 9555
env:
- name: PORT
value: "9555"
resources:
requests:
cpu: 200m
memory: 64Mi
limits:
cpu: 300m
memory: 128Mi
readinessProbe:
tcpSocket:
port: 9555
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 9555
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: adservice
spec:
type: ClusterIP
selector:
app: adservice
ports:
- name: grpc
port: 9555
targetPort: 9555

View file

@ -218,18 +218,18 @@ message PlaceOrderResponse {
OrderResult order = 1;
}
// ------------Ads service------------------
// ------------Ad service------------------
service AdsService {
rpc GetAds(AdsRequest) returns (AdsResponse) {}
service AdService {
rpc GetAds(AdRequest) returns (AdResponse) {}
}
message AdsRequest {
message AdRequest {
// List of important key words from the current page describing the context.
repeated string context_keys = 1;
}
message AdsResponse {
message AdResponse {
repeated Ad ads = 1;
}

View file

@ -38,6 +38,8 @@ build:
workspace: src/frontend
- imageName: gcr.io/microservices-demo-app/loadgenerator
workspace: src/loadgenerator
- imageName: gcr.io/microservices-demo-app/adservice
workspace: src/adservice
deploy:
kubectl:
manifests:

8
src/adservice/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
*.iml
*.ipr
*.iws
.gradle/**
.idea/**
build/**

15
src/adservice/Dockerfile Normal file
View file

@ -0,0 +1,15 @@
# adsservice
FROM openjdk:8
RUN apt-get update && apt-get install net-tools telnet
WORKDIR /app
# Next three steps are for caching dependency downloads
# to improve subsequent docker build.
COPY ["build.gradle", "gradlew", "./"]
COPY gradle gradle
RUN ./gradlew downloadRepos
COPY . .
RUN ./gradlew installDist
EXPOSE 9555
ENTRYPOINT ["/app/build/install/hipstershop/bin/AdService"]

26
src/adservice/README.md Normal file
View file

@ -0,0 +1,26 @@
# Ad Service
The Ad service provides advertisement based on context keys. If no context keys are provided then it returns random ads.
## Local Build
The Ad service uses gradlew to compile/install/distribute. Gradle wrapper is already part of the source code. To build Ad Service, run
```
cd src/adservice; ./gradlew installDist
```
It will create executable script src/adservice/build/install/hipstershop/bin/AdService
### Upgrade gradle version
If you need to upgrade the version of gradle then run
```
cd src/adservice ; ./gradlew wrapper --gradle-version <new-version>
```
## Docker Build
From repository root, run:
```
docker build --file src/adservice/Dockerfile .
```

122
src/adservice/build.gradle Normal file
View file

@ -0,0 +1,122 @@
description = 'Ad Service'
buildscript {
repositories {
mavenCentral()
mavenLocal()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.3'
}
}
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
repositories {
mavenCentral()
mavenLocal()
}
group = "adservice"
version = "0.1.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION
def opencensusVersion = "0.15.0" // LATEST_OPENCENSUS_RELEASE_VERSION
def grpcVersion = "1.10.1" // CURRENT_GRPC_VERSION
def prometheusVersion = "0.3.0"
tasks.withType(JavaCompile) {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
ext {
speed = project.hasProperty('speed') ? project.getProperty('speed') : false
offlineCompile = new File("$buildDir/output/lib")
}
dependencies {
if (speed) {
compile fileTree(dir: offlineCompile, include: '*.jar')
} else {
compile "com.google.api.grpc:proto-google-common-protos:1.11.0",
"io.opencensus:opencensus-exporter-stats-prometheus:${opencensusVersion}",
"io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}",
"io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}",
"io.opencensus:opencensus-exporter-trace-logging:${opencensusVersion}",
"io.grpc:grpc-protobuf:${grpcVersion}",
"io.grpc:grpc-stub:${grpcVersion}",
"io.grpc:grpc-netty:${grpcVersion}",
"io.grpc:grpc-services:${grpcVersion}",
"io.prometheus:simpleclient_httpserver:${prometheusVersion}"
runtime "io.opencensus:opencensus-impl:${opencensusVersion}",
"io.netty:netty-tcnative-boringssl-static:2.0.8.Final"
}
}
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1-1'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
ofSourceSet('main')
}
}
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
sourceSets {
main {
java {
srcDirs 'hipstershop'
srcDirs 'build/generated/source/proto/main/java/hipstershop'
srcDirs 'build/generated/source/proto/main/grpc/hipstershop'
}
}
}
// Provide convenience executables for trying out the examples.
apply plugin: 'application'
startScripts.enabled = false
// This to cache dependencies during Docker image building. First build will take time.
// Subsequent build will be incremental.
task downloadRepos(type: Copy) {
from configurations.compile
into offlineCompile
from configurations.runtime
into offlineCompile
}
task adService(type: CreateStartScripts) {
mainClassName = 'hipstershop.AdService'
applicationName = 'AdService'
outputDir = new File(project.buildDir, 'tmp')
classpath = jar.outputs.files + project.configurations.runtime
}
task adServiceClient(type: CreateStartScripts) {
mainClassName = 'hipstershop.AdServiceClient'
applicationName = 'AdServiceClient'
outputDir = new File(project.buildDir, 'tmp')
classpath = jar.outputs.files + project.configurations.runtime
}
applicationDistribution.into('bin') {
from(adService)
from(adServiceClient)
fileMode = 0755
}

22
src/adservice/genproto.sh Executable file
View file

@ -0,0 +1,22 @@
#!/bin/bash -eu
#
# Copyright 2018 Google LLC
#
# 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.
#!/bin/bash -e
# protos are needed in adservice folder for compiling during Docker build.
mkdir -p proto && \
cp ../../pb/demo.proto src/main/proto

Binary file not shown.

View file

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

172
src/adservice/gradlew vendored Executable file
View file

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$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=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# 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
;;
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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
src/adservice/gradlew.bat vendored Normal file
View file

@ -0,0 +1,84 @@
@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 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=
@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 init
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 init
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
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
: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 %CMD_LINE_ARGS%
: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

@ -0,0 +1 @@
rootProject.name = 'hipstershop'

View file

@ -0,0 +1,242 @@
/*
* Copyright 2018, Google LLC.
*
* 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 hipstershop;
import com.google.common.collect.ImmutableMap;
import hipstershop.Demo.Ad;
import hipstershop.Demo.AdRequest;
import hipstershop.Demo.AdResponse;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.health.v1.HealthCheckResponse.ServingStatus;
import io.grpc.stub.StreamObserver;
import io.grpc.services.*;
import io.opencensus.common.Duration;
import io.opencensus.common.Scope;
import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.stats.prometheus.PrometheusStatsCollector;
import io.opencensus.exporter.trace.logging.LoggingTraceExporter;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.AttributeValue;
import io.opencensus.trace.Span;
import io.opencensus.trace.SpanBuilder;
import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.samplers.Samplers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AdService {
private static final Logger logger = Logger.getLogger(AdService.class.getName());
private static final Tracer tracer = Tracing.getTracer();
private int MAX_ADS_TO_SERVE = 2;
private Server server;
private HealthStatusManager healthMgr;
static final AdService service = new AdService();
private void start() throws IOException {
int port = Integer.parseInt(System.getenv("PORT"));
healthMgr = new HealthStatusManager();
server = ServerBuilder.forPort(port).addService(new AdServiceImpl())
.addService(healthMgr.getHealthService()).build().start();
logger.info("Ad Service 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 ads server since JVM is shutting down");
AdService.this.stop();
System.err.println("*** server shut down");
}
});
healthMgr.setStatus("", ServingStatus.SERVING);
}
private void stop() {
if (server != null) {
healthMgr.clearStatus("");
server.shutdown();
}
}
static class AdServiceImpl extends hipstershop.AdServiceGrpc.AdServiceImplBase {
/**
* Retrieves ads based on context provided in the request {@code AdRequest}.
*
* @param req the request containing context.
* @param responseObserver the stream observer which gets notified with the value of
* {@code AdResponse}
*/
@Override
public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
AdService service = AdService.getInstance();
Span parentSpan = tracer.getCurrentSpan();
SpanBuilder spanBuilder =
tracer
.spanBuilderWithExplicitParent("Retrieve Ads", parentSpan)
.setRecordEvents(true)
.setSampler(Samplers.alwaysSample());
try (Scope scope = spanBuilder.startScopedSpan()) {
Span span = tracer.getCurrentSpan();
span.putAttribute("method", AttributeValue.stringAttributeValue("getAds"));
List<Ad> ads = new ArrayList<>();
logger.info("received ad request (context_words=" + req.getContextKeysCount() + ")");
if (req.getContextKeysCount() > 0) {
span.addAnnotation(
"Constructing Ads using context",
ImmutableMap.of(
"Context Keys",
AttributeValue.stringAttributeValue(req.getContextKeysList().toString()),
"Context Keys length",
AttributeValue.longAttributeValue(req.getContextKeysCount())));
for (int i = 0; i < req.getContextKeysCount(); i++) {
Ad ad = service.getAdsByKey(req.getContextKeys(i));
if (ad != null) {
ads.add(ad);
}
}
} else {
span.addAnnotation("No Context provided. Constructing random Ads.");
ads = service.getDefaultAds();
}
if (ads.isEmpty()) {
// Serve default ads.
span.addAnnotation("No Ads found based on context. Constructing random Ads.");
ads = service.getDefaultAds();
}
AdResponse reply = AdResponse.newBuilder().addAllAds(ads).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "GetAds Failed", e.getStatus());
return;
}
}
}
static final HashMap<String, Ad> cacheMap = new HashMap<String, Ad>();
Ad getAdsByKey(String key) {
return cacheMap.get(key);
}
public List<Ad> getDefaultAds() {
List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
Object[] keys = cacheMap.keySet().toArray();
for (int i=0; i<MAX_ADS_TO_SERVE; i++) {
ads.add(cacheMap.get(keys[new Random().nextInt(keys.length)]));
}
return ads;
}
public static AdService getInstance() {
return service;
}
/** Await termination on the main thread since the grpc library uses daemon threads. */
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
static void initializeAds() {
cacheMap.put("camera", Ad.newBuilder().setRedirectUrl( "/product/2ZYFJ3GM2N")
.setText("Film camera for sale. 50% off.").build());
cacheMap.put("bike", Ad.newBuilder().setRedirectUrl("/product/9SIQT8TOJO")
.setText("City Bike for sale. 10% off.").build());
cacheMap.put("kitchen", Ad.newBuilder().setRedirectUrl("/product/1YMWWN1N4O")
.setText("Home Barista kitchen kit for sale. Buy one, get second kit for free").build());
logger.info("Default Ads initialized");
}
public static void initStackdriver() {
logger.info("Initialize StackDriver");
// Registers all RPC views.
RpcViews.registerAllViews();
// Registers logging trace exporter.
LoggingTraceExporter.register();
long sleepTime = 10; /* seconds */
int maxAttempts = 3;
for (int i=0; i<maxAttempts; i++) {
try {
StackdriverTraceExporter.createAndRegister(
StackdriverTraceConfiguration.builder().build());
StackdriverStatsExporter.createAndRegister(
StackdriverStatsConfiguration.builder()
.setExportInterval(Duration.create(15, 0))
.build());
} catch (Exception e) {
if (i==(maxAttempts-1)) {
logger.log(Level.WARNING, "Failed to register Stackdriver Exporter." +
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
.toString());
} else {
logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds ");
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
} catch (Exception se) {
logger.log(Level.WARNING, "Exception while sleeping" + se.toString());
}
}
}
}
logger.info("StackDriver initialization complete.");
}
/** Main launches the server from the command line. */
public static void main(String[] args) throws IOException, InterruptedException {
// Add final keyword to pass checkStyle.
initializeAds();
new Thread( new Runnable() {
public void run(){
initStackdriver();
}
}).start();
// Register Prometheus exporters and export metrics to a Prometheus HTTPServer.
PrometheusStatsCollector.createAndRegister();
// Start the RPC server. You shouldn't see any output from gRPC before this.
logger.info("AdService starting.");
final AdService service = AdService.getInstance();
service.start();
service.blockUntilShutdown();
}
}

View file

@ -0,0 +1,186 @@
/*
* Copyright 2018, Google LLC.
*
* 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 hipstershop;
import hipstershop.Demo.Ad;
import hipstershop.Demo.AdRequest;
import hipstershop.Demo.AdResponse;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
import io.opencensus.common.Duration;
import io.opencensus.common.Scope;
import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.trace.logging.LoggingTraceExporter;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.SpanBuilder;
import io.opencensus.trace.Status.CanonicalCode;
import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.samplers.Samplers;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/** A simple client that requests ads from the Ads Service. */
public class AdServiceClient {
private static final Logger logger = Logger.getLogger(AdServiceClient.class.getName());
private static final Tracer tracer = Tracing.getTracer();
private final ManagedChannel channel;
private final hipstershop.AdServiceGrpc.AdServiceBlockingStub blockingStub;
/** Construct client connecting to Ad Service at {@code host:port}. */
public AdServiceClient(String host, int port) {
this(
ManagedChannelBuilder.forAddress(host, port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
.usePlaintext(true)
.build());
}
/** Construct client for accessing RouteGuide server using the existing channel. */
AdServiceClient(ManagedChannel channel) {
this.channel = channel;
blockingStub = hipstershop.AdServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
/** Get Ads from Server. */
public void getAds(String contextKey) {
logger.info("Get Ads with context " + contextKey + " ...");
AdRequest request = AdRequest.newBuilder().addContextKeys(contextKey).build();
AdResponse response;
SpanBuilder spanBuilder =
tracer.spanBuilder("AdsClient").setRecordEvents(true).setSampler(Samplers.alwaysSample());
try (Scope scope = spanBuilder.startScopedSpan()) {
tracer.getCurrentSpan().addAnnotation("Getting Ads");
response = blockingStub.getAds(request);
tracer.getCurrentSpan().addAnnotation("Received response from Ads Service.");
} catch (StatusRuntimeException e) {
tracer
.getCurrentSpan()
.setStatus(
CanonicalCode.valueOf(e.getStatus().getCode().name())
.toStatus()
.withDescription(e.getMessage()));
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
for(Ad ads: response.getAdsList()) {
logger.info("Ads: " + ads.getText());
}
}
static int getPortOrDefaultFromArgs(String[] args, int index, int defaultPort) {
int portNumber = defaultPort;
if (index < args.length) {
try {
portNumber = Integer.parseInt(args[index]);
} catch (NumberFormatException e) {
logger.warning(
String.format("Port %s is invalid, use default port %d.", args[index], defaultPort));
}
}
return portNumber;
}
static String getStringOrDefaultFromArgs(
String[] args, int index, @Nullable String defaultString) {
String s = defaultString;
if (index < args.length) {
s = args[index];
}
return s;
}
/**
* Ads Service Client main. If provided, the first element of {@code args} is the context key to
* get the ads from the Ads Service
*/
public static void main(String[] args) throws IOException, InterruptedException {
// Add final keyword to pass checkStyle.
final String contextKeys = getStringOrDefaultFromArgs(args, 0, "camera");
final String host = getStringOrDefaultFromArgs(args, 1, "localhost");
final int serverPort = getPortOrDefaultFromArgs(args, 2, 9555);
final String cloudProjectId = getStringOrDefaultFromArgs(args, 3, null);
//final int zPagePort = getPortOrDefaultFromArgs(args, 4, 3001);
// Registers all RPC views.
RpcViews.registerAllViews();
// Registers logging trace exporter.
LoggingTraceExporter.register();
// Registers Stackdriver exporters.
if (cloudProjectId != null) {
long sleepTime = 10; /* seconds */
int maxAttempts = 3;
for (int i=0; i<maxAttempts; i++) {
try {
StackdriverTraceExporter.createAndRegister(
StackdriverTraceConfiguration.builder().setProjectId(cloudProjectId).build());
StackdriverStatsExporter.createAndRegister(
StackdriverStatsConfiguration.builder()
.setProjectId(cloudProjectId)
.setExportInterval(Duration.create(15, 0))
.build());
} catch (Exception e) {
if (i==(maxAttempts-1)) {
logger.log(Level.WARNING, "Failed to register Stackdriver Exporter." +
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
.toString());
} else {
logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds");
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
} catch (Exception se) {
logger.log(Level.WARNING, "Exception while sleeping" + e.toString());
}
}
}
}
}
// Register Prometheus exporters and export metrics to a Prometheus HTTPServer.
//PrometheusStatsCollector.createAndRegister();
AdServiceClient client = new AdServiceClient(host, serverPort);
try {
client.getAds(contextKeys);
} finally {
client.shutdown();
}
logger.info("Exiting AdServiceClient...");
}
}

View file

@ -0,0 +1,242 @@
syntax = "proto3";
package hipstershop;
// -----------------Cart service-----------------
service CartService {
rpc AddItem(AddItemRequest) returns (Empty) {}
rpc GetCart(GetCartRequest) returns (Cart) {}
rpc EmptyCart(EmptyCartRequest) returns (Empty) {}
}
message CartItem {
string product_id = 1;
int32 quantity = 2;
}
message AddItemRequest {
string user_id = 1;
CartItem item = 2;
}
message EmptyCartRequest {
string user_id = 1;
}
message GetCartRequest {
string user_id = 1;
}
message Cart {
string user_id = 1;
repeated CartItem items = 2;
}
message Empty {}
// ---------------Recommendation service----------
service RecommendationService {
rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){}
}
message ListRecommendationsRequest {
string user_id = 1;
repeated string product_ids = 2;
}
message ListRecommendationsResponse {
repeated string product_ids = 1;
}
// ---------------Product Catalog----------------
service ProductCatalogService {
rpc ListProducts(Empty) returns (ListProductsResponse) {}
rpc GetProduct(GetProductRequest) returns (Product) {}
rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {}
}
message Product {
string id = 1;
string name = 2;
string description = 3;
string picture = 4;
Money price_usd = 5;
}
message ListProductsResponse {
repeated Product products = 1;
}
message GetProductRequest {
string id = 1;
}
message SearchProductsRequest {
string query = 1;
}
message SearchProductsResponse {
repeated Product results = 1;
}
// ---------------Shipping Service----------
service ShippingService {
rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {}
rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {}
}
message GetQuoteRequest {
Address address = 1;
repeated CartItem items = 2;
}
message GetQuoteResponse {
Money cost_usd = 1;
}
message ShipOrderRequest {
Address address = 1;
repeated CartItem items = 2;
}
message ShipOrderResponse {
string tracking_id = 1;
}
message Address {
string street_address = 1;
string city = 2;
string state = 3;
string country = 4;
int32 zip_code = 5;
}
// -----------------Currency service-----------------
service CurrencyService {
rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {}
rpc Convert(CurrencyConversionRequest) returns (Money) {}
}
// Represents an amount of money with its currency type.
message Money {
// The 3-letter currency code defined in ISO 4217.
string currency_code = 1;
// The whole units of the amount.
// For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
int64 units = 2;
// Number of nano (10^-9) units of the amount.
// The value must be between -999,999,999 and +999,999,999 inclusive.
// If `units` is positive, `nanos` must be positive or zero.
// If `units` is zero, `nanos` can be positive, zero, or negative.
// If `units` is negative, `nanos` must be negative or zero.
// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
int32 nanos = 3;
}
message GetSupportedCurrenciesResponse {
// The 3-letter currency code defined in ISO 4217.
repeated string currency_codes = 1;
}
message CurrencyConversionRequest {
Money from = 1;
// The 3-letter currency code defined in ISO 4217.
string to_code = 2;
}
// -------------Payment service-----------------
service PaymentService {
rpc Charge(ChargeRequest) returns (ChargeResponse) {}
}
message CreditCardInfo {
string credit_card_number = 1;
int32 credit_card_cvv = 2;
int32 credit_card_expiration_year = 3;
int32 credit_card_expiration_month = 4;
}
message ChargeRequest {
Money amount = 1;
CreditCardInfo credit_card = 2;
}
message ChargeResponse {
string transaction_id = 1;
}
// -------------Email service-----------------
service EmailService {
rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {}
}
message OrderItem {
CartItem item = 1;
Money cost = 2;
}
message OrderResult {
string order_id = 1;
string shipping_tracking_id = 2;
Money shipping_cost = 3;
Address shipping_address = 4;
repeated OrderItem items = 5;
}
message SendOrderConfirmationRequest {
string email = 1;
OrderResult order = 2;
}
// -------------Checkout service-----------------
service CheckoutService {
rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {}
}
message PlaceOrderRequest {
string user_id = 1;
string user_currency = 2;
Address address = 3;
string email = 5;
CreditCardInfo credit_card = 6;
}
message PlaceOrderResponse {
OrderResult order = 1;
}
// ------------Ad service------------------
service AdService {
rpc GetAds(AdRequest) returns (AdResponse) {}
}
message AdRequest {
// List of important key words from the current page describing the context.
repeated string context_keys = 1;
}
message AdResponse {
repeated Ad ads = 1;
}
message Ad {
// url to redirect to when an ad is clicked.
string redirect_url = 1;
// short advertisement text to display.
string text = 2;
}

View file

@ -24,8 +24,8 @@ var _ = math.Inf
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type CartItem struct {
ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId" json:"product_id,omitempty"`
Quantity int32 `protobuf:"varint,2,opt,name=quantity" json:"quantity,omitempty"`
ProductId string `protobuf:"bytes,1,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"`
Quantity int32 `protobuf:"varint,2,opt,name=quantity,proto3" json:"quantity,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -35,7 +35,7 @@ func (m *CartItem) Reset() { *m = CartItem{} }
func (m *CartItem) String() string { return proto.CompactTextString(m) }
func (*CartItem) ProtoMessage() {}
func (*CartItem) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{0}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{0}
}
func (m *CartItem) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CartItem.Unmarshal(m, b)
@ -70,8 +70,8 @@ func (m *CartItem) GetQuantity() int32 {
}
type AddItemRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
Item *CartItem `protobuf:"bytes,2,opt,name=item" json:"item,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
Item *CartItem `protobuf:"bytes,2,opt,name=item,proto3" json:"item,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -81,7 +81,7 @@ func (m *AddItemRequest) Reset() { *m = AddItemRequest{} }
func (m *AddItemRequest) String() string { return proto.CompactTextString(m) }
func (*AddItemRequest) ProtoMessage() {}
func (*AddItemRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{1}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{1}
}
func (m *AddItemRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddItemRequest.Unmarshal(m, b)
@ -116,7 +116,7 @@ func (m *AddItemRequest) GetItem() *CartItem {
}
type EmptyCartRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -126,7 +126,7 @@ func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} }
func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }
func (*EmptyCartRequest) ProtoMessage() {}
func (*EmptyCartRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{2}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{2}
}
func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)
@ -154,7 +154,7 @@ func (m *EmptyCartRequest) GetUserId() string {
}
type GetCartRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -164,7 +164,7 @@ func (m *GetCartRequest) Reset() { *m = GetCartRequest{} }
func (m *GetCartRequest) String() string { return proto.CompactTextString(m) }
func (*GetCartRequest) ProtoMessage() {}
func (*GetCartRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{3}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{3}
}
func (m *GetCartRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetCartRequest.Unmarshal(m, b)
@ -192,8 +192,8 @@ func (m *GetCartRequest) GetUserId() string {
}
type Cart struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items" json:"items,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -203,7 +203,7 @@ func (m *Cart) Reset() { *m = Cart{} }
func (m *Cart) String() string { return proto.CompactTextString(m) }
func (*Cart) ProtoMessage() {}
func (*Cart) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{4}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{4}
}
func (m *Cart) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Cart.Unmarshal(m, b)
@ -247,7 +247,7 @@ func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{5}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{5}
}
func (m *Empty) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Empty.Unmarshal(m, b)
@ -268,8 +268,8 @@ func (m *Empty) XXX_DiscardUnknown() {
var xxx_messageInfo_Empty proto.InternalMessageInfo
type ListRecommendationsRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds" json:"product_ids,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
ProductIds []string `protobuf:"bytes,2,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -279,7 +279,7 @@ func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsR
func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }
func (*ListRecommendationsRequest) ProtoMessage() {}
func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{6}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{6}
}
func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)
@ -314,7 +314,7 @@ func (m *ListRecommendationsRequest) GetProductIds() []string {
}
type ListRecommendationsResponse struct {
ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds" json:"product_ids,omitempty"`
ProductIds []string `protobuf:"bytes,1,rep,name=product_ids,json=productIds,proto3" json:"product_ids,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -324,7 +324,7 @@ func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendations
func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }
func (*ListRecommendationsResponse) ProtoMessage() {}
func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{7}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{7}
}
func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)
@ -352,11 +352,11 @@ func (m *ListRecommendationsResponse) GetProductIds() []string {
}
type Product struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
Picture string `protobuf:"bytes,4,opt,name=picture" json:"picture,omitempty"`
PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd" json:"price_usd,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
Picture string `protobuf:"bytes,4,opt,name=picture,proto3" json:"picture,omitempty"`
PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -366,7 +366,7 @@ func (m *Product) Reset() { *m = Product{} }
func (m *Product) String() string { return proto.CompactTextString(m) }
func (*Product) ProtoMessage() {}
func (*Product) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{8}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{8}
}
func (m *Product) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Product.Unmarshal(m, b)
@ -422,7 +422,7 @@ func (m *Product) GetPriceUsd() *Money {
}
type ListProductsResponse struct {
Products []*Product `protobuf:"bytes,1,rep,name=products" json:"products,omitempty"`
Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -432,7 +432,7 @@ func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} }
func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }
func (*ListProductsResponse) ProtoMessage() {}
func (*ListProductsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{9}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{9}
}
func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)
@ -460,7 +460,7 @@ func (m *ListProductsResponse) GetProducts() []*Product {
}
type GetProductRequest struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -470,7 +470,7 @@ func (m *GetProductRequest) Reset() { *m = GetProductRequest{} }
func (m *GetProductRequest) String() string { return proto.CompactTextString(m) }
func (*GetProductRequest) ProtoMessage() {}
func (*GetProductRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{10}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{10}
}
func (m *GetProductRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetProductRequest.Unmarshal(m, b)
@ -498,7 +498,7 @@ func (m *GetProductRequest) GetId() string {
}
type SearchProductsRequest struct {
Query string `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"`
Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -508,7 +508,7 @@ func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} }
func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }
func (*SearchProductsRequest) ProtoMessage() {}
func (*SearchProductsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{11}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{11}
}
func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)
@ -536,7 +536,7 @@ func (m *SearchProductsRequest) GetQuery() string {
}
type SearchProductsResponse struct {
Results []*Product `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"`
Results []*Product `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -546,7 +546,7 @@ func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{}
func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }
func (*SearchProductsResponse) ProtoMessage() {}
func (*SearchProductsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{12}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{12}
}
func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)
@ -574,8 +574,8 @@ func (m *SearchProductsResponse) GetResults() []*Product {
}
type GetQuoteRequest struct {
Address *Address `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items" json:"items,omitempty"`
Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -585,7 +585,7 @@ func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} }
func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }
func (*GetQuoteRequest) ProtoMessage() {}
func (*GetQuoteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{13}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{13}
}
func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)
@ -620,7 +620,7 @@ func (m *GetQuoteRequest) GetItems() []*CartItem {
}
type GetQuoteResponse struct {
CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd" json:"cost_usd,omitempty"`
CostUsd *Money `protobuf:"bytes,1,opt,name=cost_usd,json=costUsd,proto3" json:"cost_usd,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -630,7 +630,7 @@ func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} }
func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }
func (*GetQuoteResponse) ProtoMessage() {}
func (*GetQuoteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{14}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{14}
}
func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)
@ -658,8 +658,8 @@ func (m *GetQuoteResponse) GetCostUsd() *Money {
}
type ShipOrderRequest struct {
Address *Address `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items" json:"items,omitempty"`
Address *Address `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Items []*CartItem `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -669,7 +669,7 @@ func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} }
func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }
func (*ShipOrderRequest) ProtoMessage() {}
func (*ShipOrderRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{15}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{15}
}
func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)
@ -704,7 +704,7 @@ func (m *ShipOrderRequest) GetItems() []*CartItem {
}
type ShipOrderResponse struct {
TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId" json:"tracking_id,omitempty"`
TrackingId string `protobuf:"bytes,1,opt,name=tracking_id,json=trackingId,proto3" json:"tracking_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -714,7 +714,7 @@ func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} }
func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }
func (*ShipOrderResponse) ProtoMessage() {}
func (*ShipOrderResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{16}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{16}
}
func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)
@ -742,11 +742,11 @@ func (m *ShipOrderResponse) GetTrackingId() string {
}
type Address struct {
StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress" json:"street_address,omitempty"`
City string `protobuf:"bytes,2,opt,name=city" json:"city,omitempty"`
State string `protobuf:"bytes,3,opt,name=state" json:"state,omitempty"`
Country string `protobuf:"bytes,4,opt,name=country" json:"country,omitempty"`
ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode" json:"zip_code,omitempty"`
StreetAddress string `protobuf:"bytes,1,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"`
City string `protobuf:"bytes,2,opt,name=city,proto3" json:"city,omitempty"`
State string `protobuf:"bytes,3,opt,name=state,proto3" json:"state,omitempty"`
Country string `protobuf:"bytes,4,opt,name=country,proto3" json:"country,omitempty"`
ZipCode int32 `protobuf:"varint,5,opt,name=zip_code,json=zipCode,proto3" json:"zip_code,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -756,7 +756,7 @@ func (m *Address) Reset() { *m = Address{} }
func (m *Address) String() string { return proto.CompactTextString(m) }
func (*Address) ProtoMessage() {}
func (*Address) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{17}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{17}
}
func (m *Address) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Address.Unmarshal(m, b)
@ -814,17 +814,17 @@ func (m *Address) GetZipCode() int32 {
// Represents an amount of money with its currency type.
type Money struct {
// The 3-letter currency code defined in ISO 4217.
CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode" json:"currency_code,omitempty"`
CurrencyCode string `protobuf:"bytes,1,opt,name=currency_code,json=currencyCode,proto3" json:"currency_code,omitempty"`
// The whole units of the amount.
// For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
Units int64 `protobuf:"varint,2,opt,name=units" json:"units,omitempty"`
Units int64 `protobuf:"varint,2,opt,name=units,proto3" json:"units,omitempty"`
// Number of nano (10^-9) units of the amount.
// The value must be between -999,999,999 and +999,999,999 inclusive.
// If `units` is positive, `nanos` must be positive or zero.
// If `units` is zero, `nanos` can be positive, zero, or negative.
// If `units` is negative, `nanos` must be negative or zero.
// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
Nanos int32 `protobuf:"varint,3,opt,name=nanos" json:"nanos,omitempty"`
Nanos int32 `protobuf:"varint,3,opt,name=nanos,proto3" json:"nanos,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -834,7 +834,7 @@ func (m *Money) Reset() { *m = Money{} }
func (m *Money) String() string { return proto.CompactTextString(m) }
func (*Money) ProtoMessage() {}
func (*Money) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{18}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{18}
}
func (m *Money) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Money.Unmarshal(m, b)
@ -877,7 +877,7 @@ func (m *Money) GetNanos() int32 {
type GetSupportedCurrenciesResponse struct {
// The 3-letter currency code defined in ISO 4217.
CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes" json:"currency_codes,omitempty"`
CurrencyCodes []string `protobuf:"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3" json:"currency_codes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -887,7 +887,7 @@ func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurr
func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }
func (*GetSupportedCurrenciesResponse) ProtoMessage() {}
func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{19}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{19}
}
func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)
@ -915,9 +915,9 @@ func (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string {
}
type CurrencyConversionRequest struct {
From *Money `protobuf:"bytes,1,opt,name=from" json:"from,omitempty"`
From *Money `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
// The 3-letter currency code defined in ISO 4217.
ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode" json:"to_code,omitempty"`
ToCode string `protobuf:"bytes,2,opt,name=to_code,json=toCode,proto3" json:"to_code,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -927,7 +927,7 @@ func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionReq
func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }
func (*CurrencyConversionRequest) ProtoMessage() {}
func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{20}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{20}
}
func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)
@ -962,10 +962,10 @@ func (m *CurrencyConversionRequest) GetToCode() string {
}
type CreditCardInfo struct {
CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber" json:"credit_card_number,omitempty"`
CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv" json:"credit_card_cvv,omitempty"`
CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear" json:"credit_card_expiration_year,omitempty"`
CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth" json:"credit_card_expiration_month,omitempty"`
CreditCardNumber string `protobuf:"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3" json:"credit_card_number,omitempty"`
CreditCardCvv int32 `protobuf:"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3" json:"credit_card_cvv,omitempty"`
CreditCardExpirationYear int32 `protobuf:"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3" json:"credit_card_expiration_year,omitempty"`
CreditCardExpirationMonth int32 `protobuf:"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3" json:"credit_card_expiration_month,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -975,7 +975,7 @@ func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} }
func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }
func (*CreditCardInfo) ProtoMessage() {}
func (*CreditCardInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{21}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{21}
}
func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)
@ -1024,8 +1024,8 @@ func (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 {
}
type ChargeRequest struct {
Amount *Money `protobuf:"bytes,1,opt,name=amount" json:"amount,omitempty"`
CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard" json:"credit_card,omitempty"`
Amount *Money `protobuf:"bytes,1,opt,name=amount,proto3" json:"amount,omitempty"`
CreditCard *CreditCardInfo `protobuf:"bytes,2,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1035,7 +1035,7 @@ func (m *ChargeRequest) Reset() { *m = ChargeRequest{} }
func (m *ChargeRequest) String() string { return proto.CompactTextString(m) }
func (*ChargeRequest) ProtoMessage() {}
func (*ChargeRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{22}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{22}
}
func (m *ChargeRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChargeRequest.Unmarshal(m, b)
@ -1070,7 +1070,7 @@ func (m *ChargeRequest) GetCreditCard() *CreditCardInfo {
}
type ChargeResponse struct {
TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"`
TransactionId string `protobuf:"bytes,1,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1080,7 +1080,7 @@ func (m *ChargeResponse) Reset() { *m = ChargeResponse{} }
func (m *ChargeResponse) String() string { return proto.CompactTextString(m) }
func (*ChargeResponse) ProtoMessage() {}
func (*ChargeResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{23}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{23}
}
func (m *ChargeResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ChargeResponse.Unmarshal(m, b)
@ -1108,8 +1108,8 @@ func (m *ChargeResponse) GetTransactionId() string {
}
type OrderItem struct {
Item *CartItem `protobuf:"bytes,1,opt,name=item" json:"item,omitempty"`
Cost *Money `protobuf:"bytes,2,opt,name=cost" json:"cost,omitempty"`
Item *CartItem `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
Cost *Money `protobuf:"bytes,2,opt,name=cost,proto3" json:"cost,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1119,7 +1119,7 @@ func (m *OrderItem) Reset() { *m = OrderItem{} }
func (m *OrderItem) String() string { return proto.CompactTextString(m) }
func (*OrderItem) ProtoMessage() {}
func (*OrderItem) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{24}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{24}
}
func (m *OrderItem) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OrderItem.Unmarshal(m, b)
@ -1154,11 +1154,11 @@ func (m *OrderItem) GetCost() *Money {
}
type OrderResult struct {
OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId" json:"order_id,omitempty"`
ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId" json:"shipping_tracking_id,omitempty"`
ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost" json:"shipping_cost,omitempty"`
ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress" json:"shipping_address,omitempty"`
Items []*OrderItem `protobuf:"bytes,5,rep,name=items" json:"items,omitempty"`
OrderId string `protobuf:"bytes,1,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"`
ShippingTrackingId string `protobuf:"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3" json:"shipping_tracking_id,omitempty"`
ShippingCost *Money `protobuf:"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3" json:"shipping_cost,omitempty"`
ShippingAddress *Address `protobuf:"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3" json:"shipping_address,omitempty"`
Items []*OrderItem `protobuf:"bytes,5,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1168,7 +1168,7 @@ func (m *OrderResult) Reset() { *m = OrderResult{} }
func (m *OrderResult) String() string { return proto.CompactTextString(m) }
func (*OrderResult) ProtoMessage() {}
func (*OrderResult) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{25}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{25}
}
func (m *OrderResult) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OrderResult.Unmarshal(m, b)
@ -1224,8 +1224,8 @@ func (m *OrderResult) GetItems() []*OrderItem {
}
type SendOrderConfirmationRequest struct {
Email string `protobuf:"bytes,1,opt,name=email" json:"email,omitempty"`
Order *OrderResult `protobuf:"bytes,2,opt,name=order" json:"order,omitempty"`
Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"`
Order *OrderResult `protobuf:"bytes,2,opt,name=order,proto3" json:"order,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1235,7 +1235,7 @@ func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmat
func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }
func (*SendOrderConfirmationRequest) ProtoMessage() {}
func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{26}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{26}
}
func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)
@ -1270,11 +1270,11 @@ func (m *SendOrderConfirmationRequest) GetOrder() *OrderResult {
}
type PlaceOrderRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency" json:"user_currency,omitempty"`
Address *Address `protobuf:"bytes,3,opt,name=address" json:"address,omitempty"`
Email string `protobuf:"bytes,5,opt,name=email" json:"email,omitempty"`
CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard" json:"credit_card,omitempty"`
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
UserCurrency string `protobuf:"bytes,2,opt,name=user_currency,json=userCurrency,proto3" json:"user_currency,omitempty"`
Address *Address `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"`
CreditCard *CreditCardInfo `protobuf:"bytes,6,opt,name=credit_card,json=creditCard,proto3" json:"credit_card,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1284,7 +1284,7 @@ func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} }
func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }
func (*PlaceOrderRequest) ProtoMessage() {}
func (*PlaceOrderRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{27}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{27}
}
func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)
@ -1340,7 +1340,7 @@ func (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo {
}
type PlaceOrderResponse struct {
Order *OrderResult `protobuf:"bytes,1,opt,name=order" json:"order,omitempty"`
Order *OrderResult `protobuf:"bytes,1,opt,name=order,proto3" json:"order,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1350,7 +1350,7 @@ func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} }
func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }
func (*PlaceOrderResponse) ProtoMessage() {}
func (*PlaceOrderResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{28}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{28}
}
func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)
@ -1377,77 +1377,77 @@ func (m *PlaceOrderResponse) GetOrder() *OrderResult {
return nil
}
type AdsRequest struct {
type AdRequest struct {
// List of important key words from the current page describing the context.
ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys" json:"context_keys,omitempty"`
ContextKeys []string `protobuf:"bytes,1,rep,name=context_keys,json=contextKeys,proto3" json:"context_keys,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AdsRequest) Reset() { *m = AdsRequest{} }
func (m *AdsRequest) String() string { return proto.CompactTextString(m) }
func (*AdsRequest) ProtoMessage() {}
func (*AdsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{29}
func (m *AdRequest) Reset() { *m = AdRequest{} }
func (m *AdRequest) String() string { return proto.CompactTextString(m) }
func (*AdRequest) ProtoMessage() {}
func (*AdRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{29}
}
func (m *AdsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AdsRequest.Unmarshal(m, b)
func (m *AdRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AdRequest.Unmarshal(m, b)
}
func (m *AdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AdsRequest.Marshal(b, m, deterministic)
func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)
}
func (dst *AdsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_AdsRequest.Merge(dst, src)
func (dst *AdRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_AdRequest.Merge(dst, src)
}
func (m *AdsRequest) XXX_Size() int {
return xxx_messageInfo_AdsRequest.Size(m)
func (m *AdRequest) XXX_Size() int {
return xxx_messageInfo_AdRequest.Size(m)
}
func (m *AdsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_AdsRequest.DiscardUnknown(m)
func (m *AdRequest) XXX_DiscardUnknown() {
xxx_messageInfo_AdRequest.DiscardUnknown(m)
}
var xxx_messageInfo_AdsRequest proto.InternalMessageInfo
var xxx_messageInfo_AdRequest proto.InternalMessageInfo
func (m *AdsRequest) GetContextKeys() []string {
func (m *AdRequest) GetContextKeys() []string {
if m != nil {
return m.ContextKeys
}
return nil
}
type AdsResponse struct {
Ads []*Ad `protobuf:"bytes,1,rep,name=ads" json:"ads,omitempty"`
type AdResponse struct {
Ads []*Ad `protobuf:"bytes,1,rep,name=ads,proto3" json:"ads,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AdsResponse) Reset() { *m = AdsResponse{} }
func (m *AdsResponse) String() string { return proto.CompactTextString(m) }
func (*AdsResponse) ProtoMessage() {}
func (*AdsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{30}
func (m *AdResponse) Reset() { *m = AdResponse{} }
func (m *AdResponse) String() string { return proto.CompactTextString(m) }
func (*AdResponse) ProtoMessage() {}
func (*AdResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{30}
}
func (m *AdsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AdsResponse.Unmarshal(m, b)
func (m *AdResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AdResponse.Unmarshal(m, b)
}
func (m *AdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AdsResponse.Marshal(b, m, deterministic)
func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)
}
func (dst *AdsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_AdsResponse.Merge(dst, src)
func (dst *AdResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_AdResponse.Merge(dst, src)
}
func (m *AdsResponse) XXX_Size() int {
return xxx_messageInfo_AdsResponse.Size(m)
func (m *AdResponse) XXX_Size() int {
return xxx_messageInfo_AdResponse.Size(m)
}
func (m *AdsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_AdsResponse.DiscardUnknown(m)
func (m *AdResponse) XXX_DiscardUnknown() {
xxx_messageInfo_AdResponse.DiscardUnknown(m)
}
var xxx_messageInfo_AdsResponse proto.InternalMessageInfo
var xxx_messageInfo_AdResponse proto.InternalMessageInfo
func (m *AdsResponse) GetAds() []*Ad {
func (m *AdResponse) GetAds() []*Ad {
if m != nil {
return m.Ads
}
@ -1456,9 +1456,9 @@ func (m *AdsResponse) GetAds() []*Ad {
type Ad struct {
// url to redirect to when an ad is clicked.
RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl" json:"redirect_url,omitempty"`
RedirectUrl string `protobuf:"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3" json:"redirect_url,omitempty"`
// short advertisement text to display.
Text string `protobuf:"bytes,2,opt,name=text" json:"text,omitempty"`
Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1468,7 +1468,7 @@ func (m *Ad) Reset() { *m = Ad{} }
func (m *Ad) String() string { return proto.CompactTextString(m) }
func (*Ad) ProtoMessage() {}
func (*Ad) Descriptor() ([]byte, []int) {
return fileDescriptor_demo_c812a73334c7ff0d, []int{31}
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{31}
}
func (m *Ad) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Ad.Unmarshal(m, b)
@ -1532,8 +1532,8 @@ func init() {
proto.RegisterType((*SendOrderConfirmationRequest)(nil), "hipstershop.SendOrderConfirmationRequest")
proto.RegisterType((*PlaceOrderRequest)(nil), "hipstershop.PlaceOrderRequest")
proto.RegisterType((*PlaceOrderResponse)(nil), "hipstershop.PlaceOrderResponse")
proto.RegisterType((*AdsRequest)(nil), "hipstershop.AdsRequest")
proto.RegisterType((*AdsResponse)(nil), "hipstershop.AdsResponse")
proto.RegisterType((*AdRequest)(nil), "hipstershop.AdRequest")
proto.RegisterType((*AdResponse)(nil), "hipstershop.AdResponse")
proto.RegisterType((*Ad)(nil), "hipstershop.Ad")
}
@ -2255,165 +2255,165 @@ var _CheckoutService_serviceDesc = grpc.ServiceDesc{
Metadata: "demo.proto",
}
// AdsServiceClient is the client API for AdsService service.
// AdServiceClient is the client API for AdService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AdsServiceClient interface {
GetAds(ctx context.Context, in *AdsRequest, opts ...grpc.CallOption) (*AdsResponse, error)
type AdServiceClient interface {
GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error)
}
type adsServiceClient struct {
type adServiceClient struct {
cc *grpc.ClientConn
}
func NewAdsServiceClient(cc *grpc.ClientConn) AdsServiceClient {
return &adsServiceClient{cc}
func NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient {
return &adServiceClient{cc}
}
func (c *adsServiceClient) GetAds(ctx context.Context, in *AdsRequest, opts ...grpc.CallOption) (*AdsResponse, error) {
out := new(AdsResponse)
err := c.cc.Invoke(ctx, "/hipstershop.AdsService/GetAds", in, out, opts...)
func (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) {
out := new(AdResponse)
err := c.cc.Invoke(ctx, "/hipstershop.AdService/GetAds", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AdsServiceServer is the server API for AdsService service.
type AdsServiceServer interface {
GetAds(context.Context, *AdsRequest) (*AdsResponse, error)
// AdServiceServer is the server API for AdService service.
type AdServiceServer interface {
GetAds(context.Context, *AdRequest) (*AdResponse, error)
}
func RegisterAdsServiceServer(s *grpc.Server, srv AdsServiceServer) {
s.RegisterService(&_AdsService_serviceDesc, srv)
func RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) {
s.RegisterService(&_AdService_serviceDesc, srv)
}
func _AdsService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AdsRequest)
func _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AdRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AdsServiceServer).GetAds(ctx, in)
return srv.(AdServiceServer).GetAds(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hipstershop.AdsService/GetAds",
FullMethod: "/hipstershop.AdService/GetAds",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AdsServiceServer).GetAds(ctx, req.(*AdsRequest))
return srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest))
}
return interceptor(ctx, in, info, handler)
}
var _AdsService_serviceDesc = grpc.ServiceDesc{
ServiceName: "hipstershop.AdsService",
HandlerType: (*AdsServiceServer)(nil),
var _AdService_serviceDesc = grpc.ServiceDesc{
ServiceName: "hipstershop.AdService",
HandlerType: (*AdServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetAds",
Handler: _AdsService_GetAds_Handler,
Handler: _AdService_GetAds_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "demo.proto",
}
func init() { proto.RegisterFile("demo.proto", fileDescriptor_demo_c812a73334c7ff0d) }
func init() { proto.RegisterFile("demo.proto", fileDescriptor_demo_88bb8fdac9cd6be5) }
var fileDescriptor_demo_c812a73334c7ff0d = []byte{
// 1484 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x72, 0x13, 0xb7,
0x17, 0xcf, 0x26, 0x71, 0x1c, 0x1f, 0xc7, 0x76, 0xa2, 0x7f, 0x02, 0x66, 0xc3, 0x47, 0x50, 0x06,
0xfe, 0x50, 0x20, 0x30, 0x69, 0x67, 0xb8, 0x00, 0x4a, 0x33, 0x26, 0x63, 0x3c, 0x40, 0xa1, 0x1b,
0xe8, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0x78, 0x4b, 0x76, 0xb5, 0x48, 0xda, 0x0c, 0xe6, 0xb2,
0x7d, 0x80, 0xde, 0xf7, 0x11, 0xfa, 0x02, 0x7d, 0x87, 0xde, 0xf7, 0x15, 0xfa, 0x1c, 0x1d, 0x69,
0x57, 0xfb, 0x65, 0x3b, 0x81, 0x9b, 0xde, 0xad, 0xa4, 0x9f, 0xce, 0xf9, 0x9d, 0xa3, 0xf3, 0x65,
0x03, 0x10, 0x1a, 0xb0, 0x9d, 0x88, 0x33, 0xc9, 0x50, 0x73, 0xe4, 0x47, 0x42, 0x52, 0x2e, 0x46,
0x2c, 0xc2, 0xfb, 0xb0, 0xdc, 0x73, 0xb9, 0x1c, 0x48, 0x1a, 0xa0, 0x73, 0x00, 0x11, 0x67, 0x24,
0xf6, 0xe4, 0xd0, 0x27, 0x5d, 0x6b, 0xcb, 0xba, 0xd2, 0x70, 0x1a, 0xe9, 0xce, 0x80, 0x20, 0x1b,
0x96, 0xdf, 0xc7, 0x6e, 0x28, 0x7d, 0x39, 0xee, 0xce, 0x6f, 0x59, 0x57, 0x6a, 0x4e, 0xb6, 0xc6,
0xcf, 0xa1, 0xbd, 0x47, 0x88, 0x92, 0xe2, 0xd0, 0xf7, 0x31, 0x15, 0x12, 0x9d, 0x86, 0x7a, 0x2c,
0x28, 0xcf, 0x25, 0x2d, 0xa9, 0xe5, 0x80, 0xa0, 0xab, 0xb0, 0xe8, 0x4b, 0x1a, 0x68, 0x11, 0xcd,
0xdd, 0x8d, 0x9d, 0x02, 0x9b, 0x1d, 0x43, 0xc5, 0xd1, 0x10, 0x7c, 0x0d, 0x56, 0xf7, 0x83, 0x48,
0x8e, 0xd5, 0xf6, 0x49, 0x72, 0xf1, 0x55, 0x68, 0xf7, 0xa9, 0xfc, 0x24, 0xe8, 0x63, 0x58, 0x54,
0xb8, 0xd9, 0x1c, 0xaf, 0x41, 0x4d, 0x11, 0x10, 0xdd, 0xf9, 0xad, 0x85, 0xd9, 0x24, 0x13, 0x0c,
0xae, 0x43, 0x4d, 0xb3, 0xc4, 0xdf, 0x83, 0xfd, 0xd8, 0x17, 0xd2, 0xa1, 0x1e, 0x0b, 0x02, 0x1a,
0x12, 0x57, 0xfa, 0x2c, 0x14, 0x27, 0x3a, 0xe4, 0x02, 0x34, 0x73, 0xb7, 0x27, 0x2a, 0x1b, 0x0e,
0x64, 0x7e, 0x17, 0xf8, 0x6b, 0xd8, 0x9c, 0x2a, 0x57, 0x44, 0x2c, 0x14, 0xb4, 0x7a, 0xdf, 0x9a,
0xb8, 0xff, 0xbb, 0x05, 0xf5, 0x67, 0xc9, 0x12, 0xb5, 0x61, 0x3e, 0x23, 0x30, 0xef, 0x13, 0x84,
0x60, 0x31, 0x74, 0x03, 0xaa, 0x5f, 0xa3, 0xe1, 0xe8, 0x6f, 0xb4, 0x05, 0x4d, 0x42, 0x85, 0xc7,
0xfd, 0x48, 0x29, 0xea, 0x2e, 0xe8, 0xa3, 0xe2, 0x16, 0xea, 0x42, 0x3d, 0xf2, 0x3d, 0x19, 0x73,
0xda, 0x5d, 0xd4, 0xa7, 0x66, 0x89, 0x6e, 0x42, 0x23, 0xe2, 0xbe, 0x47, 0x87, 0xb1, 0x20, 0xdd,
0x9a, 0x7e, 0x62, 0x54, 0xf2, 0xde, 0x13, 0x16, 0xd2, 0xb1, 0xb3, 0xac, 0x41, 0x2f, 0x04, 0xc1,
0x0f, 0x61, 0x5d, 0x19, 0x97, 0xf2, 0xcb, 0xad, 0xba, 0x05, 0xcb, 0xa9, 0x09, 0x89, 0x49, 0xcd,
0xdd, 0xf5, 0x92, 0x9c, 0xf4, 0x82, 0x93, 0xa1, 0xf0, 0x36, 0xac, 0xf5, 0xa9, 0x11, 0x64, 0xbc,
0x5e, 0xb1, 0x17, 0xdf, 0x80, 0x8d, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x2b, 0x4c, 0x80, 0xeb, 0x50,
0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x84, 0x53, 0x55, 0x78, 0xca, 0x6f, 0x07,
0xea, 0x9c, 0x8a, 0xf8, 0xf0, 0x04, 0x7a, 0x06, 0x84, 0x43, 0xe8, 0xf4, 0xa9, 0xfc, 0x2e, 0x66,
0x92, 0x1a, 0x95, 0x3b, 0x50, 0x77, 0x09, 0xe1, 0x54, 0x08, 0xad, 0xb4, 0x2a, 0x62, 0x2f, 0x39,
0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x72, 0x0f, 0x56, 0x73, 0x7d, 0x29, 0xe7, 0x1b, 0xb0, 0xec, 0x31,
0x21, 0xf5, 0xdb, 0x58, 0x33, 0xdf, 0xa6, 0xae, 0x30, 0xea, 0x69, 0x18, 0xac, 0x1e, 0x8c, 0xfc,
0xe8, 0x29, 0x27, 0x94, 0xff, 0x27, 0x9c, 0xbf, 0x82, 0xb5, 0x82, 0xc2, 0x3c, 0xbc, 0x25, 0x77,
0xbd, 0x77, 0x7e, 0xf8, 0x36, 0xcf, 0x1d, 0x30, 0x5b, 0x03, 0x82, 0x7f, 0xb3, 0xa0, 0x9e, 0xea,
0x45, 0x97, 0xa0, 0x2d, 0x24, 0xa7, 0x54, 0x0e, 0x8b, 0x2c, 0x1b, 0x4e, 0x2b, 0xd9, 0x35, 0x30,
0x04, 0x8b, 0x9e, 0x29, 0x63, 0x0d, 0x47, 0x7f, 0xab, 0x00, 0x10, 0xd2, 0x95, 0x34, 0x8d, 0xf7,
0x64, 0xa1, 0x22, 0xdd, 0x63, 0x71, 0x28, 0xf9, 0xd8, 0x44, 0x7a, 0xba, 0x44, 0x67, 0x60, 0xf9,
0xa3, 0x1f, 0x0d, 0x3d, 0x46, 0xa8, 0x0e, 0xf4, 0x9a, 0x53, 0xff, 0xe8, 0x47, 0x3d, 0x46, 0x28,
0x7e, 0x09, 0x35, 0xed, 0x4a, 0xb4, 0x0d, 0x2d, 0x2f, 0xe6, 0x9c, 0x86, 0xde, 0x38, 0x01, 0x26,
0x6c, 0x56, 0xcc, 0xa6, 0x42, 0x2b, 0xc5, 0x71, 0xe8, 0x4b, 0xa1, 0xd9, 0x2c, 0x38, 0xc9, 0x42,
0xed, 0x86, 0x6e, 0xc8, 0x84, 0xa6, 0x53, 0x73, 0x92, 0x05, 0xee, 0xc3, 0xf9, 0x3e, 0x95, 0x07,
0x71, 0x14, 0x31, 0x2e, 0x29, 0xe9, 0x25, 0x72, 0x7c, 0x9a, 0xc7, 0xe5, 0x25, 0x68, 0x97, 0x54,
0x9a, 0x82, 0xd0, 0x2a, 0xea, 0x14, 0xf8, 0x47, 0x38, 0xd3, 0xcb, 0x36, 0xc2, 0x23, 0xca, 0x85,
0xcf, 0x42, 0xf3, 0xc8, 0x97, 0x61, 0xf1, 0x0d, 0x67, 0xc1, 0x31, 0x31, 0xa2, 0xcf, 0x55, 0x49,
0x93, 0x2c, 0x31, 0x2c, 0xf1, 0xe4, 0x92, 0x64, 0xda, 0x01, 0xff, 0x58, 0xd0, 0xee, 0x71, 0x4a,
0x7c, 0x55, 0x8f, 0xc9, 0x20, 0x7c, 0xc3, 0xd0, 0x75, 0x40, 0x9e, 0xde, 0x19, 0x7a, 0x2e, 0x27,
0xc3, 0x30, 0x0e, 0x5e, 0x53, 0x9e, 0xfa, 0x63, 0xd5, 0xcb, 0xb0, 0xdf, 0xea, 0x7d, 0x74, 0x19,
0x3a, 0x45, 0xb4, 0x77, 0x74, 0x94, 0xb6, 0x9c, 0x56, 0x0e, 0xed, 0x1d, 0x1d, 0xa1, 0x7b, 0xb0,
0x59, 0xc4, 0xd1, 0x0f, 0x91, 0xcf, 0x75, 0x79, 0x1c, 0x8e, 0xa9, 0xcb, 0x53, 0xdf, 0x75, 0xf3,
0x3b, 0xfb, 0x19, 0xe0, 0x07, 0xea, 0x72, 0x74, 0x1f, 0xce, 0xce, 0xb8, 0x1e, 0xb0, 0x50, 0x8e,
0xf4, 0x93, 0xd7, 0x9c, 0x33, 0xd3, 0xee, 0x3f, 0x51, 0x00, 0x3c, 0x86, 0x56, 0x6f, 0xe4, 0xf2,
0xb7, 0x59, 0x4e, 0x7f, 0x01, 0x4b, 0x6e, 0xa0, 0x22, 0xe4, 0x18, 0xe7, 0xa5, 0x08, 0x74, 0x17,
0x9a, 0x05, 0xed, 0x69, 0x43, 0xdc, 0x2c, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0, 0x6d,
0x68, 0x1b, 0xd5, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xb4, 0x09, 0x59, 0xb2, 0xb4, 0x0a,
0xbb, 0x03, 0x82, 0x7f, 0x82, 0x86, 0xce, 0x30, 0xdd, 0xf3, 0x4d, 0x37, 0xb6, 0x4e, 0xec, 0xc6,
0x2a, 0x2a, 0x54, 0x65, 0x48, 0x79, 0x4e, 0x8d, 0x0a, 0x75, 0x8e, 0x7f, 0x99, 0x87, 0xa6, 0x49,
0xe1, 0xf8, 0x50, 0xaa, 0x44, 0x61, 0x6a, 0x99, 0x13, 0xaa, 0xeb, 0xf5, 0x80, 0xa0, 0x5b, 0xb0,
0x2e, 0x46, 0x7e, 0x14, 0xa9, 0xdc, 0x2e, 0x26, 0x79, 0x12, 0x4d, 0xc8, 0x9c, 0x3d, 0xcf, 0x92,
0x1d, 0xdd, 0x86, 0x56, 0x76, 0x43, 0xb3, 0x59, 0x98, 0xc9, 0x66, 0xc5, 0x00, 0x7b, 0x4c, 0x48,
0x74, 0x1f, 0x56, 0xb3, 0x8b, 0xa6, 0x36, 0x2c, 0x1e, 0x53, 0xc1, 0x3a, 0x06, 0x6d, 0x6a, 0xc6,
0x75, 0x53, 0xc9, 0x6a, 0xba, 0x92, 0x9d, 0x2a, 0xdd, 0xca, 0x1c, 0x6a, 0x4a, 0x19, 0x81, 0xb3,
0x07, 0x34, 0x24, 0x7a, 0xbf, 0xc7, 0xc2, 0x37, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d, 0x0d,
0x5c, 0xff, 0xd0, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x9d, 0xd4,
0x91, 0xf8, 0xd4, 0x49, 0x60, 0xf8, 0x6f, 0x0b, 0xd6, 0x9e, 0x1d, 0xba, 0x1e, 0x2d, 0xd5, 0xe8,
0x99, 0x93, 0xc6, 0x36, 0xb4, 0xf4, 0x81, 0x29, 0x05, 0xa9, 0x9f, 0x57, 0xd4, 0xa6, 0xa9, 0x06,
0xc5, 0x0a, 0xbf, 0xf0, 0x29, 0x15, 0x3e, 0xb3, 0xa4, 0x56, 0xb4, 0xa4, 0x12, 0xdb, 0x4b, 0x9f,
0x17, 0xdb, 0x0f, 0x00, 0x15, 0xcd, 0xca, 0x5a, 0x6e, 0xea, 0x1d, 0xeb, 0xd3, 0xbc, 0x73, 0x13,
0x60, 0x8f, 0x64, 0x0d, 0xfe, 0x22, 0xac, 0x78, 0x2c, 0x94, 0xf4, 0x83, 0x1c, 0xbe, 0xa3, 0x63,
0x53, 0x16, 0x9b, 0xe9, 0xde, 0x23, 0x3a, 0x16, 0xf8, 0x16, 0x34, 0xf5, 0x85, 0x54, 0xdf, 0x45,
0x58, 0x70, 0x89, 0x69, 0xef, 0x9d, 0x8a, 0x17, 0x1c, 0x75, 0x86, 0xef, 0xc0, 0xfc, 0x1e, 0x51,
0xa2, 0x15, 0x77, 0x4e, 0x3d, 0x39, 0x8c, 0xb9, 0x79, 0xd3, 0xa6, 0xd9, 0x7b, 0xc1, 0x0f, 0x55,
0xc7, 0x51, 0x6a, 0x4c, 0xc7, 0x51, 0xdf, 0xbb, 0x7f, 0x59, 0xd0, 0x54, 0x39, 0x76, 0x40, 0xf9,
0x91, 0xef, 0x51, 0x74, 0x57, 0xf7, 0x31, 0x9d, 0x96, 0x9b, 0x55, 0x9f, 0x17, 0x46, 0x6b, 0xbb,
0x1c, 0xec, 0xc9, 0xec, 0x39, 0x87, 0xee, 0x40, 0x3d, 0x9d, 0x7f, 0x2b, 0xb7, 0xcb, 0x53, 0xb1,
0xbd, 0x36, 0x91, 0xe3, 0x78, 0x0e, 0x7d, 0x03, 0x8d, 0x6c, 0xd2, 0x46, 0xe7, 0x26, 0xe5, 0x17,
0x05, 0x4c, 0x55, 0xbf, 0xfb, 0xab, 0x05, 0x1b, 0xe5, 0x09, 0xd5, 0x98, 0xf5, 0x33, 0xfc, 0x6f,
0xca, 0xf8, 0x8a, 0xfe, 0x5f, 0x12, 0x33, 0x7b, 0x70, 0xb6, 0xaf, 0x9c, 0x0c, 0x4c, 0x1e, 0x4c,
0xb1, 0x98, 0x87, 0x8d, 0x74, 0xf4, 0xea, 0xb9, 0xd2, 0x3d, 0x64, 0x6f, 0x0d, 0x8b, 0x3e, 0xac,
0x14, 0xe7, 0x4c, 0x34, 0xc5, 0x0a, 0xfb, 0xe2, 0x84, 0xa6, 0xea, 0xd8, 0x87, 0xe7, 0xd0, 0x03,
0x80, 0x7c, 0xcc, 0x44, 0xe7, 0xab, 0xae, 0x2e, 0xcf, 0x9f, 0xf6, 0xd4, 0xa9, 0x10, 0xcf, 0xa1,
0x57, 0xd0, 0x2e, 0x0f, 0x96, 0x08, 0x97, 0x90, 0x53, 0x87, 0x54, 0x7b, 0xfb, 0x58, 0x4c, 0xe6,
0x85, 0x3f, 0x2c, 0xe8, 0x1c, 0xa4, 0xe5, 0xcb, 0xd8, 0x3f, 0x80, 0x65, 0x33, 0x0f, 0xa2, 0xb3,
0x55, 0xd2, 0xc5, 0xb1, 0xd4, 0x3e, 0x37, 0xe3, 0x34, 0xf3, 0xc0, 0x63, 0x68, 0x64, 0x63, 0x5a,
0x25, 0x58, 0xaa, 0xf3, 0xa2, 0x7d, 0x7e, 0xd6, 0x71, 0x46, 0xf6, 0x4f, 0x0b, 0x3a, 0xa6, 0xf8,
0x18, 0xb2, 0xaf, 0xe0, 0xd4, 0xf4, 0x31, 0x67, 0xea, 0xb3, 0x5d, 0xab, 0x12, 0x3e, 0x66, 0x3e,
0xc2, 0x73, 0xa8, 0x0f, 0xf5, 0x64, 0xe4, 0x91, 0xe8, 0x72, 0x39, 0x17, 0x66, 0x0d, 0x44, 0xf6,
0x94, 0xf6, 0x82, 0xe7, 0x76, 0x5f, 0x40, 0xfb, 0x99, 0x3b, 0x0e, 0x68, 0x98, 0x65, 0x70, 0x0f,
0x96, 0x92, 0x9e, 0x8c, 0xec, 0xb2, 0xe4, 0xe2, 0x8c, 0x60, 0x6f, 0x4e, 0x3d, 0xcb, 0x1c, 0x32,
0x82, 0x95, 0x7d, 0x55, 0x43, 0x8d, 0xd0, 0x97, 0xea, 0x27, 0xcb, 0x94, 0x56, 0x82, 0xae, 0x56,
0xa2, 0x61, 0x76, 0xbb, 0x99, 0x91, 0xb3, 0xaf, 0xa1, 0xd3, 0x1b, 0x51, 0xef, 0x1d, 0x8b, 0x33,
0x0b, 0x9e, 0x02, 0xe4, 0x95, 0xb7, 0x12, 0xdd, 0x13, 0x9d, 0xc6, 0xbe, 0x30, 0xf3, 0x3c, 0xb3,
0xe6, 0x91, 0x2e, 0xc2, 0x46, 0xfc, 0x3d, 0x58, 0xea, 0xab, 0x31, 0x5c, 0xa0, 0xd3, 0x95, 0x0a,
0x97, 0xc5, 0x78, 0x77, 0xf2, 0xc0, 0x08, 0x7b, 0xbd, 0xa4, 0xff, 0xc1, 0xf8, 0xf2, 0xdf, 0x00,
0x00, 0x00, 0xff, 0xff, 0x0d, 0x93, 0x0f, 0x58, 0xcf, 0x10, 0x00, 0x00,
var fileDescriptor_demo_88bb8fdac9cd6be5 = []byte{
// 1483 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x72, 0xd3, 0xc6,
0x17, 0x8f, 0x92, 0x38, 0x8e, 0x8f, 0x63, 0x27, 0xd9, 0x7f, 0x12, 0x8c, 0xc2, 0x47, 0xd8, 0x0c,
0xfc, 0xa1, 0x80, 0x61, 0xd2, 0xce, 0x70, 0x01, 0x2d, 0xcd, 0x98, 0x8c, 0xf1, 0x14, 0x0a, 0x55,
0xa0, 0x43, 0x87, 0x4e, 0x3d, 0x42, 0xbb, 0x60, 0x95, 0x48, 0x2b, 0x76, 0x57, 0x19, 0xcc, 0x65,
0xfb, 0x00, 0xbd, 0xef, 0x23, 0xf4, 0x05, 0xfa, 0x0e, 0xbd, 0xef, 0x2b, 0xf4, 0x39, 0x3a, 0xbb,
0xd2, 0xea, 0xcb, 0x76, 0x02, 0x37, 0xbd, 0xf3, 0x9e, 0xfd, 0xe9, 0x9c, 0xdf, 0x39, 0x7b, 0xbe,
0x12, 0x00, 0x42, 0x03, 0xd6, 0x8d, 0x38, 0x93, 0x0c, 0x35, 0x47, 0x7e, 0x24, 0x24, 0xe5, 0x62,
0xc4, 0x22, 0x7c, 0x00, 0xcb, 0x3d, 0x97, 0xcb, 0x81, 0xa4, 0x01, 0x3a, 0x0f, 0x10, 0x71, 0x46,
0x62, 0x4f, 0x0e, 0x7d, 0xd2, 0xb1, 0x76, 0xac, 0xab, 0x0d, 0xa7, 0x91, 0x4a, 0x06, 0x04, 0xd9,
0xb0, 0xfc, 0x2e, 0x76, 0x43, 0xe9, 0xcb, 0x71, 0x67, 0x7e, 0xc7, 0xba, 0x5a, 0x73, 0xb2, 0x33,
0x7e, 0x06, 0xed, 0x7d, 0x42, 0x94, 0x16, 0x87, 0xbe, 0x8b, 0xa9, 0x90, 0xe8, 0x0c, 0xd4, 0x63,
0x41, 0x79, 0xae, 0x69, 0x49, 0x1d, 0x07, 0x04, 0x5d, 0x83, 0x45, 0x5f, 0xd2, 0x40, 0xab, 0x68,
0xee, 0x6d, 0x76, 0x0b, 0x6c, 0xba, 0x86, 0x8a, 0xa3, 0x21, 0xf8, 0x3a, 0xac, 0x1d, 0x04, 0x91,
0x1c, 0x2b, 0xf1, 0x69, 0x7a, 0xf1, 0x35, 0x68, 0xf7, 0xa9, 0xfc, 0x28, 0xe8, 0x23, 0x58, 0x54,
0xb8, 0xd9, 0x1c, 0xaf, 0x43, 0x4d, 0x11, 0x10, 0x9d, 0xf9, 0x9d, 0x85, 0xd9, 0x24, 0x13, 0x0c,
0xae, 0x43, 0x4d, 0xb3, 0xc4, 0xdf, 0x83, 0xfd, 0xc8, 0x17, 0xd2, 0xa1, 0x1e, 0x0b, 0x02, 0x1a,
0x12, 0x57, 0xfa, 0x2c, 0x14, 0xa7, 0x06, 0xe4, 0x22, 0x34, 0xf3, 0xb0, 0x27, 0x26, 0x1b, 0x0e,
0x64, 0x71, 0x17, 0xf8, 0x2b, 0xd8, 0x9e, 0xaa, 0x57, 0x44, 0x2c, 0x14, 0xb4, 0xfa, 0xbd, 0x35,
0xf1, 0xfd, 0xef, 0x16, 0xd4, 0x9f, 0x26, 0x47, 0xd4, 0x86, 0xf9, 0x8c, 0xc0, 0xbc, 0x4f, 0x10,
0x82, 0xc5, 0xd0, 0x0d, 0xa8, 0x7e, 0x8d, 0x86, 0xa3, 0x7f, 0xa3, 0x1d, 0x68, 0x12, 0x2a, 0x3c,
0xee, 0x47, 0xca, 0x50, 0x67, 0x41, 0x5f, 0x15, 0x45, 0xa8, 0x03, 0xf5, 0xc8, 0xf7, 0x64, 0xcc,
0x69, 0x67, 0x51, 0xdf, 0x9a, 0x23, 0xba, 0x05, 0x8d, 0x88, 0xfb, 0x1e, 0x1d, 0xc6, 0x82, 0x74,
0x6a, 0xfa, 0x89, 0x51, 0x29, 0x7a, 0x8f, 0x59, 0x48, 0xc7, 0xce, 0xb2, 0x06, 0x3d, 0x17, 0x04,
0x3f, 0x84, 0x0d, 0xe5, 0x5c, 0xca, 0x2f, 0xf7, 0xea, 0x36, 0x2c, 0xa7, 0x2e, 0x24, 0x2e, 0x35,
0xf7, 0x36, 0x4a, 0x7a, 0xd2, 0x0f, 0x9c, 0x0c, 0x85, 0x77, 0x61, 0xbd, 0x4f, 0x8d, 0x22, 0x13,
0xf5, 0x8a, 0xbf, 0xf8, 0x26, 0x6c, 0x1e, 0x52, 0x97, 0x7b, 0xa3, 0xdc, 0x60, 0x02, 0xdc, 0x80,
0xda, 0xbb, 0x98, 0xf2, 0x71, 0x8a, 0x4d, 0x0e, 0xf8, 0x21, 0x6c, 0x55, 0xe1, 0x29, 0xbf, 0x2e,
0xd4, 0x39, 0x15, 0xf1, 0xd1, 0x29, 0xf4, 0x0c, 0x08, 0x87, 0xb0, 0xda, 0xa7, 0xf2, 0xbb, 0x98,
0x49, 0x6a, 0x4c, 0x76, 0xa1, 0xee, 0x12, 0xc2, 0xa9, 0x10, 0xda, 0x68, 0x55, 0xc5, 0x7e, 0x72,
0xe7, 0x18, 0xd0, 0xa7, 0x65, 0xe5, 0x3e, 0xac, 0xe5, 0xf6, 0x52, 0xce, 0x37, 0x61, 0xd9, 0x63,
0x42, 0xea, 0xb7, 0xb1, 0x66, 0xbe, 0x4d, 0x5d, 0x61, 0xd4, 0xd3, 0x30, 0x58, 0x3b, 0x1c, 0xf9,
0xd1, 0x13, 0x4e, 0x28, 0xff, 0x4f, 0x38, 0x7f, 0x01, 0xeb, 0x05, 0x83, 0x79, 0x7a, 0x4b, 0xee,
0x7a, 0x6f, 0xfd, 0xf0, 0x4d, 0x5e, 0x3b, 0x60, 0x44, 0x03, 0x82, 0x7f, 0xb3, 0xa0, 0x9e, 0xda,
0x45, 0x97, 0xa1, 0x2d, 0x24, 0xa7, 0x54, 0x0e, 0x8b, 0x2c, 0x1b, 0x4e, 0x2b, 0x91, 0x1a, 0x18,
0x82, 0x45, 0xcf, 0xb4, 0xb1, 0x86, 0xa3, 0x7f, 0xab, 0x04, 0x10, 0xd2, 0x95, 0x34, 0xcd, 0xf7,
0xe4, 0xa0, 0x32, 0xdd, 0x63, 0x71, 0x28, 0xf9, 0xd8, 0x64, 0x7a, 0x7a, 0x44, 0x67, 0x61, 0xf9,
0x83, 0x1f, 0x0d, 0x3d, 0x46, 0xa8, 0x4e, 0xf4, 0x9a, 0x53, 0xff, 0xe0, 0x47, 0x3d, 0x46, 0x28,
0x7e, 0x01, 0x35, 0x1d, 0x4a, 0xb4, 0x0b, 0x2d, 0x2f, 0xe6, 0x9c, 0x86, 0xde, 0x38, 0x01, 0x26,
0x6c, 0x56, 0x8c, 0x50, 0xa1, 0x95, 0xe1, 0x38, 0xf4, 0xa5, 0xd0, 0x6c, 0x16, 0x9c, 0xe4, 0xa0,
0xa4, 0xa1, 0x1b, 0x32, 0xa1, 0xe9, 0xd4, 0x9c, 0xe4, 0x80, 0xfb, 0x70, 0xa1, 0x4f, 0xe5, 0x61,
0x1c, 0x45, 0x8c, 0x4b, 0x4a, 0x7a, 0x89, 0x1e, 0x9f, 0xe6, 0x79, 0x79, 0x19, 0xda, 0x25, 0x93,
0xa6, 0x21, 0xb4, 0x8a, 0x36, 0x05, 0xfe, 0x11, 0xce, 0xf6, 0x32, 0x41, 0x78, 0x4c, 0xb9, 0xf0,
0x59, 0x68, 0x1e, 0xf9, 0x0a, 0x2c, 0xbe, 0xe6, 0x2c, 0x38, 0x21, 0x47, 0xf4, 0xbd, 0x6a, 0x69,
0x92, 0x25, 0x8e, 0x25, 0x91, 0x5c, 0x92, 0x4c, 0x07, 0xe0, 0x1f, 0x0b, 0xda, 0x3d, 0x4e, 0x89,
0xaf, 0xfa, 0x31, 0x19, 0x84, 0xaf, 0x19, 0xba, 0x01, 0xc8, 0xd3, 0x92, 0xa1, 0xe7, 0x72, 0x32,
0x0c, 0xe3, 0xe0, 0x15, 0xe5, 0x69, 0x3c, 0xd6, 0xbc, 0x0c, 0xfb, 0xad, 0x96, 0xa3, 0x2b, 0xb0,
0x5a, 0x44, 0x7b, 0xc7, 0xc7, 0xe9, 0xc8, 0x69, 0xe5, 0xd0, 0xde, 0xf1, 0x31, 0xfa, 0x12, 0xb6,
0x8b, 0x38, 0xfa, 0x3e, 0xf2, 0xb9, 0x6e, 0x8f, 0xc3, 0x31, 0x75, 0x79, 0x1a, 0xbb, 0x4e, 0xfe,
0xcd, 0x41, 0x06, 0xf8, 0x81, 0xba, 0x1c, 0xdd, 0x87, 0x73, 0x33, 0x3e, 0x0f, 0x58, 0x28, 0x47,
0xfa, 0xc9, 0x6b, 0xce, 0xd9, 0x69, 0xdf, 0x3f, 0x56, 0x00, 0x3c, 0x86, 0x56, 0x6f, 0xe4, 0xf2,
0x37, 0x59, 0x4d, 0x7f, 0x06, 0x4b, 0x6e, 0xa0, 0x32, 0xe4, 0x84, 0xe0, 0xa5, 0x08, 0x74, 0x0f,
0x9a, 0x05, 0xeb, 0xe9, 0x40, 0xdc, 0x2e, 0x57, 0x48, 0x29, 0x88, 0x0e, 0xe4, 0x4c, 0xf0, 0x1d,
0x68, 0x1b, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xb4, 0x0b, 0x59, 0xb1, 0xb4, 0x0a,
0xd2, 0x01, 0xc1, 0x3f, 0x41, 0x43, 0x57, 0x98, 0x9e, 0xf9, 0x66, 0x1a, 0x5b, 0xa7, 0x4e, 0x63,
0x95, 0x15, 0xaa, 0x33, 0xa4, 0x3c, 0xa7, 0x66, 0x85, 0xba, 0xc7, 0xbf, 0xcc, 0x43, 0xd3, 0x94,
0x70, 0x7c, 0x24, 0x55, 0xa1, 0x30, 0x75, 0xcc, 0x09, 0xd5, 0xf5, 0x79, 0x40, 0xd0, 0x6d, 0xd8,
0x10, 0x23, 0x3f, 0x8a, 0x54, 0x6d, 0x17, 0x8b, 0x3c, 0xc9, 0x26, 0x64, 0xee, 0x9e, 0x65, 0xc5,
0x8e, 0xee, 0x40, 0x2b, 0xfb, 0x42, 0xb3, 0x59, 0x98, 0xc9, 0x66, 0xc5, 0x00, 0x7b, 0x4c, 0x48,
0x74, 0x1f, 0xd6, 0xb2, 0x0f, 0x4d, 0x6f, 0x58, 0x3c, 0xa1, 0x83, 0xad, 0x1a, 0xb4, 0xe9, 0x19,
0x37, 0x4c, 0x27, 0xab, 0xe9, 0x4e, 0xb6, 0x55, 0xfa, 0x2a, 0x0b, 0xa8, 0x69, 0x65, 0x04, 0xce,
0x1d, 0xd2, 0x90, 0x68, 0x79, 0x8f, 0x85, 0xaf, 0x7d, 0x1e, 0xe8, 0xb4, 0x29, 0x8c, 0x1b, 0x1a,
0xb8, 0xfe, 0x91, 0x19, 0x37, 0xfa, 0x80, 0xba, 0x50, 0xd3, 0xa1, 0x49, 0x63, 0xdc, 0x99, 0xb4,
0x91, 0xc4, 0xd4, 0x49, 0x60, 0xf8, 0x6f, 0x0b, 0xd6, 0x9f, 0x1e, 0xb9, 0x1e, 0x2d, 0xf5, 0xe8,
0x99, 0x9b, 0xc6, 0x2e, 0xb4, 0xf4, 0x85, 0x69, 0x05, 0x69, 0x9c, 0x57, 0x94, 0xd0, 0x74, 0x83,
0x62, 0x87, 0x5f, 0xf8, 0x98, 0x0e, 0x9f, 0x79, 0x52, 0x2b, 0x7a, 0x52, 0xc9, 0xed, 0xa5, 0x4f,
0xcb, 0xed, 0x07, 0x80, 0x8a, 0x6e, 0x65, 0x23, 0x37, 0x8d, 0x8e, 0xf5, 0x71, 0xd1, 0xe9, 0x42,
0x63, 0x9f, 0x98, 0xa0, 0x5c, 0x82, 0x15, 0x8f, 0x85, 0x92, 0xbe, 0x97, 0xc3, 0xb7, 0x74, 0x6c,
0xba, 0x62, 0x33, 0x95, 0x7d, 0x43, 0xc7, 0x02, 0xdf, 0x02, 0x50, 0xf8, 0xd4, 0xda, 0x25, 0x58,
0x70, 0x89, 0x19, 0xee, 0xab, 0x95, 0x18, 0x38, 0xea, 0x0e, 0xdf, 0x85, 0xf9, 0x7d, 0xa2, 0x34,
0x2b, 0xe6, 0x9c, 0x7a, 0x72, 0x18, 0x73, 0xf3, 0xa2, 0x4d, 0x23, 0x7b, 0xce, 0x8f, 0xd4, 0xbc,
0x51, 0x56, 0xcc, 0xbc, 0x51, 0xbf, 0xf7, 0xfe, 0xb2, 0xa0, 0xa9, 0x2a, 0xec, 0x90, 0xf2, 0x63,
0xdf, 0xa3, 0xe8, 0x9e, 0x9e, 0x62, 0xba, 0x28, 0xb7, 0xab, 0x11, 0x2f, 0x2c, 0xd6, 0x76, 0x39,
0xd5, 0x93, 0xcd, 0x73, 0x0e, 0xdd, 0x85, 0x7a, 0xba, 0xfd, 0x56, 0xbe, 0x2e, 0xef, 0xc4, 0xf6,
0xfa, 0x44, 0x85, 0xe3, 0x39, 0xf4, 0x35, 0x34, 0xb2, 0x3d, 0x1b, 0x9d, 0x9f, 0xd4, 0x5f, 0x54,
0x30, 0xd5, 0xfc, 0xde, 0xaf, 0x16, 0x6c, 0x96, 0xf7, 0x53, 0xe3, 0xd6, 0xcf, 0xf0, 0xbf, 0x29,
0xcb, 0x2b, 0xfa, 0x7f, 0x49, 0xcd, 0xec, 0xb5, 0xd9, 0xbe, 0x7a, 0x3a, 0x30, 0x79, 0x30, 0xc5,
0x62, 0x1e, 0x36, 0xd3, 0xc5, 0xab, 0xe7, 0x4a, 0xf7, 0x88, 0xbd, 0x31, 0x2c, 0xfa, 0xb0, 0x52,
0xdc, 0x32, 0xd1, 0x14, 0x2f, 0xec, 0x4b, 0x13, 0x96, 0xaa, 0x4b, 0x1f, 0x9e, 0x43, 0x0f, 0x00,
0xf2, 0x25, 0x13, 0x5d, 0xa8, 0x86, 0xba, 0xbc, 0x7d, 0xda, 0x53, 0x77, 0x42, 0x3c, 0x87, 0x5e,
0x42, 0xbb, 0xbc, 0x56, 0x22, 0x5c, 0x42, 0x4e, 0x5d, 0x51, 0xed, 0xdd, 0x13, 0x31, 0x59, 0x14,
0xfe, 0xb0, 0x60, 0xf5, 0x30, 0x6d, 0x5e, 0xc6, 0xff, 0x01, 0x2c, 0x9b, 0x6d, 0x10, 0x9d, 0xab,
0x92, 0x2e, 0x2e, 0xa5, 0xf6, 0xf9, 0x19, 0xb7, 0x59, 0x04, 0x1e, 0x41, 0x23, 0x5b, 0xd2, 0x2a,
0xc9, 0x52, 0xdd, 0x16, 0xed, 0x0b, 0xb3, 0xae, 0x33, 0xb2, 0x7f, 0x5a, 0xb0, 0x6a, 0x5a, 0x8f,
0x21, 0xfb, 0x12, 0xb6, 0xa6, 0x2f, 0x39, 0x53, 0x9f, 0xed, 0x7a, 0x95, 0xf0, 0x09, 0xdb, 0x11,
0x9e, 0x43, 0x7d, 0xa8, 0x27, 0x0b, 0x8f, 0x44, 0x57, 0xca, 0xb5, 0x30, 0x6b, 0x1d, 0xb2, 0xa7,
0x0c, 0x17, 0x3c, 0xb7, 0xf7, 0x1c, 0xda, 0x4f, 0xdd, 0x71, 0x40, 0xc3, 0xac, 0x82, 0x7b, 0xb0,
0x94, 0x4c, 0x64, 0x64, 0x97, 0x35, 0x17, 0x37, 0x04, 0x7b, 0x7b, 0xea, 0x5d, 0x16, 0x90, 0x11,
0xac, 0x1c, 0xa8, 0x0e, 0x6a, 0x94, 0xbe, 0x50, 0x7f, 0xb0, 0x4c, 0x19, 0x24, 0xe8, 0x5a, 0x25,
0x1b, 0x66, 0x0f, 0x9b, 0x19, 0x35, 0xfb, 0x0a, 0x56, 0x7b, 0x23, 0xea, 0xbd, 0x65, 0x71, 0xe6,
0xc1, 0x13, 0x80, 0xbc, 0xef, 0x56, 0xb2, 0x7b, 0x62, 0xce, 0xd8, 0x17, 0x67, 0xde, 0x67, 0xde,
0x3c, 0x54, 0x2d, 0xd8, 0x68, 0xbf, 0x0b, 0x4b, 0x7d, 0xb5, 0x83, 0x0b, 0xb4, 0x55, 0x6d, 0xa7,
0xa9, 0xc6, 0x33, 0x13, 0x72, 0xa3, 0xe9, 0xd5, 0x92, 0xfe, 0xe7, 0xc5, 0xe7, 0xff, 0x06, 0x00,
0x00, 0xff, 0xff, 0x22, 0xc9, 0xfe, 0x20, 0xca, 0x10, 0x00, 0x00,
}

View file

@ -16,6 +16,7 @@ package main
import (
"context"
"time"
pb "github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto"
@ -116,20 +117,11 @@ func (fe *frontendServer) getRecommendations(ctx context.Context, userID string,
}
func (fe *frontendServer) getAd(ctx context.Context) ([]*pb.Ad, error) {
return []*pb.Ad{
&pb.Ad{
Text: "Try this OG insta camera from 1960s!",
RedirectUrl: "https://en.wikipedia.org/wiki/Instant_camera#Polaroid_cameras",
},
&pb.Ad{
Text: "Check out the new instagrammy vacation destinations!",
RedirectUrl: "https://en.wikipedia.org/wiki/Italy",
},
}, nil
ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
defer cancel()
// TODO(rghetia): uncomment below and revove the code above
// resp, err := pb.NewAdsServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdsRequest{
// ContextKeys: nil,
// })
// return resp.GetAds(), errors.Wrap(err, "failed to get ads")
resp, err := pb.NewAdServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdRequest{
ContextKeys: nil,
})
return resp.GetAds(), errors.Wrap(err, "failed to get ads")
}