Merge pull request #5 from GoogleCloudPlatform/master
Merge from Upstream
This commit is contained in:
commit
988f399fd0
31 changed files with 1911 additions and 3752 deletions
|
@ -3,6 +3,12 @@
|
||||||
We'd love to accept your patches and contributions to this project. There are
|
We'd love to accept your patches and contributions to this project. There are
|
||||||
just a few small guidelines you need to follow.
|
just a few small guidelines you need to follow.
|
||||||
|
|
||||||
|
## Development Principles (for Googlers)
|
||||||
|
|
||||||
|
There are a few principles for developing or refactoring the service
|
||||||
|
implementations. Read the [Development Principles
|
||||||
|
Guide](./docs/development-principles.md).
|
||||||
|
|
||||||
## Contributor License Agreement
|
## Contributor License Agreement
|
||||||
|
|
||||||
Contributions to this project must be accompanied by a Contributor License
|
Contributions to this project must be accompanied by a Contributor License
|
||||||
|
|
44
docs/development-principles.md
Normal file
44
docs/development-principles.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Development Principles
|
||||||
|
|
||||||
|
> **Note:** This document outlines guidances behind some development decisions
|
||||||
|
> behind the Hipster Shop demo application.
|
||||||
|
|
||||||
|
### Minimal configuration
|
||||||
|
|
||||||
|
Running the demo locally or on GCP should not require minimal to no
|
||||||
|
configuration unless absolutely necessary to run critical parts of the demo.
|
||||||
|
|
||||||
|
Configuration that takes multiple steps, especially such as creating service
|
||||||
|
accounts should be avoided.
|
||||||
|
|
||||||
|
### App must work well outside GCP
|
||||||
|
|
||||||
|
Demo application should work reasonably well when it is not deployed to GCP
|
||||||
|
services. The experience of running the application locally or on GCP should
|
||||||
|
be close.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
- OpenCensus prints the traces to stdout when it cannot connect to GCP.
|
||||||
|
- Stackdriver Debugging tries connecting to GCP multiple times, eventually gives
|
||||||
|
up.
|
||||||
|
|
||||||
|
### Running on GCP must not reduce functionality
|
||||||
|
|
||||||
|
Running the demo on the GCP must not reduce/lose any of the capabilities
|
||||||
|
developers have when running locally.
|
||||||
|
|
||||||
|
For example: Logs should still be printed to stdout/stderr even though logs are
|
||||||
|
uploaded to Stackdriver Logging when on GCP, so that developers can use "kubectl
|
||||||
|
logs" to diagnose each container.
|
||||||
|
|
||||||
|
### Microservice implementations should not be complex
|
||||||
|
|
||||||
|
Each service should provide a minimal implementation and try to avoid
|
||||||
|
unnecessary code and logic that's not executed.
|
||||||
|
|
||||||
|
Keep in mind that any service implementation is a decent example of “a GRPC
|
||||||
|
application that runs on Kubernetes”. Keeping the source code short and
|
||||||
|
navigable will serve this purpose.
|
||||||
|
|
||||||
|
It is okay to have intentional inefficiencies in the code as they help
|
||||||
|
illustrate the capabilities of profiling and diagnostics offerings.
|
|
@ -45,12 +45,12 @@ spec:
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
initialDelaySeconds: 15
|
initialDelaySeconds: 15
|
||||||
exec:
|
exec:
|
||||||
command: ["/cartservice_probe"]
|
command: ["/bin/grpc_health_probe", "-addr=:7070"]
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
initialDelaySeconds: 15
|
initialDelaySeconds: 15
|
||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
exec:
|
exec:
|
||||||
command: ["/cartservice_probe"]
|
command: ["/bin/grpc_health_probe", "-addr=:7070"]
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|
|
@ -38,7 +38,7 @@ spec:
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
initialDelaySeconds: 10
|
initialDelaySeconds: 10
|
||||||
httpGet:
|
httpGet:
|
||||||
path: "/"
|
path: "/_healthz"
|
||||||
port: 8080
|
port: 8080
|
||||||
httpHeaders:
|
httpHeaders:
|
||||||
- name: "Cookie"
|
- name: "Cookie"
|
||||||
|
|
|
@ -64,6 +64,10 @@ message Product {
|
||||||
string description = 3;
|
string description = 3;
|
||||||
string picture = 4;
|
string picture = 4;
|
||||||
Money price_usd = 5;
|
Money price_usd = 5;
|
||||||
|
|
||||||
|
// Categories such as "vintage" or "gardening" that can be used to look up
|
||||||
|
// other related products.
|
||||||
|
repeated string categories = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListProductsResponse {
|
message ListProductsResponse {
|
||||||
|
|
|
@ -25,8 +25,9 @@ repositories {
|
||||||
group = "adservice"
|
group = "adservice"
|
||||||
version = "0.1.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION
|
version = "0.1.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION
|
||||||
|
|
||||||
def opencensusVersion = "0.15.0" // LATEST_OPENCENSUS_RELEASE_VERSION
|
def opencensusVersion = "0.16.1" // LATEST_OPENCENSUS_RELEASE_VERSION
|
||||||
def grpcVersion = "1.15.0" // CURRENT_GRPC_VERSION
|
def grpcVersion = "1.15.0" // CURRENT_GRPC_VERSION
|
||||||
|
def jacksonVersion = "2.9.6"
|
||||||
def prometheusVersion = "0.3.0"
|
def prometheusVersion = "0.3.0"
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
@ -52,9 +53,13 @@ dependencies {
|
||||||
"io.grpc:grpc-stub:${grpcVersion}",
|
"io.grpc:grpc-stub:${grpcVersion}",
|
||||||
"io.grpc:grpc-netty:${grpcVersion}",
|
"io.grpc:grpc-netty:${grpcVersion}",
|
||||||
"io.grpc:grpc-services:${grpcVersion}",
|
"io.grpc:grpc-services:${grpcVersion}",
|
||||||
"io.prometheus:simpleclient_httpserver:${prometheusVersion}"
|
"io.prometheus:simpleclient_httpserver:${prometheusVersion}",
|
||||||
|
"org.apache.logging.log4j:log4j-core:2.11.1"
|
||||||
|
|
||||||
runtime "io.opencensus:opencensus-impl:${opencensusVersion}",
|
runtime "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}",
|
||||||
|
"com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}",
|
||||||
|
"io.opencensus:opencensus-contrib-log-correlation-log4j2:${opencensusVersion}",
|
||||||
|
"io.opencensus:opencensus-impl:${opencensusVersion}",
|
||||||
"io.netty:netty-tcnative-boringssl-static:2.0.8.Final"
|
"io.netty:netty-tcnative-boringssl-static:2.0.8.Final"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +111,8 @@ task adService(type: CreateStartScripts) {
|
||||||
applicationName = 'AdService'
|
applicationName = 'AdService'
|
||||||
outputDir = new File(project.buildDir, 'tmp')
|
outputDir = new File(project.buildDir, 'tmp')
|
||||||
classpath = jar.outputs.files + project.configurations.runtime
|
classpath = jar.outputs.files + project.configurations.runtime
|
||||||
|
defaultJvmOpts =
|
||||||
|
["-Dlog4j2.contextDataInjector=io.opencensus.contrib.logcorrelation.log4j2.OpenCensusTraceContextDataInjector"]
|
||||||
}
|
}
|
||||||
|
|
||||||
task adServiceClient(type: CreateStartScripts) {
|
task adServiceClient(type: CreateStartScripts) {
|
||||||
|
@ -113,6 +120,8 @@ task adServiceClient(type: CreateStartScripts) {
|
||||||
applicationName = 'AdServiceClient'
|
applicationName = 'AdServiceClient'
|
||||||
outputDir = new File(project.buildDir, 'tmp')
|
outputDir = new File(project.buildDir, 'tmp')
|
||||||
classpath = jar.outputs.files + project.configurations.runtime
|
classpath = jar.outputs.files + project.configurations.runtime
|
||||||
|
defaultJvmOpts =
|
||||||
|
["-Dlog4j2.contextDataInjector=io.opencensus.contrib.logcorrelation.log4j2.OpenCensusTraceContextDataInjector"]
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationDistribution.into('bin') {
|
applicationDistribution.into('bin') {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
package hipstershop;
|
package hipstershop;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableListMultimap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import hipstershop.Demo.Ad;
|
import hipstershop.Demo.Ad;
|
||||||
import hipstershop.Demo.AdRequest;
|
import hipstershop.Demo.AdRequest;
|
||||||
import hipstershop.Demo.AdResponse;
|
import hipstershop.Demo.AdResponse;
|
||||||
|
@ -42,16 +44,18 @@ import io.opencensus.trace.Tracer;
|
||||||
import io.opencensus.trace.Tracing;
|
import io.opencensus.trace.Tracing;
|
||||||
import io.opencensus.trace.samplers.Samplers;
|
import io.opencensus.trace.samplers.Samplers;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import java.util.logging.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
public class AdService {
|
public class AdService {
|
||||||
private static final Logger logger = Logger.getLogger(AdService.class.getName());
|
private static final Logger logger = LogManager.getLogger(AdService.class);
|
||||||
|
|
||||||
private static final Tracer tracer = Tracing.getTracer();
|
private static final Tracer tracer = Tracing.getTracer();
|
||||||
|
|
||||||
|
@ -109,8 +113,8 @@ public class AdService {
|
||||||
try (Scope scope = spanBuilder.startScopedSpan()) {
|
try (Scope scope = spanBuilder.startScopedSpan()) {
|
||||||
Span span = tracer.getCurrentSpan();
|
Span span = tracer.getCurrentSpan();
|
||||||
span.putAttribute("method", AttributeValue.stringAttributeValue("getAds"));
|
span.putAttribute("method", AttributeValue.stringAttributeValue("getAds"));
|
||||||
List<Ad> ads = new ArrayList<>();
|
List<Ad> allAds = new ArrayList<>();
|
||||||
logger.info("received ad request (context_words=" + req.getContextKeysCount() + ")");
|
logger.info("received ad request (context_words=" + req.getContextKeysList() + ")");
|
||||||
if (req.getContextKeysCount() > 0) {
|
if (req.getContextKeysCount() > 0) {
|
||||||
span.addAnnotation(
|
span.addAnnotation(
|
||||||
"Constructing Ads using context",
|
"Constructing Ads using context",
|
||||||
|
@ -120,42 +124,41 @@ public class AdService {
|
||||||
"Context Keys length",
|
"Context Keys length",
|
||||||
AttributeValue.longAttributeValue(req.getContextKeysCount())));
|
AttributeValue.longAttributeValue(req.getContextKeysCount())));
|
||||||
for (int i = 0; i < req.getContextKeysCount(); i++) {
|
for (int i = 0; i < req.getContextKeysCount(); i++) {
|
||||||
Ad ad = service.getAdsByKey(req.getContextKeys(i));
|
Collection<Ad> ads = service.getAdsByCategory(req.getContextKeys(i));
|
||||||
if (ad != null) {
|
allAds.addAll(ads);
|
||||||
ads.add(ad);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
span.addAnnotation("No Context provided. Constructing random Ads.");
|
span.addAnnotation("No Context provided. Constructing random Ads.");
|
||||||
ads = service.getDefaultAds();
|
allAds = service.getRandomAds();
|
||||||
}
|
}
|
||||||
if (ads.isEmpty()) {
|
if (allAds.isEmpty()) {
|
||||||
// Serve default ads.
|
// Serve random ads.
|
||||||
span.addAnnotation("No Ads found based on context. Constructing random Ads.");
|
span.addAnnotation("No Ads found based on context. Constructing random Ads.");
|
||||||
ads = service.getDefaultAds();
|
allAds = service.getRandomAds();
|
||||||
}
|
}
|
||||||
AdResponse reply = AdResponse.newBuilder().addAllAds(ads).build();
|
AdResponse reply = AdResponse.newBuilder().addAllAds(allAds).build();
|
||||||
responseObserver.onNext(reply);
|
responseObserver.onNext(reply);
|
||||||
responseObserver.onCompleted();
|
responseObserver.onCompleted();
|
||||||
} catch (StatusRuntimeException e) {
|
} catch (StatusRuntimeException e) {
|
||||||
logger.log(Level.WARNING, "GetAds Failed", e.getStatus());
|
logger.log(Level.WARN, "GetAds Failed", e.getStatus());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final HashMap<String, Ad> cacheMap = new HashMap<String, Ad>();
|
static final ImmutableListMultimap<String, Ad> adsMap = createAdsMap();
|
||||||
|
|
||||||
Ad getAdsByKey(String key) {
|
Collection<Ad> getAdsByCategory(String category) {
|
||||||
return cacheMap.get(key);
|
return adsMap.get(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Random random = new Random();
|
||||||
|
|
||||||
public List<Ad> getDefaultAds() {
|
public List<Ad> getRandomAds() {
|
||||||
List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
|
List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
|
||||||
Object[] keys = cacheMap.keySet().toArray();
|
Collection<Ad> allAds = adsMap.values();
|
||||||
for (int i=0; i<MAX_ADS_TO_SERVE; i++) {
|
for (int i=0; i<MAX_ADS_TO_SERVE; i++) {
|
||||||
ads.add(cacheMap.get(keys[new Random().nextInt(keys.length)]));
|
ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));
|
||||||
}
|
}
|
||||||
return ads;
|
return ads;
|
||||||
}
|
}
|
||||||
|
@ -171,14 +174,28 @@ public class AdService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initializeAds() {
|
static ImmutableListMultimap<String, Ad> createAdsMap() {
|
||||||
cacheMap.put("camera", Ad.newBuilder().setRedirectUrl( "/product/2ZYFJ3GM2N")
|
Ad camera = Ad.newBuilder().setRedirectUrl("/product/2ZYFJ3GM2N")
|
||||||
.setText("Film camera for sale. 50% off.").build());
|
.setText("Film camera for sale. 50% off.").build();
|
||||||
cacheMap.put("bike", Ad.newBuilder().setRedirectUrl("/product/9SIQT8TOJO")
|
Ad lens = Ad.newBuilder().setRedirectUrl("/product/66VCHSJNUP")
|
||||||
.setText("City Bike for sale. 10% off.").build());
|
.setText("Vintage camera lens for sale. 20% off.").build();
|
||||||
cacheMap.put("kitchen", Ad.newBuilder().setRedirectUrl("/product/1YMWWN1N4O")
|
Ad recordPlayer = Ad.newBuilder().setRedirectUrl("/product/0PUK6V6EV0")
|
||||||
.setText("Home Barista kitchen kit for sale. Buy one, get second kit for free").build());
|
.setText("Vintage record player for sale. 30% off.").build();
|
||||||
logger.info("Default Ads initialized");
|
Ad bike = Ad.newBuilder().setRedirectUrl("/product/9SIQT8TOJO")
|
||||||
|
.setText("City Bike for sale. 10% off.").build();
|
||||||
|
Ad baristaKit = Ad.newBuilder().setRedirectUrl("/product/1YMWWN1N4O")
|
||||||
|
.setText("Home Barista kitchen kit for sale. Buy one, get second kit for free").build();
|
||||||
|
Ad airPlant = Ad.newBuilder().setRedirectUrl("/product/6E92ZMYYFZ")
|
||||||
|
.setText("Air plants for sale. Buy two, get third one for free").build();
|
||||||
|
Ad terrarium = Ad.newBuilder().setRedirectUrl("/product/L9ECAV7KIM")
|
||||||
|
.setText("Terrarium for sale. Buy one, get second one for free").build();
|
||||||
|
return ImmutableListMultimap.<String, Ad>builder()
|
||||||
|
.putAll("photography", camera, lens)
|
||||||
|
.putAll("vintage", camera, lens, recordPlayer)
|
||||||
|
.put("cycling", bike)
|
||||||
|
.put("cookware", baristaKit)
|
||||||
|
.putAll("gardening", airPlant, terrarium)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initStackdriver() {
|
public static void initStackdriver() {
|
||||||
|
@ -202,7 +219,7 @@ public class AdService {
|
||||||
.build());
|
.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (i==(maxAttempts-1)) {
|
if (i==(maxAttempts-1)) {
|
||||||
logger.log(Level.WARNING, "Failed to register Stackdriver Exporter." +
|
logger.log(Level.WARN, "Failed to register Stackdriver Exporter." +
|
||||||
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
|
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
|
||||||
.toString());
|
.toString());
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,7 +227,7 @@ public class AdService {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
|
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
|
||||||
} catch (Exception se) {
|
} catch (Exception se) {
|
||||||
logger.log(Level.WARNING, "Exception while sleeping" + se.toString());
|
logger.log(Level.WARN, "Exception while sleeping" + se.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,8 +239,6 @@ public class AdService {
|
||||||
public static void main(String[] args) throws IOException, InterruptedException {
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
// Add final keyword to pass checkStyle.
|
// Add final keyword to pass checkStyle.
|
||||||
|
|
||||||
initializeAds();
|
|
||||||
|
|
||||||
new Thread( new Runnable() {
|
new Thread( new Runnable() {
|
||||||
public void run(){
|
public void run(){
|
||||||
initStackdriver();
|
initStackdriver();
|
||||||
|
|
|
@ -38,13 +38,14 @@ import io.opencensus.trace.Tracing;
|
||||||
import io.opencensus.trace.samplers.Samplers;
|
import io.opencensus.trace.samplers.Samplers;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
/** A simple client that requests ads from the Ads Service. */
|
/** A simple client that requests ads from the Ads Service. */
|
||||||
public class AdServiceClient {
|
public class AdServiceClient {
|
||||||
private static final Logger logger = Logger.getLogger(AdServiceClient.class.getName());
|
private static final Logger logger = LogManager.getLogger(AdServiceClient.class);
|
||||||
|
|
||||||
private static final Tracer tracer = Tracing.getTracer();
|
private static final Tracer tracer = Tracing.getTracer();
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ public class AdServiceClient {
|
||||||
CanonicalCode.valueOf(e.getStatus().getCode().name())
|
CanonicalCode.valueOf(e.getStatus().getCode().name())
|
||||||
.toStatus()
|
.toStatus()
|
||||||
.withDescription(e.getMessage()));
|
.withDescription(e.getMessage()));
|
||||||
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
|
logger.log(Level.WARN, "RPC failed: {0}", e.getStatus());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(Ad ads: response.getAdsList()) {
|
for(Ad ads: response.getAdsList()) {
|
||||||
|
@ -104,7 +105,7 @@ public class AdServiceClient {
|
||||||
try {
|
try {
|
||||||
portNumber = Integer.parseInt(args[index]);
|
portNumber = Integer.parseInt(args[index]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
logger.warning(
|
logger.warn(
|
||||||
String.format("Port %s is invalid, use default port %d.", args[index], defaultPort));
|
String.format("Port %s is invalid, use default port %d.", args[index], defaultPort));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +157,7 @@ public class AdServiceClient {
|
||||||
.build());
|
.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (i==(maxAttempts-1)) {
|
if (i==(maxAttempts-1)) {
|
||||||
logger.log(Level.WARNING, "Failed to register Stackdriver Exporter." +
|
logger.log(Level.WARN, "Failed to register Stackdriver Exporter." +
|
||||||
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
|
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e
|
||||||
.toString());
|
.toString());
|
||||||
} else {
|
} else {
|
||||||
|
@ -164,7 +165,7 @@ public class AdServiceClient {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
|
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
|
||||||
} catch (Exception se) {
|
} catch (Exception se) {
|
||||||
logger.log(Level.WARNING, "Exception while sleeping" + e.toString());
|
logger.log(Level.WARN, "Exception while sleeping" + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,10 @@ message Product {
|
||||||
string description = 3;
|
string description = 3;
|
||||||
string picture = 4;
|
string picture = 4;
|
||||||
Money price_usd = 5;
|
Money price_usd = 5;
|
||||||
|
|
||||||
|
// Categories such as "vintage" or "gardening" that can be used to look up
|
||||||
|
// other related products.
|
||||||
|
repeated string categories = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListProductsResponse {
|
message ListProductsResponse {
|
||||||
|
|
24
src/adservice/src/main/resources/log4j2.xml
Normal file
24
src/adservice/src/main/resources/log4j2.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="WARN">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="STDOUT" target="SYSTEM_OUT">
|
||||||
|
|
||||||
|
<!-- This is a JSON format that can be read by the Stackdriver Logging agent. The trace and
|
||||||
|
span IDs are interpreted by Stackdriver, and "traceSampled" is a custom field. -->
|
||||||
|
<JsonLayout compact="true" eventEol="true">
|
||||||
|
<KeyValuePair key="logging.googleapis.com/trace" value="$${ctx:opencensusTraceId}"/>
|
||||||
|
<KeyValuePair key="logging.googleapis.com/spanId" value="$${ctx:opencensusSpanId}"/>
|
||||||
|
<KeyValuePair key="traceSampled" value="$${ctx:opencensusTraceSampled}"/>
|
||||||
|
</JsonLayout>
|
||||||
|
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Logger name="io.grpc.netty" level="INFO"/>
|
||||||
|
<Logger name="io.netty" level="INFO"/>
|
||||||
|
<Logger name="sun.net" level="INFO"/>
|
||||||
|
<Root level="TRACE">
|
||||||
|
<AppenderRef ref="STDOUT"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
|
@ -1,13 +1,3 @@
|
||||||
FROM golang:1.10 as probe
|
|
||||||
RUN wget -qO/go/bin/dep https://github.com/golang/dep/releases/download/v0.5.0/dep-linux-amd64 && \
|
|
||||||
chmod +x /go/bin/dep
|
|
||||||
ENV PROJECT github.com/GoogleCloudPlatform/microservices-demo/src/cartservice/probe
|
|
||||||
WORKDIR /go/src/$PROJECT
|
|
||||||
COPY probe/Gopkg.* ./
|
|
||||||
RUN dep ensure --vendor-only -v
|
|
||||||
COPY ./probe ./
|
|
||||||
RUN go build -o /cartservice_probe .
|
|
||||||
|
|
||||||
FROM microsoft/dotnet:2.1-sdk-alpine as builder
|
FROM microsoft/dotnet:2.1-sdk-alpine as builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
@ -17,8 +7,11 @@ RUN dotnet restore && \
|
||||||
|
|
||||||
# cartservice
|
# cartservice
|
||||||
FROM alpine:3.8
|
FROM alpine:3.8
|
||||||
# Add the probe
|
|
||||||
COPY --from=probe /cartservice_probe /cartservice_probe
|
RUN GRPC_HEALTH_PROBE_VERSION=v0.1.0-alpha.1 && \
|
||||||
|
wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
|
||||||
|
chmod +x /bin/grpc_health_probe
|
||||||
|
|
||||||
# Dependencies for runtime
|
# Dependencies for runtime
|
||||||
# busybox-extras => telnet
|
# busybox-extras => telnet
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
|
@ -32,4 +25,4 @@ RUN apk add --no-cache \
|
||||||
icu
|
icu
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /cartservice .
|
COPY --from=builder /cartservice .
|
||||||
ENTRYPOINT ["./cartservice", "start"]
|
ENTRYPOINT ["./cartservice", "start"]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using cartservice.interfaces;
|
using cartservice.interfaces;
|
||||||
|
using Grpc.Core;
|
||||||
using Grpc.Health.V1;
|
using Grpc.Health.V1;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using static Grpc.Health.V1.Health;
|
using static Grpc.Health.V1.Health;
|
||||||
|
@ -11,12 +13,12 @@ namespace cartservice {
|
||||||
this.dependency = dependency;
|
this.dependency = dependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealthCheckResponse Check (HealthCheckRequest request) {
|
public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context){
|
||||||
Console.WriteLine ("Checking CartService Health");
|
Console.WriteLine ("Checking CartService Health");
|
||||||
|
|
||||||
return new HealthCheckResponse {
|
return Task.FromResult(new HealthCheckResponse {
|
||||||
Status = dependency.Ping() ? HealthCheckResponse.Types.ServingStatus.Serving : HealthCheckResponse.Types.ServingStatus.NotServing
|
Status = dependency.Ping() ? HealthCheckResponse.Types.ServingStatus.Serving : HealthCheckResponse.Types.ServingStatus.NotServing
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
|
||||||
<PackageReference Include="Google.Protobuf.Tools" Version="3.5.1" />
|
<PackageReference Include="Google.Protobuf.Tools" Version="3.5.1" />
|
||||||
<PackageReference Include="grpc" Version="1.12.0" />
|
<PackageReference Include="grpc" Version="1.12.0" />
|
||||||
<PackageReference Include="Grpc.HealthCheck" Version="1.15.0" />
|
<PackageReference Include="Grpc.HealthCheck" Version="1.12.0" />
|
||||||
<PackageReference Include="grpc.tools" Version="1.12.0" />
|
<PackageReference Include="grpc.tools" Version="1.12.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
vendor/
|
|
101
src/cartservice/probe/Gopkg.lock
generated
101
src/cartservice/probe/Gopkg.lock
generated
|
@ -1,101 +0,0 @@
|
||||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
|
||||||
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/golang/protobuf"
|
|
||||||
packages = [
|
|
||||||
"proto",
|
|
||||||
"ptypes",
|
|
||||||
"ptypes/any",
|
|
||||||
"ptypes/duration",
|
|
||||||
"ptypes/timestamp"
|
|
||||||
]
|
|
||||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
|
||||||
version = "v1.1.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "golang.org/x/net"
|
|
||||||
packages = [
|
|
||||||
"context",
|
|
||||||
"http/httpguts",
|
|
||||||
"http2",
|
|
||||||
"http2/hpack",
|
|
||||||
"idna",
|
|
||||||
"internal/timeseries",
|
|
||||||
"trace"
|
|
||||||
]
|
|
||||||
revision = "f4c29de78a2a91c00474a2e689954305c350adf9"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "golang.org/x/sys"
|
|
||||||
packages = ["unix"]
|
|
||||||
revision = "0ffbfd41fbef8ffcf9b62b0b0aa3a5873ed7a4fe"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "golang.org/x/text"
|
|
||||||
packages = [
|
|
||||||
"collate",
|
|
||||||
"collate/build",
|
|
||||||
"internal/colltab",
|
|
||||||
"internal/gen",
|
|
||||||
"internal/tag",
|
|
||||||
"internal/triegen",
|
|
||||||
"internal/ucd",
|
|
||||||
"language",
|
|
||||||
"secure/bidirule",
|
|
||||||
"transform",
|
|
||||||
"unicode/bidi",
|
|
||||||
"unicode/cldr",
|
|
||||||
"unicode/norm",
|
|
||||||
"unicode/rangetable"
|
|
||||||
]
|
|
||||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
|
||||||
version = "v0.3.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "google.golang.org/genproto"
|
|
||||||
packages = ["googleapis/rpc/status"]
|
|
||||||
revision = "daca94659cb50e9f37c1b834680f2e46358f10b0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "google.golang.org/grpc"
|
|
||||||
packages = [
|
|
||||||
".",
|
|
||||||
"balancer",
|
|
||||||
"balancer/base",
|
|
||||||
"balancer/roundrobin",
|
|
||||||
"codes",
|
|
||||||
"connectivity",
|
|
||||||
"credentials",
|
|
||||||
"encoding",
|
|
||||||
"encoding/proto",
|
|
||||||
"grpclog",
|
|
||||||
"internal",
|
|
||||||
"internal/backoff",
|
|
||||||
"internal/channelz",
|
|
||||||
"internal/envconfig",
|
|
||||||
"internal/grpcrand",
|
|
||||||
"internal/transport",
|
|
||||||
"keepalive",
|
|
||||||
"metadata",
|
|
||||||
"naming",
|
|
||||||
"peer",
|
|
||||||
"resolver",
|
|
||||||
"resolver/dns",
|
|
||||||
"resolver/passthrough",
|
|
||||||
"stats",
|
|
||||||
"status",
|
|
||||||
"tap"
|
|
||||||
]
|
|
||||||
revision = "32fb0ac620c32ba40a4626ddf94d90d12cce3455"
|
|
||||||
version = "v1.14.0"
|
|
||||||
|
|
||||||
[solve-meta]
|
|
||||||
analyzer-name = "dep"
|
|
||||||
analyzer-version = 1
|
|
||||||
inputs-digest = "8f3c07df5ebc7dc4d50ca8a6c274eef95f3045d33bbe5f384271fa87166a457e"
|
|
||||||
solver-name = "gps-cdcl"
|
|
||||||
solver-version = 1
|
|
|
@ -1,42 +0,0 @@
|
||||||
# Gopkg.toml example
|
|
||||||
#
|
|
||||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
|
||||||
# for detailed Gopkg.toml documentation.
|
|
||||||
#
|
|
||||||
# required = ["github.com/user/thing/cmd/thing"]
|
|
||||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project"
|
|
||||||
# version = "1.0.0"
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project2"
|
|
||||||
# branch = "dev"
|
|
||||||
# source = "github.com/myfork/project2"
|
|
||||||
#
|
|
||||||
# [[override]]
|
|
||||||
# name = "github.com/x/y"
|
|
||||||
# version = "2.4.0"
|
|
||||||
#
|
|
||||||
# [prune]
|
|
||||||
# non-go = false
|
|
||||||
# go-tests = true
|
|
||||||
# unused-packages = true
|
|
||||||
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/golang/protobuf"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "golang.org/x/net"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "google.golang.org/grpc"
|
|
||||||
version = "1.14.0"
|
|
||||||
|
|
||||||
[prune]
|
|
||||||
go-tests = true
|
|
||||||
unused-packages = true
|
|
|
@ -1,4 +0,0 @@
|
||||||
# cartservice Probe
|
|
||||||
|
|
||||||
This probe makes a call to the cartservice over localhost and exits to verify
|
|
||||||
liveness of the cartservice.
|
|
|
@ -1,22 +0,0 @@
|
||||||
#!/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
|
|
||||||
|
|
||||||
PATH=$PATH:$GOPATH/bin
|
|
||||||
protodir=../../../pb
|
|
||||||
|
|
||||||
protoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,51 +0,0 @@
|
||||||
// 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 main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
pb "github.com/GoogleCloudPlatform/microservices-demo/src/cartservice/probe/genproto"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
port := os.Getenv("PORT")
|
|
||||||
if port == "" {
|
|
||||||
log.Fatal("probe is executed without PORT env var")
|
|
||||||
}
|
|
||||||
log.Printf("probe executing on port %q", port)
|
|
||||||
|
|
||||||
conn, err := grpc.DialContext(context.TODO(),
|
|
||||||
"127.0.0.1:"+port,
|
|
||||||
grpc.WithBlock(),
|
|
||||||
grpc.WithTimeout(time.Second*3),
|
|
||||||
grpc.WithInsecure(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("probe failed: failed to connect: %+v", err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
if _, err := pb.NewCartServiceClient(conn).GetCart(context.TODO(),
|
|
||||||
&pb.GetCartRequest{UserId: "exec-probe-nonexistinguser"}); err != nil {
|
|
||||||
log.Fatalf("probe failed: failed to query: %+v", err)
|
|
||||||
}
|
|
||||||
log.Println("probe successful")
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -64,6 +64,10 @@ message Product {
|
||||||
string description = 3;
|
string description = 3;
|
||||||
string picture = 4;
|
string picture = 4;
|
||||||
Money price_usd = 5;
|
Money price_usd = 5;
|
||||||
|
|
||||||
|
// Categories such as "vintage" or "gardening" that can be used to look up
|
||||||
|
// other related products.
|
||||||
|
repeated string categories = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListProductsResponse {
|
message ListProductsResponse {
|
||||||
|
@ -218,18 +222,18 @@ message PlaceOrderResponse {
|
||||||
OrderResult order = 1;
|
OrderResult order = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------Ads service------------------
|
// ------------Ad service------------------
|
||||||
|
|
||||||
service AdsService {
|
service AdService {
|
||||||
rpc GetAds(AdsRequest) returns (AdsResponse) {}
|
rpc GetAds(AdRequest) returns (AdResponse) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message AdsRequest {
|
message AdRequest {
|
||||||
// List of important key words from the current page describing the context.
|
// List of important key words from the current page describing the context.
|
||||||
repeated string context_keys = 1;
|
repeated string context_keys = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AdsResponse {
|
message AdResponse {
|
||||||
repeated Ad ads = 1;
|
repeated Ad ads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
src/frontend/Gopkg.lock
generated
11
src/frontend/Gopkg.lock
generated
|
@ -26,17 +26,6 @@
|
||||||
revision = "37aa2801fbf0205003e15636096ebf0373510288"
|
revision = "37aa2801fbf0205003e15636096ebf0373510288"
|
||||||
version = "v0.5.0"
|
version = "v0.5.0"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:3ef905a7059a17712b7b27315692992f84f356e828d38f6ff0624e04103ec675"
|
|
||||||
name = "github.com/GoogleCloudPlatform/microservices-demo"
|
|
||||||
packages = [
|
|
||||||
"src/frontend/genproto",
|
|
||||||
"src/frontend/money",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "6d969441585ade8c91c235115c7cdb12ac61354f"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:72856926f8208767b837bf51e3373f49139f61889b67dc7fd3c2a0fd711e3f7a"
|
digest = "1:72856926f8208767b837bf51e3373f49139f61889b67dc7fd3c2a0fd711e3f7a"
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
|
|
|
@ -33,10 +33,6 @@
|
||||||
name = "contrib.go.opencensus.io/exporter/stackdriver"
|
name = "contrib.go.opencensus.io/exporter/stackdriver"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/GoogleCloudPlatform/microservices-demo"
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
|
|
||||||
package hipstershop
|
package hipstershop
|
||||||
|
|
||||||
import proto "github.com/golang/protobuf/proto"
|
import (
|
||||||
import fmt "fmt"
|
fmt "fmt"
|
||||||
import math "math"
|
proto "github.com/golang/protobuf/proto"
|
||||||
|
math "math"
|
||||||
|
)
|
||||||
|
|
||||||
import (
|
import (
|
||||||
context "golang.org/x/net/context"
|
context "golang.org/x/net/context"
|
||||||
|
@ -35,16 +37,17 @@ func (m *CartItem) Reset() { *m = CartItem{} }
|
||||||
func (m *CartItem) String() string { return proto.CompactTextString(m) }
|
func (m *CartItem) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CartItem) ProtoMessage() {}
|
func (*CartItem) ProtoMessage() {}
|
||||||
func (*CartItem) Descriptor() ([]byte, []int) {
|
func (*CartItem) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{0}
|
return fileDescriptor_ca53982754088a9d, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CartItem) XXX_Unmarshal(b []byte) error {
|
func (m *CartItem) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_CartItem.Unmarshal(m, b)
|
return xxx_messageInfo_CartItem.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_CartItem.Marshal(b, m, deterministic)
|
return xxx_messageInfo_CartItem.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *CartItem) XXX_Merge(src proto.Message) {
|
func (m *CartItem) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_CartItem.Merge(dst, src)
|
xxx_messageInfo_CartItem.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *CartItem) XXX_Size() int {
|
func (m *CartItem) XXX_Size() int {
|
||||||
return xxx_messageInfo_CartItem.Size(m)
|
return xxx_messageInfo_CartItem.Size(m)
|
||||||
|
@ -81,16 +84,17 @@ func (m *AddItemRequest) Reset() { *m = AddItemRequest{} }
|
||||||
func (m *AddItemRequest) String() string { return proto.CompactTextString(m) }
|
func (m *AddItemRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*AddItemRequest) ProtoMessage() {}
|
func (*AddItemRequest) ProtoMessage() {}
|
||||||
func (*AddItemRequest) Descriptor() ([]byte, []int) {
|
func (*AddItemRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{1}
|
return fileDescriptor_ca53982754088a9d, []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AddItemRequest) XXX_Unmarshal(b []byte) error {
|
func (m *AddItemRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_AddItemRequest.Unmarshal(m, b)
|
return xxx_messageInfo_AddItemRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *AddItemRequest) XXX_Merge(src proto.Message) {
|
func (m *AddItemRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_AddItemRequest.Merge(dst, src)
|
xxx_messageInfo_AddItemRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *AddItemRequest) XXX_Size() int {
|
func (m *AddItemRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_AddItemRequest.Size(m)
|
return xxx_messageInfo_AddItemRequest.Size(m)
|
||||||
|
@ -126,16 +130,17 @@ func (m *EmptyCartRequest) Reset() { *m = EmptyCartRequest{} }
|
||||||
func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }
|
func (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*EmptyCartRequest) ProtoMessage() {}
|
func (*EmptyCartRequest) ProtoMessage() {}
|
||||||
func (*EmptyCartRequest) Descriptor() ([]byte, []int) {
|
func (*EmptyCartRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{2}
|
return fileDescriptor_ca53982754088a9d, []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {
|
func (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)
|
return xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *EmptyCartRequest) XXX_Merge(src proto.Message) {
|
func (m *EmptyCartRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_EmptyCartRequest.Merge(dst, src)
|
xxx_messageInfo_EmptyCartRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *EmptyCartRequest) XXX_Size() int {
|
func (m *EmptyCartRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_EmptyCartRequest.Size(m)
|
return xxx_messageInfo_EmptyCartRequest.Size(m)
|
||||||
|
@ -164,16 +169,17 @@ func (m *GetCartRequest) Reset() { *m = GetCartRequest{} }
|
||||||
func (m *GetCartRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GetCartRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetCartRequest) ProtoMessage() {}
|
func (*GetCartRequest) ProtoMessage() {}
|
||||||
func (*GetCartRequest) Descriptor() ([]byte, []int) {
|
func (*GetCartRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{3}
|
return fileDescriptor_ca53982754088a9d, []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GetCartRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GetCartRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetCartRequest.Unmarshal(m, b)
|
return xxx_messageInfo_GetCartRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *GetCartRequest) XXX_Merge(src proto.Message) {
|
func (m *GetCartRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_GetCartRequest.Merge(dst, src)
|
xxx_messageInfo_GetCartRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *GetCartRequest) XXX_Size() int {
|
func (m *GetCartRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_GetCartRequest.Size(m)
|
return xxx_messageInfo_GetCartRequest.Size(m)
|
||||||
|
@ -203,16 +209,17 @@ func (m *Cart) Reset() { *m = Cart{} }
|
||||||
func (m *Cart) String() string { return proto.CompactTextString(m) }
|
func (m *Cart) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Cart) ProtoMessage() {}
|
func (*Cart) ProtoMessage() {}
|
||||||
func (*Cart) Descriptor() ([]byte, []int) {
|
func (*Cart) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{4}
|
return fileDescriptor_ca53982754088a9d, []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Cart) XXX_Unmarshal(b []byte) error {
|
func (m *Cart) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Cart.Unmarshal(m, b)
|
return xxx_messageInfo_Cart.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Cart.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Cart.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Cart) XXX_Merge(src proto.Message) {
|
func (m *Cart) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Cart.Merge(dst, src)
|
xxx_messageInfo_Cart.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Cart) XXX_Size() int {
|
func (m *Cart) XXX_Size() int {
|
||||||
return xxx_messageInfo_Cart.Size(m)
|
return xxx_messageInfo_Cart.Size(m)
|
||||||
|
@ -247,16 +254,17 @@ func (m *Empty) Reset() { *m = Empty{} }
|
||||||
func (m *Empty) String() string { return proto.CompactTextString(m) }
|
func (m *Empty) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Empty) ProtoMessage() {}
|
func (*Empty) ProtoMessage() {}
|
||||||
func (*Empty) Descriptor() ([]byte, []int) {
|
func (*Empty) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{5}
|
return fileDescriptor_ca53982754088a9d, []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Empty) XXX_Unmarshal(b []byte) error {
|
func (m *Empty) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Empty.Unmarshal(m, b)
|
return xxx_messageInfo_Empty.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Empty) XXX_Merge(src proto.Message) {
|
func (m *Empty) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Empty.Merge(dst, src)
|
xxx_messageInfo_Empty.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Empty) XXX_Size() int {
|
func (m *Empty) XXX_Size() int {
|
||||||
return xxx_messageInfo_Empty.Size(m)
|
return xxx_messageInfo_Empty.Size(m)
|
||||||
|
@ -279,16 +287,17 @@ func (m *ListRecommendationsRequest) Reset() { *m = ListRecommendationsR
|
||||||
func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListRecommendationsRequest) ProtoMessage() {}
|
func (*ListRecommendationsRequest) ProtoMessage() {}
|
||||||
func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {
|
func (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{6}
|
return fileDescriptor_ca53982754088a9d, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)
|
return xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ListRecommendationsRequest) XXX_Merge(src proto.Message) {
|
func (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ListRecommendationsRequest.Merge(dst, src)
|
xxx_messageInfo_ListRecommendationsRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ListRecommendationsRequest) XXX_Size() int {
|
func (m *ListRecommendationsRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_ListRecommendationsRequest.Size(m)
|
return xxx_messageInfo_ListRecommendationsRequest.Size(m)
|
||||||
|
@ -324,16 +333,17 @@ func (m *ListRecommendationsResponse) Reset() { *m = ListRecommendations
|
||||||
func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListRecommendationsResponse) ProtoMessage() {}
|
func (*ListRecommendationsResponse) ProtoMessage() {}
|
||||||
func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {
|
func (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{7}
|
return fileDescriptor_ca53982754088a9d, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)
|
return xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ListRecommendationsResponse) XXX_Merge(src proto.Message) {
|
func (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ListRecommendationsResponse.Merge(dst, src)
|
xxx_messageInfo_ListRecommendationsResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ListRecommendationsResponse) XXX_Size() int {
|
func (m *ListRecommendationsResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_ListRecommendationsResponse.Size(m)
|
return xxx_messageInfo_ListRecommendationsResponse.Size(m)
|
||||||
|
@ -352,11 +362,14 @@ func (m *ListRecommendationsResponse) GetProductIds() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Product struct {
|
type Product struct {
|
||||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,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"`
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,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"`
|
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"`
|
PriceUsd *Money `protobuf:"bytes,5,opt,name=price_usd,json=priceUsd,proto3" json:"price_usd,omitempty"`
|
||||||
|
// Categories such as "vintage" or "gardening" that can be used to look up
|
||||||
|
// other related products.
|
||||||
|
Categories []string `protobuf:"bytes,6,rep,name=categories,proto3" json:"categories,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -366,16 +379,17 @@ func (m *Product) Reset() { *m = Product{} }
|
||||||
func (m *Product) String() string { return proto.CompactTextString(m) }
|
func (m *Product) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Product) ProtoMessage() {}
|
func (*Product) ProtoMessage() {}
|
||||||
func (*Product) Descriptor() ([]byte, []int) {
|
func (*Product) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{8}
|
return fileDescriptor_ca53982754088a9d, []int{8}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Product) XXX_Unmarshal(b []byte) error {
|
func (m *Product) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Product.Unmarshal(m, b)
|
return xxx_messageInfo_Product.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Product.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Product.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Product) XXX_Merge(src proto.Message) {
|
func (m *Product) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Product.Merge(dst, src)
|
xxx_messageInfo_Product.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Product) XXX_Size() int {
|
func (m *Product) XXX_Size() int {
|
||||||
return xxx_messageInfo_Product.Size(m)
|
return xxx_messageInfo_Product.Size(m)
|
||||||
|
@ -421,6 +435,13 @@ func (m *Product) GetPriceUsd() *Money {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Product) GetCategories() []string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Categories
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ListProductsResponse struct {
|
type ListProductsResponse struct {
|
||||||
Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"`
|
Products []*Product `protobuf:"bytes,1,rep,name=products,proto3" json:"products,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
@ -432,16 +453,17 @@ func (m *ListProductsResponse) Reset() { *m = ListProductsResponse{} }
|
||||||
func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ListProductsResponse) ProtoMessage() {}
|
func (*ListProductsResponse) ProtoMessage() {}
|
||||||
func (*ListProductsResponse) Descriptor() ([]byte, []int) {
|
func (*ListProductsResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{9}
|
return fileDescriptor_ca53982754088a9d, []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)
|
return xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ListProductsResponse) XXX_Merge(src proto.Message) {
|
func (m *ListProductsResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ListProductsResponse.Merge(dst, src)
|
xxx_messageInfo_ListProductsResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ListProductsResponse) XXX_Size() int {
|
func (m *ListProductsResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_ListProductsResponse.Size(m)
|
return xxx_messageInfo_ListProductsResponse.Size(m)
|
||||||
|
@ -470,16 +492,17 @@ func (m *GetProductRequest) Reset() { *m = GetProductRequest{} }
|
||||||
func (m *GetProductRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GetProductRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetProductRequest) ProtoMessage() {}
|
func (*GetProductRequest) ProtoMessage() {}
|
||||||
func (*GetProductRequest) Descriptor() ([]byte, []int) {
|
func (*GetProductRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{10}
|
return fileDescriptor_ca53982754088a9d, []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GetProductRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GetProductRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetProductRequest.Unmarshal(m, b)
|
return xxx_messageInfo_GetProductRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *GetProductRequest) XXX_Merge(src proto.Message) {
|
func (m *GetProductRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_GetProductRequest.Merge(dst, src)
|
xxx_messageInfo_GetProductRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *GetProductRequest) XXX_Size() int {
|
func (m *GetProductRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_GetProductRequest.Size(m)
|
return xxx_messageInfo_GetProductRequest.Size(m)
|
||||||
|
@ -508,16 +531,17 @@ func (m *SearchProductsRequest) Reset() { *m = SearchProductsRequest{} }
|
||||||
func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }
|
func (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*SearchProductsRequest) ProtoMessage() {}
|
func (*SearchProductsRequest) ProtoMessage() {}
|
||||||
func (*SearchProductsRequest) Descriptor() ([]byte, []int) {
|
func (*SearchProductsRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{11}
|
return fileDescriptor_ca53982754088a9d, []int{11}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {
|
func (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)
|
return xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *SearchProductsRequest) XXX_Merge(src proto.Message) {
|
func (m *SearchProductsRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_SearchProductsRequest.Merge(dst, src)
|
xxx_messageInfo_SearchProductsRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *SearchProductsRequest) XXX_Size() int {
|
func (m *SearchProductsRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_SearchProductsRequest.Size(m)
|
return xxx_messageInfo_SearchProductsRequest.Size(m)
|
||||||
|
@ -546,16 +570,17 @@ func (m *SearchProductsResponse) Reset() { *m = SearchProductsResponse{}
|
||||||
func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }
|
func (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*SearchProductsResponse) ProtoMessage() {}
|
func (*SearchProductsResponse) ProtoMessage() {}
|
||||||
func (*SearchProductsResponse) Descriptor() ([]byte, []int) {
|
func (*SearchProductsResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{12}
|
return fileDescriptor_ca53982754088a9d, []int{12}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {
|
func (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)
|
return xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *SearchProductsResponse) XXX_Merge(src proto.Message) {
|
func (m *SearchProductsResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_SearchProductsResponse.Merge(dst, src)
|
xxx_messageInfo_SearchProductsResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *SearchProductsResponse) XXX_Size() int {
|
func (m *SearchProductsResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_SearchProductsResponse.Size(m)
|
return xxx_messageInfo_SearchProductsResponse.Size(m)
|
||||||
|
@ -585,16 +610,17 @@ func (m *GetQuoteRequest) Reset() { *m = GetQuoteRequest{} }
|
||||||
func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetQuoteRequest) ProtoMessage() {}
|
func (*GetQuoteRequest) ProtoMessage() {}
|
||||||
func (*GetQuoteRequest) Descriptor() ([]byte, []int) {
|
func (*GetQuoteRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{13}
|
return fileDescriptor_ca53982754088a9d, []int{13}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)
|
return xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *GetQuoteRequest) XXX_Merge(src proto.Message) {
|
func (m *GetQuoteRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_GetQuoteRequest.Merge(dst, src)
|
xxx_messageInfo_GetQuoteRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *GetQuoteRequest) XXX_Size() int {
|
func (m *GetQuoteRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_GetQuoteRequest.Size(m)
|
return xxx_messageInfo_GetQuoteRequest.Size(m)
|
||||||
|
@ -630,16 +656,17 @@ func (m *GetQuoteResponse) Reset() { *m = GetQuoteResponse{} }
|
||||||
func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }
|
func (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetQuoteResponse) ProtoMessage() {}
|
func (*GetQuoteResponse) ProtoMessage() {}
|
||||||
func (*GetQuoteResponse) Descriptor() ([]byte, []int) {
|
func (*GetQuoteResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{14}
|
return fileDescriptor_ca53982754088a9d, []int{14}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {
|
func (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)
|
return xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *GetQuoteResponse) XXX_Merge(src proto.Message) {
|
func (m *GetQuoteResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_GetQuoteResponse.Merge(dst, src)
|
xxx_messageInfo_GetQuoteResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *GetQuoteResponse) XXX_Size() int {
|
func (m *GetQuoteResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_GetQuoteResponse.Size(m)
|
return xxx_messageInfo_GetQuoteResponse.Size(m)
|
||||||
|
@ -669,16 +696,17 @@ func (m *ShipOrderRequest) Reset() { *m = ShipOrderRequest{} }
|
||||||
func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ShipOrderRequest) ProtoMessage() {}
|
func (*ShipOrderRequest) ProtoMessage() {}
|
||||||
func (*ShipOrderRequest) Descriptor() ([]byte, []int) {
|
func (*ShipOrderRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{15}
|
return fileDescriptor_ca53982754088a9d, []int{15}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)
|
return xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ShipOrderRequest) XXX_Merge(src proto.Message) {
|
func (m *ShipOrderRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ShipOrderRequest.Merge(dst, src)
|
xxx_messageInfo_ShipOrderRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ShipOrderRequest) XXX_Size() int {
|
func (m *ShipOrderRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_ShipOrderRequest.Size(m)
|
return xxx_messageInfo_ShipOrderRequest.Size(m)
|
||||||
|
@ -714,16 +742,17 @@ func (m *ShipOrderResponse) Reset() { *m = ShipOrderResponse{} }
|
||||||
func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ShipOrderResponse) ProtoMessage() {}
|
func (*ShipOrderResponse) ProtoMessage() {}
|
||||||
func (*ShipOrderResponse) Descriptor() ([]byte, []int) {
|
func (*ShipOrderResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{16}
|
return fileDescriptor_ca53982754088a9d, []int{16}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)
|
return xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ShipOrderResponse) XXX_Merge(src proto.Message) {
|
func (m *ShipOrderResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ShipOrderResponse.Merge(dst, src)
|
xxx_messageInfo_ShipOrderResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ShipOrderResponse) XXX_Size() int {
|
func (m *ShipOrderResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_ShipOrderResponse.Size(m)
|
return xxx_messageInfo_ShipOrderResponse.Size(m)
|
||||||
|
@ -756,16 +785,17 @@ func (m *Address) Reset() { *m = Address{} }
|
||||||
func (m *Address) String() string { return proto.CompactTextString(m) }
|
func (m *Address) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Address) ProtoMessage() {}
|
func (*Address) ProtoMessage() {}
|
||||||
func (*Address) Descriptor() ([]byte, []int) {
|
func (*Address) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{17}
|
return fileDescriptor_ca53982754088a9d, []int{17}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Address) XXX_Unmarshal(b []byte) error {
|
func (m *Address) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Address.Unmarshal(m, b)
|
return xxx_messageInfo_Address.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Address.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Address.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Address) XXX_Merge(src proto.Message) {
|
func (m *Address) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Address.Merge(dst, src)
|
xxx_messageInfo_Address.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Address) XXX_Size() int {
|
func (m *Address) XXX_Size() int {
|
||||||
return xxx_messageInfo_Address.Size(m)
|
return xxx_messageInfo_Address.Size(m)
|
||||||
|
@ -834,16 +864,17 @@ func (m *Money) Reset() { *m = Money{} }
|
||||||
func (m *Money) String() string { return proto.CompactTextString(m) }
|
func (m *Money) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Money) ProtoMessage() {}
|
func (*Money) ProtoMessage() {}
|
||||||
func (*Money) Descriptor() ([]byte, []int) {
|
func (*Money) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{18}
|
return fileDescriptor_ca53982754088a9d, []int{18}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Money) XXX_Unmarshal(b []byte) error {
|
func (m *Money) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Money.Unmarshal(m, b)
|
return xxx_messageInfo_Money.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Money.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Money.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Money) XXX_Merge(src proto.Message) {
|
func (m *Money) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Money.Merge(dst, src)
|
xxx_messageInfo_Money.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Money) XXX_Size() int {
|
func (m *Money) XXX_Size() int {
|
||||||
return xxx_messageInfo_Money.Size(m)
|
return xxx_messageInfo_Money.Size(m)
|
||||||
|
@ -887,16 +918,17 @@ func (m *GetSupportedCurrenciesResponse) Reset() { *m = GetSupportedCurr
|
||||||
func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GetSupportedCurrenciesResponse) ProtoMessage() {}
|
func (*GetSupportedCurrenciesResponse) ProtoMessage() {}
|
||||||
func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {
|
func (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{19}
|
return fileDescriptor_ca53982754088a9d, []int{19}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)
|
return xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {
|
func (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(dst, src)
|
xxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *GetSupportedCurrenciesResponse) XXX_Size() int {
|
func (m *GetSupportedCurrenciesResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)
|
return xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)
|
||||||
|
@ -927,16 +959,17 @@ func (m *CurrencyConversionRequest) Reset() { *m = CurrencyConversionReq
|
||||||
func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }
|
func (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CurrencyConversionRequest) ProtoMessage() {}
|
func (*CurrencyConversionRequest) ProtoMessage() {}
|
||||||
func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {
|
func (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{20}
|
return fileDescriptor_ca53982754088a9d, []int{20}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {
|
func (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)
|
return xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *CurrencyConversionRequest) XXX_Merge(src proto.Message) {
|
func (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_CurrencyConversionRequest.Merge(dst, src)
|
xxx_messageInfo_CurrencyConversionRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *CurrencyConversionRequest) XXX_Size() int {
|
func (m *CurrencyConversionRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_CurrencyConversionRequest.Size(m)
|
return xxx_messageInfo_CurrencyConversionRequest.Size(m)
|
||||||
|
@ -975,16 +1008,17 @@ func (m *CreditCardInfo) Reset() { *m = CreditCardInfo{} }
|
||||||
func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }
|
func (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CreditCardInfo) ProtoMessage() {}
|
func (*CreditCardInfo) ProtoMessage() {}
|
||||||
func (*CreditCardInfo) Descriptor() ([]byte, []int) {
|
func (*CreditCardInfo) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{21}
|
return fileDescriptor_ca53982754088a9d, []int{21}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {
|
func (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)
|
return xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)
|
return xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *CreditCardInfo) XXX_Merge(src proto.Message) {
|
func (m *CreditCardInfo) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_CreditCardInfo.Merge(dst, src)
|
xxx_messageInfo_CreditCardInfo.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *CreditCardInfo) XXX_Size() int {
|
func (m *CreditCardInfo) XXX_Size() int {
|
||||||
return xxx_messageInfo_CreditCardInfo.Size(m)
|
return xxx_messageInfo_CreditCardInfo.Size(m)
|
||||||
|
@ -1035,16 +1069,17 @@ func (m *ChargeRequest) Reset() { *m = ChargeRequest{} }
|
||||||
func (m *ChargeRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ChargeRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ChargeRequest) ProtoMessage() {}
|
func (*ChargeRequest) ProtoMessage() {}
|
||||||
func (*ChargeRequest) Descriptor() ([]byte, []int) {
|
func (*ChargeRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{22}
|
return fileDescriptor_ca53982754088a9d, []int{22}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ChargeRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ChargeRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ChargeRequest.Unmarshal(m, b)
|
return xxx_messageInfo_ChargeRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ChargeRequest) XXX_Merge(src proto.Message) {
|
func (m *ChargeRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ChargeRequest.Merge(dst, src)
|
xxx_messageInfo_ChargeRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ChargeRequest) XXX_Size() int {
|
func (m *ChargeRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_ChargeRequest.Size(m)
|
return xxx_messageInfo_ChargeRequest.Size(m)
|
||||||
|
@ -1080,16 +1115,17 @@ func (m *ChargeResponse) Reset() { *m = ChargeResponse{} }
|
||||||
func (m *ChargeResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ChargeResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ChargeResponse) ProtoMessage() {}
|
func (*ChargeResponse) ProtoMessage() {}
|
||||||
func (*ChargeResponse) Descriptor() ([]byte, []int) {
|
func (*ChargeResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{23}
|
return fileDescriptor_ca53982754088a9d, []int{23}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ChargeResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ChargeResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_ChargeResponse.Unmarshal(m, b)
|
return xxx_messageInfo_ChargeResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *ChargeResponse) XXX_Merge(src proto.Message) {
|
func (m *ChargeResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_ChargeResponse.Merge(dst, src)
|
xxx_messageInfo_ChargeResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *ChargeResponse) XXX_Size() int {
|
func (m *ChargeResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_ChargeResponse.Size(m)
|
return xxx_messageInfo_ChargeResponse.Size(m)
|
||||||
|
@ -1119,16 +1155,17 @@ func (m *OrderItem) Reset() { *m = OrderItem{} }
|
||||||
func (m *OrderItem) String() string { return proto.CompactTextString(m) }
|
func (m *OrderItem) String() string { return proto.CompactTextString(m) }
|
||||||
func (*OrderItem) ProtoMessage() {}
|
func (*OrderItem) ProtoMessage() {}
|
||||||
func (*OrderItem) Descriptor() ([]byte, []int) {
|
func (*OrderItem) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{24}
|
return fileDescriptor_ca53982754088a9d, []int{24}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *OrderItem) XXX_Unmarshal(b []byte) error {
|
func (m *OrderItem) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_OrderItem.Unmarshal(m, b)
|
return xxx_messageInfo_OrderItem.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)
|
return xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *OrderItem) XXX_Merge(src proto.Message) {
|
func (m *OrderItem) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_OrderItem.Merge(dst, src)
|
xxx_messageInfo_OrderItem.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *OrderItem) XXX_Size() int {
|
func (m *OrderItem) XXX_Size() int {
|
||||||
return xxx_messageInfo_OrderItem.Size(m)
|
return xxx_messageInfo_OrderItem.Size(m)
|
||||||
|
@ -1168,16 +1205,17 @@ func (m *OrderResult) Reset() { *m = OrderResult{} }
|
||||||
func (m *OrderResult) String() string { return proto.CompactTextString(m) }
|
func (m *OrderResult) String() string { return proto.CompactTextString(m) }
|
||||||
func (*OrderResult) ProtoMessage() {}
|
func (*OrderResult) ProtoMessage() {}
|
||||||
func (*OrderResult) Descriptor() ([]byte, []int) {
|
func (*OrderResult) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{25}
|
return fileDescriptor_ca53982754088a9d, []int{25}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *OrderResult) XXX_Unmarshal(b []byte) error {
|
func (m *OrderResult) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_OrderResult.Unmarshal(m, b)
|
return xxx_messageInfo_OrderResult.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)
|
return xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *OrderResult) XXX_Merge(src proto.Message) {
|
func (m *OrderResult) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_OrderResult.Merge(dst, src)
|
xxx_messageInfo_OrderResult.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *OrderResult) XXX_Size() int {
|
func (m *OrderResult) XXX_Size() int {
|
||||||
return xxx_messageInfo_OrderResult.Size(m)
|
return xxx_messageInfo_OrderResult.Size(m)
|
||||||
|
@ -1235,16 +1273,17 @@ func (m *SendOrderConfirmationRequest) Reset() { *m = SendOrderConfirmat
|
||||||
func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }
|
func (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*SendOrderConfirmationRequest) ProtoMessage() {}
|
func (*SendOrderConfirmationRequest) ProtoMessage() {}
|
||||||
func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {
|
func (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{26}
|
return fileDescriptor_ca53982754088a9d, []int{26}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {
|
func (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)
|
return xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {
|
func (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_SendOrderConfirmationRequest.Merge(dst, src)
|
xxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *SendOrderConfirmationRequest) XXX_Size() int {
|
func (m *SendOrderConfirmationRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_SendOrderConfirmationRequest.Size(m)
|
return xxx_messageInfo_SendOrderConfirmationRequest.Size(m)
|
||||||
|
@ -1284,16 +1323,17 @@ func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} }
|
||||||
func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }
|
func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*PlaceOrderRequest) ProtoMessage() {}
|
func (*PlaceOrderRequest) ProtoMessage() {}
|
||||||
func (*PlaceOrderRequest) Descriptor() ([]byte, []int) {
|
func (*PlaceOrderRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{27}
|
return fileDescriptor_ca53982754088a9d, []int{27}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {
|
func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)
|
return xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *PlaceOrderRequest) XXX_Merge(src proto.Message) {
|
func (m *PlaceOrderRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_PlaceOrderRequest.Merge(dst, src)
|
xxx_messageInfo_PlaceOrderRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *PlaceOrderRequest) XXX_Size() int {
|
func (m *PlaceOrderRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_PlaceOrderRequest.Size(m)
|
return xxx_messageInfo_PlaceOrderRequest.Size(m)
|
||||||
|
@ -1350,16 +1390,17 @@ func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} }
|
||||||
func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }
|
func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*PlaceOrderResponse) ProtoMessage() {}
|
func (*PlaceOrderResponse) ProtoMessage() {}
|
||||||
func (*PlaceOrderResponse) Descriptor() ([]byte, []int) {
|
func (*PlaceOrderResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{28}
|
return fileDescriptor_ca53982754088a9d, []int{28}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {
|
func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)
|
return xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *PlaceOrderResponse) XXX_Merge(src proto.Message) {
|
func (m *PlaceOrderResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_PlaceOrderResponse.Merge(dst, src)
|
xxx_messageInfo_PlaceOrderResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *PlaceOrderResponse) XXX_Size() int {
|
func (m *PlaceOrderResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_PlaceOrderResponse.Size(m)
|
return xxx_messageInfo_PlaceOrderResponse.Size(m)
|
||||||
|
@ -1389,16 +1430,17 @@ func (m *AdRequest) Reset() { *m = AdRequest{} }
|
||||||
func (m *AdRequest) String() string { return proto.CompactTextString(m) }
|
func (m *AdRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*AdRequest) ProtoMessage() {}
|
func (*AdRequest) ProtoMessage() {}
|
||||||
func (*AdRequest) Descriptor() ([]byte, []int) {
|
func (*AdRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{29}
|
return fileDescriptor_ca53982754088a9d, []int{29}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AdRequest) XXX_Unmarshal(b []byte) error {
|
func (m *AdRequest) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_AdRequest.Unmarshal(m, b)
|
return xxx_messageInfo_AdRequest.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)
|
return xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *AdRequest) XXX_Merge(src proto.Message) {
|
func (m *AdRequest) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_AdRequest.Merge(dst, src)
|
xxx_messageInfo_AdRequest.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *AdRequest) XXX_Size() int {
|
func (m *AdRequest) XXX_Size() int {
|
||||||
return xxx_messageInfo_AdRequest.Size(m)
|
return xxx_messageInfo_AdRequest.Size(m)
|
||||||
|
@ -1427,16 +1469,17 @@ func (m *AdResponse) Reset() { *m = AdResponse{} }
|
||||||
func (m *AdResponse) String() string { return proto.CompactTextString(m) }
|
func (m *AdResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*AdResponse) ProtoMessage() {}
|
func (*AdResponse) ProtoMessage() {}
|
||||||
func (*AdResponse) Descriptor() ([]byte, []int) {
|
func (*AdResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{30}
|
return fileDescriptor_ca53982754088a9d, []int{30}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AdResponse) XXX_Unmarshal(b []byte) error {
|
func (m *AdResponse) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_AdResponse.Unmarshal(m, b)
|
return xxx_messageInfo_AdResponse.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)
|
return xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *AdResponse) XXX_Merge(src proto.Message) {
|
func (m *AdResponse) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_AdResponse.Merge(dst, src)
|
xxx_messageInfo_AdResponse.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *AdResponse) XXX_Size() int {
|
func (m *AdResponse) XXX_Size() int {
|
||||||
return xxx_messageInfo_AdResponse.Size(m)
|
return xxx_messageInfo_AdResponse.Size(m)
|
||||||
|
@ -1468,16 +1511,17 @@ func (m *Ad) Reset() { *m = Ad{} }
|
||||||
func (m *Ad) String() string { return proto.CompactTextString(m) }
|
func (m *Ad) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Ad) ProtoMessage() {}
|
func (*Ad) ProtoMessage() {}
|
||||||
func (*Ad) Descriptor() ([]byte, []int) {
|
func (*Ad) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_demo_88bb8fdac9cd6be5, []int{31}
|
return fileDescriptor_ca53982754088a9d, []int{31}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Ad) XXX_Unmarshal(b []byte) error {
|
func (m *Ad) XXX_Unmarshal(b []byte) error {
|
||||||
return xxx_messageInfo_Ad.Unmarshal(m, b)
|
return xxx_messageInfo_Ad.Unmarshal(m, b)
|
||||||
}
|
}
|
||||||
func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
return xxx_messageInfo_Ad.Marshal(b, m, deterministic)
|
return xxx_messageInfo_Ad.Marshal(b, m, deterministic)
|
||||||
}
|
}
|
||||||
func (dst *Ad) XXX_Merge(src proto.Message) {
|
func (m *Ad) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_Ad.Merge(dst, src)
|
xxx_messageInfo_Ad.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *Ad) XXX_Size() int {
|
func (m *Ad) XXX_Size() int {
|
||||||
return xxx_messageInfo_Ad.Size(m)
|
return xxx_messageInfo_Ad.Size(m)
|
||||||
|
@ -2319,101 +2363,102 @@ var _AdService_serviceDesc = grpc.ServiceDesc{
|
||||||
Metadata: "demo.proto",
|
Metadata: "demo.proto",
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("demo.proto", fileDescriptor_demo_88bb8fdac9cd6be5) }
|
func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) }
|
||||||
|
|
||||||
var fileDescriptor_demo_88bb8fdac9cd6be5 = []byte{
|
var fileDescriptor_ca53982754088a9d = []byte{
|
||||||
// 1483 bytes of a gzipped FileDescriptorProto
|
// 1500 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x72, 0xd3, 0xc6,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7,
|
||||||
0x17, 0x8f, 0x92, 0x38, 0x8e, 0x8f, 0x63, 0x27, 0xd9, 0x7f, 0x12, 0x8c, 0xc2, 0x47, 0xd8, 0x0c,
|
0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81,
|
||||||
0xfc, 0xa1, 0x80, 0x61, 0xd2, 0xce, 0x70, 0x01, 0x2d, 0xcd, 0x98, 0x8c, 0xf1, 0x14, 0x0a, 0x55,
|
0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0,
|
||||||
0xa0, 0x43, 0x87, 0x4e, 0x3d, 0x42, 0xbb, 0x60, 0x95, 0x48, 0x2b, 0x76, 0x57, 0x19, 0xcc, 0x65,
|
0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc,
|
||||||
0xfb, 0x00, 0xbd, 0xef, 0x23, 0xf4, 0x05, 0xfa, 0x0e, 0xbd, 0xef, 0x2b, 0xf4, 0x39, 0x3a, 0xbb,
|
0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8,
|
||||||
0xd2, 0xea, 0xcb, 0x76, 0x02, 0x37, 0xbd, 0xf3, 0x9e, 0xfd, 0xe9, 0x9c, 0xdf, 0x39, 0x7b, 0xbe,
|
0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8,
|
||||||
0x12, 0x00, 0x42, 0x03, 0xd6, 0x8d, 0x38, 0x93, 0x0c, 0x35, 0x47, 0x7e, 0x24, 0x24, 0xe5, 0x62,
|
0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29,
|
||||||
0xc4, 0x22, 0x7c, 0x00, 0xcb, 0x3d, 0x97, 0xcb, 0x81, 0xa4, 0x01, 0x3a, 0x0f, 0x10, 0x71, 0x46,
|
0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88,
|
||||||
0x62, 0x4f, 0x0e, 0x7d, 0xd2, 0xb1, 0x76, 0xac, 0xab, 0x0d, 0xa7, 0x91, 0x4a, 0x06, 0x04, 0xd9,
|
0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20,
|
||||||
0xb0, 0xfc, 0x2e, 0x76, 0x43, 0xe9, 0xcb, 0x71, 0x67, 0x7e, 0xc7, 0xba, 0x5a, 0x73, 0xb2, 0x33,
|
0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93,
|
||||||
0x7e, 0x06, 0xed, 0x7d, 0x42, 0x94, 0x16, 0x87, 0xbe, 0x8b, 0xa9, 0x90, 0xe8, 0x0c, 0xd4, 0x63,
|
0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0,
|
||||||
0x41, 0x79, 0xae, 0x69, 0x49, 0x1d, 0x07, 0x04, 0x5d, 0x83, 0x45, 0x5f, 0xd2, 0x40, 0xab, 0x68,
|
0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad,
|
||||||
0xee, 0x6d, 0x76, 0x0b, 0x6c, 0xba, 0x86, 0x8a, 0xa3, 0x21, 0xf8, 0x3a, 0xac, 0x1d, 0x04, 0x91,
|
0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e,
|
||||||
0x1c, 0x2b, 0xf1, 0x69, 0x7a, 0xf1, 0x35, 0x68, 0xf7, 0xa9, 0xfc, 0x28, 0xe8, 0x23, 0x58, 0x54,
|
0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85,
|
||||||
0xb8, 0xd9, 0x1c, 0xaf, 0x43, 0x4d, 0x11, 0x10, 0x9d, 0xf9, 0x9d, 0x85, 0xd9, 0x24, 0x13, 0x0c,
|
0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32,
|
||||||
0xae, 0x43, 0x4d, 0xb3, 0xc4, 0xdf, 0x83, 0xfd, 0xc8, 0x17, 0xd2, 0xa1, 0x1e, 0x0b, 0x02, 0x1a,
|
0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20,
|
||||||
0x12, 0x57, 0xfa, 0x2c, 0x14, 0xa7, 0x06, 0xe4, 0x22, 0x34, 0xf3, 0xb0, 0x27, 0x26, 0x1b, 0x0e,
|
0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2,
|
||||||
0x64, 0x71, 0x17, 0xf8, 0x2b, 0xd8, 0x9e, 0xaa, 0x57, 0x44, 0x2c, 0x14, 0xb4, 0xfa, 0xbd, 0x35,
|
0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7,
|
||||||
0xf1, 0xfd, 0xef, 0x16, 0xd4, 0x9f, 0x26, 0x47, 0xd4, 0x86, 0xf9, 0x8c, 0xc0, 0xbc, 0x4f, 0x10,
|
0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d,
|
||||||
0x82, 0xc5, 0xd0, 0x0d, 0xa8, 0x7e, 0x8d, 0x86, 0xa3, 0x7f, 0xa3, 0x1d, 0x68, 0x12, 0x2a, 0x3c,
|
0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8,
|
||||||
0xee, 0x47, 0xca, 0x50, 0x67, 0x41, 0x5f, 0x15, 0x45, 0xa8, 0x03, 0xf5, 0xc8, 0xf7, 0x64, 0xcc,
|
0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93,
|
||||||
0x69, 0x67, 0x51, 0xdf, 0x9a, 0x23, 0xba, 0x05, 0x8d, 0x88, 0xfb, 0x1e, 0x1d, 0xc6, 0x82, 0x74,
|
0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b,
|
||||||
0x6a, 0xfa, 0x89, 0x51, 0x29, 0x7a, 0x8f, 0x59, 0x48, 0xc7, 0xce, 0xb2, 0x06, 0x3d, 0x17, 0x04,
|
0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28,
|
||||||
0x3f, 0x84, 0x0d, 0xe5, 0x5c, 0xca, 0x2f, 0xf7, 0xea, 0x36, 0x2c, 0xa7, 0x2e, 0x24, 0x2e, 0x35,
|
0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04,
|
||||||
0xf7, 0x36, 0x4a, 0x7a, 0xd2, 0x0f, 0x9c, 0x0c, 0x85, 0x77, 0x61, 0xbd, 0x4f, 0x8d, 0x22, 0x13,
|
0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72,
|
||||||
0xf5, 0x8a, 0xbf, 0xf8, 0x26, 0x6c, 0x1e, 0x52, 0x97, 0x7b, 0xa3, 0xdc, 0x60, 0x02, 0xdc, 0x80,
|
0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99,
|
||||||
0xda, 0xbb, 0x98, 0xf2, 0x71, 0x8a, 0x4d, 0x0e, 0xf8, 0x21, 0x6c, 0x55, 0xe1, 0x29, 0xbf, 0x2e,
|
0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab,
|
||||||
0xd4, 0x39, 0x15, 0xf1, 0xd1, 0x29, 0xf4, 0x0c, 0x08, 0x87, 0xb0, 0xda, 0xa7, 0xf2, 0xbb, 0x98,
|
0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7,
|
||||||
0x49, 0x6a, 0x4c, 0x76, 0xa1, 0xee, 0x12, 0xc2, 0xa9, 0x10, 0xda, 0x68, 0x55, 0xc5, 0x7e, 0x72,
|
0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26,
|
||||||
0xe7, 0x18, 0xd0, 0xa7, 0x65, 0xe5, 0x3e, 0xac, 0xe5, 0xf6, 0x52, 0xce, 0x37, 0x61, 0xd9, 0x63,
|
0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f,
|
||||||
0x42, 0xea, 0xb7, 0xb1, 0x66, 0xbe, 0x4d, 0x5d, 0x61, 0xd4, 0xd3, 0x30, 0x58, 0x3b, 0x1c, 0xf9,
|
0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0,
|
||||||
0xd1, 0x13, 0x4e, 0x28, 0xff, 0x4f, 0x38, 0x7f, 0x01, 0xeb, 0x05, 0x83, 0x79, 0x7a, 0x4b, 0xee,
|
0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07,
|
||||||
0x7a, 0x6f, 0xfd, 0xf0, 0x4d, 0x5e, 0x3b, 0x60, 0x44, 0x03, 0x82, 0x7f, 0xb3, 0xa0, 0x9e, 0xda,
|
0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe,
|
||||||
0x45, 0x97, 0xa1, 0x2d, 0x24, 0xa7, 0x54, 0x0e, 0x8b, 0x2c, 0x1b, 0x4e, 0x2b, 0x91, 0x1a, 0x18,
|
0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34,
|
||||||
0x82, 0x45, 0xcf, 0xb4, 0xb1, 0x86, 0xa3, 0x7f, 0xab, 0x04, 0x10, 0xd2, 0x95, 0x34, 0xcd, 0xf7,
|
0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52,
|
||||||
0xe4, 0xa0, 0x32, 0xdd, 0x63, 0x71, 0x28, 0xf9, 0xd8, 0x64, 0x7a, 0x7a, 0x44, 0x67, 0x61, 0xf9,
|
0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3,
|
||||||
0x83, 0x1f, 0x0d, 0x3d, 0x46, 0xa8, 0x4e, 0xf4, 0x9a, 0x53, 0xff, 0xe0, 0x47, 0x3d, 0x46, 0x28,
|
0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11,
|
||||||
0x7e, 0x01, 0x35, 0x1d, 0x4a, 0xb4, 0x0b, 0x2d, 0x2f, 0xe6, 0x9c, 0x86, 0xde, 0x38, 0x01, 0x26,
|
0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63,
|
||||||
0x6c, 0x56, 0x8c, 0x50, 0xa1, 0x95, 0xe1, 0x38, 0xf4, 0xa5, 0xd0, 0x6c, 0x16, 0x9c, 0xe4, 0xa0,
|
0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13,
|
||||||
0xa4, 0xa1, 0x1b, 0x32, 0xa1, 0xe9, 0xd4, 0x9c, 0xe4, 0x80, 0xfb, 0x70, 0xa1, 0x4f, 0xe5, 0x61,
|
0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49,
|
||||||
0x1c, 0x45, 0x8c, 0x4b, 0x4a, 0x7a, 0x89, 0x1e, 0x9f, 0xe6, 0x79, 0x79, 0x19, 0xda, 0x25, 0x93,
|
0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a,
|
||||||
0xa6, 0x21, 0xb4, 0x8a, 0x36, 0x05, 0xfe, 0x11, 0xce, 0xf6, 0x32, 0x41, 0x78, 0x4c, 0xb9, 0xf0,
|
0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29,
|
||||||
0x59, 0x68, 0x1e, 0xf9, 0x0a, 0x2c, 0xbe, 0xe6, 0x2c, 0x38, 0x21, 0x47, 0xf4, 0xbd, 0x6a, 0x69,
|
0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca,
|
||||||
0x92, 0x25, 0x8e, 0x25, 0x91, 0x5c, 0x92, 0x4c, 0x07, 0xe0, 0x1f, 0x0b, 0xda, 0x3d, 0x4e, 0x89,
|
0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55,
|
||||||
0xaf, 0xfa, 0x31, 0x19, 0x84, 0xaf, 0x19, 0xba, 0x01, 0xc8, 0xd3, 0x92, 0xa1, 0xe7, 0x72, 0x32,
|
0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71,
|
||||||
0x0c, 0xe3, 0xe0, 0x15, 0xe5, 0x69, 0x3c, 0xd6, 0xbc, 0x0c, 0xfb, 0xad, 0x96, 0xa3, 0x2b, 0xb0,
|
0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97,
|
||||||
0x5a, 0x44, 0x7b, 0xc7, 0xc7, 0xe9, 0xc8, 0x69, 0xe5, 0xd0, 0xde, 0xf1, 0x31, 0xfa, 0x12, 0xb6,
|
0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d,
|
||||||
0x8b, 0x38, 0xfa, 0x3e, 0xf2, 0xb9, 0x6e, 0x8f, 0xc3, 0x31, 0x75, 0x79, 0x1a, 0xbb, 0x4e, 0xfe,
|
0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff,
|
||||||
0xcd, 0x41, 0x06, 0xf8, 0x81, 0xba, 0x1c, 0xdd, 0x87, 0x73, 0x33, 0x3e, 0x0f, 0x58, 0x28, 0x47,
|
0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb,
|
||||||
0xfa, 0xc9, 0x6b, 0xce, 0xd9, 0x69, 0xdf, 0x3f, 0x56, 0x00, 0x3c, 0x86, 0x56, 0x6f, 0xe4, 0xf2,
|
0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1,
|
||||||
0x37, 0x59, 0x4d, 0x7f, 0x06, 0x4b, 0x6e, 0xa0, 0x32, 0xe4, 0x84, 0xe0, 0xa5, 0x08, 0x74, 0x0f,
|
0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8,
|
||||||
0x9a, 0x05, 0xeb, 0xe9, 0x40, 0xdc, 0x2e, 0x57, 0x48, 0x29, 0x88, 0x0e, 0xe4, 0x4c, 0xf0, 0x1d,
|
0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4,
|
||||||
0x68, 0x1b, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xb4, 0x0b, 0x59, 0xb1, 0xb4, 0x0a,
|
0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0,
|
||||||
0xd2, 0x01, 0xc1, 0x3f, 0x41, 0x43, 0x57, 0x98, 0x9e, 0xf9, 0x66, 0x1a, 0x5b, 0xa7, 0x4e, 0x63,
|
0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69,
|
||||||
0x95, 0x15, 0xaa, 0x33, 0xa4, 0x3c, 0xa7, 0x66, 0x85, 0xba, 0xc7, 0xbf, 0xcc, 0x43, 0xd3, 0x94,
|
0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb,
|
||||||
0x70, 0x7c, 0x24, 0x55, 0xa1, 0x30, 0x75, 0xcc, 0x09, 0xd5, 0xf5, 0x79, 0x40, 0xd0, 0x6d, 0xd8,
|
0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d,
|
||||||
0x10, 0x23, 0x3f, 0x8a, 0x54, 0x6d, 0x17, 0x8b, 0x3c, 0xc9, 0x26, 0x64, 0xee, 0x9e, 0x65, 0xc5,
|
0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7,
|
||||||
0x8e, 0xee, 0x40, 0x2b, 0xfb, 0x42, 0xb3, 0x59, 0x98, 0xc9, 0x66, 0xc5, 0x00, 0x7b, 0x4c, 0x48,
|
0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99,
|
||||||
0x74, 0x1f, 0xd6, 0xb2, 0x0f, 0x4d, 0x6f, 0x58, 0x3c, 0xa1, 0x83, 0xad, 0x1a, 0xb4, 0xe9, 0x19,
|
0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98,
|
||||||
0x37, 0x4c, 0x27, 0xab, 0xe9, 0x4e, 0xb6, 0x55, 0xfa, 0x2a, 0x0b, 0xa8, 0x69, 0x65, 0x04, 0xce,
|
0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9,
|
||||||
0x1d, 0xd2, 0x90, 0x68, 0x79, 0x8f, 0x85, 0xaf, 0x7d, 0x1e, 0xe8, 0xb4, 0x29, 0x8c, 0x1b, 0x1a,
|
0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02,
|
||||||
0xb8, 0xfe, 0x91, 0x19, 0x37, 0xfa, 0x80, 0xba, 0x50, 0xd3, 0xa1, 0x49, 0x63, 0xdc, 0x99, 0xb4,
|
0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d,
|
||||||
0x91, 0xc4, 0xd4, 0x49, 0x60, 0xf8, 0x6f, 0x0b, 0xd6, 0x9f, 0x1e, 0xb9, 0x1e, 0x2d, 0xf5, 0xe8,
|
0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d,
|
||||||
0x99, 0x9b, 0xc6, 0x2e, 0xb4, 0xf4, 0x85, 0x69, 0x05, 0x69, 0x9c, 0x57, 0x94, 0xd0, 0x74, 0x83,
|
0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa,
|
||||||
0x62, 0x87, 0x5f, 0xf8, 0x98, 0x0e, 0x9f, 0x79, 0x52, 0x2b, 0x7a, 0x52, 0xc9, 0xed, 0xa5, 0x4f,
|
0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9,
|
||||||
0xcb, 0xed, 0x07, 0x80, 0x8a, 0x6e, 0x65, 0x23, 0x37, 0x8d, 0x8e, 0xf5, 0x71, 0xd1, 0xe9, 0x42,
|
0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7,
|
||||||
0x63, 0x9f, 0x98, 0xa0, 0x5c, 0x82, 0x15, 0x8f, 0x85, 0x92, 0xbe, 0x97, 0xc3, 0xb7, 0x74, 0x6c,
|
0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce,
|
||||||
0xba, 0x62, 0x33, 0x95, 0x7d, 0x43, 0xc7, 0x02, 0xdf, 0x02, 0x50, 0xf8, 0xd4, 0xda, 0x25, 0x58,
|
0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47,
|
||||||
0x70, 0x89, 0x19, 0xee, 0xab, 0x95, 0x18, 0x38, 0xea, 0x0e, 0xdf, 0x85, 0xf9, 0x7d, 0xa2, 0x34,
|
0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d,
|
||||||
0x2b, 0xe6, 0x9c, 0x7a, 0x72, 0x18, 0x73, 0xf3, 0xa2, 0x4d, 0x23, 0x7b, 0xce, 0x8f, 0xd4, 0xbc,
|
0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23,
|
||||||
0x51, 0x56, 0xcc, 0xbc, 0x51, 0xbf, 0xf7, 0xfe, 0xb2, 0xa0, 0xa9, 0x2a, 0xec, 0x90, 0xf2, 0x63,
|
0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac,
|
||||||
0xdf, 0xa3, 0xe8, 0x9e, 0x9e, 0x62, 0xba, 0x28, 0xb7, 0xab, 0x11, 0x2f, 0x2c, 0xd6, 0x76, 0x39,
|
0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca,
|
||||||
0xd5, 0x93, 0xcd, 0x73, 0x0e, 0xdd, 0x85, 0x7a, 0xba, 0xfd, 0x56, 0xbe, 0x2e, 0xef, 0xc4, 0xf6,
|
0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb,
|
||||||
0xfa, 0x44, 0x85, 0xe3, 0x39, 0xf4, 0x35, 0x34, 0xb2, 0x3d, 0x1b, 0x9d, 0x9f, 0xd4, 0x5f, 0x54,
|
0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99,
|
||||||
0x30, 0xd5, 0xfc, 0xde, 0xaf, 0x16, 0x6c, 0x96, 0xf7, 0x53, 0xe3, 0xd6, 0xcf, 0xf0, 0xbf, 0x29,
|
0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe,
|
||||||
0xcb, 0x2b, 0xfa, 0x7f, 0x49, 0xcd, 0xec, 0xb5, 0xd9, 0xbe, 0x7a, 0x3a, 0x30, 0x79, 0x30, 0xc5,
|
0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff,
|
||||||
0x62, 0x1e, 0x36, 0xd3, 0xc5, 0xab, 0xe7, 0x4a, 0xf7, 0x88, 0xbd, 0x31, 0x2c, 0xfa, 0xb0, 0x52,
|
0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07,
|
||||||
0xdc, 0x32, 0xd1, 0x14, 0x2f, 0xec, 0x4b, 0x13, 0x96, 0xaa, 0x4b, 0x1f, 0x9e, 0x43, 0x0f, 0x00,
|
0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87,
|
||||||
0xf2, 0x25, 0x13, 0x5d, 0xa8, 0x86, 0xba, 0xbc, 0x7d, 0xda, 0x53, 0x77, 0x42, 0x3c, 0x87, 0x5e,
|
0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8,
|
||||||
0x42, 0xbb, 0xbc, 0x56, 0x22, 0x5c, 0x42, 0x4e, 0x5d, 0x51, 0xed, 0xdd, 0x13, 0x31, 0x59, 0x14,
|
0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33,
|
||||||
0xfe, 0xb0, 0x60, 0xf5, 0x30, 0x6d, 0x5e, 0xc6, 0xff, 0x01, 0x2c, 0x9b, 0x6d, 0x10, 0x9d, 0xab,
|
0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93,
|
||||||
0x92, 0x2e, 0x2e, 0xa5, 0xf6, 0xf9, 0x19, 0xb7, 0x59, 0x04, 0x1e, 0x41, 0x23, 0x5b, 0xd2, 0x2a,
|
0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2,
|
||||||
0xc9, 0x52, 0xdd, 0x16, 0xed, 0x0b, 0xb3, 0xae, 0x33, 0xb2, 0x7f, 0x5a, 0xb0, 0x6a, 0x5a, 0x8f,
|
0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43,
|
||||||
0x21, 0xfb, 0x12, 0xb6, 0xa6, 0x2f, 0x39, 0x53, 0x9f, 0xed, 0x7a, 0x95, 0xf0, 0x09, 0xdb, 0x11,
|
0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6,
|
||||||
0x9e, 0x43, 0x7d, 0xa8, 0x27, 0x0b, 0x8f, 0x44, 0x57, 0xca, 0xb5, 0x30, 0x6b, 0x1d, 0xb2, 0xa7,
|
0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31,
|
||||||
0x0c, 0x17, 0x3c, 0xb7, 0xf7, 0x1c, 0xda, 0x4f, 0xdd, 0x71, 0x40, 0xc3, 0xac, 0x82, 0x7b, 0xb0,
|
0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21,
|
||||||
0x94, 0x4c, 0x64, 0x64, 0x97, 0x35, 0x17, 0x37, 0x04, 0x7b, 0x7b, 0xea, 0x5d, 0x16, 0x90, 0x11,
|
0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc,
|
||||||
0xac, 0x1c, 0xa8, 0x0e, 0x6a, 0x94, 0xbe, 0x50, 0x7f, 0xb0, 0x4c, 0x19, 0x24, 0xe8, 0x5a, 0x25,
|
0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43,
|
||||||
0x1b, 0x66, 0x0f, 0x9b, 0x19, 0x35, 0xfb, 0x0a, 0x56, 0x7b, 0x23, 0xea, 0xbd, 0x65, 0x71, 0xe6,
|
0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd,
|
||||||
0xc1, 0x13, 0x80, 0xbc, 0xef, 0x56, 0xb2, 0x7b, 0x62, 0xce, 0xd8, 0x17, 0x67, 0xde, 0x67, 0xde,
|
0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2,
|
||||||
0x3c, 0x54, 0x2d, 0xd8, 0x68, 0xbf, 0x0b, 0x4b, 0x7d, 0xb5, 0x83, 0x0b, 0xb4, 0x55, 0x6d, 0xa7,
|
0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f,
|
||||||
0xa9, 0xc6, 0x33, 0x13, 0x72, 0xa3, 0xe9, 0xd5, 0x92, 0xfe, 0xe7, 0xc5, 0xe7, 0xff, 0x06, 0x00,
|
0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a,
|
||||||
0x00, 0xff, 0xff, 0x22, 0xc9, 0xfe, 0x20, 0xca, 0x10, 0x00, 0x00,
|
0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b,
|
||||||
|
0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
"products": ps,
|
"products": ps,
|
||||||
"cart_size": len(cart),
|
"cart_size": len(cart),
|
||||||
"banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments
|
"banner_color": os.Getenv("BANNER_COLOR"), // illustrates canary deployments
|
||||||
"ad": fe.chooseAd(r.Context(), log),
|
"ad": fe.chooseAd(r.Context(), []string{}, log),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ func (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request)
|
||||||
if err := templates.ExecuteTemplate(w, "product", map[string]interface{}{
|
if err := templates.ExecuteTemplate(w, "product", map[string]interface{}{
|
||||||
"session_id": sessionID(r),
|
"session_id": sessionID(r),
|
||||||
"request_id": r.Context().Value(ctxKeyRequestID{}),
|
"request_id": r.Context().Value(ctxKeyRequestID{}),
|
||||||
"ad": fe.chooseAd(r.Context(), log),
|
"ad": fe.chooseAd(r.Context(), p.Categories, log),
|
||||||
"user_currency": currentCurrency(r),
|
"user_currency": currentCurrency(r),
|
||||||
"currencies": currencies,
|
"currencies": currencies,
|
||||||
"product": product,
|
"product": product,
|
||||||
|
@ -346,8 +346,8 @@ func (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Requ
|
||||||
|
|
||||||
// chooseAd queries for advertisements available and randomly chooses one, if
|
// chooseAd queries for advertisements available and randomly chooses one, if
|
||||||
// available. It ignores the error retrieving the ad since it is not critical.
|
// available. It ignores the error retrieving the ad since it is not critical.
|
||||||
func (fe *frontendServer) chooseAd(ctx context.Context, log logrus.FieldLogger) *pb.Ad {
|
func (fe *frontendServer) chooseAd(ctx context.Context, ctxKeys []string, log logrus.FieldLogger) *pb.Ad {
|
||||||
ads, err := fe.getAd(ctx)
|
ads, err := fe.getAd(ctx, ctxKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("error", err).Warn("failed to retrieve ads")
|
log.WithField("error", err).Warn("failed to retrieve ads")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -116,12 +116,12 @@ func (fe *frontendServer) getRecommendations(ctx context.Context, userID string,
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe *frontendServer) getAd(ctx context.Context) ([]*pb.Ad, error) {
|
func (fe *frontendServer) getAd(ctx context.Context, ctxKeys []string) ([]*pb.Ad, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
|
ctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
resp, err := pb.NewAdServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdRequest{
|
resp, err := pb.NewAdServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdRequest{
|
||||||
ContextKeys: nil,
|
ContextKeys: ctxKeys,
|
||||||
})
|
})
|
||||||
return resp.GetAds(), errors.Wrap(err, "failed to get ads")
|
return resp.GetAds(), errors.Wrap(err, "failed to get ads")
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,10 @@ message Product {
|
||||||
string description = 3;
|
string description = 3;
|
||||||
string picture = 4;
|
string picture = 4;
|
||||||
Money price_usd = 5;
|
Money price_usd = 5;
|
||||||
|
|
||||||
|
// Categories such as "vintage" or "gardening" that can be used to look up
|
||||||
|
// other related products.
|
||||||
|
repeated string categories = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ListProductsResponse {
|
message ListProductsResponse {
|
||||||
|
@ -218,18 +222,18 @@ message PlaceOrderResponse {
|
||||||
OrderResult order = 1;
|
OrderResult order = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------Ads service------------------
|
// ------------Ad service------------------
|
||||||
|
|
||||||
service AdsService {
|
service AdService {
|
||||||
rpc GetAds(AdsRequest) returns (AdsResponse) {}
|
rpc GetAds(AdRequest) returns (AdResponse) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message AdsRequest {
|
message AdRequest {
|
||||||
// List of important key words from the current page describing the context.
|
// List of important key words from the current page describing the context.
|
||||||
repeated string context_keys = 1;
|
repeated string context_keys = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AdsResponse {
|
message AdResponse {
|
||||||
repeated Ad ads = 1;
|
repeated Ad ads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 67,
|
"units": 67,
|
||||||
"nanos": 990000000
|
"nanos": 990000000
|
||||||
}
|
},
|
||||||
|
"categories": ["vintage"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "66VCHSJNUP",
|
"id": "66VCHSJNUP",
|
||||||
|
@ -20,7 +21,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 12,
|
"units": 12,
|
||||||
"nanos": 490000000
|
"nanos": 490000000
|
||||||
}
|
},
|
||||||
|
"categories": ["photography", "vintage"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "1YMWWN1N4O",
|
"id": "1YMWWN1N4O",
|
||||||
|
@ -30,7 +32,8 @@
|
||||||
"priceUsd": {
|
"priceUsd": {
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 124
|
"units": 124
|
||||||
}
|
},
|
||||||
|
"categories": ["cookware"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "L9ECAV7KIM",
|
"id": "L9ECAV7KIM",
|
||||||
|
@ -41,7 +44,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 36,
|
"units": 36,
|
||||||
"nanos": 450000000
|
"nanos": 450000000
|
||||||
}
|
},
|
||||||
|
"categories": ["gardening"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "2ZYFJ3GM2N",
|
"id": "2ZYFJ3GM2N",
|
||||||
|
@ -51,7 +55,8 @@
|
||||||
"priceUsd": {
|
"priceUsd": {
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 2245
|
"units": 2245
|
||||||
}
|
},
|
||||||
|
"categories": ["photography", "vintage"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "0PUK6V6EV0",
|
"id": "0PUK6V6EV0",
|
||||||
|
@ -62,7 +67,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 65,
|
"units": 65,
|
||||||
"nanos": 500000000
|
"nanos": 500000000
|
||||||
}
|
},
|
||||||
|
"categories": ["music", "vintage"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "LS4PSXUNUM",
|
"id": "LS4PSXUNUM",
|
||||||
|
@ -73,7 +79,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 24,
|
"units": 24,
|
||||||
"nanos": 330000000
|
"nanos": 330000000
|
||||||
}
|
},
|
||||||
|
"categories": ["cookware"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9SIQT8TOJO",
|
"id": "9SIQT8TOJO",
|
||||||
|
@ -84,7 +91,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 789,
|
"units": 789,
|
||||||
"nanos": 500000000
|
"nanos": 500000000
|
||||||
}
|
},
|
||||||
|
"categories": ["cycling"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "6E92ZMYYFZ",
|
"id": "6E92ZMYYFZ",
|
||||||
|
@ -95,7 +103,8 @@
|
||||||
"currencyCode": "USD",
|
"currencyCode": "USD",
|
||||||
"units": 12,
|
"units": 12,
|
||||||
"nanos": 300000000
|
"nanos": 300000000
|
||||||
}
|
},
|
||||||
|
"categories": ["gardening"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue