Sync docs from v1.2.0.M2 to gh-pages
20
spring-cloud-gcp/1.2.0.M2/reference/html/Guardfile
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'asciidoctor'
|
||||
require 'erb'
|
||||
|
||||
guard 'shell' do
|
||||
watch(/.*\.adoc$/) {|m|
|
||||
Asciidoctor.render_file('index.adoc', \
|
||||
:in_place => true, \
|
||||
:safe => Asciidoctor::SafeMode::UNSAFE, \
|
||||
:attributes=> { \
|
||||
'source-highlighter' => 'prettify', \
|
||||
'icons' => 'font', \
|
||||
'linkcss'=> 'true', \
|
||||
'copycss' => 'true', \
|
||||
'doctype' => 'book'})
|
||||
}
|
||||
end
|
||||
|
||||
guard 'livereload' do
|
||||
watch(%r{^.+\.(css|js|html)$})
|
||||
end
|
||||
325
spring-cloud-gcp/1.2.0.M2/reference/html/README.html
Normal file
@@ -0,0 +1,325 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Framework on Google Cloud Platform</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<h1>Spring Framework on Google Cloud Platform</h1>
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_initializr">Spring Initializr</a></li>
|
||||
<li><a href="#_spring_cloud_gcp_bill_of_materials_bom">Spring Cloud GCP Bill of Materials (BOM)</a></li>
|
||||
<li><a href="#_spring_milestones_maven_repository">Spring Milestones Maven Repository</a></li>
|
||||
<li><a href="#_spring_snapshots_maven_repository">Spring Snapshots Maven Repository</a></li>
|
||||
<li><a href="#_spring_boot_starters">Spring Boot Starters</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="preamble">
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>This project makes it easy for Spring users to run their applications on Google Cloud Platform.
|
||||
You can check our project website <a href="https://cloud.spring.io/spring-cloud-gcp">here</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For a deep dive into the project, refer to the <a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-gcp/1.1.0.RELEASE/single/spring-cloud-gcp.html">Spring Cloud GCP 1.1 Reference Document</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you prefer to learn by doing, try <a href="https://codelabs.developers.google.com/spring">Spring on GCP codelabs</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Currently, this repository provides support for:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-pubsub">Spring Cloud GCP Pub/Sub, including Spring Integration Channel Adapters</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-pubsub-stream-binder">Spring Cloud GCP Pub/Sub Stream Binder</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-storage">Spring Resource Abstraction for Google Cloud Storage, including Spring Integration Channel Adapters</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-data-spanner">Spring Data Cloud Spanner</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-data-datastore">Spring Data Cloud Datastore</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-vision">Google Cloud Vision API Template</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Boot starters</p>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter">GCP Support</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-config">Google Cloud Config</a> (Beta)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-data-spanner">Google Cloud Spanner</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-data-datastore">Google Cloud Datastore</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-logging">Google Cloud Logging</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-pubsub">Google Cloud Pub/Sub</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-sql-mysql">Google Cloud SQL MySQL</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-sql-postgresql">Google Cloud SQL PostgreSQL</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-storage">Google Cloud Storage</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-trace">Stackdriver Trace with Spring Cloud Sleuth</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-security-iap">Google Cloud IAP Authentication</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="spring-cloud-gcp-starters/spring-cloud-gcp-starter-vision">Google Cloud Vision API</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you have any other ideas, suggestions or bug reports, please use our <a href="https://github.com/spring-cloud/spring-cloud-gcp/issues">GitHub issue tracker</a> and let us know!
|
||||
We would love to hear from you.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you want to collaborate in the project, we would also love to get your Pull Requests.
|
||||
Before you start working on one, please take a look at our <a href="CONTRIBUTING.adoc">collaboration manual</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_initializr"><a class="link" href="#_spring_initializr">Spring Initializr</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Initializr contains Spring Cloud GCP auto-configuration support through the <code>GCP Support</code> entry.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>GCP Messaging</code> contains the Spring Cloud GCP messaging support with Google Cloud Pub/Sub working out of the box.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Similarly to <code>GCP Messaging</code>, <code>GCP Storage</code> contains the Google Cloud Storage support with no other dependencies needed.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_cloud_gcp_bill_of_materials_bom"><a class="link" href="#_spring_cloud_gcp_bill_of_materials_bom">Spring Cloud GCP Bill of Materials (BOM)</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>If you’re a Maven Central user, add our BOM to your pom.xml <code><dependencyManagement></code> section.
|
||||
This will allow you to omit versions for any of the Maven dependencies and instead delegate versioning to the BOM.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-dependencies</artifactId>
|
||||
<version>1.1.0.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_milestones_maven_repository"><a class="link" href="#_spring_milestones_maven_repository">Spring Milestones Maven Repository</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>The latest non-GA Maven artifacts for the project are available in the Spring Milestones repository instead of Maven Central.
|
||||
They are named like <code>1.1.0.M1</code> or <code>1.1.0.M2</code> and are released more frequently than GA <code>RELEASE</code> versions.
|
||||
You will want to make sure that the repository is added to your <code>pom.xml</code> file or globally in your <a href="https://maven.apache.org/settings.html"><code>settings.xml</code></a> file.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_snapshots_maven_repository"><a class="link" href="#_spring_snapshots_maven_repository">Spring Snapshots Maven Repository</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>We offer <code>BUILD-SNAPSHOT</code> versions that always reflect the latest code changes to the underlying GitHub repository for Spring Cloud GCP via the Spring Snapshots Repository:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring SnapShots</name>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, the <code>1.2.0.BUILD-SNAPSHOT</code> is available from this repository.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_boot_starters"><a class="link" href="#_spring_boot_starters">Spring Boot Starters</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Boot greatly simplifies the Spring Cloud GCP experience.
|
||||
Our starters handle the object instantiation and configuration logic so you don’t have to.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Every starter depends on the GCP starter to provide critical bits of configuration, like the GCP project ID or OAuth2 credentials location.
|
||||
You can configure these as properties in, for example, a properties file:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.gcp.project-id=[YOUR_GCP_PROJECT_ID]
|
||||
spring.cloud.gcp.credentials.location=file:[LOCAL_PRIVATE_KEY_FILE]
|
||||
spring.cloud.gcp.credentials.scopes=[SCOPE_1],[SCOPE_2],[SCOPE_3]</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>These properties are optional and, if not specified, Spring Boot will attempt to automatically find them for you.
|
||||
For details on how Spring Boot finds these properties, refer to the <a href="https://cloud.spring.io/spring-cloud-gcp">documentation</a>.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If your app is running on Google App Engine or Google Compute Engine, in most cases, you should omit the <code>spring.cloud.gcp.credentials.location</code> property and, instead, let the Spring Cloud GCP Core Starter find the correct credentials for those environments.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
150
spring-cloud-gcp/1.2.0.M2/reference/html/cloudfoundry.html
Normal file
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Cloud Foundry</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_cloud_foundry">Cloud Foundry</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_cloud_foundry"><a class="link" href="#_cloud_foundry">Cloud Foundry</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides support for Cloud Foundry’s <a href="https://docs.pivotal.io/partners/gcp-sb/index.html">GCP Service Broker</a>.
|
||||
Our Pub/Sub, Cloud Spanner, Storage, Stackdriver Trace and Cloud SQL MySQL and PostgreSQL starters are Cloud Foundry aware and retrieve properties like project ID, credentials, etc., that are used in auto configuration from the Cloud Foundry environment.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In cases like Pub/Sub’s topic and subscription, or Storage’s bucket name, where those parameters are not used in auto configuration, you can fetch them using the VCAP mapping provided by Spring Boot.
|
||||
For example, to retrieve the provisioned Pub/Sub topic, you can use the <code>vcap.services.mypubsub.credentials.topic_name</code> property from the application environment.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If the same service is bound to the same application more than once, the auto configuration will not be able to choose among bindings and will not be activated for that service.
|
||||
This includes both MySQL and PostgreSQL bindings to the same app.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="admonitionblock warning">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-warning" title="Warning"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
In order for the Cloud SQL integration to work in Cloud Foundry, auto-reconfiguration must be disabled.
|
||||
You can do so using the <code>cf set-env <APP> JBP_CONFIG_SPRING_AUTO_RECONFIGURATION '{enabled: false}'</code> command.
|
||||
Otherwise, Cloud Foundry will produce a <code>DataSource</code> with an invalid JDBC URL (i.e., <code>jdbc:mysql://null/null</code>).
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
376
spring-cloud-gcp/1.2.0.M2/reference/html/config.html
Normal file
@@ -0,0 +1,376 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Cloud Config</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_cloud_config">Spring Cloud Config</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_quick_start">Quick start</a></li>
|
||||
<li><a href="#_refreshing_the_configuration_at_runtime">Refreshing the configuration at runtime</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_cloud_config"><a class="link" href="#_spring_cloud_config">Spring Cloud Config</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP makes it possible to use the <a href="https://cloud.google.com/deployment-manager/runtime-configurator/reference/rest/">Google Runtime Configuration API</a> as a <a href="https://cloud.spring.io/spring-cloud-config/">Spring Cloud Config</a> server to remotely store your application configuration data.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP Config support is provided via its own Spring Boot starter.
|
||||
It enables the use of the Google Runtime Configuration API as a source for Spring Boot configuration properties.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
The Google Cloud Runtime Configuration service is in beta status.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-config</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-config'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The following parameters are configurable in Spring Cloud GCP Config:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables the Config client</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.name</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of your application</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of the <code>spring.application.name</code> property.
|
||||
If none, <code>application</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.profile</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Active profile</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Value of the <code>spring.profiles.active</code> property.
|
||||
If more than a single profile, last one is chosen</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.timeout-millis</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Timeout in milliseconds for connecting to the Google Runtime Configuration API</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>60000</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.project-id</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">GCP project ID where the Google Runtime Configuration API is hosted</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">OAuth2 credentials for authenticating with the Google Runtime Configuration API</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Base64-encoded OAuth2 credentials for authenticating with the Google Runtime Configuration API</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.config.credentials.scopes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://developers.google.com/identity/protocols/googlescopes">OAuth2 scope</a> for Spring Cloud GCP Config credentials</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/cloudruntimeconfig" class="bare">https://www.googleapis.com/auth/cloudruntimeconfig</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
These properties should be specified in a <a href="https://cloud.spring.io/spring-cloud-static/spring-cloud.html#_the_bootstrap_application_context"><code>bootstrap.yml</code>/<code>bootstrap.properties</code></a> file, rather than the usual <code>applications.yml</code>/<code>application.properties</code>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Core properties, as described in <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a>, do not apply to Spring Cloud GCP Config.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_quick_start"><a class="link" href="#_quick_start">Quick start</a></h3>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p>Create a configuration in the Google Runtime Configuration API that is called <code>${spring.application.name}_${spring.profiles.active}</code>.
|
||||
In other words, if <code>spring.application.name</code> is <code>myapp</code> and <code>spring.profiles.active</code> is <code>prod</code>, the configuration should be called <code>myapp_prod</code>.</p>
|
||||
<div class="paragraph">
|
||||
<p>In order to do that, you should have the <a href="https://cloud.google.com/sdk/">Google Cloud SDK</a> installed, own a Google Cloud Project and run the following command:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>gcloud init # if this is your first Google Cloud SDK run.
|
||||
gcloud beta runtime-config configs create myapp_prod
|
||||
gcloud beta runtime-config configs variables set myapp.queue-size 25 --config-name myapp_prod</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Configure your <code>bootstrap.properties</code> file with your application’s configuration data:</p>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.application.name=myapp
|
||||
spring.profiles.active=prod</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Add the <code>@ConfigurationProperties</code> annotation to a Spring-managed bean:</p>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>@Component
|
||||
@ConfigurationProperties("myapp")
|
||||
public class SampleConfig {
|
||||
|
||||
private int queueSize;
|
||||
|
||||
public int getQueueSize() {
|
||||
return this.queueSize;
|
||||
}
|
||||
|
||||
public void setQueueSize(int queueSize) {
|
||||
this.queueSize = queueSize;
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>When your Spring application starts, the <code>queueSize</code> field value will be set to 25 for the above <code>SampleConfig</code> bean.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_refreshing_the_configuration_at_runtime"><a class="link" href="#_refreshing_the_configuration_at_runtime">Refreshing the configuration at runtime</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.spring.io/spring-cloud-static/docs/1.0.x/spring-cloud.html#_endpoints">Spring Cloud</a> provides support to have configuration parameters be reloadable with the POST request to <code>/actuator/refresh</code> endpoint.</p>
|
||||
</div>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p>Add the Spring Boot Actuator dependency:</p>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre><dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Add <code>@RefreshScope</code> to your Spring configuration class to have parameters be reloadable at runtime.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Add <code>management.endpoints.web.exposure.include=refresh</code> to your <code>application.properties</code> to allow unrestricted access to <code>/actuator/refresh</code>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Update a property with <code>gcloud</code>:</p>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>$ gcloud beta runtime-config configs variables set \
|
||||
myapp.queue_size 200 \
|
||||
--config-name myapp_prod</pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>Send a POST request to the refresh endpoint:</p>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>$ curl -XPOST https://myapp.host.com/actuator/refresh</pre>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-config-sample">sample application</a> and a <a href="https://codelabs.developers.google.com/codelabs/cloud-spring-runtime-config/index.html">codelab</a> are available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
342
spring-cloud-gcp/1.2.0.M2/reference/html/core.html
Normal file
@@ -0,0 +1,342 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Cloud GCP Core</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#spring-cloud-gcp-core">Spring Cloud GCP Core</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_project_id">Project ID</a></li>
|
||||
<li><a href="#_credentials">Credentials</a></li>
|
||||
<li><a href="#_environment">Environment</a></li>
|
||||
<li><a href="#_spring_initializr">Spring Initializr</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="spring-cloud-gcp-core"><a class="link" href="#spring-cloud-gcp-core">Spring Cloud GCP Core</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Each Spring Cloud GCP module uses <code>GcpProjectIdProvider</code> and <code>CredentialsProvider</code> to get the GCP project ID and access credentials.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides a Spring Boot starter to auto-configure the core components.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_project_id"><a class="link" href="#_project_id">Project ID</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><code>GcpProjectIdProvider</code> is a functional interface that returns a GCP project ID string.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface GcpProjectIdProvider {
|
||||
String getProjectId();
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP starter auto-configures a <code>GcpProjectIdProvider</code>.
|
||||
If a <code>spring.cloud.gcp.project-id</code> property is specified, the provided <code>GcpProjectIdProvider</code> returns that property value.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">spring.cloud.gcp.project-id=my-gcp-project-id</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Otherwise, the project ID is discovered based on an
|
||||
<a href="https://googlecloudplatform.github.io/google-cloud-java/google-cloud-clients/apidocs/com/google/cloud/ServiceOptions.html#getDefaultProjectId--">ordered list of rules</a>:</p>
|
||||
</div>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p>The project ID specified by the <code>GOOGLE_CLOUD_PROJECT</code> environment variable</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The Google App Engine project ID</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The project ID specified in the JSON credentials file pointed by the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The Google Cloud SDK project ID</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The Google Compute Engine project ID, from the Google Compute Engine Metadata Server</p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_credentials"><a class="link" href="#_credentials">Credentials</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><code>CredentialsProvider</code> is a functional interface that returns the credentials to authenticate and authorize calls to Google Cloud Client Libraries.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface CredentialsProvider {
|
||||
Credentials getCredentials() throws IOException;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP starter auto-configures a <code>CredentialsProvider</code>.
|
||||
It uses the <code>spring.cloud.gcp.credentials.location</code> property to locate the OAuth2 private key of a Google service account.
|
||||
Keep in mind this property is a Spring Resource, so the credentials file can be obtained from a number of <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html#resources-implementations">different locations</a> such as the file system, classpath, URL, etc.
|
||||
The next example specifies the credentials location property in the file system.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.gcp.credentials.location=file:/usr/local/key.json</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Alternatively, you can set the credentials by directly specifying the <code>spring.cloud.gcp.credentials.encoded-key</code> property.
|
||||
The value should be the base64-encoded account private key in JSON format.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If that credentials aren’t specified through properties, the starter tries to discover credentials from a <a href="https://github.com/GoogleCloudPlatform/google-cloud-java#authentication">number of places</a>:</p>
|
||||
</div>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p>Credentials file pointed to by the <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variable</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Credentials provided by the Google Cloud SDK <code>gcloud auth application-default login</code> command</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google App Engine built-in credentials</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Cloud Shell built-in credentials</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Compute Engine built-in credentials</p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If your app is running on Google App Engine or Google Compute Engine, in most cases, you should omit the <code>spring.cloud.gcp.credentials.location</code> property and, instead, let the Spring Cloud GCP Starter get the correct credentials for those environments.
|
||||
On App Engine Standard, the <a href="https://cloud.google.com/appengine/docs/standard/java/appidentity/">App Identity service account credentials</a> are used, on App Engine Flexible, the <a href="https://cloud.google.com/appengine/docs/flexible/java/service-account">Flexible service account credential</a> are used and on Google Compute Engine, the <a href="https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#using_the_compute_engine_default_service_account">Compute Engine Default Service Account</a> is used.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_scopes"><a class="link" href="#_scopes">Scopes</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>By default, the credentials provided by the Spring Cloud GCP Starter contain scopes for every service supported by Spring Cloud GCP.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 50%;">
|
||||
<col style="width: 50%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Service</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Scope</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Spanner</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/spanner.admin" class="bare">https://www.googleapis.com/auth/spanner.admin</a>, <a href="https://www.googleapis.com/auth/spanner.data" class="bare">https://www.googleapis.com/auth/spanner.data</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Datastore</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/datastore" class="bare">https://www.googleapis.com/auth/datastore</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Pub/Sub</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/pubsub" class="bare">https://www.googleapis.com/auth/pubsub</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Storage (Read Only)</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/devstorage.read_only" class="bare">https://www.googleapis.com/auth/devstorage.read_only</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Storage (Write/Write)</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/devstorage.read_write" class="bare">https://www.googleapis.com/auth/devstorage.read_write</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Runtime Config</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/cloudruntimeconfig" class="bare">https://www.googleapis.com/auth/cloudruntimeconfig</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Trace (Append)</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/trace.append" class="bare">https://www.googleapis.com/auth/trace.append</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Platform</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/cloud-platform" class="bare">https://www.googleapis.com/auth/cloud-platform</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/cloud-vision" class="bare">https://www.googleapis.com/auth/cloud-vision</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP starter allows you to configure a custom scope list for the provided credentials.
|
||||
To do that, specify a comma-delimited list of <a href="https://developers.google.com/identity/protocols/googlescopes">Google OAuth2 scopes</a> in the <code>spring.cloud.gcp.credentials.scopes</code> property.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>spring.cloud.gcp.credentials.scopes</code> is a comma-delimited list of <a href="https://developers.google.com/identity/protocols/googlescopes">Google OAuth2 scopes</a> for Google Cloud Platform services that the credentials returned by the provided <code>CredentialsProvider</code> support.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.gcp.credentials.scopes=https://www.googleapis.com/auth/pubsub,https://www.googleapis.com/auth/sqlservice.admin</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can also use <code>DEFAULT_SCOPES</code> placeholder as a scope to represent the starters default scopes, and append the additional scopes you need to add.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.gcp.credentials.scopes=DEFAULT_SCOPES,https://www.googleapis.com/auth/cloud-vision</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_environment"><a class="link" href="#_environment">Environment</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><code>GcpEnvironmentProvider</code> is a functional interface, auto-configured by the Spring Cloud GCP starter, that returns a <code>GcpEnvironment</code> enum.
|
||||
The provider can help determine programmatically in which GCP environment (App Engine Flexible, App Engine Standard, Kubernetes Engine or Compute Engine) the application is deployed.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface GcpEnvironmentProvider {
|
||||
GcpEnvironment getCurrentEnvironment();
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_spring_initializr"><a class="link" href="#_spring_initializr">Spring Initializr</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>This starter is available from <a href="https://start.spring.io/">Spring Initializr</a> through the <code>GCP Support</code> entry.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
1
spring-cloud-gcp/1.2.0.M2/reference/html/css/spring.css
Normal file
1979
spring-cloud-gcp/1.2.0.M2/reference/html/datastore.html
Normal file
BIN
spring-cloud-gcp/1.2.0.M2/reference/html/favicon.ico
Normal file
|
After Width: | Height: | Size: 109 KiB |
245
spring-cloud-gcp/1.2.0.M2/reference/html/firestore.html
Normal file
@@ -0,0 +1,245 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Cloud Firestore</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_cloud_firestore">Cloud Firestore</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_using_cloud_firestore">Using Cloud Firestore</a></li>
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_cloud_firestore"><a class="link" href="#_cloud_firestore">Cloud Firestore</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides a convenience starter which automatically configures authentication settings and client objects needed to begin using <a href="https://cloud.google.com/firestore/">Google Cloud Firestore</a> in native mode.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>See <a href="https://cloud.google.com/firestore/docs/">documentation</a> to learn more about Cloud Firestore.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To begin using this library, add the <code>spring-cloud-gcp-starter-firestore</code> artifact to your project.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-firestore</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-firestore'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_using_cloud_firestore"><a class="link" href="#_using_cloud_firestore">Using Cloud Firestore</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The starter automatically configures and registers a <code>Firestore</code> bean in the Spring application context. To start using it, simply use the <code>@Autowired</code> annotation.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
||||
Firestore firestore;
|
||||
|
||||
void writeDocumentFromObject() throws ExecutionException, InterruptedException {
|
||||
// Add document data with id "joe" using a custom User class
|
||||
User data = new User("Joe",
|
||||
Arrays.asList(
|
||||
new Phone(12345, PhoneType.CELL),
|
||||
new Phone(54321, PhoneType.WORK)));
|
||||
|
||||
// .get() blocks on response
|
||||
WriteResult writeResult = this.firestore.document("users/joe").set(data).get();
|
||||
|
||||
LOGGER.info("Update time: " + writeResult.getUpdateTime());
|
||||
}
|
||||
|
||||
User readDocumentToObject() throws ExecutionException, InterruptedException {
|
||||
ApiFuture<DocumentSnapshot> documentFuture =
|
||||
this.firestore.document("users/joe").get();
|
||||
|
||||
User user = documentFuture.get().toObject(User.class);
|
||||
|
||||
LOGGER.info("read: " + user);
|
||||
|
||||
return user;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Boot starter for Google Cloud Firestore provides the following configuration options:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.firestore.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables or disables Pub/Sub auto-configuration</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.firestore.project-id</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">GCP project ID where the Google Cloud Firestore API is hosted, if different from the one in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.firestore.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">OAuth2 credentials for authenticating with the Google Cloud Datastore API, if different from the ones in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.firestore.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Base64-encoded OAuth2 credentials for authenticating with the Google Cloud Datastore API, if different from the ones in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.firestore.credentials.scopes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://developers.google.com/identity/protocols/googlescopes">OAuth2 scope</a> for Spring Cloud GCP Cloud Datastore credentials</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/datastore" class="bare">https://www.googleapis.com/auth/datastore</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud-gcp/spring-cloud-gcp-samples/spring-cloud-gcp-firestore-sample">sample application</a> is available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
390
spring-cloud-gcp/1.2.0.M2/reference/html/getting-started.html
Normal file
@@ -0,0 +1,390 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Getting Started</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_getting_started">Getting Started</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_setting_up_dependencies">Setting up Dependencies</a></li>
|
||||
<li><a href="#_learning_spring_cloud_gcp">Learning Spring Cloud GCP</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_getting_started"><a class="link" href="#_getting_started">Getting Started</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>This section describes how to get up to speed with Spring Cloud GCP libraries.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_setting_up_dependencies"><a class="link" href="#_setting_up_dependencies">Setting up Dependencies</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>All Spring Cloud GCP artifacts are made available through Maven Central.
|
||||
The following resources are provided to help you setup the libraries for your project:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Maven Bill of Materials for dependency management</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Starter Dependencies for depending on Spring Cloud GCP modules</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You may also consult our <a href="https://github.com/spring-cloud/spring-cloud-gcp">Github project</a> to examine the code or build directly from source.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_bill_of_materials"><a class="link" href="#_bill_of_materials">Bill of Materials</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP Bill of Materials (BOM) contains the versions of all the dependencies it uses.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you’re a Maven user, adding the following to your pom.xml file will allow you omit any Spring Cloud GCP dependency version numbers from your configuration.
|
||||
Instead, the version of the BOM you’re using determines the versions of the used dependencies.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-dependencies</artifactId>
|
||||
<version>1.2.0.M2</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>See the <a href="#README.adoc">sections</a> in the README for selecting an available version and Maven repository.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In the following sections, it will be assumed you are using the Spring Cloud GCP BOM and the dependency snippets will not contain versions.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle users can achieve the same kind of BOM experience using Spring’s <a href="https://github.com/spring-gradle-plugins/dependency-management-plugin">dependency-management-plugin</a> Gradle plugin.
|
||||
For simplicity, the Gradle dependency snippets in the remainder of this document will also omit their versions.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_starter_dependencies"><a class="link" href="#_starter_dependencies">Starter Dependencies</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP offers <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-starters">starter dependencies</a> through Maven to easily depend on different modules of the library.
|
||||
Each starter contains all the dependencies and transitive dependencies needed to begin using their corresponding Spring Cloud GCP module.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, if you wish to write a Spring application with Cloud Pub/Sub, you would include the <code>spring-cloud-gcp-starter-pubsub</code> dependency in your project.
|
||||
You do <strong>not</strong> need to include the underlying <code>spring-cloud-gcp-pubsub</code> dependency, because the <code>starter</code> dependency includes it.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A summary of these artifacts are provided below.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3334%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Spring Cloud GCP Starter</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Maven Artifact Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Core</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Automatically configure authentication and Google project settings</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="core.html#spring-cloud-gcp-core">org.springframework.cloud:spring-cloud-gcp-starter</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Spanner</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides integrations with Google Cloud Spanner</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="spanner.html#_spring_data_cloud_spanner">org.springframework.cloud:spring-cloud-gcp-starter-data-spanner</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Datastore</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides integrations with Google Cloud Datastore</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="datastore.html#_spring_data_cloud_datastore">org.springframework.cloud:spring-cloud-gcp-starter-data-datastore</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Pub/Sub</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides integrations with Google Cloud Pub/Sub</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="pubsub.html#_google_cloud_pubsub">org.springframework.cloud:spring-cloud-gcp-starter-pubsub</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Logging</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables Stackdriver Logging</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="logging.html#_stackdriver_logging">org.springframework.cloud:spring-cloud-gcp-starter-logging</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SQL - MySQL</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud SQL integrations with MySQL</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="sql.html#_spring_jdbc">org.springframework.cloud:spring-cloud-gcp-starter-sql-mysql</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SQL - PostgreSQL</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud SQL integrations with PostgreSQL</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="sql.html#_spring_jdbc">org.springframework.cloud:spring-cloud-gcp-starter-sql-postgresql</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Storage</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides integrations with Google Cloud Storage and Spring Resource</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="storage.html#_spring_resources">org.springframework.cloud:spring-cloud-gcp-starter-storage</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Config</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables usage of Google Runtime Configuration API as a Spring Cloud Config server</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="config.html#_spring_cloud_config">org.springframework.cloud:spring-cloud-gcp-starter-config</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Trace</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables instrumentation with Google Stackdriver Tracing</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="trace.html#_spring_cloud_sleuth">org.springframework.cloud:spring-cloud-gcp-starter-trace</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides integrations with Google Cloud Vision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="vision.html#_google_cloud_vision">org.springframework.cloud:spring-cloud-gcp-starter-vision</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Security - IAP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides a security layer over applications deployed to Google Cloud</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="security-iap.html#_cloud_identity_aware_proxy_iap_authentication">org.springframework.cloud:spring-cloud-gcp-starter-security-iap</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_spring_initializr"><a class="link" href="#_spring_initializr">Spring Initializr</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://start.spring.io/">Spring Initializr</a> is a tool which generates the scaffolding code for a new Spring Boot project.
|
||||
It handles the work of generating the Maven or Gradle build file so you do not have to manually add the dependencies yourself.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Initializr offers three modules from Spring Cloud GCP that you can use to generate your project.</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>GCP Support</strong>: The GCP Support module contains auto-configuration support for every Spring Cloud GCP integration.
|
||||
Most of the autoconfiguration code is only enabled if the required dependency is added to your project.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>GCP Messaging</strong>: Google Cloud Pub/Sub integrations work out of the box.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>GCP Storage</strong>: Google Cloud Storage integrations work out of the box.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_learning_spring_cloud_gcp"><a class="link" href="#_learning_spring_cloud_gcp">Learning Spring Cloud GCP</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>There are a variety of resources to help you learn how to use Spring Cloud GCP libraries.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_sample_applications"><a class="link" href="#_sample_applications">Sample Applications</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The easiest way to learn how to use Spring Cloud GCP is to consult the <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples">sample applications on Github</a>.
|
||||
Spring Cloud GCP provides sample applications which demonstrate how to use every integration in the library.
|
||||
The table below highlights several samples of the most commonly used integrations in Spring Cloud GCP.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 50%;">
|
||||
<col style="width: 50%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">GCP Integration</th>
|
||||
<th class="tableblock halign-left valign-top">Sample Application</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Pub/Sub</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-sample">spring-cloud-gcp-pubsub-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Spanner</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-data-spanner-sample">spring-cloud-gcp-data-spanner-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Datastore</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-data-datastore-sample">spring-cloud-gcp-data-datastore-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud SQL (w/ MySQL)</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample">spring-cloud-gcp-sql-mysql-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Storage</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-storage-resource-sample">spring-cloud-gcp-storage-resource-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Stackdriver Logging</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-logging-sample">spring-cloud-gcp-logging-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Trace</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-trace-sample">spring-cloud-gcp-trace-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Vision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-vision-api-sample">spring-cloud-gcp-vision-api-sample</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Security - IAP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-security-iap-sample">spring-cloud-gcp-security-iap-sample</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="paragraph">
|
||||
<p>Each sample application demonstrates how to use Spring Cloud GCP libraries in context and how to setup the dependencies for the project.
|
||||
The applications are fully functional and can be deployed to Google Cloud Platform as well.
|
||||
If you are interested, you may consult guides for <a href="https://codelabs.developers.google.com/codelabs/cloud-app-engine-springboot/index.html">deploying an application to AppEngine</a> and <a href="https://codelabs.developers.google.com/codelabs/cloud-springboot-kubernetes/index.html">to Google Kubernetes Engine</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_codelabs"><a class="link" href="#_codelabs">Codelabs</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>For a more hands-on approach, there are several guides and codelabs to help you get up to speed.
|
||||
These guides provide step-by-step instructions for building an application using Spring Cloud GCP.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Some examples include:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-app-engine-springboot/index.html">Deploy a Spring Boot app to App Engine</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cloud-gcp-kotlin/index.html">Build a Kotlin Spring Boot app with Cloud SQL and Cloud Pub/Sub</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-spring-datastore/index.html">Build a Spring Boot application with Datastore</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cloud-gcp-pubsub-integration/index.html">Messaging with Spring Integration and Cloud Pub/Sub</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The full collection of Spring codelabs can be found on the <a href="https://codelabs.developers.google.com/spring">Google Developer Codelabs page</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 66 KiB |
2
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/highlight.min.js
vendored
Normal file
99
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/a11y-dark.min.css
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/* a11y-dark theme */
|
||||
/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */
|
||||
/* @author: ericwbailey */
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #d4d0ab;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion {
|
||||
color: #ffa07a;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #f5ab35;
|
||||
}
|
||||
|
||||
/* Yellow */
|
||||
.hljs-attribute {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition {
|
||||
color: #abe338;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #00e0e0;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #dcc6e0;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #2b2b2b;
|
||||
color: #f8f8f2;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-bullet,
|
||||
.hljs-comment,
|
||||
.hljs-link,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-params,
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-type,
|
||||
.hljs-quote {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
89
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/an-old-hope.min.css
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
An Old Hope – Star Wars Syntax (c) Gustavo Costa <gusbemacbe@gmail.com>
|
||||
Original theme - Ocean Dark Theme – by https://github.com/gavsiu
|
||||
Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom
|
||||
|
||||
*/
|
||||
|
||||
/* Death Star Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote
|
||||
{
|
||||
color: #B6B18B;
|
||||
}
|
||||
|
||||
/* Darth Vader */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion
|
||||
{
|
||||
color: #EB3C54;
|
||||
}
|
||||
|
||||
/* Threepio */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link
|
||||
{
|
||||
color: #E7CE56;
|
||||
}
|
||||
|
||||
/* Luke Skywalker */
|
||||
.hljs-attribute
|
||||
{
|
||||
color: #EE7C2B;
|
||||
}
|
||||
|
||||
/* Obi Wan Kenobi */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition
|
||||
{
|
||||
color: #4FB4D7;
|
||||
}
|
||||
|
||||
/* Yoda */
|
||||
.hljs-title,
|
||||
.hljs-section
|
||||
{
|
||||
color: #78BB65;
|
||||
}
|
||||
|
||||
/* Mace Windu */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag
|
||||
{
|
||||
color: #B45EA4;
|
||||
}
|
||||
|
||||
/* Millenium Falcon */
|
||||
.hljs
|
||||
{
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1C1D21;
|
||||
color: #c0c5ce;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
77
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/atom-one-dark-reasonable.min.css
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
|
||||
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
*/
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
line-height: 1.3em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.hljs-keyword, .hljs-operator {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match .hljs-constructor {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function .hljs-params {
|
||||
color: #A6E22E;
|
||||
}
|
||||
.hljs-function .hljs-params .hljs-typing {
|
||||
color: #FD971F;
|
||||
}
|
||||
.hljs-module-access .hljs-module {
|
||||
color: #7e57c2;
|
||||
}
|
||||
.hljs-constructor {
|
||||
color: #e2b93d;
|
||||
}
|
||||
.hljs-constructor .hljs-string {
|
||||
color: #9CCC65;
|
||||
}
|
||||
.hljs-comment, .hljs-quote {
|
||||
color: #b18eb1;
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-doctag, .hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
.hljs-built_in, .hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/atom-one-dark.min.css
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Dark by Daniel Gamage
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
base: #282c34
|
||||
mono-1: #abb2bf
|
||||
mono-2: #818896
|
||||
mono-3: #5c6370
|
||||
hue-1: #56b6c2
|
||||
hue-2: #61aeee
|
||||
hue-3: #c678dd
|
||||
hue-4: #98c379
|
||||
hue-5: #e06c75
|
||||
hue-5-2: #be5046
|
||||
hue-6: #d19a66
|
||||
hue-6-2: #e6c07b
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6370;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/atom-one-light.min.css
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
76
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/dracula.min.css
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Dracula Theme v1.2.0
|
||||
|
||||
https://github.com/zenorocha/dracula-theme
|
||||
|
||||
Copyright 2015, All rights reserved
|
||||
|
||||
Code licensed under the MIT license
|
||||
http://zenorocha.mit-license.org
|
||||
|
||||
@author Éverton Ribeiro <nuxlli@gmail.com>
|
||||
@author Zeno Rocha <hi@zenorocha.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #282a36;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-section,
|
||||
.hljs-link {
|
||||
color: #8be9fd;
|
||||
}
|
||||
|
||||
.hljs-function .hljs-keyword {
|
||||
color: #ff79c6;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #f1fa8c;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #6272a4;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
99
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/github.min.css
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
83
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/monokai-sublime.min.css
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
|
||||
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #23241f;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-tag,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-emphasis {
|
||||
color: #a8a8a2;
|
||||
}
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-quote,
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal,
|
||||
.hljs-link {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-class {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-attr {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-attribute {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.hljs-params,
|
||||
.hljs-class .hljs-title {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #75715e;
|
||||
}
|
||||
70
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/monokai.min.css
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Monokai style - ported by Luigi Maselli - http://grigio.org
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #272822; color: #ddd;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-strong,
|
||||
.hljs-name {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.hljs-code {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.hljs-class .hljs-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #bf79db;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet,
|
||||
.hljs-subst,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-emphasis,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #75715e;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-doctag,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-type,
|
||||
.hljs-selector-id {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/solarized-light.min.css
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
|
||||
Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #fdf6e3;
|
||||
color: #657b83;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #93a1a1;
|
||||
}
|
||||
|
||||
/* Solarized Green */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-addition {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
/* Solarized Cyan */
|
||||
.hljs-number,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-meta-string,
|
||||
.hljs-literal,
|
||||
.hljs-doctag,
|
||||
.hljs-regexp {
|
||||
color: #2aa198;
|
||||
}
|
||||
|
||||
/* Solarized Blue */
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
/* Solarized Yellow */
|
||||
.hljs-attribute,
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type {
|
||||
color: #b58900;
|
||||
}
|
||||
|
||||
/* Solarized Orange */
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-subst,
|
||||
.hljs-meta,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-link {
|
||||
color: #cb4b16;
|
||||
}
|
||||
|
||||
/* Solarized Red */
|
||||
.hljs-built_in,
|
||||
.hljs-deletion {
|
||||
color: #dc322f;
|
||||
}
|
||||
|
||||
.hljs-formula {
|
||||
background: #eee8d5;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
80
spring-cloud-gcp/1.2.0.M2/reference/html/js/highlight/styles/zenburn.min.css
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
|
||||
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
|
||||
based on dark.css by Ivan Sagalaev
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #3f3f3f;
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-tag {
|
||||
color: #e3ceab;
|
||||
}
|
||||
|
||||
.hljs-template-tag {
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #8cd0d3;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute {
|
||||
color: #efdcbc;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #efefaf;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
color: #8f8f8f;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-section,
|
||||
.hljs-type {
|
||||
color: #efef8f;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link {
|
||||
color: #dca3a3;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-string,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #cc9393;
|
||||
}
|
||||
|
||||
.hljs-addition,
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-meta {
|
||||
color: #7f9f7f;
|
||||
}
|
||||
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
107
spring-cloud-gcp/1.2.0.M2/reference/html/js/toc.js
Normal file
@@ -0,0 +1,107 @@
|
||||
var toctitle = document.getElementById('toctitle');
|
||||
var path = window.location.pathname;
|
||||
if (toctitle != null) {
|
||||
var oldtoc = toctitle.nextElementSibling;
|
||||
var newtoc = document.createElement('div');
|
||||
newtoc.setAttribute('id', 'tocbot');
|
||||
newtoc.setAttribute('class', 'js-toc desktop-toc');
|
||||
oldtoc.setAttribute('class', 'mobile-toc');
|
||||
oldtoc.parentNode.appendChild(newtoc);
|
||||
tocbot.init({
|
||||
contentSelector: '#content',
|
||||
headingSelector: 'h1, h2, h3, h4, h5',
|
||||
positionFixedSelector: 'body',
|
||||
fixedSidebarOffset: 90,
|
||||
smoothScroll: false
|
||||
});
|
||||
if (!path.endsWith("index.html") && !path.endsWith("/")) {
|
||||
var link = document.createElement("a");
|
||||
link.setAttribute("href", "index.html");
|
||||
link.innerHTML = "<span><i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i></span> Back to index";
|
||||
var block = document.createElement("div");
|
||||
block.setAttribute('class', 'back-action');
|
||||
block.appendChild(link);
|
||||
var toc = document.getElementById('toc');
|
||||
var next = document.getElementById('toctitle').nextElementSibling;
|
||||
toc.insertBefore(block, next);
|
||||
}
|
||||
}
|
||||
|
||||
var headerHtml = '<div id="header-spring">\n' +
|
||||
'<h1>\n' +
|
||||
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0"\n' +
|
||||
'viewBox="0 0 245.8 45.3" style="enable-background:new 0 0 245.8 45.3;" xml:space="preserve">\n' +
|
||||
'<g id="logos">\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st0" d="M39.4,3.7c-0.6,1.5-1.4,2.8-2.3,4c-3.9-4-9.3-6.4-15.2-6.4c-11.7,0-21.3,9.5-21.3,21.3\n' +
|
||||
'c0,6.2,2.6,11.7,6.8,15.6l0.8,0.7c3.7,3.1,8.5,5,13.7,5c11.2,0,20.4-8.7,21.2-19.8C43.7,18.7,42.1,11.8,39.4,3.7z M10.5,38.3\n' +
|
||||
'c-0.6,0.8-1.8,0.9-2.6,0.3C7.1,37.9,7,36.8,7.6,36c0.6-0.8,1.8-0.9,2.6-0.3C11,36.4,11.1,37.5,10.5,38.3z M39.3,31.9\n' +
|
||||
'c-5.2,7-16.5,4.6-23.6,5c0,0-1.3,0.1-2.6,0.3c0,0,0.5-0.2,1.1-0.4c5-1.7,7.4-2.1,10.5-3.7c5.8-3,11.5-9.4,12.7-16.1\n' +
|
||||
'c-2.2,6.4-8.9,12-14.9,14.2c-4.2,1.5-11.7,3-11.7,3c0,0-0.3-0.2-0.3-0.2c-5.1-2.5-5.3-13.6,4-17.1c4.1-1.6,8-0.7,12.4-1.8\n' +
|
||||
'C31.6,14.1,37,10.6,39.2,6C41.7,13.3,44.7,24.8,39.3,31.9z"/>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st0" d="M55.2,30.9c-0.5-0.3-0.9-0.9-0.9-1.6c0-1.1,0.8-1.9,1.9-1.9c0.4,0,0.7,0.1,1,0.3c2,1.3,4.1,2,5.9,2\n' +
|
||||
'c2,0,3.2-0.9,3.2-2.2v-0.1c0-1.6-2.2-2.2-4.6-2.9c-3-0.9-6.5-2.1-6.5-6.1v-0.1c0-3.9,3.2-6.3,7.4-6.3c2.2,0,4.5,0.6,6.5,1.7\n' +
|
||||
'c0.7,0.4,1.1,1,1.1,1.8c0,1.1-0.9,1.9-2,1.9c-0.4,0-0.6-0.1-0.9-0.2c-1.7-0.9-3.4-1.4-4.9-1.4c-1.8,0-2.9,0.9-2.9,2v0.1\n' +
|
||||
'c0,1.5,2.2,2.2,4.7,2.9c3,0.9,6.4,2.3,6.4,6v0.1c0,4.3-3.4,6.5-7.7,6.5C60.4,33.3,57.6,32.5,55.2,30.9z"/>\n' +
|
||||
'<path class="st0" d="M72.5,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1.4c1.5-2.2,3.7-3.9,7-3.9c4.8,0,9.6,3.8,9.6,10.7\n' +
|
||||
'v0.1c0,6.8-4.7,10.7-9.6,10.7c-3.4,0-5.6-1.7-7-3.6V37c0,1.3-1.1,2.4-2.4,2.4c-1.3,0-2.3-1-2.3-2.4V14.3z M89.1,22.7L89.1,22.7\n' +
|
||||
'c0-4.1-2.7-6.7-5.9-6.7c-3.2,0-6,2.7-6,6.6v0.1c0,4,2.8,6.6,6,6.6C86.4,29.3,89.1,26.7,89.1,22.7z"/>\n' +
|
||||
'<path class="st0" d="M95.7,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1.1c0.2-1.8,3.1-3.5,5.2-3.5c1.5,0,2.3,1,2.3,2.3\n' +
|
||||
'c0,1.3-0.8,2.1-1.9,2.3c-3.4,0.6-5.7,3.5-5.7,7.6V31c0,1.3-1.1,2.3-2.4,2.3c-1.3,0-2.3-1-2.3-2.3V14.3z"/>\n' +
|
||||
'<path class="st0" d="M109.7,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4V31c0,1.3-1.1,2.3-2.4,2.3c-1.3,0-2.3-1-2.3-2.3V14.3\n' +
|
||||
'z"/>\n' +
|
||||
'<path class="st0" d="M116.9,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1c1.3-1.9,3.2-3.4,6.5-3.4c4.7,0,7.4,3.1,7.4,7.9V31\n' +
|
||||
'c0,1.3-1,2.3-2.3,2.3c-1.3,0-2.4-1-2.4-2.3v-9.7c0-3.2-1.6-5-4.4-5c-2.7,0-4.7,1.9-4.7,5.1V31c0,1.3-1.1,2.3-2.4,2.3\n' +
|
||||
'c-1.3,0-2.3-1-2.3-2.3V14.3z"/>\n' +
|
||||
'<path class="st0" d="M156.2,11.9c-1.3,0-2.4,1.1-2.4,2.4v1.4c-1.5-2.2-3.7-3.9-7-3.9c-4.9,0-9.6,3.8-9.6,10.7v0.1\n' +
|
||||
'c0,6.8,4.7,10.7,9.6,10.7c3.4,0,5.6-1.7,7-3.6c-0.2,3.7-2.5,5.7-6.5,5.7c-2.4,0-4.5-0.6-6.3-1.6c-0.2-0.1-0.5-0.2-0.9-0.2\n' +
|
||||
'c-1.1,0-2,0.9-2,2c0,0.9,0.5,1.6,1.3,1.9c2.5,1.2,5.1,1.8,8,1.8c3.7,0,6.6-0.9,8.5-2.8c1.7-1.7,2.7-4.3,2.7-7.8V14.3\n' +
|
||||
'C158.5,13,157.5,11.9,156.2,11.9z M147.9,29.2c-3.2,0-5.9-2.5-5.9-6.6v-0.1c0-4,2.7-6.6,5.9-6.6c3.2,0,6,2.7,6,6.6v0.1\n' +
|
||||
'C153.9,26.6,151.1,29.2,147.9,29.2z"/>\n' +
|
||||
'<path class="st0" d="M114.5,6.3c0,1.3-1.1,2.4-2.4,2.4c-1.3,0-2.4-1.1-2.4-2.4c0-1.3,1.1-2.4,2.4-2.4\n' +
|
||||
'C113.4,3.9,114.5,4.9,114.5,6.3z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'<g class="st1">\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M200.1,21.1H198V19h2.1V21.1z M200.1,32.9H198V22.6h2.1V32.9z"/>\n' +
|
||||
'</g>\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M212.5,22.6l-3,8.9c-0.5,1.5-1.4,1.6-2.2,1.6c-1.1,0-1.8-0.5-2.2-1.6l-2.5-7.4h-1v-1.5h2.6l2.6,8.3\n' +
|
||||
'c0.1,0.4,0.2,0.6,0.5,0.6c0.3,0,0.4-0.2,0.5-0.6l2.6-8.3H212.5z"/>\n' +
|
||||
'<path class="st2" d="M217.8,22.6c2.8,0,4.7,1.8,4.7,4.5v1.6c0,2.6-1.9,4.5-4.7,4.5c-2.8,0-4.7-1.8-4.7-4.5v-1.6\n' +
|
||||
'C213,24.4,215,22.6,217.8,22.6 M217.8,31.4c1.7,0,2.7-1.3,2.7-2.8v-1.6c0-1.5-1-2.8-2.7-2.8c-1.8,0-2.7,1.3-2.7,2.8v1.6\n' +
|
||||
'C215.1,30.2,216,31.4,217.8,31.4"/>\n' +
|
||||
'<path class="st2" d="M239.6,22.9c-1.1-0.3-2.7-0.5-4-0.5c-2.8,0-4.6,1.8-4.6,4.6v1.1c0,2.9,1.7,4.7,4.6,4.7c0.1,0,0.6,0,0.8,0\n' +
|
||||
'v-1.7c-0.1,0-0.7,0-0.8,0c-1.5,0-2.6-1.2-2.6-2.9v-1.1c0-1.8,1-2.9,2.6-2.9c0.7,0,1.7,0.1,2.1,0.1l0.1,0l0,8.6h2.1v-9.6\n' +
|
||||
'C240,23.1,240,23,239.6,22.9"/>\n' +
|
||||
'<rect x="242.1" y="19" class="st2" width="2.1" height="13.9"/>\n' +
|
||||
'<path class="st2" d="M190.5,19h-3.8v13.9h2.2V20.9h1.3c0.3,0,0.5,0,0.8,0c1.9,0,2.9,0.8,2.9,2.3c0,0.1,0,0.1,0,0.2\n' +
|
||||
'c0,1.4-0.8,2.3-2.9,2.3c-0.2,0-0.4,0-0.6,0c0,0.5,0,1.5,0,1.9c0.2,0,0.4,0,0.6,0c3,0,5.2-1.2,5.2-4.2c0-0.1,0-0.1,0-0.2\n' +
|
||||
'C196.2,20.2,193.9,19,190.5,19"/>\n' +
|
||||
'<path class="st2" d="M226.3,20.4v2.2h3.5v1.7h-3.5v6c0,0.9,0.6,1,1.5,1h2v1.7H227c-2,0-2.9-0.8-2.9-2.6v-9.6L226.3,20.4z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M167.7,32.9v-10h1.1v3.8c0.6-0.8,1.5-1.3,2.4-1.3c1.9,0,3.2,1.5,3.2,3.8c0,2.4-1.3,3.8-3.2,3.8\n' +
|
||||
'c-1,0-1.9-0.5-2.4-1.3v1.1H167.7z M171,32.1c1.5,0,2.3-1.2,2.3-2.8c0-1.6-0.9-2.8-2.3-2.8c-0.9,0-1.8,0.5-2.2,1.2v3.3\n' +
|
||||
'C169.2,31.6,170.1,32.1,171,32.1z"/>\n' +
|
||||
'<path class="st2" d="M175.9,34.7c0.2,0.1,0.4,0.1,0.6,0.1c0.5,0,0.8-0.2,1.1-0.8l0.5-1.1l-3-7.3h1.2l2.4,5.9l2.4-5.9h1.2\n' +
|
||||
'l-3.6,8.7c-0.4,1-1.2,1.5-2.1,1.5c-0.2,0-0.6,0-0.8-0.1L175.9,34.7z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</svg>\n' +
|
||||
'\n' +
|
||||
'</h1>\n' +
|
||||
'</div>';
|
||||
|
||||
var header = document.createElement("div");
|
||||
header.innerHTML = headerHtml;
|
||||
document.body.insertBefore(header, document.body.firstChild);
|
||||
@@ -0,0 +1 @@
|
||||
.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B}
|
||||
1
spring-cloud-gcp/1.2.0.M2/reference/html/js/tocbot/tocbot.min.js
vendored
Normal file
166
spring-cloud-gcp/1.2.0.M2/reference/html/kotlin.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Kotlin Support</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_kotlin_support">Kotlin Support</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_prerequisites">Prerequisites</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_kotlin_support"><a class="link" href="#_kotlin_support">Kotlin Support</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>The latest version of the Spring Framework provides first-class support for Kotlin.
|
||||
For Kotlin users of Spring, the Spring Cloud GCP libraries work out-of-the-box and are fully interoperable with Kotlin applications.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For more information on building a Spring application in Kotlin, please consult the <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/languages.html#kotlin">Spring Kotlin documentation</a>.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_prerequisites"><a class="link" href="#_prerequisites">Prerequisites</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Ensure that your Kotlin application is properly set up.
|
||||
Based on your build system, you will need to include the correct Kotlin build plugin in your project:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://kotlinlang.org/docs/reference/using-maven.html">Kotlin Maven Plugin</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://kotlinlang.org/docs/reference/using-gradle.html">Kotlin Gradle Plugin</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Depending on your application’s needs, you may need to augment your build configuration with compiler plugins:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support">Kotlin Spring Plugin</a>: Makes your Spring configuration classes/members non-final for convenience.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support">Kotlin JPA Plugin</a>: Enables using JPA in Kotlin applications.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Once your Kotlin project is properly configured, the Spring Cloud GCP libraries will work within your application without any additional setup.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample">Kotlin sample application</a> is provided to demonstrate a working Maven setup and various Spring Cloud GCP integrations from within Kotlin.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
430
spring-cloud-gcp/1.2.0.M2/reference/html/logging.html
Normal file
@@ -0,0 +1,430 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Stackdriver Logging</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_stackdriver_logging">Stackdriver Logging</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_web_mvc_interceptor">Web MVC Interceptor</a></li>
|
||||
<li><a href="#_logback_support">Logback Support</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_stackdriver_logging"><a class="link" href="#_stackdriver_logging">Stackdriver Logging</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-logging</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-logging'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.google.com/logging/">Stackdriver Logging</a> is the managed logging service provided by Google Cloud Platform.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This module provides support for associating a web request trace ID with the corresponding log entries.
|
||||
It does so by retrieving the <code>X-B3-TraceId</code> value from the <a href="https://logback.qos.ch/manual/mdc.html">Mapped Diagnostic Context (MDC)</a>, which is set by Spring Cloud Sleuth.
|
||||
If Spring Cloud Sleuth isn’t used, the configured <code>TraceIdExtractor</code> extracts the desired header value and sets it as the log entry’s trace ID.
|
||||
This allows grouping of log messages by request, for example, in the <a href="https://console.cloud.google.com/logs/viewer">Google Cloud Console Logs viewer</a>.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Due to the way logging is set up, the GCP project ID and credentials defined in <code>application.properties</code> are ignored.
|
||||
Instead, you should set the <code>GOOGLE_CLOUD_PROJECT</code> and <code>GOOGLE_APPLICATION_CREDENTIALS</code> environment variables to the project ID and credentials private key location, respectively.
|
||||
You can do this easily if you’re using the <a href="https://cloud.google.com/sdk">Google Cloud SDK</a>, using the <code>gcloud config set project [YOUR_PROJECT_ID]</code> and <code>gcloud auth application-default login</code> commands, respectively.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_web_mvc_interceptor"><a class="link" href="#_web_mvc_interceptor">Web MVC Interceptor</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>For use in Web MVC-based applications, <code>TraceIdLoggingWebMvcInterceptor</code> is provided that extracts the request trace ID from an HTTP request using a <code>TraceIdExtractor</code> and stores it in a thread-local, which can then be used in a logging appender to add the trace ID metadata to log messages.</p>
|
||||
</div>
|
||||
<div class="admonitionblock warning">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-warning" title="Warning"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If Spring Cloud GCP Trace is enabled, the logging module disables itself and delegates log correlation to Spring Cloud Sleuth.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>LoggingWebMvcConfigurer</code> configuration class is also provided to help register the <code>TraceIdLoggingWebMvcInterceptor</code> in Spring MVC applications.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Applications hosted on the Google Cloud Platform include trace IDs under the <code>x-cloud-trace-context</code> header, which will be included in log entries.
|
||||
However, if Sleuth is used the trace ID will be picked up from the MDC.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_logback_support"><a class="link" href="#_logback_support">Logback Support</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Currently, only Logback is supported and there are 2 possibilities to log to Stackdriver via this library with Logback: via direct API calls and through JSON-formatted console logs.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_log_via_api"><a class="link" href="#_log_via_api">Log via API</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>A Stackdriver appender is available using <code>org/springframework/cloud/gcp/logging/logback-appender.xml</code>.
|
||||
This appender builds a Stackdriver Logging log entry from a JUL or Logback log entry, adds a trace ID to it and sends it to Stackdriver Logging.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>STACKDRIVER_LOG_NAME</code> and <code>STACKDRIVER_LOG_FLUSH_LEVEL</code> environment variables can be used to customize the <code>STACKDRIVER</code> appender.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Your configuration may then look like this:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><configuration>
|
||||
<include resource="org/springframework/cloud/gcp/logging/logback-appender.xml" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STACKDRIVER" />
|
||||
</root>
|
||||
</configuration></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you want to have more control over the log output, you can further configure the appender.
|
||||
The following properties are available:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3334%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Property</th>
|
||||
<th class="tableblock halign-left valign-top">Default Value</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>log</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.log</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The Stackdriver Log name.
|
||||
This can also be set via the <code>STACKDRIVER_LOG_NAME</code> environmental variable.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>flushLevel</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WARN</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">If a log entry with this level is encountered, trigger a flush of locally buffered log to Stackdriver Logging.
|
||||
This can also be set via the <code>STACKDRIVER_LOG_FLUSH_LEVEL</code> environmental variable.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_log_via_console"><a class="link" href="#_log_via_console">Log via Console</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>For Logback, a <code>org/springframework/cloud/gcp/logging/logback-json-appender.xml</code> file is made available for import to make it easier to configure the JSON Logback appender.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Your configuration may then look something like this:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><configuration>
|
||||
<include resource="org/springframework/cloud/gcp/logging/logback-json-appender.xml" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE_JSON" />
|
||||
</root>
|
||||
</configuration></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If your application is running on Google Kubernetes Engine, Google Compute Engine or Google App Engine Flexible, your console logging is automatically saved to Google Stackdriver Logging.
|
||||
Therefore, you can just include <code>org/springframework/cloud/gcp/logging/logback-json-appender.xml</code> in your logging configuration, which logs JSON entries to the console.
|
||||
The trace id will be set correctly.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you want to have more control over the log output, you can further configure the appender.
|
||||
The following properties are available:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3334%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Property</th>
|
||||
<th class="tableblock halign-left valign-top">Default Value</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>projectId</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
|
||||
<p>If not set, default value is determined in the following order:</p>
|
||||
</div>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p><code>SPRING_CLOUD_GCP_LOGGING_PROJECT_ID</code> Environmental Variable.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Value of <code>DefaultGcpProjectIdProvider.getProjectId()</code></p>
|
||||
</li>
|
||||
</ol>
|
||||
</div></div></td>
|
||||
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
|
||||
<p>This is used to generate fully qualified Stackdriver Trace ID format: <code>projects/[PROJECT-ID]/traces/[TRACE-ID]</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This format is required to correlate trace between Stackdriver Trace and Stackdriver Logging.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If <code>projectId</code> is not set and cannot be determined, then it’ll log <code>traceId</code> without the fully qualified format.</p>
|
||||
</div></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeTraceId</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the <code>traceId</code> be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeSpanId</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the <code>spanId</code> be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeLevel</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the severity be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeThreadName</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the thread name be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeMDC</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should all MDC properties be included.
|
||||
The MDC properties <code>X-B3-TraceId</code>, <code>X-B3-SpanId</code> and <code>X-Span-Export</code> provided by Spring Sleuth will get excluded as they get handled separately</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeLoggerName</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the name of the logger be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeFormattedMessage</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the formatted log message be included.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeExceptionInMessage</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the stacktrace be appended to the formatted log message.
|
||||
This setting is only evaluated if <code>includeFormattedMessage</code> is <code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeContextName</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the logging context be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeMessage</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the log message with blank placeholders be included</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>includeException</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the stacktrace be included as a own field</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>serviceContext</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">none</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Define the Stackdriver service context data (service and version). This allows filtering of error reports for service and version in the <a href="https://console.cloud.google.com/errors">Google Cloud Error Reporting View</a>.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>customJson</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">none</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Defines custom json data. Data will be added to the json output.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="paragraph">
|
||||
<p>This is an example of such an Logback configuration:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><configuration >
|
||||
<property name="projectId" value="${projectId:-${GOOGLE_CLOUD_PROJECT}}"/>
|
||||
|
||||
<appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="org.springframework.cloud.gcp.logging.StackdriverJsonLayout">
|
||||
<projectId>${projectId}</projectId>
|
||||
|
||||
<!--<includeTraceId>true</includeTraceId>-->
|
||||
<!--<includeSpanId>true</includeSpanId>-->
|
||||
<!--<includeLevel>true</includeLevel>-->
|
||||
<!--<includeThreadName>true</includeThreadName>-->
|
||||
<!--<includeMDC>true</includeMDC>-->
|
||||
<!--<includeLoggerName>true</includeLoggerName>-->
|
||||
<!--<includeFormattedMessage>true</includeFormattedMessage>-->
|
||||
<!--<includeExceptionInMessage>true</includeExceptionInMessage>-->
|
||||
<!--<includeContextName>true</includeContextName>-->
|
||||
<!--<includeMessage>false</includeMessage>-->
|
||||
<!--<includeException>false</includeException>-->
|
||||
<!--<serviceContext>
|
||||
<service>service-name</service>
|
||||
<version>service-version</version>
|
||||
</serviceContext>-->
|
||||
<!--<customJson>{"custom-key": "custom-value"}</customJson>-->
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
</configuration></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-logging-sample">Sample Spring Boot Application</a> is provided to show how to use the Cloud logging starter.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
176
spring-cloud-gcp/1.2.0.M2/reference/html/memorystore.html
Normal file
@@ -0,0 +1,176 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Cloud Memorystore for Redis</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_cloud_memorystore_for_redis">Cloud Memorystore for Redis</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_spring_caching">Spring Caching</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_cloud_memorystore_for_redis"><a class="link" href="#_cloud_memorystore_for_redis">Cloud Memorystore for Redis</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="sect2">
|
||||
<h3 id="_spring_caching"><a class="link" href="#_spring_caching">Spring Caching</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.google.com/memorystore/">Cloud Memorystore for Redis</a> provides a fully managed in-memory data store service.
|
||||
Cloud Memorystore is compatible with the Redis protocol, allowing easy integration with <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html">Spring Caching</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>All you have to do is create a Cloud Memorystore instance and use its IP address in <code>application.properties</code> file as <code>spring.redis.host</code> property value.
|
||||
Everything else is exactly the same as setting up redis-backed Spring caching.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
<div class="paragraph">
|
||||
<p>Memorystore instances and your application instances have to be located in the same region.</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In short, the following dependencies are needed:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>And then you can use <code>org.springframework.cache.annotation.Cacheable</code> annotation for methods you’d like to be cached.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Cacheable("cache1")
|
||||
public String hello(@PathVariable String name) {
|
||||
....
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you are interested in a detailed how-to guide, please check <a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cache-memorystore/">Spring Boot Caching using Cloud Memorystore codelab</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Cloud Memorystore documentation can be found <a href="https://cloud.google.com/memorystore/docs/redis/">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
823
spring-cloud-gcp/1.2.0.M2/reference/html/pubsub.html
Normal file
@@ -0,0 +1,823 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Google Cloud Pub/Sub</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_google_cloud_pubsub">Google Cloud Pub/Sub</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
<li><a href="#_pubsub_operations_template">Pub/Sub Operations & Template</a></li>
|
||||
<li><a href="#_reactive_stream_subscription">Reactive Stream Subscription</a></li>
|
||||
<li><a href="#_pubsub_management">Pub/Sub management</a></li>
|
||||
<li><a href="#pubsub-configuration">Configuration</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_google_cloud_pubsub"><a class="link" href="#_google_cloud_pubsub">Google Cloud Pub/Sub</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides an abstraction layer to publish to and subscribe from Google Cloud Pub/Sub topics and to create, list or delete Google Cloud Pub/Sub topics and subscriptions.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A Spring Boot starter is provided to auto-configure the various required Pub/Sub components.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-pubsub'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This starter is also available from <a href="https://start.spring.io">Spring Initializr</a> through the <code>GCP Messaging</code> entry.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Sample applications for <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-sample">using the template</a> and <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-reactive-sample">using a subscription-backed reactive stream</a> are available.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_pubsub_operations_template"><a class="link" href="#_pubsub_operations_template">Pub/Sub Operations & Template</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubOperations</code> is an abstraction that allows Spring users to use Google Cloud Pub/Sub without depending on any Google Cloud Pub/Sub API semantics.
|
||||
It provides the common set of operations needed to interact with Google Cloud Pub/Sub.
|
||||
<code>PubSubTemplate</code> is the default implementation of <code>PubSubOperations</code> and it uses the <a href="https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-pubsub">Google Cloud Java Client for Pub/Sub</a> to interact with Google Cloud Pub/Sub.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_publishing_to_a_topic"><a class="link" href="#_publishing_to_a_topic">Publishing to a topic</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubTemplate</code> provides asynchronous methods to publish messages to a Google Cloud Pub/Sub topic.
|
||||
The <code>publish()</code> method takes in a topic name to post the message to, a payload of a generic type and, optionally, a map with the message headers.
|
||||
The topic name could either be a canonical topic name within the current project, or the fully-qualified name referring to a topic in a different project using the <code>projects/<project_name>/topics/<topic_name></code> format.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to publish a message to a Google Cloud Pub/Sub topic:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Map<String, String> headers = Collections.singletonMap("key1", "val1");
|
||||
pubSubTemplate.publish(topicName, "message", headers).get();</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>By default, the <code>SimplePubSubMessageConverter</code> is used to convert payloads of type <code>byte[]</code>, <code>ByteString</code>, <code>ByteBuffer</code>, and <code>String</code> to Pub/Sub messages.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_subscribing_to_a_subscription"><a class="link" href="#_subscribing_to_a_subscription">Subscribing to a subscription</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>Google Cloud Pub/Sub allows many subscriptions to be associated to the same topic.
|
||||
<code>PubSubTemplate</code> allows you to listen to subscriptions via the <code>subscribe()</code> method.
|
||||
When listening to a subscription, messages will be pulled from Google Cloud Pub/Sub
|
||||
asynchronously and passed to a user provided message handler.</p>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_example"><a class="link" href="#_example">Example</a></h5>
|
||||
<div class="paragraph">
|
||||
<p>Subscribe to a subscription with a message handler:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Subscriber subscriber = pubSubTemplate.subscribe(subscriptionName, (message) -> {
|
||||
logger.info("Message received from " + subscriptionName + " subscription: "
|
||||
+ message.getPubsubMessage().getData().toStringUtf8());
|
||||
message.ack();
|
||||
});</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_subscribe_methods"><a class="link" href="#_subscribe_methods">Subscribe methods</a></h5>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubTemplate</code> provides the following subscribe methods:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 20%;">
|
||||
<col style="width: 80%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">subscribe(String subscription, Consumer<BasicAcknowledgeablePubsubMessage> messageConsumer)</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">asynchronously pulls messages and passes them to <code>messageConsumer</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">subscribeAndConvert(String subscription,
|
||||
Consumer<ConvertedBasicAcknowledgeablePubsubMessage<T>> messageConsumer,
|
||||
Class<T> payloadType)</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">same as <code>pull</code>, but converts message payload to <code>payloadType</code> using the converter configured in the template</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_pulling_messages_from_a_subscription"><a class="link" href="#_pulling_messages_from_a_subscription">Pulling messages from a subscription</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>Google Cloud Pub/Sub supports synchronous pulling of messages from a subscription.
|
||||
This is different from subscribing to a subscription, in the sense that subscribing is an asynchronous task.</p>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_example_2"><a class="link" href="#_example_2">Example</a></h5>
|
||||
<div class="paragraph">
|
||||
<p>Pull up to 10 messages:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">int maxMessages = 10;
|
||||
boolean returnImmediately = false;
|
||||
List<AcknowledgeablePubsubMessage> messages = pubSubTemplate.pull(subscriptionName, maxMessages,
|
||||
returnImmediately);
|
||||
|
||||
//acknowledge the messages
|
||||
pubSubTemplate.ack(messages);
|
||||
|
||||
messages.forEach(message -> logger.info(message.getPubsubMessage().getData().toStringUtf8()));</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_pull_methods"><a class="link" href="#_pull_methods">Pull methods</a></h5>
|
||||
<div class="paragraph">
|
||||
<p><code>PubsubTemplate</code> provides the following pull methods:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 20%;">
|
||||
<col style="width: 80%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">pull(String subscription, Integer maxMessages,
|
||||
Boolean returnImmediately)</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Pulls a number of messages from a subscription, allowing for the retry settings to be configured.
|
||||
Any messages received by <code>pull()</code> are not automatically acknowledged. See <a href="#_acknowledging_messages">Acknowledging messages</a>.</p>
|
||||
<p class="tableblock"> If <code>returnImmediately</code> is <code>true</code>, the system will respond immediately even if it there are no messages available to return in the <code>Pull</code> response. Otherwise, the system may wait (for a bounded amount of time) until at least one message is available, rather than returning no messages.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">pullAndAck</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Works the same as the <code>pull</code> method and, additionally, acknowledges all received messages.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">pullNext</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Allows for a single message to be pulled and automatically acknowledged from a subscription.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top"><p class="tableblock">pullAndConvert</p></th>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Works the same as the <code>pull</code> method and, additionally, converts the Pub/Sub binary payload to an object of the desired type, using the converter configured in the template.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_acknowledging_messages"><a class="link" href="#_acknowledging_messages">Acknowledging messages</a></h5>
|
||||
<div class="paragraph">
|
||||
<p>There are two ways to acknowledge messages.</p>
|
||||
</div>
|
||||
<div class="olist arabic">
|
||||
<ol class="arabic">
|
||||
<li>
|
||||
<p>To acknowledge multiple messages at once, you can use the <code>PubSubTemplate.ack()</code> method.
|
||||
You can also use the <code>PubSubTemplate.nack()</code> for negatively acknowledging messages.
|
||||
Using these methods for acknowledging messages in batches is more efficient than acknowledging messages individually, but they <strong>require</strong> the collection of messages to be from the same project.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>To acknowledge messages individually you can use the <code>ack()</code> or <code>nack()</code> method on each of them (to acknowledge or negatively acknowledge, correspondingly).</p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
All <code>ack()</code>, <code>nack()</code>, and <code>modifyAckDeadline()</code> methods on messages as well as <code>PubSubSubscriberTemplate</code> are implemented asynchronously, returning a <code>ListenableFuture<Void></code> to be able to process the asynchronous execution.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_json_support"><a class="link" href="#_json_support">JSON support</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>For serialization and deserialization of POJOs using Jackson JSON, configure a <code>PubSubMessageConverter</code> bean, and the Spring Boot starter for GCP Pub/Sub will automatically wire it into the <code>PubSubTemplate</code>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">// Note: The ObjectMapper is used to convert Java POJOs to and from JSON.
|
||||
// You will have to configure your own instance if you are unable to depend
|
||||
// on the ObjectMapper provided by Spring Boot starters.
|
||||
@Bean
|
||||
public PubSubMessageConverter pubSubMessageConverter() {
|
||||
return new JacksonPubSubMessageConverter(new ObjectMapper());
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Alternatively, you can set it directly by calling the <code>setMessageConverter()</code> method on the <code>PubSubTemplate</code>.
|
||||
Other implementations of the <code>PubSubMessageConverter</code> can also be configured in the same manner.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Assuming you have the following class defined:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">static class TestUser {
|
||||
|
||||
String username;
|
||||
|
||||
String password;
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can serialize objects to JSON on publish automatically:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">TestUser user = new TestUser();
|
||||
user.setUsername("John");
|
||||
user.setPassword("password");
|
||||
pubSubTemplate.publish(topicName, user);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>And thatt’s how you convert messages to objects on pull:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">int maxMessages = 1;
|
||||
boolean returnImmediately = false;
|
||||
List<ConvertedAcknowledgeablePubsubMessage<TestUser>> messages = pubSubTemplate.pullAndConvert(
|
||||
subscriptionName, maxMessages, returnImmediately, TestUser.class);
|
||||
|
||||
ConvertedAcknowledgeablePubsubMessage<TestUser> message = messages.get(0);
|
||||
|
||||
//acknowledge the message
|
||||
message.ack();
|
||||
|
||||
TestUser receivedTestUser = message.getPayload();</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Please refer to our <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-json-sample">Pub/Sub JSON Payload Sample App</a> as a reference for using this functionality.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_reactive_stream_subscription"><a class="link" href="#_reactive_stream_subscription">Reactive Stream Subscription</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>It is also possible to acquire a reactive stream backed by a subscription.
|
||||
To do so, a Project Reactor dependency (<code>io.projectreactor:reactor-core</code>) must be added to the project.
|
||||
The combination of the Pub/Sub starter and the Project Reactor dependencies will then make a <code>PubSubReactiveFactory</code> bean available, which can then be used to get a <code>Publisher</code>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
||||
PubSubReactiveFactory reactiveFactory;
|
||||
|
||||
// ...
|
||||
|
||||
Flux<AcknowledgeablePubsubMessage> flux
|
||||
= reactiveFactory.createPolledFlux("exampleSubscription", 1000);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>Flux</code> then represents an infinite stream of GCP Pub/Sub messages coming in through the specified subscription.
|
||||
For unlimited demand, the Pub/Sub subscription will be polled regularly, at intervals determined by <code>pollingPeriodMs</code> parameter passed in when creating the <code>Flux</code>.
|
||||
For bounded demand, the <code>pollingPeriodMs</code> parameter is unused.
|
||||
Instead, as many messages as possible (up to the requested number) are delivered immediately, with the remaining messages delivered as they become available.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The full range of Project Reactor operations can be applied to the stream.
|
||||
For example, if you only want to fetch 5 messages, you can use <code>limitRequest</code> operation to turn the infinite stream into a finite one:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">Flux<AcknowledgeablePubsubMessage> fiveMessageFlux = flux.limitRequest(5);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Acknowledging messages flowing through the <code>Flux</code> should be manually acknowledged.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">flux.doOnNext(AcknowledgeablePubsubMessage::ack);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_pubsub_management"><a class="link" href="#_pubsub_management">Pub/Sub management</a></h3>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> is the abstraction provided by Spring Cloud GCP to manage Google Cloud Pub/Sub resources.
|
||||
It allows for the creation, deletion and listing of topics and subscriptions.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Generally when referring to topics, you can either use the short canonical topic name within the current project, or the fully-qualified name referring to a topic in a different project using the <code>projects/<project_name>/topics/<topic_name></code> format.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> depends on <code>GcpProjectIdProvider</code> and either a <code>CredentialsProvider</code> or a <code>TopicAdminClient</code> and a <code>SubscriptionAdminClient</code>.
|
||||
If given a <code>CredentialsProvider</code>, it creates a <code>TopicAdminClient</code> and a <code>SubscriptionAdminClient</code> with the Google Cloud Java Library for Pub/Sub default settings.
|
||||
The Spring Boot starter for GCP Pub/Sub auto-configures a <code>PubSubAdmin</code> object using the <code>GcpProjectIdProvider</code> and the <code>CredentialsProvider</code> auto-configured by the Spring Boot GCP Core starter.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_creating_a_topic"><a class="link" href="#_creating_a_topic">Creating a topic</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to create topics:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Topic createTopic(String topicName)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to create a Google Cloud Pub/Sub topic:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void newTopic() {
|
||||
pubSubAdmin.createTopic("topicName");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_deleting_a_topic"><a class="link" href="#_deleting_a_topic">Deleting a topic</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to delete topics:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void deleteTopic(String topicName)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to delete a Google Cloud Pub/Sub topic:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void deleteTopic() {
|
||||
pubSubAdmin.deleteTopic("topicName");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_listing_topics"><a class="link" href="#_listing_topics">Listing topics</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to list topics:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public List<Topic> listTopics</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to list every Google Cloud Pub/Sub topic name in a project:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">List<String> topics = pubSubAdmin
|
||||
.listTopics()
|
||||
.stream()
|
||||
.map(Topic::getName)
|
||||
.collect(Collectors.toList());</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_creating_a_subscription"><a class="link" href="#_creating_a_subscription">Creating a subscription</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to create subscriptions to existing topics:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Subscription createSubscription(String subscriptionName, String topicName, Integer ackDeadline, String pushEndpoint)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to create a Google Cloud Pub/Sub subscription:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void newSubscription() {
|
||||
pubSubAdmin.createSubscription("subscriptionName", "topicName", 10, “https://my.endpoint/push”);
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Alternative methods with default settings are provided for ease of use.
|
||||
The default value for <code>ackDeadline</code> is 10 seconds.
|
||||
If <code>pushEndpoint</code> isn’t specified, the subscription uses message pulling, instead.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Subscription createSubscription(String subscriptionName, String topicName)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Subscription createSubscription(String subscriptionName, String topicName, Integer ackDeadline)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public Subscription createSubscription(String subscriptionName, String topicName, String pushEndpoint)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_deleting_a_subscription"><a class="link" href="#_deleting_a_subscription">Deleting a subscription</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to delete subscriptions:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void deleteSubscription(String subscriptionName)</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to delete a Google Cloud Pub/Sub subscription:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public void deleteSubscription() {
|
||||
pubSubAdmin.deleteSubscription("subscriptionName");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_listing_subscriptions"><a class="link" href="#_listing_subscriptions">Listing subscriptions</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubAdmin</code> implements a method to list subscriptions:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public List<Subscription> listSubscriptions()</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to list every subscription name in a project:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">List<String> subscriptions = pubSubAdmin
|
||||
.listSubscriptions()
|
||||
.stream()
|
||||
.map(Subscription::getName)
|
||||
.collect(Collectors.toList());</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="pubsub-configuration"><a class="link" href="#pubsub-configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Boot starter for Google Cloud Pub/Sub provides the following configuration options:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables or disables Pub/Sub auto-configuration</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.project-id</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">GCP project ID where the Google Cloud Pub/Sub API is hosted, if different from the one in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">OAuth2 credentials for authenticating with the
|
||||
Google Cloud Pub/Sub API, if different from the ones in the
|
||||
<a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Base64-encoded contents of OAuth2 account private key for authenticating with the
|
||||
Google Cloud Pub/Sub API, if different from the ones in the
|
||||
<a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.credentials.scopes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://developers.google.com/identity/protocols/googlescopes">OAuth2 scope</a> for Spring Cloud GCP
|
||||
Pub/Sub credentials</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/pubsub" class="bare">https://www.googleapis.com/auth/pubsub</a></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.keepAliveIntervalMinutes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Determines frequency of keepalive gRPC ping</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>5 minutes</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.subscriber.parallel-pull-count</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The number of pull workers</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The available number of processors</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.subscriber.max-ack-extension-period</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The maximum period a message ack deadline will be extended, in seconds</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.subscriber.pull-endpoint</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The endpoint for synchronous pulling messages</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">pubsub.googleapis.com:443</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].executor-threads</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of threads used by <code>Subscriber</code> instances created by <code>SubscriberFactory</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.total-timeout-seconds</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">TotalTimeout has ultimate control over how long the logic should keep trying the remote call until it gives up completely.
|
||||
The higher the total timeout, the more retries can be attempted.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.initial-retry-delay-second</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">InitialRetryDelay controls the delay before the first retry.
|
||||
Subsequent retries will use this value adjusted according to the RetryDelayMultiplier.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.retry-delay-multiplier</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">RetryDelayMultiplier controls the change in retry delay.
|
||||
The retry delay of the previous call is multiplied by the RetryDelayMultiplier to calculate the retry delay for the next call.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.max-retry-delay-seconds</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">MaxRetryDelay puts a limit on the value of the retry delay, so that the RetryDelayMultiplier
|
||||
can’t increase the retry delay higher than this amount.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.max-attempts</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">MaxAttempts defines the maximum number of attempts to perform.
|
||||
If this value is greater than 0, and the number of attempts reaches this limit, the logic will give up retrying even if the total retry time is still lower than TotalTimeout.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.jittered</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Jitter determines if the delay time should be randomized.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.initial-rpc-timeout-seconds</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">InitialRpcTimeout controls the timeout for the initial RPC.
|
||||
Subsequent calls will use this value adjusted according to the RpcTimeoutMultiplier.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.rpc-timeout-multiplier</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">RpcTimeoutMultiplier controls the change in RPC timeout.
|
||||
The timeout of the previous call is multiplied by the RpcTimeoutMultiplier to calculate the timeout for the next call.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher].retry.max-rpc-timeout-seconds</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">MaxRpcTimeout puts a limit on the value of the RPC timeout, so that the RpcTimeoutMultiplier
|
||||
can’t increase the RPC timeout higher than this amount.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher.batching].flow-control.max-outstanding-element-count</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum number of outstanding elements to keep in memory before enforcing flow control.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher.batching].flow-control.max-outstanding-request-bytes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum number of outstanding bytes to keep in memory before enforcing flow control.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unlimited</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.[subscriber,publisher.batching].flow-control.limit-exceeded-behavior</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The behavior when the specified limits are exceeded.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Block</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.publisher.batching.element-count-threshold</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The element count threshold to use for batching.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unset (threshold does not apply)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.publisher.batching.request-byte-threshold</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The request byte threshold to use for batching.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unset (threshold does not apply)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.publisher.batching.delay-threshold-seconds</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">The delay threshold to use for batching.
|
||||
After this amount of time has elapsed (counting from the first element added), the elements will be wrapped up in a batch and sent.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unset (threshold does not apply)</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.pubsub.publisher.batching.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables batching.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
105
spring-cloud-gcp/1.2.0.M2/reference/html/sagan-boot.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Untitled</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book">
|
||||
<div id="header">
|
||||
</div>
|
||||
<div id="content">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
271
spring-cloud-gcp/1.2.0.M2/reference/html/sagan-index.html
Normal file
@@ -0,0 +1,271 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Features</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_features">Features</a></li>
|
||||
<li><a href="#_spring_initializr">Spring Initializr</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_gcp_support">GCP Support</a></li>
|
||||
<li><a href="#_gcp_messaging">GCP Messaging</a></li>
|
||||
<li><a href="#_gcp_storage">GCP Storage</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#_code_samples">Code Samples</a></li>
|
||||
<li><a href="#_code_challenges">Code Challenges</a></li>
|
||||
<li><a href="#_getting_started_guides">Getting Started Guides</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="preamble">
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP project makes the Spring Framework a first-class citizen of Google Cloud Platform (GCP).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_features"><a class="link" href="#_features">Features</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>The Spring Cloud GCP project offers the following features:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Spring Cloud GCP Pub/Sub, including Spring Integration Channel Adapters</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Cloud GCP Pub/Sub Stream Binder</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Resource Abstraction for Google Cloud Storage, including Spring Integration Channel Adapters</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Data Cloud SQL</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Data Cloud Spanner</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Spring Data Cloud Datastore</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Cloud Vision API Template</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Cloud Stackdriver Logging & Tracing</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Google Cloud Config (Beta)</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_initializr"><a class="link" href="#_spring_initializr">Spring Initializr</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>There are three entries in <a href="http://start.spring.io/">Spring Initializr</a> for Spring Cloud GCP.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_gcp_support"><a class="link" href="#_gcp_support">GCP Support</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The GCP Support entry contains auto-configuration support for every Spring Cloud GCP integration.
|
||||
Most of the auto-configuration code is only enabled if other dependencies are added to the classpath.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 50%;">
|
||||
<col style="width: 50%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Spring Cloud GCP Starter</th>
|
||||
<th class="tableblock halign-left valign-top">Required dependencies</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Config</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-config</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Spanner</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-data-spanner</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Cloud Datastore</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-data-datastore</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Logging</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-logging</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SQL - MySql</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-sql-mysql</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">SQL - PostgreSQL</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-sql-postgres</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Trace</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-trace</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Vision</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-vision</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Security - IAP</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>org.springframework.cloud:spring-cloud-gcp-starter-security-iap</code></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_gcp_messaging"><a class="link" href="#_gcp_messaging">GCP Messaging</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The GCP Messaging entry adds the GCP Support entry and all the required dependencies so that the Google Cloud Pub/Sub integration work out of the box.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_gcp_storage"><a class="link" href="#_gcp_storage">GCP Storage</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The GCP Storage entry adds the GCP Support entry and all the required dependencies so that the Google Cloud Storage integration work out of the box.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_code_samples"><a class="link" href="#_code_samples">Code Samples</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>There are <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples">code samples</a> available that demonstrate the usage of all our integration.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-vision-api-sample">the Vision API sample</a> shows how to use <code>spring-cloud-gcp-starter-vision</code> to automatically configure Vision API clients.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_code_challenges"><a class="link" href="#_code_challenges">Code Challenges</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>In a code challenge, you perform a task step by step, using one integration.
|
||||
There are a number of challenges available in the <a href="https://codelabs.developers.google.com/spring">Google Developers Codelabs</a> page.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect1">
|
||||
<h2 id="_getting_started_guides"><a class="link" href="#_getting_started_guides">Getting Started Guides</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>A Spring Getting Started guide on messaging with Spring Integration Channel Adapters for Google Cloud Pub/Sub is available from <a href="https://spring.io/guides/gs/messaging-gcp-pubsub/">Spring Guides</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
278
spring-cloud-gcp/1.2.0.M2/reference/html/security-iap.html
Normal file
@@ -0,0 +1,278 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Cloud Identity-Aware Proxy (IAP) Authentication</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_cloud_identity_aware_proxy_iap_authentication">Cloud Identity-Aware Proxy (IAP) Authentication</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_cloud_identity_aware_proxy_iap_authentication"><a class="link" href="#_cloud_identity_aware_proxy_iap_authentication">Cloud Identity-Aware Proxy (IAP) Authentication</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.google.com/iap/">Cloud Identity-Aware Proxy (IAP)</a> provides a security layer over applications deployed to Google Cloud.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The IAP starter uses <a href="https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#oauth2resourceserver">Spring Security OAuth 2.0 Resource Server</a> functionality to automatically extract user identity from the proxy-injected <code>x-goog-iap-jwt-assertion</code> HTTP header.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The following claims are validated automatically:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Issue time</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Expiration time</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Issuer</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Audience</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <em>audience</em> (<code>"aud"</code> claim) validation string is automatically determined when the application is running on App Engine Standard or App Engine Flexible.
|
||||
This functionality relies on Cloud Resource Manager API to retrieve project details, so the following setup is needed:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Enable Cloud Resource Manager API in <a href="https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com">GCP Console</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Make sure your application has <code>resourcemanager.projects.get</code> permission.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>App Engine automatic <em>audience</em> determination can be overridden by using <code>spring.cloud.gcp.security.iap.audience</code> property.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For Compute Engine or Kubernetes Engine <code>spring.cloud.gcp.security.iap.audience</code> property <strong>must</strong> be provided, as the <em>audience</em> string depends on the specific Backend Services setup and cannot be inferred automatically.
|
||||
To determine the <em>audience</em> value, follow directions in IAP <a href="https://cloud.google.com/iap/docs/signed-headers-howto#verify_the_jwt_payload">Verify the JWT payload</a> guide.
|
||||
If <code>spring.cloud.gcp.security.iap.audience</code> is not provided, the application will fail to start the following message:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>No qualifying bean of type 'org.springframework.cloud.gcp.security.iap.AudienceProvider' available.</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If you create a custom <a href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html"><code>WebSecurityConfigurerAdapter</code></a>, enable extracting user identity by adding <code>.oauth2ResourceServer().jwt()</code> configuration to the <a href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html"><code>HttpSecurity</code></a> object.
|
||||
If no custom <a href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html"><code>WebSecurityConfigurerAdapter</code></a> is present, nothing needs to be done because Spring Boot will add this customization by default.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Starter Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-security-iap</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Starter Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-security-iap'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The following properties are available.</p>
|
||||
</div>
|
||||
<div class="admonitionblock caution">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-caution" title="Caution"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Modifying registry, algorithm, and header properties might be useful for testing, but the defaults should not be changed in production.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="tableblock halign-left valign-top">Name</th>
|
||||
<th class="tableblock halign-left valign-top">Description</th>
|
||||
<th class="tableblock halign-left valign-top">Required</th>
|
||||
<th class="tableblock halign-left valign-top">Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.security.iap.registry</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Link to JWK public key registry.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><a href="https://www.gstatic.com/iap/verify/public_key-jwk" class="bare">https://www.gstatic.com/iap/verify/public_key-jwk</a></code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.security.iap.algorithm</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Encryption algorithm used to sign the JWK token.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ES256</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.security.iap.header</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Header from which to extract the JWK key.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>x-goog-iap-jwt-assertion</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.security.iap.issuer</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">JWK issuer to verify.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><a href="https://cloud.google.com/iap" class="bare">https://cloud.google.com/iap</a></code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.security.iap.audience</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Custom JWK audience to verify.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false on App Engine; true on GCE/GKE</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-security-iap-sample">sample application</a> is available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
2055
spring-cloud-gcp/1.2.0.M2/reference/html/spanner.html
Normal file
@@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Cloud Bus</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_cloud_bus">Spring Cloud Bus</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_configuration_management_with_spring_cloud_config_and_spring_cloud_bus">Configuration Management with Spring Cloud Config and Spring Cloud Bus</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_cloud_bus"><a class="link" href="#_spring_cloud_bus">Spring Cloud Bus</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Using <a href="https://cloud.google.com/pubsub/">Cloud Pub/Sub</a> as the <a href="https://spring.io/projects/spring-cloud-bus">Spring Cloud Bus</a> implementation is as simple as importing the <code>spring-cloud-gcp-starter-bus-pubsub</code> starter.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This starter brings in the <a href="spring-stream.html#_spring_cloud_stream">Spring Cloud Stream binder for Cloud Pub/Sub</a>, which is used to both publish and subscribe to the bus.
|
||||
If the bus topic (named <code>springCloudBus</code> by default) does not exist, the binder automatically creates it.
|
||||
The binder also creates anonymous subscriptions for each project using the <code>spring-cloud-gcp-starter-bus-pubsub</code> starter.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-bus-pubsub</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-groovy hljs" data-lang="groovy">dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-bus-pubsub'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration_management_with_spring_cloud_config_and_spring_cloud_bus"><a class="link" href="#_configuration_management_with_spring_cloud_config_and_spring_cloud_bus">Configuration Management with Spring Cloud Config and Spring Cloud Bus</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud Bus can be used to push configuration changes from a Spring Cloud Config server to the clients listening on the same bus.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use GCP Pub/Sub as the bus implementation, both the configuration server and the configuration client need the <code>spring-cloud-gcp-starter-bus-pubsub</code> dependency.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>All other configuration is standard to <a href="https://spring.io/projects/spring-cloud-config">Spring Cloud Config</a>.</p>
|
||||
</div>
|
||||
<div class="imageblock">
|
||||
<div class="content">
|
||||
<img src="./images/spring_cloud_bus_over_pubsub.png" alt="spring cloud bus over pubsub">
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud Config Server typically runs on port <code>8888</code>, and can read configuration from a <a href="https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_environment_repository">variety of source control systems</a> such as GitHub, and even from the local filesystem.
|
||||
When the server is notified that new configuration is available, it fetches the updated configuration and sends a notification (<code>RefreshRemoteApplicationEvent</code>) out via Spring Cloud Bus.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>When configuration is stored locally, config server polls the parent directory for changes.
|
||||
With configuration stored in source control repository, such as GitHub, the config server needs to be notified that a new version of configuration is available.
|
||||
In a deployed server, this would be done automatically through a GitHub webhook, but in a local testing scenario, the <code>/monitor</code> HTTP endpoint needs to be invoked manually.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre>curl -X POST http://localhost:8888/monitor -H "X-Github-Event: push" -H "Content-Type: application/json" -d '{"commits": [{"modified": ["application.properties"]}]}'</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>By adding the <code>spring-cloud-gcp-starter-bus-pubsub</code> dependency, you instruct Spring Cloud Bus to use Cloud Pub/Sub to broadcast configuration changes.
|
||||
Spring Cloud Bus will then create a topic named <code>springCloudBus</code>, as well as a subscription for each configuration client.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The configuration server happens to also be a configuration client, subscribing to the configuration changes that it sends out.
|
||||
Thus, in a scenario with one configuration server and one configuration client, two anonymous subscriptions to the <code>springCloudBus</code> topic are created.
|
||||
However, a config server disables configuration refresh by default (see <a href="https://static.javadoc.io/org.springframework.cloud/spring-cloud-config-server/2.1.0.RELEASE/index.html">ConfigServerBootstrapApplicationListener</a> for more details).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-bus-config-sample">demo application</a> showing configuration management and distribution over a Cloud Pub/Sub-powered bus is available.
|
||||
The sample contains two examples of configuration management with Spring Cloud Bus: one monitoring a local file system, and the other retrieving configuration from a GitHub repository.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
8028
spring-cloud-gcp/1.2.0.M2/reference/html/spring-cloud-gcp.html
Normal file
@@ -0,0 +1,418 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Channel Adapters for Cloud Pub/Sub</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_channel_adapters_for_cloud_pubsub">Channel Adapters for Cloud Pub/Sub</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect2">
|
||||
<h3 id="_channel_adapters_for_cloud_pubsub"><a class="link" href="#_channel_adapters_for_cloud_pubsub">Channel Adapters for Cloud Pub/Sub</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The channel adapters for Google Cloud Pub/Sub connect your Spring <a href="https://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#channel"><code>MessageChannels</code></a> to Google Cloud Pub/Sub topics and subscriptions.
|
||||
This enables messaging between different processes, applications or micro-services backed up by Google Cloud Pub/Sub.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Integration Channel Adapters for Google Cloud Pub/Sub are included in the <code>spring-cloud-gcp-pubsub</code> module.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-pubsub</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-pubsub'
|
||||
compile group: 'org.springframework.integration', name: 'spring-integration-core'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_channel_adapter_using_pubsub_streaming_pull"><a class="link" href="#_inbound_channel_adapter_using_pubsub_streaming_pull">Inbound channel adapter (using Pub/Sub Streaming Pull)</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubInboundChannelAdapter</code> is the inbound channel adapter for GCP Pub/Sub that listens to a GCP Pub/Sub subscription for new messages.
|
||||
It converts new messages to an internal Spring <a href="https://docs.spring.io/spring-integration/reference/html/messaging-construction-chapter.html#message"><code>Message</code></a> and then sends it to the bound output channel.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Google Pub/Sub treats message payloads as byte arrays.
|
||||
So, by default, the inbound channel adapter will construct the Spring <code>Message</code> with <code>byte[]</code> as the payload.
|
||||
However, you can change the desired payload type by setting the <code>payloadType</code> property of the <code>PubSubInboundChannelAdapter</code>.
|
||||
The <code>PubSubInboundChannelAdapter</code> delegates the conversion to the desired payload type to the <code>PubSubMessageConverter</code> configured in the <code>PubSubTemplate</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the inbound channel adapter, a <code>PubSubInboundChannelAdapter</code> must be provided and configured on the user application side.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
public MessageChannel pubsubInputChannel() {
|
||||
return new PublishSubscribeChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PubSubInboundChannelAdapter messageChannelAdapter(
|
||||
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
|
||||
SubscriberFactory subscriberFactory) {
|
||||
PubSubInboundChannelAdapter adapter =
|
||||
new PubSubInboundChannelAdapter(subscriberFactory, "subscriptionName");
|
||||
adapter.setOutputChannel(inputChannel);
|
||||
adapter.setAckMode(AckMode.MANUAL);
|
||||
|
||||
return adapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In the example, we first specify the <code>MessageChannel</code> where the adapter is going to write incoming messages to.
|
||||
The <code>MessageChannel</code> implementation isn’t important here.
|
||||
Depending on your use case, you might want to use a <code>MessageChannel</code> other than <code>PublishSubscribeChannel</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Then, we declare a <code>PubSubInboundChannelAdapter</code> bean.
|
||||
It requires the channel we just created and a <code>SubscriberFactory</code>, which creates <code>Subscriber</code> objects from the Google Cloud Java Client for Pub/Sub.
|
||||
The Spring Boot starter for GCP Pub/Sub provides a configured <code>SubscriberFactory</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>PubSubInboundChannelAdapter</code> supports three acknowledgement modes, with <code>AckMode.AUTO</code> being the default value;</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Automatic acking (<code>AckMode.AUTO</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A message is acked with GCP Pub/Sub if the adapter sent it to the channel and no exceptions were thrown.
|
||||
If a <code>RuntimeException</code> is thrown while the message is processed, then the message is nacked.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Automatic acking OK (<code>AckMode.AUTO_ACK</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A message is acked with GCP Pub/Sub if the adapter sent it to the channel and no exceptions were thrown.
|
||||
If a <code>RuntimeException</code> is thrown while the message is processed, then the message is neither acked / nor nacked.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This is useful when using the subscription’s ack deadline timeout as a retry delivery backoff mechanism.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Manually acking (<code>AckMode.MANUAL</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The adapter attaches a <code>BasicAcknowledgeablePubsubMessage</code> object to the <code>Message</code> headers.
|
||||
Users can extract the <code>BasicAcknowledgeablePubsubMessage</code> using the <code>GcpPubSubHeaders.ORIGINAL_MESSAGE</code> key and use it to (n)ack a message.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "pubsubInputChannel")
|
||||
public MessageHandler messageReceiver() {
|
||||
return message -> {
|
||||
LOGGER.info("Message arrived! Payload: " + new String((byte[]) message.getPayload()));
|
||||
BasicAcknowledgeablePubsubMessage originalMessage =
|
||||
message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class);
|
||||
originalMessage.ack();
|
||||
};
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_pollable_message_source_using_pubsub_synchronous_pull"><a class="link" href="#_pollable_message_source_using_pubsub_synchronous_pull">Pollable Message Source (using Pub/Sub Synchronous Pull)</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>While <code>PubSubInboundChannelAdapter</code>, through the underlying Asynchronous Pull Pub/Sub mechanism, provides the best performance for high-volume applications that receive a steady flow of messages, it can create load balancing anomalies due to message caching.
|
||||
This behavior is most obvious when publishing a large batch of small messages that take a long time to process individually.
|
||||
It manifests as one subscriber taking up most messages, even if multiple subscribers are available to take on the work.
|
||||
For a more detailed explanation of this scenario, see <a href="https://cloud.google.com/pubsub/docs/pull#dealing-with-large-backlogs-of-small-messages">GCP Pub/Sub documentation</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In such a scenario, a <code>PubSubMessageSource</code> can help spread the load between different subscribers more evenly.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>As with the Inbound Channel Adapter, the message source has a configurable acknowledgement mode, payload type, and header mapping.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The default behavior is to return from the synchronous pull operation immediately if no messages are present.
|
||||
This can be overridden by using <code>setBlockOnPull()</code> method to wait for at least one message to arrive.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>By default, <code>PubSubMessageSource</code> pulls from the subscription one message at a time.
|
||||
To pull a batch of messages on each request, use the <code>setMaxFetchSize()</code> method to set the batch size.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "pubsubInputChannel", poller = @Poller(fixedDelay = "100"))
|
||||
public MessageSource<Object> pubsubAdapter(PubSubTemplate pubSubTemplate) {
|
||||
PubSubMessageSource messageSource = new PubSubMessageSource(pubSubTemplate, "exampleSubscription");
|
||||
messageSource.setAckMode(AckMode.MANUAL);
|
||||
messageSource.setPayloadType(String.class);
|
||||
messageSource.setBlockOnPull(true);
|
||||
messageSource.setMaxFetchSize(100);
|
||||
return messageSource;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>@InboundChannelAdapter</code> annotation above ensures that the configured <code>MessageSource</code> is polled for messages, which are then available for manipulation with any Spring Integration mechanism on the <code>pubsubInputChannel</code> message channel.
|
||||
For example, messages can be retrieved in a method annotated with <code>@ServiceActivator</code>, as seen below.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For additional flexibility, <code>PubSubMessageSource</code> attaches an <code>AcknowledgeablePubSubMessage</code> object to the <code>GcpPubSubHeaders.ORIGINAL_MESSAGE</code> message header.
|
||||
The object can be used for manually (n)acking the message.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@ServiceActivator(inputChannel = "pubsubInputChannel")
|
||||
public void messageReceiver(String payload,
|
||||
@Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) AcknowledgeablePubsubMessage message)
|
||||
throws InterruptedException {
|
||||
LOGGER.info("Message arrived by Synchronous Pull! Payload: " + payload);
|
||||
message.ack();
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
<code>AcknowledgeablePubSubMessage</code> objects acquired by synchronous pull are aware of their own acknowledgement IDs.
|
||||
Streaming pull does not expose this information due to limitations of the underlying API, and returns <code>BasicAcknowledgeablePubsubMessage</code> objects that allow acking/nacking individual messages, but not extracting acknowledgement IDs for future processing.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_outbound_channel_adapter"><a class="link" href="#_outbound_channel_adapter">Outbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubMessageHandler</code> is the outbound channel adapter for GCP Pub/Sub that listens for new messages on a Spring <code>MessageChannel</code>.
|
||||
It uses <code>PubSubTemplate</code> to post them to a GCP Pub/Sub topic.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To construct a Pub/Sub representation of the message, the outbound channel adapter needs to convert the Spring <code>Message</code> payload to a byte array representation expected by Pub/Sub.
|
||||
It delegates this conversion to the <code>PubSubTemplate</code>.
|
||||
To customize the conversion, you can specify a <code>PubSubMessageConverter</code> in the <code>PubSubTemplate</code> that should convert the <code>Object</code> payload and headers of the Spring <code>Message</code> to a <code>PubsubMessage</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the outbound channel adapter, a <code>PubSubMessageHandler</code> bean must be provided and configured on the user application side.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "pubsubOutputChannel")
|
||||
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
|
||||
return new PubSubMessageHandler(pubsubTemplate, "topicName");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The provided <code>PubSubTemplate</code> contains all the necessary configuration to publish messages to a GCP Pub/Sub topic.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubMessageHandler</code> publishes messages asynchronously by default.
|
||||
A publish timeout can be configured for synchronous publishing.
|
||||
If none is provided, the adapter waits indefinitely for a response.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>It is possible to set user-defined callbacks for the <code>publish()</code> call in <code>PubSubMessageHandler</code> through the <code>setPublishFutureCallback()</code> method.
|
||||
These are useful to process the message ID, in case of success, or the error if any was thrown.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To override the default destination you can use the <code>GcpPubSubHeaders.DESTINATION</code> header.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
||||
private MessageChannel pubsubOutputChannel;
|
||||
|
||||
public void handleMessage(Message<?> msg) throws MessagingException {
|
||||
final Message<?> message = MessageBuilder
|
||||
.withPayload(msg.getPayload())
|
||||
.setHeader(GcpPubSubHeaders.TOPIC, "customTopic").build();
|
||||
pubsubOutputChannel.send(message);
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>It is also possible to set an SpEL expression for the topic with the <code>setTopicExpression()</code> or <code>setTopicExpressionString()</code> methods.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_header_mapping"><a class="link" href="#_header_mapping">Header mapping</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>These channel adapters contain header mappers that allow you to map, or filter out, headers from Spring to Google Cloud Pub/Sub messages, and vice-versa.
|
||||
By default, the inbound channel adapter maps every header on the Google Cloud Pub/Sub messages to the Spring messages produced by the adapter.
|
||||
The outbound channel adapter maps every header from Spring messages into Google Cloud Pub/Sub ones, except the ones added by Spring, like headers with key <code>"id"</code>, <code>"timestamp"</code> and <code>"gcp_pubsub_acknowledgement"</code>.
|
||||
In the process, the outbound mapper also converts the value of the headers into string.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Each adapter declares a <code>setHeaderMapper()</code> method to let you further customize which headers you want to map from Spring to Google Cloud Pub/Sub, and vice-versa.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, to filter out headers <code>"foo"</code>, <code>"bar"</code> and all headers starting with the prefix "prefix_", you can use <code>setHeaderMapper()</code> along with the <code>PubSubHeaderMapper</code> implementation provided by this module.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">PubSubMessageHandler adapter = ...
|
||||
...
|
||||
PubSubHeaderMapper headerMapper = new PubSubHeaderMapper();
|
||||
headerMapper.setOutboundHeaderPatterns("!foo", "!bar", "!prefix_*", "*");
|
||||
adapter.setHeaderMapper(headerMapper);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
The order in which the patterns are declared in <code>PubSubHeaderMapper.setOutboundHeaderPatterns()</code> and <code>PubSubHeaderMapper.setInboundHeaderPatterns()</code> matters.
|
||||
The first patterns have precedence over the following ones.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In the previous example, the <code>"*"</code> pattern means every header is mapped.
|
||||
However, because it comes last in the list, <a href="https://docs.spring.io/spring-integration/api/org/springframework/integration/util/PatternMatchUtils.html#smartMatch-java.lang.String-java.lang.String…​-">the previous patterns take precedence</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Available examples:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample">sender and receiver sample application</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-json-sample">JSON payloads sample application</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cloud-gcp-pubsub-integration/index.html">codelab</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Channel Adapters for Google Cloud Storage</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_channel_adapters_for_google_cloud_storage">Channel Adapters for Google Cloud Storage</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect2">
|
||||
<h3 id="_channel_adapters_for_google_cloud_storage"><a class="link" href="#_channel_adapters_for_google_cloud_storage">Channel Adapters for Google Cloud Storage</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The channel adapters for Google Cloud Storage allow you to read and write files to Google Cloud Storage through <code>MessageChannels</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides two inbound adapters, <code>GcsInboundFileSynchronizingMessageSource</code> and <code>GcsStreamingMessageSource</code>, and one outbound adapter, <code>GcsMessageHandler</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Integration Channel Adapters for Google Cloud Storage are included in the <code>spring-cloud-gcp-storage</code> module.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the Storage portion of Spring Integration for Spring Cloud GCP, you must also provide the <code>spring-integration-file</code> dependency, since it isn’t pulled transitively.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-storage</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-file</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-storage'
|
||||
compile group: 'org.springframework.integration', name: 'spring-integration-file'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_channel_adapter"><a class="link" href="#_inbound_channel_adapter">Inbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The Google Cloud Storage inbound channel adapter polls a Google Cloud Storage bucket for new files and sends each of them in a <code>Message</code> payload to the <code>MessageChannel</code> specified in the <code>@InboundChannelAdapter</code> annotation.
|
||||
The files are temporarily stored in a folder in the local file system.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage inbound channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "new-file-channel", poller = @Poller(fixedDelay = "5000"))
|
||||
public MessageSource<File> synchronizerAdapter(Storage gcs) {
|
||||
GcsInboundFileSynchronizer synchronizer = new GcsInboundFileSynchronizer(gcs);
|
||||
synchronizer.setRemoteDirectory("your-gcs-bucket");
|
||||
|
||||
GcsInboundFileSynchronizingMessageSource synchAdapter =
|
||||
new GcsInboundFileSynchronizingMessageSource(synchronizer);
|
||||
synchAdapter.setLocalDirectory(new File("local-directory"));
|
||||
|
||||
return synchAdapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_streaming_channel_adapter"><a class="link" href="#_inbound_streaming_channel_adapter">Inbound streaming channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The inbound streaming channel adapter is similar to the normal inbound channel adapter, except it does not require files to be stored in the file system.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage inbound streaming channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "streaming-channel", poller = @Poller(fixedDelay = "5000"))
|
||||
public MessageSource<InputStream> streamingAdapter(Storage gcs) {
|
||||
GcsStreamingMessageSource adapter =
|
||||
new GcsStreamingMessageSource(new GcsRemoteFileTemplate(new GcsSessionFactory(gcs)));
|
||||
adapter.setRemoteDirectory("your-gcs-bucket");
|
||||
return adapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_outbound_channel_adapter"><a class="link" href="#_outbound_channel_adapter">Outbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The outbound channel adapter allows files to be written to Google Cloud Storage.
|
||||
When it receives a <code>Message</code> containing a payload of type <code>File</code>, it writes that file to the Google Cloud Storage bucket specified in the adapter.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage outbound channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "writeFiles")
|
||||
public MessageHandler outboundChannelAdapter(Storage gcs) {
|
||||
GcsMessageHandler outboundChannelAdapter = new GcsMessageHandler(new GcsSessionFactory(gcs));
|
||||
outboundChannelAdapter.setRemoteDirectoryExpression(new ValueExpression<>("your-gcs-bucket"));
|
||||
|
||||
return outboundChannelAdapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-storage-sample">sample application</a> is available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
548
spring-cloud-gcp/1.2.0.M2/reference/html/spring-integration.html
Normal file
@@ -0,0 +1,548 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Integration</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_integration">Spring Integration</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_channel_adapters_for_cloud_pubsub">Channel Adapters for Cloud Pub/Sub</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
<li><a href="#_channel_adapters_for_google_cloud_storage">Channel Adapters for Google Cloud Storage</a></li>
|
||||
<li><a href="#_sample_2">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_integration"><a class="link" href="#_spring_integration">Spring Integration</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides Spring Integration adapters that allow your applications to use Enterprise Integration Patterns backed up by Google Cloud Platform services.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_channel_adapters_for_cloud_pubsub"><a class="link" href="#_channel_adapters_for_cloud_pubsub">Channel Adapters for Cloud Pub/Sub</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The channel adapters for Google Cloud Pub/Sub connect your Spring <a href="https://docs.spring.io/spring-integration/reference/html/messaging-channels-section.html#channel"><code>MessageChannels</code></a> to Google Cloud Pub/Sub topics and subscriptions.
|
||||
This enables messaging between different processes, applications or micro-services backed up by Google Cloud Pub/Sub.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Integration Channel Adapters for Google Cloud Pub/Sub are included in the <code>spring-cloud-gcp-pubsub</code> module.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-pubsub</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-pubsub'
|
||||
compile group: 'org.springframework.integration', name: 'spring-integration-core'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_channel_adapter_using_pubsub_streaming_pull"><a class="link" href="#_inbound_channel_adapter_using_pubsub_streaming_pull">Inbound channel adapter (using Pub/Sub Streaming Pull)</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubInboundChannelAdapter</code> is the inbound channel adapter for GCP Pub/Sub that listens to a GCP Pub/Sub subscription for new messages.
|
||||
It converts new messages to an internal Spring <a href="https://docs.spring.io/spring-integration/reference/html/messaging-construction-chapter.html#message"><code>Message</code></a> and then sends it to the bound output channel.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Google Pub/Sub treats message payloads as byte arrays.
|
||||
So, by default, the inbound channel adapter will construct the Spring <code>Message</code> with <code>byte[]</code> as the payload.
|
||||
However, you can change the desired payload type by setting the <code>payloadType</code> property of the <code>PubSubInboundChannelAdapter</code>.
|
||||
The <code>PubSubInboundChannelAdapter</code> delegates the conversion to the desired payload type to the <code>PubSubMessageConverter</code> configured in the <code>PubSubTemplate</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the inbound channel adapter, a <code>PubSubInboundChannelAdapter</code> must be provided and configured on the user application side.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
public MessageChannel pubsubInputChannel() {
|
||||
return new PublishSubscribeChannel();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PubSubInboundChannelAdapter messageChannelAdapter(
|
||||
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
|
||||
SubscriberFactory subscriberFactory) {
|
||||
PubSubInboundChannelAdapter adapter =
|
||||
new PubSubInboundChannelAdapter(subscriberFactory, "subscriptionName");
|
||||
adapter.setOutputChannel(inputChannel);
|
||||
adapter.setAckMode(AckMode.MANUAL);
|
||||
|
||||
return adapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In the example, we first specify the <code>MessageChannel</code> where the adapter is going to write incoming messages to.
|
||||
The <code>MessageChannel</code> implementation isn’t important here.
|
||||
Depending on your use case, you might want to use a <code>MessageChannel</code> other than <code>PublishSubscribeChannel</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Then, we declare a <code>PubSubInboundChannelAdapter</code> bean.
|
||||
It requires the channel we just created and a <code>SubscriberFactory</code>, which creates <code>Subscriber</code> objects from the Google Cloud Java Client for Pub/Sub.
|
||||
The Spring Boot starter for GCP Pub/Sub provides a configured <code>SubscriberFactory</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>PubSubInboundChannelAdapter</code> supports three acknowledgement modes, with <code>AckMode.AUTO</code> being the default value;</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Automatic acking (<code>AckMode.AUTO</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A message is acked with GCP Pub/Sub if the adapter sent it to the channel and no exceptions were thrown.
|
||||
If a <code>RuntimeException</code> is thrown while the message is processed, then the message is nacked.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Automatic acking OK (<code>AckMode.AUTO_ACK</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A message is acked with GCP Pub/Sub if the adapter sent it to the channel and no exceptions were thrown.
|
||||
If a <code>RuntimeException</code> is thrown while the message is processed, then the message is neither acked / nor nacked.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This is useful when using the subscription’s ack deadline timeout as a retry delivery backoff mechanism.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Manually acking (<code>AckMode.MANUAL</code>)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The adapter attaches a <code>BasicAcknowledgeablePubsubMessage</code> object to the <code>Message</code> headers.
|
||||
Users can extract the <code>BasicAcknowledgeablePubsubMessage</code> using the <code>GcpPubSubHeaders.ORIGINAL_MESSAGE</code> key and use it to (n)ack a message.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "pubsubInputChannel")
|
||||
public MessageHandler messageReceiver() {
|
||||
return message -> {
|
||||
LOGGER.info("Message arrived! Payload: " + new String((byte[]) message.getPayload()));
|
||||
BasicAcknowledgeablePubsubMessage originalMessage =
|
||||
message.getHeaders().get(GcpPubSubHeaders.ORIGINAL_MESSAGE, BasicAcknowledgeablePubsubMessage.class);
|
||||
originalMessage.ack();
|
||||
};
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_pollable_message_source_using_pubsub_synchronous_pull"><a class="link" href="#_pollable_message_source_using_pubsub_synchronous_pull">Pollable Message Source (using Pub/Sub Synchronous Pull)</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>While <code>PubSubInboundChannelAdapter</code>, through the underlying Asynchronous Pull Pub/Sub mechanism, provides the best performance for high-volume applications that receive a steady flow of messages, it can create load balancing anomalies due to message caching.
|
||||
This behavior is most obvious when publishing a large batch of small messages that take a long time to process individually.
|
||||
It manifests as one subscriber taking up most messages, even if multiple subscribers are available to take on the work.
|
||||
For a more detailed explanation of this scenario, see <a href="https://cloud.google.com/pubsub/docs/pull#dealing-with-large-backlogs-of-small-messages">GCP Pub/Sub documentation</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In such a scenario, a <code>PubSubMessageSource</code> can help spread the load between different subscribers more evenly.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>As with the Inbound Channel Adapter, the message source has a configurable acknowledgement mode, payload type, and header mapping.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The default behavior is to return from the synchronous pull operation immediately if no messages are present.
|
||||
This can be overridden by using <code>setBlockOnPull()</code> method to wait for at least one message to arrive.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>By default, <code>PubSubMessageSource</code> pulls from the subscription one message at a time.
|
||||
To pull a batch of messages on each request, use the <code>setMaxFetchSize()</code> method to set the batch size.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "pubsubInputChannel", poller = @Poller(fixedDelay = "100"))
|
||||
public MessageSource<Object> pubsubAdapter(PubSubTemplate pubSubTemplate) {
|
||||
PubSubMessageSource messageSource = new PubSubMessageSource(pubSubTemplate, "exampleSubscription");
|
||||
messageSource.setAckMode(AckMode.MANUAL);
|
||||
messageSource.setPayloadType(String.class);
|
||||
messageSource.setBlockOnPull(true);
|
||||
messageSource.setMaxFetchSize(100);
|
||||
return messageSource;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>@InboundChannelAdapter</code> annotation above ensures that the configured <code>MessageSource</code> is polled for messages, which are then available for manipulation with any Spring Integration mechanism on the <code>pubsubInputChannel</code> message channel.
|
||||
For example, messages can be retrieved in a method annotated with <code>@ServiceActivator</code>, as seen below.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For additional flexibility, <code>PubSubMessageSource</code> attaches an <code>AcknowledgeablePubSubMessage</code> object to the <code>GcpPubSubHeaders.ORIGINAL_MESSAGE</code> message header.
|
||||
The object can be used for manually (n)acking the message.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@ServiceActivator(inputChannel = "pubsubInputChannel")
|
||||
public void messageReceiver(String payload,
|
||||
@Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) AcknowledgeablePubsubMessage message)
|
||||
throws InterruptedException {
|
||||
LOGGER.info("Message arrived by Synchronous Pull! Payload: " + payload);
|
||||
message.ack();
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
<code>AcknowledgeablePubSubMessage</code> objects acquired by synchronous pull are aware of their own acknowledgement IDs.
|
||||
Streaming pull does not expose this information due to limitations of the underlying API, and returns <code>BasicAcknowledgeablePubsubMessage</code> objects that allow acking/nacking individual messages, but not extracting acknowledgement IDs for future processing.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_outbound_channel_adapter"><a class="link" href="#_outbound_channel_adapter">Outbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubMessageHandler</code> is the outbound channel adapter for GCP Pub/Sub that listens for new messages on a Spring <code>MessageChannel</code>.
|
||||
It uses <code>PubSubTemplate</code> to post them to a GCP Pub/Sub topic.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To construct a Pub/Sub representation of the message, the outbound channel adapter needs to convert the Spring <code>Message</code> payload to a byte array representation expected by Pub/Sub.
|
||||
It delegates this conversion to the <code>PubSubTemplate</code>.
|
||||
To customize the conversion, you can specify a <code>PubSubMessageConverter</code> in the <code>PubSubTemplate</code> that should convert the <code>Object</code> payload and headers of the Spring <code>Message</code> to a <code>PubsubMessage</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the outbound channel adapter, a <code>PubSubMessageHandler</code> bean must be provided and configured on the user application side.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "pubsubOutputChannel")
|
||||
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
|
||||
return new PubSubMessageHandler(pubsubTemplate, "topicName");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The provided <code>PubSubTemplate</code> contains all the necessary configuration to publish messages to a GCP Pub/Sub topic.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>PubSubMessageHandler</code> publishes messages asynchronously by default.
|
||||
A publish timeout can be configured for synchronous publishing.
|
||||
If none is provided, the adapter waits indefinitely for a response.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>It is possible to set user-defined callbacks for the <code>publish()</code> call in <code>PubSubMessageHandler</code> through the <code>setPublishFutureCallback()</code> method.
|
||||
These are useful to process the message ID, in case of success, or the error if any was thrown.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To override the default destination you can use the <code>GcpPubSubHeaders.DESTINATION</code> header.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
||||
private MessageChannel pubsubOutputChannel;
|
||||
|
||||
public void handleMessage(Message<?> msg) throws MessagingException {
|
||||
final Message<?> message = MessageBuilder
|
||||
.withPayload(msg.getPayload())
|
||||
.setHeader(GcpPubSubHeaders.TOPIC, "customTopic").build();
|
||||
pubsubOutputChannel.send(message);
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>It is also possible to set an SpEL expression for the topic with the <code>setTopicExpression()</code> or <code>setTopicExpressionString()</code> methods.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_header_mapping"><a class="link" href="#_header_mapping">Header mapping</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>These channel adapters contain header mappers that allow you to map, or filter out, headers from Spring to Google Cloud Pub/Sub messages, and vice-versa.
|
||||
By default, the inbound channel adapter maps every header on the Google Cloud Pub/Sub messages to the Spring messages produced by the adapter.
|
||||
The outbound channel adapter maps every header from Spring messages into Google Cloud Pub/Sub ones, except the ones added by Spring, like headers with key <code>"id"</code>, <code>"timestamp"</code> and <code>"gcp_pubsub_acknowledgement"</code>.
|
||||
In the process, the outbound mapper also converts the value of the headers into string.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Each adapter declares a <code>setHeaderMapper()</code> method to let you further customize which headers you want to map from Spring to Google Cloud Pub/Sub, and vice-versa.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, to filter out headers <code>"foo"</code>, <code>"bar"</code> and all headers starting with the prefix "prefix_", you can use <code>setHeaderMapper()</code> along with the <code>PubSubHeaderMapper</code> implementation provided by this module.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">PubSubMessageHandler adapter = ...
|
||||
...
|
||||
PubSubHeaderMapper headerMapper = new PubSubHeaderMapper();
|
||||
headerMapper.setOutboundHeaderPatterns("!foo", "!bar", "!prefix_*", "*");
|
||||
adapter.setHeaderMapper(headerMapper);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
The order in which the patterns are declared in <code>PubSubHeaderMapper.setOutboundHeaderPatterns()</code> and <code>PubSubHeaderMapper.setInboundHeaderPatterns()</code> matters.
|
||||
The first patterns have precedence over the following ones.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>In the previous example, the <code>"*"</code> pattern means every header is mapped.
|
||||
However, because it comes last in the list, <a href="https://docs.spring.io/spring-integration/api/org/springframework/integration/util/PatternMatchUtils.html#smartMatch-java.lang.String-java.lang.String…​-">the previous patterns take precedence</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Available examples:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-sample">sender and receiver sample application</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-pubsub-json-sample">JSON payloads sample application</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cloud-gcp-pubsub-integration/index.html">codelab</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_channel_adapters_for_google_cloud_storage"><a class="link" href="#_channel_adapters_for_google_cloud_storage">Channel Adapters for Google Cloud Storage</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The channel adapters for Google Cloud Storage allow you to read and write files to Google Cloud Storage through <code>MessageChannels</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides two inbound adapters, <code>GcsInboundFileSynchronizingMessageSource</code> and <code>GcsStreamingMessageSource</code>, and one outbound adapter, <code>GcsMessageHandler</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Integration Channel Adapters for Google Cloud Storage are included in the <code>spring-cloud-gcp-storage</code> module.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To use the Storage portion of Spring Integration for Spring Cloud GCP, you must also provide the <code>spring-integration-file</code> dependency, since it isn’t pulled transitively.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-storage</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-file</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-storage'
|
||||
compile group: 'org.springframework.integration', name: 'spring-integration-file'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_channel_adapter"><a class="link" href="#_inbound_channel_adapter">Inbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The Google Cloud Storage inbound channel adapter polls a Google Cloud Storage bucket for new files and sends each of them in a <code>Message</code> payload to the <code>MessageChannel</code> specified in the <code>@InboundChannelAdapter</code> annotation.
|
||||
The files are temporarily stored in a folder in the local file system.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage inbound channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "new-file-channel", poller = @Poller(fixedDelay = "5000"))
|
||||
public MessageSource<File> synchronizerAdapter(Storage gcs) {
|
||||
GcsInboundFileSynchronizer synchronizer = new GcsInboundFileSynchronizer(gcs);
|
||||
synchronizer.setRemoteDirectory("your-gcs-bucket");
|
||||
|
||||
GcsInboundFileSynchronizingMessageSource synchAdapter =
|
||||
new GcsInboundFileSynchronizingMessageSource(synchronizer);
|
||||
synchAdapter.setLocalDirectory(new File("local-directory"));
|
||||
|
||||
return synchAdapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_inbound_streaming_channel_adapter"><a class="link" href="#_inbound_streaming_channel_adapter">Inbound streaming channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The inbound streaming channel adapter is similar to the normal inbound channel adapter, except it does not require files to be stored in the file system.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage inbound streaming channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@InboundChannelAdapter(channel = "streaming-channel", poller = @Poller(fixedDelay = "5000"))
|
||||
public MessageSource<InputStream> streamingAdapter(Storage gcs) {
|
||||
GcsStreamingMessageSource adapter =
|
||||
new GcsStreamingMessageSource(new GcsRemoteFileTemplate(new GcsSessionFactory(gcs)));
|
||||
adapter.setRemoteDirectory("your-gcs-bucket");
|
||||
return adapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_outbound_channel_adapter_2"><a class="link" href="#_outbound_channel_adapter_2">Outbound channel adapter</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The outbound channel adapter allows files to be written to Google Cloud Storage.
|
||||
When it receives a <code>Message</code> containing a payload of type <code>File</code>, it writes that file to the Google Cloud Storage bucket specified in the adapter.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of how to configure a Google Cloud Storage outbound channel adapter.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
|
||||
@ServiceActivator(inputChannel = "writeFiles")
|
||||
public MessageHandler outboundChannelAdapter(Storage gcs) {
|
||||
GcsMessageHandler outboundChannelAdapter = new GcsMessageHandler(new GcsSessionFactory(gcs));
|
||||
outboundChannelAdapter.setRemoteDirectoryExpression(new ValueExpression<>("your-gcs-bucket"));
|
||||
|
||||
return outboundChannelAdapter;
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample_2"><a class="link" href="#_sample_2">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-integration-storage-sample">sample application</a> is available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
302
spring-cloud-gcp/1.2.0.M2/reference/html/spring-stream.html
Normal file
@@ -0,0 +1,302 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Cloud Stream</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_cloud_stream">Spring Cloud Stream</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_overview">Overview</a></li>
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_streaming_vs_polled_input">Streaming vs. Polled Input</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_cloud_stream"><a class="link" href="#_spring_cloud_stream">Spring Cloud Stream</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides a <a href="https://cloud.spring.io/spring-cloud-stream/">Spring Cloud Stream</a> binder to Google Cloud Pub/Sub.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The provided binder relies on the <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub/src/main/java/org/springframework/cloud/gcp/pubsub/integration">Spring Integration Channel Adapters for Google Cloud Pub/Sub</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-pubsub-stream-binder</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-pubsub-stream-binder'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_overview"><a class="link" href="#_overview">Overview</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>This binder binds producers to Google Cloud Pub/Sub topics and consumers to subscriptions.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Partitioning is currently not supported by this binder.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>You can configure the Spring Cloud Stream Binder for Google Cloud Pub/Sub to automatically generate the underlying resources, like the Google Cloud Pub/Sub topics and subscriptions for producers and consumers.
|
||||
For that, you can use the <code>spring.cloud.stream.gcp.pubsub.bindings.<channelName>.<consumer|producer>.auto-create-resources</code> property, which is turned ON by default.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Starting with version 1.1, these and other binder properties can be configured globally for all the bindings, e.g. <code>spring.cloud.stream.gcp.pubsub.default.consumer.auto-create-resources</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If you are using Pub/Sub auto-configuration from the Spring Cloud GCP Pub/Sub Starter, you should refer to the <a href="#pubsub-configuration">configuration</a> section for other Pub/Sub parameters.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
To use this binder with a <a href="https://cloud.google.com/pubsub/docs/emulator">running emulator</a>, configure its host and port via <code>spring.cloud.gcp.pubsub.emulator-host</code>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_producer_destination_configuration"><a class="link" href="#_producer_destination_configuration">Producer Destination Configuration</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>If automatic resource creation is turned ON and the topic corresponding to the destination name does not exist, it will be created.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, for the following configuration, a topic called <code>myEvents</code> would be created.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">application.properties</div>
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.stream.bindings.events.destination=myEvents
|
||||
spring.cloud.stream.gcp.pubsub.bindings.events.producer.auto-create-resources=true</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_consumer_destination_configuration"><a class="link" href="#_consumer_destination_configuration">Consumer Destination Configuration</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>If automatic resource creation is turned ON and the subscription and/or the topic do not exist for a consumer, a subscription and potentially a topic will be created.
|
||||
The topic name will be the same as the destination name, and the subscription name will be the destination name followed by the consumer group name.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Regardless of the <code>auto-create-resources</code> setting, if the consumer group is not specified, an anonymous one will be created with the name <code>anonymous.<destinationName>.<randomUUID></code>.
|
||||
Then when the binder shuts down, all Pub/Sub subscriptions created for anonymous consumer groups will be automatically cleaned up.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, for the following configuration, a topic named <code>myEvents</code> and a subscription called <code>myEvents.consumerGroup1</code> would be created.
|
||||
If the consumer group is not specified, a subscription called <code>anonymous.myEvents.a6d83782-c5a3-4861-ac38-e6e2af15a7be</code> would be created and later cleaned up.</p>
|
||||
</div>
|
||||
<div class="admonitionblock important">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-important" title="Important"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If you are manually creating Pub/Sub subscriptions for consumers, make sure that they follow the naming convention of <code><destinationName>.<consumerGroup></code>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="title">application.properties</div>
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.cloud.stream.bindings.events.destination=myEvents
|
||||
spring.cloud.stream.gcp.pubsub.bindings.events.consumer.auto-create-resources=true
|
||||
|
||||
# specify consumer group, and avoid anonymous consumer group generation
|
||||
spring.cloud.stream.bindings.events.group=consumerGroup1</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_streaming_vs_polled_input"><a class="link" href="#_streaming_vs_polled_input">Streaming vs. Polled Input</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Many Spring Cloud Stream applications will use the built-in <code>Sink</code> binding, which triggers the <em>streaming</em> input binder creation.
|
||||
Messages can then be consumed with an input handler marked by <code>@StreamListener(Sink.INPUT)</code> annotation, at whatever rate Pub/Sub sends them.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For more control over the rate of message arrival, a polled input binder can be set up by defining a custom binding interface with an <code>@Input</code>-annotated method returning <code>PollableMessageSource</code>.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface PollableSink {
|
||||
|
||||
@Input("input")
|
||||
PollableMessageSource input();
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>PollableMessageSource</code> can then be injected and queried, as needed.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@EnableBinding(PollableSink.class)
|
||||
public class SinkExample {
|
||||
|
||||
@Autowired
|
||||
PollableMessageSource destIn;
|
||||
|
||||
@Bean
|
||||
public ApplicationRunner singlePollRunner() {
|
||||
return args -> {
|
||||
// This will poll only once.
|
||||
// Add a loop or a scheduler to get more messages.
|
||||
destIn.poll((message) -> System.out.println("Message retrieved: " + message));
|
||||
};
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Sample applications are available:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>For <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-binder-sample">streaming input</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>For <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-pubsub-polling-binder-sample">polled input</a>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
345
spring-cloud-gcp/1.2.0.M2/reference/html/sql.html
Normal file
@@ -0,0 +1,345 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring JDBC</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_jdbc">Spring JDBC</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_prerequisites">Prerequisites</a></li>
|
||||
<li><a href="#_spring_boot_starter_for_google_cloud_sql">Spring Boot Starter for Google Cloud SQL</a></li>
|
||||
<li><a href="#_samples">Samples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_jdbc"><a class="link" href="#_spring_jdbc">Spring JDBC</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP adds integrations with
|
||||
<a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html">Spring JDBC</a> so you can run your MySQL or PostgreSQL databases in Google Cloud SQL using Spring JDBC, or other libraries that depend on it like Spring Data JPA.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Cloud SQL support is provided by Spring Cloud GCP in the form of two Spring Boot starters, one for MySQL and another one for PostgreSQL.
|
||||
The role of the starters is to read configuration from properties and assume default settings so that user experience connecting to MySQL and PostgreSQL is as simple as possible.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-sql-mysql'
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-sql-postgresql'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_prerequisites"><a class="link" href="#_prerequisites">Prerequisites</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>In order to use the Spring Boot Starters for Google Cloud SQL, the Google Cloud SQL API must be enabled in your GCP project.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To do that, go to the <a href="https://console.cloud.google.com/apis/library">API library page</a> of the Google Cloud Console, search for "Cloud SQL API", click the first result and enable the API.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
There are several similar "Cloud SQL" results.
|
||||
You must access the "Google Cloud SQL API" one and enable the API from there.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_spring_boot_starter_for_google_cloud_sql"><a class="link" href="#_spring_boot_starter_for_google_cloud_sql">Spring Boot Starter for Google Cloud SQL</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Boot Starters for Google Cloud SQL provide an auto-configured <a href="https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html"><code>DataSource</code></a> object.
|
||||
Coupled with Spring JDBC, it provides a
|
||||
<a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jdbc.html#jdbc-JdbcTemplate"><code>JdbcTemplate</code></a> object bean that allows for operations such as querying and modifying a database.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public List<Map<String, Object>> listUsers() {
|
||||
return jdbcTemplate.queryForList("SELECT * FROM user;");
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can rely on
|
||||
<a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database">Spring Boot data source auto-configuration</a> to configure a <code>DataSource</code> bean.
|
||||
In other words, properties like the SQL username, <code>spring.datasource.username</code>, and password, <code>spring.datasource.password</code> can be used.
|
||||
There is also some configuration specific to Google Cloud SQL:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3333%;">
|
||||
<col style="width: 33.3334%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Property name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.sql.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables or disables Cloud SQL auto configuration</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.sql.database-name</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the database to connect to.</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.sql.instance-connection-name</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">A string containing a Google Cloud SQL instance’s project ID, region and name, each separated by a colon.
|
||||
For example, <code>my-project-id:my-region:my-instance-name</code>.</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.sql.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">File system path to the Google OAuth2 credentials private key file.
|
||||
Used to authenticate and authorize new connections to a Google Cloud SQL instance.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default credentials provided by the Spring GCP Boot starter</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.sql.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Base64-encoded contents of OAuth2 account private key in JSON format.
|
||||
Used to authenticate and authorize new connections to a Google Cloud SQL instance.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default credentials provided by the Spring GCP Boot starter</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
If you provide your own <code>spring.datasource.url</code>, it will be ignored, unless you disable Cloud SQL auto configuration with <code>spring.cloud.gcp.sql.enabled=false</code>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_datasource_creation_flow"><a class="link" href="#_datasource_creation_flow"><code>DataSource</code> creation flow</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>Based on the previous properties, the Spring Boot starter for Google Cloud SQL creates a <code>CloudSqlJdbcInfoProvider</code> object which is used to obtain an instance’s JDBC URL and driver class name.
|
||||
If you provide your own <code>CloudSqlJdbcInfoProvider</code> bean, it is used instead and the properties related to building the JDBC URL or driver class are ignored.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>DataSourceProperties</code> object provided by Spring Boot Autoconfigure is mutated in order to use the JDBC URL and driver class names provided by <code>CloudSqlJdbcInfoProvider</code>, unless those values were provided in the properties.
|
||||
It is in the <code>DataSourceProperties</code> mutation step that the credentials factory is registered in a system property to be <code>SqlCredentialFactory</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>DataSource</code> creation is delegated to
|
||||
<a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html">Spring Boot</a>.
|
||||
You can select the type of connection pool (e.g., Tomcat, HikariCP, etc.) by <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database">adding their dependency to the classpath</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Using the created <code>DataSource</code> in conjunction with Spring JDBC provides you with a fully configured and operational <code>JdbcTemplate</code> object that you can use to interact with your SQL database.
|
||||
You can connect to your database with as little as a database and instance names.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_troubleshooting_tips"><a class="link" href="#_troubleshooting_tips">Troubleshooting tips</a></h4>
|
||||
<div class="sect4">
|
||||
<h5 id="connection-issues"><a class="link" href="#connection-issues">Connection issues</a></h5>
|
||||
<div class="paragraph">
|
||||
<p>If you’re not able to connect to a database and see an endless loop of <code>Connecting to Cloud SQL instance […​] on IP […​]</code>, it’s likely that exceptions are being thrown and logged at a level lower than your logger’s level.
|
||||
This may be the case with HikariCP, if your logger is set to INFO or higher level.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To see what’s going on in the background, you should add a <code>logback.xml</code> file to your application resources folder, that looks like this:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="com.zaxxer.hikari.pool" level="DEBUG"/>
|
||||
</configuration></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_errors_like_c_g_cloud_sql_core_sslsocketfactory_re_throwing_cached_exception_due_to_attempt_to_refresh_instance_information_too_soon_after_error"><a class="link" href="#_errors_like_c_g_cloud_sql_core_sslsocketfactory_re_throwing_cached_exception_due_to_attempt_to_refresh_instance_information_too_soon_after_error">Errors like <code>c.g.cloud.sql.core.SslSocketFactory : Re-throwing cached exception due to attempt to refresh instance information too soon after error</code></a></h5>
|
||||
<div class="paragraph">
|
||||
<p>If you see a lot of errors like this in a loop and can’t connect to your database, this is usually a symptom that something isn’t right with the permissions of your credentials or the Google Cloud SQL API is not enabled.
|
||||
Verify that the Google Cloud SQL API is enabled in the Cloud Console and that your service account has the <a href="https://cloud.google.com/sql/docs/mysql/project-access-control#roles">necessary IAM roles</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To find out what’s causing the issue, you can enable DEBUG logging level as mentioned <a href="#connection-issues">above</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect4">
|
||||
<h5 id="_postgresql_java_net_socketexception_already_connected_issue"><a class="link" href="#_postgresql_java_net_socketexception_already_connected_issue">PostgreSQL: <code>java.net.SocketException: already connected</code> issue</a></h5>
|
||||
<div class="paragraph">
|
||||
<p>We found this exception to be common if your Maven project’s parent is <code>spring-boot</code> version <code>1.5.x</code>, or in any other circumstance that would cause the version of the <code>org.postgresql:postgresql</code> dependency to be an older one (e.g., <code>9.4.1212.jre7</code>).</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To fix this, re-declare the dependency in its correct version.
|
||||
For example, in Maven:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.1.1</version>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_samples"><a class="link" href="#_samples">Samples</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Available sample applications and codelabs:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample">Spring Cloud GCP MySQL</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample">Spring Cloud GCP PostgreSQL</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-data-jpa-sample">Spring Data JPA with Spring Cloud GCP SQL</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Codelab: <a href="https://codelabs.developers.google.com/codelabs/cloud-spring-petclinic-cloudsql/index.html">Spring Pet Clinic using Cloud SQL</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
269
spring-cloud-gcp/1.2.0.M2/reference/html/storage.html
Normal file
@@ -0,0 +1,269 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Resources</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_resources">Spring Resources</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_google_cloud_storage">Google Cloud Storage</a></li>
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_resources"><a class="link" href="#_spring_resources">Spring Resources</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p><a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html">Spring Resources</a> are an abstraction for a number of low-level resources, such as file system files, classpath files, servlet context-relative files, etc.
|
||||
Spring Cloud GCP adds a new resource type: a Google Cloud Storage (GCS) object.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A Spring Boot starter is provided to auto-configure the various Storage components.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-storage'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This starter is also available from <a href="https://start.spring.io/">Spring Initializr</a> through the <code>GCP Storage</code> entry.</p>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_google_cloud_storage"><a class="link" href="#_google_cloud_storage">Google Cloud Storage</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Resource Abstraction for Google Cloud Storage allows GCS objects to be accessed by their GCS URL using the <code>@Value</code> annotation:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Value("gs://[YOUR_GCS_BUCKET]/[GCS_FILE_NAME]")
|
||||
private Resource gcsResource;</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>…​or the Spring application context</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">SpringApplication.run(...).getResource("gs://[YOUR_GCS_BUCKET]/[GCS_FILE_NAME]");</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This creates a <code>Resource</code> object that can be used to read the object, among <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html#resources-resource">other possible operations</a>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>It is also possible to write to a <code>Resource</code>, although a <code>WriteableResource</code> is required.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Value("gs://[YOUR_GCS_BUCKET]/[GCS_FILE_NAME]")
|
||||
private Resource gcsResource;
|
||||
...
|
||||
try (OutputStream os = ((WritableResource) gcsResource).getOutputStream()) {
|
||||
os.write("foo".getBytes());
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>To work with the <code>Resource</code> as a Google Cloud Storage resource, cast it to <code>GoogleStorageResource</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If the resource path refers to an object on Google Cloud Storage (as opposed to a bucket), then the <code>getBlob</code> method can be called to obtain a <a href="https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java"><code>Blob</code></a>.
|
||||
This type represents a GCS file, which has associated <a href="https://cloud.google.com/storage/docs/gsutil/addlhelp/WorkingWithObjectMetadata">metadata</a>, such as content-type, that can be set.
|
||||
The <code>createSignedUrl</code> method can also be used to obtain <a href="https://cloud.google.com/storage/docs/access-control/signed-urls">signed URLs</a> for GCS objects.
|
||||
However, creating signed URLs requires that the resource was created using service account credentials.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Boot Starter for Google Cloud Storage auto-configures the <code>Storage</code> bean required by the <code>spring-cloud-gcp-storage</code> module, based on the <code>CredentialsProvider</code> provided by the Spring Boot GCP starter.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_setting_the_content_type"><a class="link" href="#_setting_the_content_type">Setting the Content Type</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>You can set the content-type of Google Cloud Storage files from their corresponding <code>Resource</code> objects:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">((GoogleStorageResource)gcsResource).getBlob().toBuilder().setContentType("text/html").build().update();</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The Spring Boot Starter for Google Cloud Storage provides the following configuration options:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.storage.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables the GCP storage APIs.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.storage.auto-create-files</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Creates files and buckets on Google Cloud Storage when writes are made to non-existent files</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.storage.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">OAuth2 credentials for authenticating with the Google Cloud Storage API, if different from the ones in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.storage.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Base64-encoded contents of OAuth2 account private key for authenticating with the Google Cloud Storage API, if different from the ones in the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Core Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.storage.credentials.scopes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://developers.google.com/identity/protocols/googlescopes">OAuth2 scope</a> for Spring Cloud GCP Storage credentials</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://www.googleapis.com/auth/devstorage.read_write" class="bare">https://www.googleapis.com/auth/devstorage.read_write</a></p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-storage-resource-sample">sample application</a> and a <a href="https://codelabs.developers.google.com/codelabs/spring-cloud-gcp-gcs/index.html">codelab</a> are available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
411
spring-cloud-gcp/1.2.0.M2/reference/html/trace.html
Normal file
@@ -0,0 +1,411 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Spring Cloud Sleuth</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_spring_cloud_sleuth">Spring Cloud Sleuth</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_tracing">Tracing</a></li>
|
||||
<li><a href="#_spring_boot_starter_for_stackdriver_trace">Spring Boot Starter for Stackdriver Trace</a></li>
|
||||
<li><a href="#_overriding_the_auto_configuration">Overriding the auto-configuration</a></li>
|
||||
<li><a href="#_customizing_spans">Customizing spans</a></li>
|
||||
<li><a href="#_integration_with_logging">Integration with Logging</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_spring_cloud_sleuth"><a class="link" href="#_spring_cloud_sleuth">Spring Cloud Sleuth</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.spring.io/spring-cloud-sleuth/">Spring Cloud Sleuth</a> is an instrumentation framework for Spring Boot applications.
|
||||
It captures trace information and can forward traces to services like Zipkin for storage and analysis.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Google Cloud Platform provides its own managed distributed tracing service called <a href="https://cloud.google.com/trace/">Stackdriver Trace</a>.
|
||||
Instead of running and maintaining your own Zipkin instance and storage, you can use Stackdriver Trace to store traces, view trace details, generate latency distributions graphs, and generate performance regression reports.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This Spring Cloud GCP starter can forward Spring Cloud Sleuth traces to Stackdriver Trace without an intermediary Zipkin server.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-trace</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-trace'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You must enable Stackdriver Trace API from the Google Cloud Console in order to capture traces.
|
||||
Navigate to the <a href="https://console.cloud.google.com/apis/api/cloudtrace.googleapis.com/overview">Stackdriver Trace API</a> for your project and make sure it’s enabled.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
<div class="paragraph">
|
||||
<p>If you are already using a Zipkin server capturing trace information from multiple platform/frameworks, you can also use a <a href="https://cloud.google.com/trace/docs/zipkin">Stackdriver Zipkin proxy</a> to forward those traces to Stackdriver Trace without modifying existing applications.</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_tracing"><a class="link" href="#_tracing">Tracing</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud Sleuth uses the <a href="https://github.com/openzipkin/brave">Brave tracer</a> to generate traces.
|
||||
This integration enables Brave to use the <a href="https://github.com/openzipkin/zipkin-gcp/tree/master/propagation-stackdriver"><code>StackdriverTracePropagation</code></a> propagation.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>A propagation is responsible for extracting trace context from an entity (e.g., an HTTP servlet request) and injecting trace context into an entity.
|
||||
A canonical example of the propagation usage is a web server that receives an HTTP request, which triggers other HTTP requests from the server before returning an HTTP response to the original caller.
|
||||
In the case of <code>StackdriverTracePropagation</code>, first it looks for trace context in the <code>x-cloud-trace-context</code> key (e.g., an HTTP request header).
|
||||
The value of the <code>x-cloud-trace-context</code> key can be formatted in three different ways:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>x-cloud-trace-context: TRACE_ID</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>x-cloud-trace-context: TRACE_ID/SPAN_ID</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>x-cloud-trace-context: TRACE_ID/SPAN_ID;o=TRACE_TRUE</code></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>TRACE_ID</code> is a 32-character hexadecimal value that encodes a 128-bit number.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>SPAN_ID</code> is an unsigned long.
|
||||
Since Stackdriver Trace doesn’t support span joins, a new span ID is always generated, regardless of the one specified in <code>x-cloud-trace-context</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>TRACE_TRUE</code> can either be <code>0</code> if the entity should be untraced, or <code>1</code> if it should be traced.
|
||||
This field forces the decision of whether or not to trace the request; if omitted then the decision is deferred to the sampler.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If a <code>x-cloud-trace-context</code> key isn’t found, <code>StackdriverTracePropagation</code> falls back to tracing with the <a href="https://github.com/openzipkin/b3-propagation">X-B3 headers</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_spring_boot_starter_for_stackdriver_trace"><a class="link" href="#_spring_boot_starter_for_stackdriver_trace">Spring Boot Starter for Stackdriver Trace</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Spring Boot Starter for Stackdriver Trace uses Spring Cloud Sleuth and auto-configures a <a href="https://github.com/openzipkin/zipkin-gcp/blob/master/sender-stackdriver/src/main/java/zipkin2/reporter/stackdriver/StackdriverSender.java">StackdriverSender</a> that sends the Sleuth’s trace information to Stackdriver Trace.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>All configurations are optional:</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Auto-configure Spring Cloud Sleuth to send traces to Stackdriver Trace.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.project-id</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Overrides the project ID from the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.credentials.location</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Overrides the credentials location from the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.credentials.encoded-key</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Overrides the credentials encoded key from the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.credentials.scopes</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Overrides the credentials scopes from the <a href="#spring-cloud-gcp-core">Spring Cloud GCP Module</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.num-executor-threads</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of threads used by the Trace executor</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.authority</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/2 authority the channel claims to be connecting to.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.compression</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name of the compression to use in Trace calls</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.deadline-ms</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Call deadline in milliseconds</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.max-inbound-size</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum size for inbound messages</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.max-outbound-size</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Maximum size for outbound messages</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.wait-for-ready</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">Waits for the channel to be ready</a> in case of a transient failure</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.trace.messageTimeout</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Timeout in seconds before pending spans will be sent in batches to GCP Stackdriver Trace. (previously <code>spring.zipkin.messageTimeout</code>)</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="paragraph">
|
||||
<p>You can use core Spring Cloud Sleuth properties to control Sleuth’s sampling rate, etc.
|
||||
Read <a href="https://cloud.spring.io/spring-cloud-sleuth/">Sleuth documentation</a> for more information on Sleuth configurations.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>For example, when you are testing to see the traces are going through, you can set the sampling rate to 100%.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>spring.sleuth.sampler.probability=1 # Send 100% of the request traces to Stackdriver.
|
||||
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*) # Ignore some URL paths.</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP Trace does override some Sleuth configurations:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Always uses 128-bit Trace IDs.
|
||||
This is required by Stackdriver Trace.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Does not use Span joins.
|
||||
Span joins will share the span ID between the client and server Spans.
|
||||
Stackdriver requires that every Span ID within a Trace to be unique, so Span joins are not supported.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Uses <code>StackdriverHttpClientParser</code> and <code>StackdriverHttpServerParser</code> by default to populate Stackdriver related fields.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_overriding_the_auto_configuration"><a class="link" href="#_overriding_the_auto_configuration">Overriding the auto-configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud Sleuth supports sending traces to multiple tracing systems as of version 2.1.0.
|
||||
In order to get this to work, every tracing system needs to have a <code>Reporter<Span></code> and <code>Sender</code>.
|
||||
If you want to override the provided beans you need to give them a specific name.
|
||||
To do this you can use respectively <code>StackdriverTraceAutoConfiguration.REPORTER_BEAN_NAME</code> and <code>StackdriverTraceAutoConfiguration.SENDER_BEAN_NAME</code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_customizing_spans"><a class="link" href="#_customizing_spans">Customizing spans</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>You can add additional tags and annotations to spans by using the <code>brave.SpanCustomizer</code>, which is available in the application context.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here’s an example that uses <code>WebMvcConfigurer</code> to configure an MVC interceptor that adds two extra tags to all web controller spans.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@SpringBootApplication
|
||||
public class Application implements WebMvcConfigurer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SpanCustomizer spanCustomizer;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new HandlerInterceptor() {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
spanCustomizer.tag("session-id", request.getSession().getId());
|
||||
spanCustomizer.tag("environment", "QA");
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>You can then search and filter traces based on these additional tags in the Stackdriver Trace service.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_integration_with_logging"><a class="link" href="#_integration_with_logging">Integration with Logging</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Integration with Stackdriver Logging is available through the <a href="logging.adoc">Stackdriver Logging Support</a>.
|
||||
If the Trace integration is used together with the Logging one, the request logs will be associated to the corresponding traces.
|
||||
The trace logs can be viewed by going to the <a href="https://console.cloud.google.com/traces/traces">Google Cloud Console Trace List</a>, selecting a trace and pressing the <code>Logs → View</code> link in the <code>Details</code> section.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>A <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-trace-sample">sample application</a> and a <a href="https://codelabs.developers.google.com/codelabs/cloud-spring-cloud-gcp-trace/index.html">codelab</a> are available.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
452
spring-cloud-gcp/1.2.0.M2/reference/html/vision.html
Normal file
@@ -0,0 +1,452 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 1.5.7.1">
|
||||
<title>Google Cloud Vision</title>
|
||||
<link rel="stylesheet" href="css/spring.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.switch {
|
||||
border-width: 1px 1px 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.switch--item {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
color: #7a2518;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch--item:not(:first-child) {
|
||||
border-width: 0 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #7a2518;
|
||||
}
|
||||
|
||||
.switch--item.selected {
|
||||
background-color: #7a2519;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function addBlockSwitches() {
|
||||
$('.primary').each(function() {
|
||||
primary = $(this);
|
||||
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
||||
primary.children('.title').remove();
|
||||
});
|
||||
$('.secondary').each(function(idx, node) {
|
||||
secondary = $(node);
|
||||
primary = findPrimary(secondary);
|
||||
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
||||
switchItem.content.addClass('hidden');
|
||||
findPrimary(secondary).append(switchItem.content);
|
||||
secondary.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function createBlockSwitch(primary) {
|
||||
blockSwitch = $('<div class="switch"></div>');
|
||||
primary.prepend(blockSwitch);
|
||||
return blockSwitch;
|
||||
}
|
||||
|
||||
function findPrimary(secondary) {
|
||||
candidate = secondary.prev();
|
||||
while (!candidate.is('.primary')) {
|
||||
candidate = candidate.prev();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function createSwitchItem(block, blockSwitch) {
|
||||
blockName = block.children('.title').text();
|
||||
content = block.children('.content').first().append(block.next('.colist'));
|
||||
item = $('<div class="switch--item">' + blockName + '</div>');
|
||||
item.on('click', '', content, function(e) {
|
||||
$(this).addClass('selected');
|
||||
$(this).siblings().removeClass('selected');
|
||||
e.data.siblings('.content').addClass('hidden');
|
||||
e.data.removeClass('hidden');
|
||||
});
|
||||
blockSwitch.append(item);
|
||||
return {'item': item, 'content': content};
|
||||
}
|
||||
|
||||
$(addBlockSwitches);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body class="book toc2 toc-left">
|
||||
<div id="header">
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
<ul class="sectlevel1">
|
||||
<li><a href="#_google_cloud_vision">Google Cloud Vision</a>
|
||||
<ul class="sectlevel2">
|
||||
<li><a href="#_dependency_setup">Dependency Setup</a></li>
|
||||
<li><a href="#_image_analysis">Image Analysis</a></li>
|
||||
<li><a href="#_document_ocr_template">Document OCR Template</a></li>
|
||||
<li><a href="#_configuration">Configuration</a></li>
|
||||
<li><a href="#_sample">Sample</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="sect1">
|
||||
<h2 id="_google_cloud_vision"><a class="link" href="#_google_cloud_vision">Google Cloud Vision</a></h2>
|
||||
<div class="sectionbody">
|
||||
<div class="paragraph">
|
||||
<p>The <a href="https://cloud.google.com/vision/">Google Cloud Vision API</a> allows users to leverage machine learning algorithms for processing images and documents including: image classification, face detection, text extraction, optical character recognition, and others.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Spring Cloud GCP provides:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>A convenience starter which automatically configures authentication settings and client objects needed to begin using the <a href="https://cloud.google.com/vision/">Google Cloud Vision API</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>CloudVisionTemplate</code> which simplifies interactions with the Cloud Vision API.</p>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>Allows you to easily send images to the API as Spring Resources.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Offers convenience methods for common operations, such as classifying content of an image.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>DocumentOcrTemplate</code> which offers convenient methods for running <a href="https://cloud.google.com/vision/docs/pdf">optical character recognition (OCR)</a> on PDF and TIFF documents.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_dependency_setup"><a class="link" href="#_dependency_setup">Dependency Setup</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>To begin using this library, add the <code>spring-cloud-gcp-starter-vision</code> artifact to your project.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates, using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-vision</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-vision'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_cloud_vision_ocr_dependencies"><a class="link" href="#_cloud_vision_ocr_dependencies">Cloud Vision OCR Dependencies</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>If you are interested in applying optical character recognition (OCR) on documents for your project, you’ll need to add both <code>spring-cloud-gcp-starter-vision</code> and <code>spring-cloud-gcp-starter-storage</code> to your dependencies.
|
||||
The storage starter is necessary because the Cloud Vision API will process your documents and write OCR output files all within your Google Cloud Storage buckets.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Maven coordinates using <a href="getting-started.html#_bill_of_materials">Spring Cloud GCP BOM</a>:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-vision</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-starter-storage</artifactId>
|
||||
</dependency></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Gradle coordinates:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code>dependencies {
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-vision'
|
||||
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-storage'
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_image_analysis"><a class="link" href="#_image_analysis">Image Analysis</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The <code>CloudVisionTemplate</code> allows you to easily analyze images; it provides the following method for interfacing with Cloud Vision:</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>public AnnotateImageResponse analyzeImage(Resource imageResource, Feature.Type…​ featureTypes)</code></p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><strong>Parameters:</strong></p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>Resource imageResource</code> refers to the Spring Resource of the image object you wish to analyze.
|
||||
The Google Cloud Vision documentation provides a <a href="https://cloud.google.com/vision/docs/supported-files">list of the image types that they support</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>Feature.Type…​ featureTypes</code> refers to a var-arg array of Cloud Vision Features to extract from the image.
|
||||
A feature refers to a kind of image analysis one wishes to perform on an image, such as label detection, OCR recognition, facial detection, etc.
|
||||
One may specify multiple features to analyze within one request.
|
||||
A full list of Cloud Vision Features is provided in the <a href="https://cloud.google.com/vision/docs/features">Cloud Vision Feature docs</a>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><strong>Returns:</strong></p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href="https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.AnnotateImageResponse"><code>AnnotateImageResponse</code></a> contains the results of all the feature analyses that were specified in the request.
|
||||
For each feature type that you provide in the request, <code>AnnotateImageResponse</code> provides a getter method to get the result of that feature analysis.
|
||||
For example, if you analyzed an image using the <code>LABEL_DETECTION</code> feature, you would retrieve the results from the response using <code>annotateImageResponse.getLabelAnnotationsList()</code>.</p>
|
||||
<div class="paragraph">
|
||||
<p><code>AnnotateImageResponse</code> is provided by the Google Cloud Vision libraries; please consult the <a href="https://cloud.google.com/vision/docs/reference/rpc/google.cloud.vision.v1#google.cloud.vision.v1.AnnotateImageResponse">RPC reference</a> or <a href="https://googleapis.github.io/googleapis/java/all/latest/apidocs/com/google/cloud/vision/v1/AnnotateImageResponse.html">Javadoc</a> for more details.
|
||||
Additionally, you may consult the <a href="https://cloud.google.com/vision/docs/">Cloud Vision docs</a> to familiarize yourself with the concepts and features of the API.</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_detect_image_labels_example"><a class="link" href="#_detect_image_labels_example">Detect Image Labels Example</a></h4>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://cloud.google.com/vision/docs/detecting-labels">Image labeling</a> refers to producing labels that describe the contents of an image.
|
||||
Below is a code sample of how this is done using the Cloud Vision Spring Template.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@Autowired
|
||||
private CloudVisionTemplate cloudVisionTemplate;
|
||||
|
||||
public void processImage() {
|
||||
Resource imageResource = this.resourceLoader.getResource("my_image.jpg");
|
||||
AnnotateImageResponse response = this.cloudVisionTemplate.analyzeImage(
|
||||
imageResource, Type.LABEL_DETECTION);
|
||||
System.out.println("Image Classification results: " + response.getLabelAnnotationsList());
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_document_ocr_template"><a class="link" href="#_document_ocr_template">Document OCR Template</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The <code>DocumentOcrTemplate</code> allows you to easily run <a href="https://cloud.google.com/vision/docs/pdf">optical character recognition (OCR)</a> on your PDF and TIFF documents stored in your Google Storage bucket.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>First, you will need to create a bucket in <a href="https://console.cloud.google.com/storage">Google Cloud Storage</a> and <a href="https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-java">upload the documents you wish to process into the bucket</a>.</p>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_running_ocr_on_a_document"><a class="link" href="#_running_ocr_on_a_document">Running OCR on a Document</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>When OCR is run on a document, the Cloud Vision APIs will output a collection of OCR output files in JSON which describe the text content, bounding rectangles of words and letters, and other information about the document.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The <code>DocumentOcrTemplate</code> provides the following method for running OCR on a document saved in Google Cloud Storage:</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>ListenableFuture<DocumentOcrResultSet> runOcrForDocument(GoogleStorageLocation document, GoogleStorageLocation outputFilePathPrefix)</code></p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The method allows you to specify the location of the document and the output location for where all the JSON output files will be saved in Google Cloud Storage.
|
||||
It returns a <code>ListenableFuture</code> containing <code>DocumentOcrResultSet</code> which contains the OCR content of the document.</p>
|
||||
</div>
|
||||
<div class="admonitionblock note">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="icon">
|
||||
<i class="fa icon-note" title="Note"></i>
|
||||
</td>
|
||||
<td class="content">
|
||||
Running OCR on a document is an operation that can take between several minutes to several hours depending on how large the document is.
|
||||
It is recommended to register callbacks to the returned ListenableFuture or ignore it and process the JSON output files at a later point in time using <code>readOcrOutputFile</code> or <code>readOcrOutputFileSet</code>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_running_ocr_example"><a class="link" href="#_running_ocr_example">Running OCR Example</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>Below is a code snippet of how to run OCR on a document stored in a Google Storage bucket and read the text in the first page of the document.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre>@Autowired
|
||||
private DocumentOcrTemplate documentOcrTemplate;
|
||||
|
||||
public void runOcrOnDocument() {
|
||||
GoogleStorageLocation document = GoogleStorageLocation.forFile(
|
||||
"your-bucket", "test.pdf");
|
||||
GoogleStorageLocation outputLocationPrefix = GoogleStorageLocation.forFolder(
|
||||
"your-bucket", "output_folder/test.pdf/");
|
||||
|
||||
ListenableFuture<DocumentOcrResultSet> result =
|
||||
this.documentOcrTemplate.runOcrForDocument(
|
||||
document, outputLocationPrefix);
|
||||
|
||||
DocumentOcrResultSet ocrPages = result.get(5, TimeUnit.MINUTES);
|
||||
|
||||
String page1Text = ocrPages.getPage(1).getText();
|
||||
System.out.println(page1Text);
|
||||
}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_reading_ocr_output_files"><a class="link" href="#_reading_ocr_output_files">Reading OCR Output Files</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>In some use-cases, you may need to directly read OCR output files stored in Google Cloud Storage.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><code>DocumentOcrTemplate</code> offers the following methods for reading and processing OCR output files:</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>readOcrOutputFileSet(GoogleStorageLocation jsonOutputFilePathPrefix)</code>:
|
||||
Reads a collection of OCR output files under a file path prefix and returns the parsed contents.
|
||||
All of the files under the path should correspond to the same document.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>readOcrOutputFile(GoogleStorageLocation jsonFile)</code>:
|
||||
Reads a single OCR output file and returns the parsed contents.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="_reading_ocr_output_files_example"><a class="link" href="#_reading_ocr_output_files_example">Reading OCR Output Files Example</a></h4>
|
||||
<div class="paragraph">
|
||||
<p>The code snippet below describes how to read the OCR output files of a single document.</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre>@Autowired
|
||||
private DocumentOcrTemplate documentOcrTemplate;
|
||||
|
||||
// Parses the OCR output files corresponding to a single document in a directory
|
||||
public void parseOutputFileSet() {
|
||||
GoogleStorageLocation ocrOutputPrefix = GoogleStorageLocation.forFolder(
|
||||
"your-bucket", "json_output_set/");
|
||||
|
||||
DocumentOcrResultSet result = this.documentOcrTemplate.readOcrOutputFileSet(ocrOutputPrefix);
|
||||
System.out.println("Page 2 text: " + result.getPage(2).getText());
|
||||
}
|
||||
|
||||
// Parses a single OCR output file
|
||||
public void parseSingleOutputFile() {
|
||||
GoogleStorageLocation ocrOutputFile = GoogleStorageLocation.forFile(
|
||||
"your-bucket", "json_output_set/test_output-2-to-2.json");
|
||||
|
||||
DocumentOcrResultSet result = this.documentOcrTemplate.readOcrOutputFile(ocrOutputFile);
|
||||
System.out.println("Page 2 text: " + result.getPage(2).getText());
|
||||
}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>The following options may be configured with Spring Cloud GCP Vision libraries.</p>
|
||||
</div>
|
||||
<table class="tableblock frame-all grid-all stretch">
|
||||
<colgroup>
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
<col style="width: 25%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Name</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Required</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Default value</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.vision.enabled</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Enables or disables Cloud Vision autoconfiguration</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.vision.executors-threads-count</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of threads used during document OCR processing for waiting on long-running OCR operations</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>spring.cloud.gcp.vision.json-output-batch-size</code></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of document pages to include in each OCR output file.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">20</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sect2">
|
||||
<h3 id="_sample"><a class="link" href="#_sample">Sample</a></h3>
|
||||
<div class="paragraph">
|
||||
<p>Samples are provided to show example usages of Spring Cloud GCP with Google Cloud Vision.</p>
|
||||
</div>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>The <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-vision-api-sample">Image Labeling Sample</a> shows you how to use image labelling in your Spring application.
|
||||
The application generates labels describing the content inside the images you specify in the application.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-vision-ocr-demo">Document OCR demo</a> shows how you can apply OCR processing on your PDF/TIFF documents in order to extract their text contents.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
||||
<script type="text/javascript" src="js/toc.js"></script>
|
||||
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
||||
<script src="js/highlight/highlight.min.js"></script>
|
||||
<script>hljs.initHighlighting()</script>
|
||||
</body>
|
||||
</html>
|
||||
20
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/Guardfile
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'asciidoctor'
|
||||
require 'erb'
|
||||
|
||||
guard 'shell' do
|
||||
watch(/.*\.adoc$/) {|m|
|
||||
Asciidoctor.render_file('index.adoc', \
|
||||
:in_place => true, \
|
||||
:safe => Asciidoctor::SafeMode::UNSAFE, \
|
||||
:attributes=> { \
|
||||
'source-highlighter' => 'prettify', \
|
||||
'icons' => 'font', \
|
||||
'linkcss'=> 'true', \
|
||||
'copycss' => 'true', \
|
||||
'doctype' => 'book'})
|
||||
}
|
||||
end
|
||||
|
||||
guard 'livereload' do
|
||||
watch(%r{^.+\.(css|js|html)$})
|
||||
end
|
||||
BIN
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/favicon.ico
Normal file
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 66 KiB |
2
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/highlight.min.js
vendored
Normal file
99
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/a11y-dark.min.css
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/* a11y-dark theme */
|
||||
/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */
|
||||
/* @author: ericwbailey */
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #d4d0ab;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion {
|
||||
color: #ffa07a;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #f5ab35;
|
||||
}
|
||||
|
||||
/* Yellow */
|
||||
.hljs-attribute {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition {
|
||||
color: #abe338;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #00e0e0;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #dcc6e0;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #2b2b2b;
|
||||
color: #f8f8f2;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-bullet,
|
||||
.hljs-comment,
|
||||
.hljs-link,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-params,
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-type,
|
||||
.hljs-quote {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
89
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/an-old-hope.min.css
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
An Old Hope – Star Wars Syntax (c) Gustavo Costa <gusbemacbe@gmail.com>
|
||||
Original theme - Ocean Dark Theme – by https://github.com/gavsiu
|
||||
Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom
|
||||
|
||||
*/
|
||||
|
||||
/* Death Star Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote
|
||||
{
|
||||
color: #B6B18B;
|
||||
}
|
||||
|
||||
/* Darth Vader */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion
|
||||
{
|
||||
color: #EB3C54;
|
||||
}
|
||||
|
||||
/* Threepio */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link
|
||||
{
|
||||
color: #E7CE56;
|
||||
}
|
||||
|
||||
/* Luke Skywalker */
|
||||
.hljs-attribute
|
||||
{
|
||||
color: #EE7C2B;
|
||||
}
|
||||
|
||||
/* Obi Wan Kenobi */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition
|
||||
{
|
||||
color: #4FB4D7;
|
||||
}
|
||||
|
||||
/* Yoda */
|
||||
.hljs-title,
|
||||
.hljs-section
|
||||
{
|
||||
color: #78BB65;
|
||||
}
|
||||
|
||||
/* Mace Windu */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag
|
||||
{
|
||||
color: #B45EA4;
|
||||
}
|
||||
|
||||
/* Millenium Falcon */
|
||||
.hljs
|
||||
{
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1C1D21;
|
||||
color: #c0c5ce;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.hljs-emphasis
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
|
||||
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
|
||||
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
*/
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
line-height: 1.3em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.hljs-keyword, .hljs-operator {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match .hljs-constructor {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function .hljs-params {
|
||||
color: #A6E22E;
|
||||
}
|
||||
.hljs-function .hljs-params .hljs-typing {
|
||||
color: #FD971F;
|
||||
}
|
||||
.hljs-module-access .hljs-module {
|
||||
color: #7e57c2;
|
||||
}
|
||||
.hljs-constructor {
|
||||
color: #e2b93d;
|
||||
}
|
||||
.hljs-constructor .hljs-string {
|
||||
color: #9CCC65;
|
||||
}
|
||||
.hljs-comment, .hljs-quote {
|
||||
color: #b18eb1;
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-doctag, .hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
.hljs-built_in, .hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/atom-one-dark.min.css
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Dark by Daniel Gamage
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
base: #282c34
|
||||
mono-1: #abb2bf
|
||||
mono-2: #818896
|
||||
mono-3: #5c6370
|
||||
hue-1: #56b6c2
|
||||
hue-2: #61aeee
|
||||
hue-3: #c678dd
|
||||
hue-4: #98c379
|
||||
hue-5: #e06c75
|
||||
hue-5-2: #be5046
|
||||
hue-6: #d19a66
|
||||
hue-6-2: #e6c07b
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6370;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
96
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/atom-one-light.min.css
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
76
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/dracula.min.css
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
Dracula Theme v1.2.0
|
||||
|
||||
https://github.com/zenorocha/dracula-theme
|
||||
|
||||
Copyright 2015, All rights reserved
|
||||
|
||||
Code licensed under the MIT license
|
||||
http://zenorocha.mit-license.org
|
||||
|
||||
@author Éverton Ribeiro <nuxlli@gmail.com>
|
||||
@author Zeno Rocha <hi@zenorocha.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #282a36;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-section,
|
||||
.hljs-link {
|
||||
color: #8be9fd;
|
||||
}
|
||||
|
||||
.hljs-function .hljs-keyword {
|
||||
color: #ff79c6;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-type,
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #f1fa8c;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #6272a4;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-doctag,
|
||||
.hljs-type,
|
||||
.hljs-name,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
99
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/github.min.css
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
83
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/monokai-sublime.min.css
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
|
||||
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #23241f;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-tag,
|
||||
.hljs-subst {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-strong,
|
||||
.hljs-emphasis {
|
||||
color: #a8a8a2;
|
||||
}
|
||||
|
||||
.hljs-bullet,
|
||||
.hljs-quote,
|
||||
.hljs-number,
|
||||
.hljs-regexp,
|
||||
.hljs-literal,
|
||||
.hljs-link {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.hljs-code,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-class {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-name,
|
||||
.hljs-attr {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-attribute {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.hljs-params,
|
||||
.hljs-class .hljs-title {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #75715e;
|
||||
}
|
||||
70
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/monokai.min.css
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Monokai style - ported by Luigi Maselli - http://grigio.org
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #272822; color: #ddd;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-strong,
|
||||
.hljs-name {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.hljs-code {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.hljs-class .hljs-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.hljs-attribute,
|
||||
.hljs-symbol,
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #bf79db;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet,
|
||||
.hljs-subst,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-emphasis,
|
||||
.hljs-type,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-addition,
|
||||
.hljs-variable,
|
||||
.hljs-template-tag,
|
||||
.hljs-template-variable {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-deletion,
|
||||
.hljs-meta {
|
||||
color: #75715e;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-doctag,
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-type,
|
||||
.hljs-selector-id {
|
||||
font-weight: bold;
|
||||
}
|
||||
84
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/solarized-light.min.css
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
|
||||
Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #fdf6e3;
|
||||
color: #657b83;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #93a1a1;
|
||||
}
|
||||
|
||||
/* Solarized Green */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-addition {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
/* Solarized Cyan */
|
||||
.hljs-number,
|
||||
.hljs-string,
|
||||
.hljs-meta .hljs-meta-string,
|
||||
.hljs-literal,
|
||||
.hljs-doctag,
|
||||
.hljs-regexp {
|
||||
color: #2aa198;
|
||||
}
|
||||
|
||||
/* Solarized Blue */
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
/* Solarized Yellow */
|
||||
.hljs-attribute,
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-class .hljs-title,
|
||||
.hljs-type {
|
||||
color: #b58900;
|
||||
}
|
||||
|
||||
/* Solarized Orange */
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-subst,
|
||||
.hljs-meta,
|
||||
.hljs-meta .hljs-keyword,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-link {
|
||||
color: #cb4b16;
|
||||
}
|
||||
|
||||
/* Solarized Red */
|
||||
.hljs-built_in,
|
||||
.hljs-deletion {
|
||||
color: #dc322f;
|
||||
}
|
||||
|
||||
.hljs-formula {
|
||||
background: #eee8d5;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
80
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/highlight/styles/zenburn.min.css
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
|
||||
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
|
||||
based on dark.css by Ivan Sagalaev
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
background: #3f3f3f;
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-tag {
|
||||
color: #e3ceab;
|
||||
}
|
||||
|
||||
.hljs-template-tag {
|
||||
color: #dcdcdc;
|
||||
}
|
||||
|
||||
.hljs-number {
|
||||
color: #8cd0d3;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute {
|
||||
color: #efdcbc;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #efefaf;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
color: #8f8f8f;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-section,
|
||||
.hljs-type {
|
||||
color: #efef8f;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link {
|
||||
color: #dca3a3;
|
||||
}
|
||||
|
||||
.hljs-deletion,
|
||||
.hljs-string,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name {
|
||||
color: #cc9393;
|
||||
}
|
||||
|
||||
.hljs-addition,
|
||||
.hljs-comment,
|
||||
.hljs-quote,
|
||||
.hljs-meta {
|
||||
color: #7f9f7f;
|
||||
}
|
||||
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
107
spring-cloud-gcp/1.2.0.M2/reference/htmlsingle/js/toc.js
Normal file
@@ -0,0 +1,107 @@
|
||||
var toctitle = document.getElementById('toctitle');
|
||||
var path = window.location.pathname;
|
||||
if (toctitle != null) {
|
||||
var oldtoc = toctitle.nextElementSibling;
|
||||
var newtoc = document.createElement('div');
|
||||
newtoc.setAttribute('id', 'tocbot');
|
||||
newtoc.setAttribute('class', 'js-toc desktop-toc');
|
||||
oldtoc.setAttribute('class', 'mobile-toc');
|
||||
oldtoc.parentNode.appendChild(newtoc);
|
||||
tocbot.init({
|
||||
contentSelector: '#content',
|
||||
headingSelector: 'h1, h2, h3, h4, h5',
|
||||
positionFixedSelector: 'body',
|
||||
fixedSidebarOffset: 90,
|
||||
smoothScroll: false
|
||||
});
|
||||
if (!path.endsWith("index.html") && !path.endsWith("/")) {
|
||||
var link = document.createElement("a");
|
||||
link.setAttribute("href", "index.html");
|
||||
link.innerHTML = "<span><i class=\"fa fa-chevron-left\" aria-hidden=\"true\"></i></span> Back to index";
|
||||
var block = document.createElement("div");
|
||||
block.setAttribute('class', 'back-action');
|
||||
block.appendChild(link);
|
||||
var toc = document.getElementById('toc');
|
||||
var next = document.getElementById('toctitle').nextElementSibling;
|
||||
toc.insertBefore(block, next);
|
||||
}
|
||||
}
|
||||
|
||||
var headerHtml = '<div id="header-spring">\n' +
|
||||
'<h1>\n' +
|
||||
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0"\n' +
|
||||
'viewBox="0 0 245.8 45.3" style="enable-background:new 0 0 245.8 45.3;" xml:space="preserve">\n' +
|
||||
'<g id="logos">\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st0" d="M39.4,3.7c-0.6,1.5-1.4,2.8-2.3,4c-3.9-4-9.3-6.4-15.2-6.4c-11.7,0-21.3,9.5-21.3,21.3\n' +
|
||||
'c0,6.2,2.6,11.7,6.8,15.6l0.8,0.7c3.7,3.1,8.5,5,13.7,5c11.2,0,20.4-8.7,21.2-19.8C43.7,18.7,42.1,11.8,39.4,3.7z M10.5,38.3\n' +
|
||||
'c-0.6,0.8-1.8,0.9-2.6,0.3C7.1,37.9,7,36.8,7.6,36c0.6-0.8,1.8-0.9,2.6-0.3C11,36.4,11.1,37.5,10.5,38.3z M39.3,31.9\n' +
|
||||
'c-5.2,7-16.5,4.6-23.6,5c0,0-1.3,0.1-2.6,0.3c0,0,0.5-0.2,1.1-0.4c5-1.7,7.4-2.1,10.5-3.7c5.8-3,11.5-9.4,12.7-16.1\n' +
|
||||
'c-2.2,6.4-8.9,12-14.9,14.2c-4.2,1.5-11.7,3-11.7,3c0,0-0.3-0.2-0.3-0.2c-5.1-2.5-5.3-13.6,4-17.1c4.1-1.6,8-0.7,12.4-1.8\n' +
|
||||
'C31.6,14.1,37,10.6,39.2,6C41.7,13.3,44.7,24.8,39.3,31.9z"/>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st0" d="M55.2,30.9c-0.5-0.3-0.9-0.9-0.9-1.6c0-1.1,0.8-1.9,1.9-1.9c0.4,0,0.7,0.1,1,0.3c2,1.3,4.1,2,5.9,2\n' +
|
||||
'c2,0,3.2-0.9,3.2-2.2v-0.1c0-1.6-2.2-2.2-4.6-2.9c-3-0.9-6.5-2.1-6.5-6.1v-0.1c0-3.9,3.2-6.3,7.4-6.3c2.2,0,4.5,0.6,6.5,1.7\n' +
|
||||
'c0.7,0.4,1.1,1,1.1,1.8c0,1.1-0.9,1.9-2,1.9c-0.4,0-0.6-0.1-0.9-0.2c-1.7-0.9-3.4-1.4-4.9-1.4c-1.8,0-2.9,0.9-2.9,2v0.1\n' +
|
||||
'c0,1.5,2.2,2.2,4.7,2.9c3,0.9,6.4,2.3,6.4,6v0.1c0,4.3-3.4,6.5-7.7,6.5C60.4,33.3,57.6,32.5,55.2,30.9z"/>\n' +
|
||||
'<path class="st0" d="M72.5,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1.4c1.5-2.2,3.7-3.9,7-3.9c4.8,0,9.6,3.8,9.6,10.7\n' +
|
||||
'v0.1c0,6.8-4.7,10.7-9.6,10.7c-3.4,0-5.6-1.7-7-3.6V37c0,1.3-1.1,2.4-2.4,2.4c-1.3,0-2.3-1-2.3-2.4V14.3z M89.1,22.7L89.1,22.7\n' +
|
||||
'c0-4.1-2.7-6.7-5.9-6.7c-3.2,0-6,2.7-6,6.6v0.1c0,4,2.8,6.6,6,6.6C86.4,29.3,89.1,26.7,89.1,22.7z"/>\n' +
|
||||
'<path class="st0" d="M95.7,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1.1c0.2-1.8,3.1-3.5,5.2-3.5c1.5,0,2.3,1,2.3,2.3\n' +
|
||||
'c0,1.3-0.8,2.1-1.9,2.3c-3.4,0.6-5.7,3.5-5.7,7.6V31c0,1.3-1.1,2.3-2.4,2.3c-1.3,0-2.3-1-2.3-2.3V14.3z"/>\n' +
|
||||
'<path class="st0" d="M109.7,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4V31c0,1.3-1.1,2.3-2.4,2.3c-1.3,0-2.3-1-2.3-2.3V14.3\n' +
|
||||
'z"/>\n' +
|
||||
'<path class="st0" d="M116.9,14.3c0-1.3,1-2.4,2.3-2.4c1.3,0,2.4,1.1,2.4,2.4v1c1.3-1.9,3.2-3.4,6.5-3.4c4.7,0,7.4,3.1,7.4,7.9V31\n' +
|
||||
'c0,1.3-1,2.3-2.3,2.3c-1.3,0-2.4-1-2.4-2.3v-9.7c0-3.2-1.6-5-4.4-5c-2.7,0-4.7,1.9-4.7,5.1V31c0,1.3-1.1,2.3-2.4,2.3\n' +
|
||||
'c-1.3,0-2.3-1-2.3-2.3V14.3z"/>\n' +
|
||||
'<path class="st0" d="M156.2,11.9c-1.3,0-2.4,1.1-2.4,2.4v1.4c-1.5-2.2-3.7-3.9-7-3.9c-4.9,0-9.6,3.8-9.6,10.7v0.1\n' +
|
||||
'c0,6.8,4.7,10.7,9.6,10.7c3.4,0,5.6-1.7,7-3.6c-0.2,3.7-2.5,5.7-6.5,5.7c-2.4,0-4.5-0.6-6.3-1.6c-0.2-0.1-0.5-0.2-0.9-0.2\n' +
|
||||
'c-1.1,0-2,0.9-2,2c0,0.9,0.5,1.6,1.3,1.9c2.5,1.2,5.1,1.8,8,1.8c3.7,0,6.6-0.9,8.5-2.8c1.7-1.7,2.7-4.3,2.7-7.8V14.3\n' +
|
||||
'C158.5,13,157.5,11.9,156.2,11.9z M147.9,29.2c-3.2,0-5.9-2.5-5.9-6.6v-0.1c0-4,2.7-6.6,5.9-6.6c3.2,0,6,2.7,6,6.6v0.1\n' +
|
||||
'C153.9,26.6,151.1,29.2,147.9,29.2z"/>\n' +
|
||||
'<path class="st0" d="M114.5,6.3c0,1.3-1.1,2.4-2.4,2.4c-1.3,0-2.4-1.1-2.4-2.4c0-1.3,1.1-2.4,2.4-2.4\n' +
|
||||
'C113.4,3.9,114.5,4.9,114.5,6.3z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'<g class="st1">\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M200.1,21.1H198V19h2.1V21.1z M200.1,32.9H198V22.6h2.1V32.9z"/>\n' +
|
||||
'</g>\n' +
|
||||
'<g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M212.5,22.6l-3,8.9c-0.5,1.5-1.4,1.6-2.2,1.6c-1.1,0-1.8-0.5-2.2-1.6l-2.5-7.4h-1v-1.5h2.6l2.6,8.3\n' +
|
||||
'c0.1,0.4,0.2,0.6,0.5,0.6c0.3,0,0.4-0.2,0.5-0.6l2.6-8.3H212.5z"/>\n' +
|
||||
'<path class="st2" d="M217.8,22.6c2.8,0,4.7,1.8,4.7,4.5v1.6c0,2.6-1.9,4.5-4.7,4.5c-2.8,0-4.7-1.8-4.7-4.5v-1.6\n' +
|
||||
'C213,24.4,215,22.6,217.8,22.6 M217.8,31.4c1.7,0,2.7-1.3,2.7-2.8v-1.6c0-1.5-1-2.8-2.7-2.8c-1.8,0-2.7,1.3-2.7,2.8v1.6\n' +
|
||||
'C215.1,30.2,216,31.4,217.8,31.4"/>\n' +
|
||||
'<path class="st2" d="M239.6,22.9c-1.1-0.3-2.7-0.5-4-0.5c-2.8,0-4.6,1.8-4.6,4.6v1.1c0,2.9,1.7,4.7,4.6,4.7c0.1,0,0.6,0,0.8,0\n' +
|
||||
'v-1.7c-0.1,0-0.7,0-0.8,0c-1.5,0-2.6-1.2-2.6-2.9v-1.1c0-1.8,1-2.9,2.6-2.9c0.7,0,1.7,0.1,2.1,0.1l0.1,0l0,8.6h2.1v-9.6\n' +
|
||||
'C240,23.1,240,23,239.6,22.9"/>\n' +
|
||||
'<rect x="242.1" y="19" class="st2" width="2.1" height="13.9"/>\n' +
|
||||
'<path class="st2" d="M190.5,19h-3.8v13.9h2.2V20.9h1.3c0.3,0,0.5,0,0.8,0c1.9,0,2.9,0.8,2.9,2.3c0,0.1,0,0.1,0,0.2\n' +
|
||||
'c0,1.4-0.8,2.3-2.9,2.3c-0.2,0-0.4,0-0.6,0c0,0.5,0,1.5,0,1.9c0.2,0,0.4,0,0.6,0c3,0,5.2-1.2,5.2-4.2c0-0.1,0-0.1,0-0.2\n' +
|
||||
'C196.2,20.2,193.9,19,190.5,19"/>\n' +
|
||||
'<path class="st2" d="M226.3,20.4v2.2h3.5v1.7h-3.5v6c0,0.9,0.6,1,1.5,1h2v1.7H227c-2,0-2.9-0.8-2.9-2.6v-9.6L226.3,20.4z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'<g>\n' +
|
||||
'<path class="st2" d="M167.7,32.9v-10h1.1v3.8c0.6-0.8,1.5-1.3,2.4-1.3c1.9,0,3.2,1.5,3.2,3.8c0,2.4-1.3,3.8-3.2,3.8\n' +
|
||||
'c-1,0-1.9-0.5-2.4-1.3v1.1H167.7z M171,32.1c1.5,0,2.3-1.2,2.3-2.8c0-1.6-0.9-2.8-2.3-2.8c-0.9,0-1.8,0.5-2.2,1.2v3.3\n' +
|
||||
'C169.2,31.6,170.1,32.1,171,32.1z"/>\n' +
|
||||
'<path class="st2" d="M175.9,34.7c0.2,0.1,0.4,0.1,0.6,0.1c0.5,0,0.8-0.2,1.1-0.8l0.5-1.1l-3-7.3h1.2l2.4,5.9l2.4-5.9h1.2\n' +
|
||||
'l-3.6,8.7c-0.4,1-1.2,1.5-2.1,1.5c-0.2,0-0.6,0-0.8-0.1L175.9,34.7z"/>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</g>\n' +
|
||||
'</svg>\n' +
|
||||
'\n' +
|
||||
'</h1>\n' +
|
||||
'</div>';
|
||||
|
||||
var header = document.createElement("div");
|
||||
header.innerHTML = headerHtml;
|
||||
document.body.insertBefore(header, document.body.firstChild);
|
||||
@@ -0,0 +1 @@
|
||||
.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B}
|
||||