Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f1c039665 | ||
|
|
8015f19f5e | ||
|
|
25055b05c9 | ||
|
|
08d11b7ba0 | ||
|
|
f1ea897e3d | ||
|
|
4cb2ff3ca4 | ||
|
|
1b4d58711e | ||
|
|
f9dbd1a0ce | ||
|
|
6649205bb7 | ||
|
|
220304faad | ||
|
|
bd81ee5a49 | ||
|
|
37d1f68766 | ||
|
|
d2fe7d0e74 | ||
|
|
380dae16d2 | ||
|
|
6aa71d45f9 | ||
|
|
635a6d4dd6 | ||
|
|
a69d53c17f | ||
|
|
0afc216d21 | ||
|
|
801a0057fd | ||
|
|
ec6fd8a902 | ||
|
|
0320e60cf0 | ||
|
|
90d0c1d778 | ||
|
|
058ae80419 | ||
|
|
89fb210f18 | ||
|
|
cf84ac7ec9 | ||
|
|
ae05044c46 | ||
|
|
7d1b01daf6 | ||
|
|
d7d36846a1 | ||
|
|
d48aa09b9c | ||
|
|
02a6dbc08a | ||
|
|
e4a023fa64 | ||
|
|
1e10dfe1a3 | ||
|
|
e8837c83e9 | ||
|
|
b4b9ea8112 | ||
|
|
c571f7479c | ||
|
|
63d7580a69 | ||
|
|
c466aa5dd3 | ||
|
|
acb59258c3 | ||
|
|
e5022757a9 | ||
|
|
ddad8010eb | ||
|
|
fc3e2e1c64 | ||
|
|
eb169f8186 | ||
|
|
5fd7c9ddcf | ||
|
|
8898ceb4a7 | ||
|
|
c4e9a93d02 | ||
|
|
d8ab39eba7 | ||
|
|
6a5f101656 | ||
|
|
88d34035a6 | ||
|
|
81ef425b1b | ||
|
|
280f311677 | ||
|
|
8da5068cac | ||
|
|
9276e1ddc6 | ||
|
|
fab1f7b38e | ||
|
|
a09146a2ed | ||
|
|
0dfc97289f | ||
|
|
13c7ee54a8 | ||
|
|
7c927c7f38 | ||
|
|
c98a7be0e2 | ||
|
|
8f9c69ea02 | ||
|
|
df3f9a386e |
20
.github/actions/algolia-config.json
vendored
20
.github/actions/algolia-config.json
vendored
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"index_name": "session-docs",
|
||||
"start_urls": [
|
||||
"https://docs.spring.io/spring-session/reference/"
|
||||
],
|
||||
"selectors": {
|
||||
"lvl0": {
|
||||
"selector": "//nav[@class='crumbs']//li[@class='crumb'][last()-1]",
|
||||
"type": "xpath",
|
||||
"global": true,
|
||||
"default_value": "Home"
|
||||
},
|
||||
"lvl1": ".doc h1",
|
||||
"lvl2": ".doc h2",
|
||||
"lvl3": ".doc h3",
|
||||
"lvl4": ".doc h4",
|
||||
"text": ".doc p, .doc td.content, .doc th.tableblock"
|
||||
}
|
||||
}
|
||||
|
||||
20
.github/actions/algolia-deploy.sh
vendored
20
.github/actions/algolia-deploy.sh
vendored
@@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
HOST="$1"
|
||||
HOST_PATH="$2"
|
||||
SSH_PRIVATE_KEY="$3"
|
||||
SSH_KNOWN_HOST="$4"
|
||||
|
||||
|
||||
if [ "$#" -ne 4 ]; then
|
||||
echo -e "not enough arguments USAGE:\n\n$0 \$HOST \$HOST_PATH \$SSH_PRIVATE_KEY \$SSH_KNOWN_HOSTS \n\n" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use a non-default path to avoid overriding when testing locally
|
||||
SSH_PRIVATE_KEY_PATH=~/.ssh/github-actions-docs
|
||||
install -m 600 -D /dev/null "$SSH_PRIVATE_KEY_PATH"
|
||||
echo "$SSH_PRIVATE_KEY" > "$SSH_PRIVATE_KEY_PATH"
|
||||
echo "$SSH_KNOWN_HOST" > ~/.ssh/known_hosts
|
||||
rsync --delete -avze "ssh -i $SSH_PRIVATE_KEY_PATH" spring-session-docs/build/site/ "$HOST:$HOST_PATH"
|
||||
rm -f "$SSH_PRIVATE_KEY_PATH"
|
||||
21
.github/actions/algolia-docsearch-scraper.sh
vendored
21
.github/actions/algolia-docsearch-scraper.sh
vendored
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
###
|
||||
# Docs
|
||||
# config.json https://docsearch.algolia.com/docs/config-file
|
||||
# Run the crawler https://docsearch.algolia.com/docs/run-your-own/#run-the-crawl-from-the-docker-image
|
||||
|
||||
### USAGE
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo -e "not enough arguments USAGE:\n\n$0 \$ALGOLIA_APPLICATION_ID \$ALGOLIA_API_KEY \$CONFIG_FILE\n\n" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script Parameters
|
||||
APPLICATION_ID=$1
|
||||
API_KEY=$2
|
||||
CONFIG_FILE=$3
|
||||
|
||||
#### Script
|
||||
script_dir=$(dirname $0)
|
||||
docker run -e "APPLICATION_ID=$APPLICATION_ID" -e "API_KEY=$API_KEY" -e "CONFIG=$(cat $CONFIG_FILE | jq -r tostring)" algolia/docsearch-scraper
|
||||
5
.github/actions/dispatch.sh
vendored
5
.github/actions/dispatch.sh
vendored
@@ -1,5 +0,0 @@
|
||||
REPOSITORY_REF="$1"
|
||||
TOKEN="$2"
|
||||
|
||||
curl -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${TOKEN}" --request POST --data '{"event_type": "request-build-reference"}' https://api.github.com/repos/${REPOSITORY_REF}/dispatches
|
||||
echo "Requested Build for $REPOSITORY_REF"
|
||||
16
.github/workflows/algolia-index.yml
vendored
16
.github/workflows/algolia-index.yml
vendored
@@ -1,16 +0,0 @@
|
||||
name: Update Algolia Index
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
jobs:
|
||||
update:
|
||||
name: Update Algolia Index
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v2
|
||||
- name: Update Index
|
||||
run: ${GITHUB_WORKSPACE}/.github/actions/algolia-docsearch-scraper.sh "${{ secrets.ALGOLIA_APPLICATION_ID }}" "${{ secrets.ALGOLIA_WRITE_API_KEY }}" "${GITHUB_WORKSPACE}/.github/actions/algolia-config.json"
|
||||
36
.github/workflows/antora-generate.yml
vendored
36
.github/workflows/antora-generate.yml
vendored
@@ -1,36 +0,0 @@
|
||||
name: Generate Antora Files and Request Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
|
||||
env:
|
||||
GH_ACTIONS_REPO_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
- name: Generate antora.yml
|
||||
run: ./gradlew :spring-session-docs:generateAntora
|
||||
- name: Extract Branch Name
|
||||
id: extract_branch_name
|
||||
run: echo "##[set-output name=generated_branch_name;]$(echo ${GITHUB_REPOSITORY}/${GITHUB_REF##*/})"
|
||||
- name: Push generated antora files to the spring-generated-docs
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.4
|
||||
with:
|
||||
branch: ${{ steps.extract_branch_name.outputs.generated_branch_name }} # The branch the action should deploy to.
|
||||
folder: "spring-session-docs/build/generateAntora" # The folder the action should deploy.
|
||||
repository-name: "spring-io/spring-generated-docs"
|
||||
token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
- name: Dispatch Build Request
|
||||
run: ${GITHUB_WORKSPACE}/.github/actions/dispatch.sh 'spring-projects/spring-session' "$GH_ACTIONS_REPO_TOKEN"
|
||||
30
.github/workflows/deploy-docs.yml
vendored
Normal file
30
.github/workflows/deploy-docs.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Deploy Docs
|
||||
on:
|
||||
push:
|
||||
branches-ignore: [ gh-pages ]
|
||||
tags: '**'
|
||||
repository_dispatch:
|
||||
types: request-build-reference # legacy
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: read-all
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'spring-projects'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: docs-build
|
||||
fetch-depth: 1
|
||||
- name: Dispatch (partial build)
|
||||
if: github.ref_type == 'branch'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }}
|
||||
- name: Dispatch (full build)
|
||||
if: github.ref_type == 'tag'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD)
|
||||
33
.github/workflows/deploy-reference.yml
vendored
33
.github/workflows/deploy-reference.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Build & Deploy Reference
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: request-build-reference
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: deploy
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew :spring-session-docs:antora --stacktrace
|
||||
- name: Cleanup Gradle Cache
|
||||
# Remove some files from the Gradle cache, so they aren't cached by GitHub Actions.
|
||||
# Restoring these files from a GitHub Actions cache might cause problems for future builds.
|
||||
run: |
|
||||
rm -f ~/.gradle/caches/modules-2/modules-2.lock
|
||||
rm -f ~/.gradle/caches/modules-2/gc.properties
|
||||
- name: Deploy
|
||||
run: ${GITHUB_WORKSPACE}/.github/actions/algolia-deploy.sh "${{ secrets.DOCS_USERNAME }}@${{ secrets.DOCS_HOST }}" "/opt/www/domains/spring.io/docs/htdocs/spring-session/reference/" "${{ secrets.DOCS_SSH_KEY }}" "${{ secrets.DOCS_SSH_HOST_KEY }}"
|
||||
20
.github/workflows/rebuild-search-index.yml
vendored
Normal file
20
.github/workflows/rebuild-search-index.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Rebuild Search Index
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch:
|
||||
permissions: read-all
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository_owner == 'spring-projects'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: docs-build
|
||||
fetch-depth: 1
|
||||
- name: Dispatch
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}
|
||||
run: gh workflow run rebuild-search-index.yml -r $(git rev-parse --abbrev-ref HEAD)
|
||||
@@ -25,6 +25,13 @@ If you are reporting a bug, please help to speed up problem diagnosis by providi
|
||||
information as possible. Ideally, that would include a small sample project that
|
||||
reproduces the problem.
|
||||
|
||||
== Create your branch from the oldest maintenance branch
|
||||
|
||||
Create your topic branch to be submitted as a pull request from the oldest impacted and supported maintenance branch.
|
||||
You can find the supported versions by looking at the https://github.com/spring-projects/spring-session/milestones[milestones page].
|
||||
Switch to a branch named `<major>.<minor>.x` from the smallest milestone in the format of `<major>.<minor>.<patch>(-<prerelease>)`.
|
||||
The spring team will ensure the code gets merged forward into additional branches.
|
||||
|
||||
|
||||
== Sign the Contributor License Agreement
|
||||
If you have not previously done so, please fill out and
|
||||
|
||||
@@ -26,6 +26,10 @@ sourceSets {
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
checkAntoraVersion {
|
||||
id = "org.springframework.antora.check-version"
|
||||
implementationClass = "org.springframework.gradle.antora.AntoraVersionPlugin"
|
||||
}
|
||||
managementConfiguration {
|
||||
id = "io.spring.convention.management-configuration"
|
||||
implementationClass = "io.spring.gradle.convention.ManagementConfigurationPlugin"
|
||||
@@ -54,6 +58,7 @@ configurations {
|
||||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.8.8'
|
||||
implementation 'net.sourceforge.saxon:saxon:9.1.0.8'
|
||||
implementation 'org.yaml:snakeyaml:1.30'
|
||||
implementation localGroovy()
|
||||
|
||||
implementation 'io.github.gradle-nexus:publish-plugin:1.1.0'
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.springframework.gradle.antora;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin;
|
||||
|
||||
public class AntoraVersionPlugin implements Plugin<Project> {
|
||||
public static final String ANTORA_CHECK_VERSION_TASK_NAME = "antoraCheckVersion";
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
TaskProvider<CheckAntoraVersionTask> antoraCheckVersion = project.getTasks().register(ANTORA_CHECK_VERSION_TASK_NAME, CheckAntoraVersionTask.class, new Action<CheckAntoraVersionTask>() {
|
||||
@Override
|
||||
public void execute(CheckAntoraVersionTask antoraCheckVersion) {
|
||||
antoraCheckVersion.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP);
|
||||
antoraCheckVersion.setDescription("Checks the antora.yml version properties match the Gradle version");
|
||||
antoraCheckVersion.getAntoraVersion().convention(project.provider(() -> getDefaultAntoraVersion(project)));
|
||||
antoraCheckVersion.getAntoraPrerelease().convention(project.provider(() -> getDefaultAntoraPrerelease(project)));
|
||||
antoraCheckVersion.getAntoraDisplayVersion().convention(project.provider(() -> getDefaultAntoraDisplayVersion(project)));
|
||||
antoraCheckVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
|
||||
}
|
||||
});
|
||||
project.getPlugins().withType(LifecycleBasePlugin.class, new Action<LifecycleBasePlugin>() {
|
||||
@Override
|
||||
public void execute(LifecycleBasePlugin lifecycleBasePlugin) {
|
||||
project.getTasks().named(LifecycleBasePlugin.CHECK_TASK_NAME).configure(new Action<Task>() {
|
||||
@Override
|
||||
public void execute(Task check) {
|
||||
check.dependsOn(antoraCheckVersion);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
project.getTasks().register("antoraUpdateVersion", UpdateAntoraVersionTask.class, new Action<UpdateAntoraVersionTask>() {
|
||||
@Override
|
||||
public void execute(UpdateAntoraVersionTask antoraUpdateVersion) {
|
||||
antoraUpdateVersion.setGroup("Release");
|
||||
antoraUpdateVersion.setDescription("Updates the antora.yml version properties to match the Gradle version");
|
||||
antoraUpdateVersion.getAntoraYmlFile().fileProvider(project.provider(() -> project.file("antora.yml")));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String getDefaultAntoraVersion(Project project) {
|
||||
String projectVersion = getProjectVersion(project);
|
||||
return AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
|
||||
}
|
||||
|
||||
private static String getDefaultAntoraPrerelease(Project project) {
|
||||
String projectVersion = getProjectVersion(project);
|
||||
return AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
|
||||
}
|
||||
|
||||
private static String getDefaultAntoraDisplayVersion(Project project) {
|
||||
String projectVersion = getProjectVersion(project);
|
||||
return AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
|
||||
}
|
||||
|
||||
private static String getProjectVersion(Project project) {
|
||||
Object projectVersion = project.getVersion();
|
||||
if (projectVersion == null) {
|
||||
throw new GradleException("Please define antoraVersion and antoraPrerelease on " + ANTORA_CHECK_VERSION_TASK_NAME + " or provide a Project version so they can be defaulted");
|
||||
}
|
||||
return String.valueOf(projectVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.gradle.antora;
|
||||
|
||||
public class AntoraVersionUtils {
|
||||
|
||||
public static String getDefaultAntoraVersion(String projectVersion) {
|
||||
int preReleaseIndex = getSnapshotIndex(projectVersion);
|
||||
return isSnapshot(projectVersion) ? projectVersion.substring(0, preReleaseIndex) : projectVersion;
|
||||
}
|
||||
|
||||
public static String getDefaultAntoraPrerelease(String projectVersion) {
|
||||
if (isSnapshot(projectVersion)) {
|
||||
int preReleaseIndex = getSnapshotIndex(projectVersion);
|
||||
return projectVersion.substring(preReleaseIndex);
|
||||
}
|
||||
if (isPreRelease(projectVersion)) {
|
||||
return Boolean.TRUE.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDefaultAntoraDisplayVersion(String projectVersion) {
|
||||
if (!isSnapshot(projectVersion) && isPreRelease(projectVersion)) {
|
||||
return getDefaultAntoraVersion(projectVersion);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isSnapshot(String projectVersion) {
|
||||
return getSnapshotIndex(projectVersion) >= 0;
|
||||
}
|
||||
|
||||
private static int getSnapshotIndex(String projectVersion) {
|
||||
return projectVersion.lastIndexOf("-SNAPSHOT");
|
||||
}
|
||||
|
||||
private static boolean isPreRelease(String projectVersion) {
|
||||
return projectVersion.lastIndexOf("-") >= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.springframework.gradle.antora;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
public abstract class CheckAntoraVersionTask extends DefaultTask {
|
||||
|
||||
@TaskAction
|
||||
public void check() throws FileNotFoundException {
|
||||
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
|
||||
String expectedAntoraVersion = getAntoraVersion().get();
|
||||
String expectedAntoraPrerelease = getAntoraPrerelease().getOrElse(null);
|
||||
String expectedAntoraDisplayVersion = getAntoraDisplayVersion().getOrElse(null);
|
||||
|
||||
Representer representer = new Representer();
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
|
||||
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
|
||||
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
|
||||
|
||||
String actualAntoraPrerelease = antoraYml.getPrerelease();
|
||||
boolean preReleaseMatches = antoraYml.getPrerelease() == null && expectedAntoraPrerelease == null ||
|
||||
(actualAntoraPrerelease != null && actualAntoraPrerelease.equals(expectedAntoraPrerelease));
|
||||
String actualAntoraDisplayVersion = antoraYml.getDisplay_version();
|
||||
boolean displayVersionMatches = antoraYml.getDisplay_version() == null && expectedAntoraDisplayVersion == null ||
|
||||
(actualAntoraDisplayVersion != null && actualAntoraDisplayVersion.equals(expectedAntoraDisplayVersion));
|
||||
String actualAntoraVersion = antoraYml.getVersion();
|
||||
if (!preReleaseMatches ||
|
||||
!displayVersionMatches ||
|
||||
!expectedAntoraVersion.equals(actualAntoraVersion)) {
|
||||
throw new GradleException("The Gradle version of '" + getProject().getVersion() + "' should have version: '"
|
||||
+ expectedAntoraVersion + "' prerelease: '" + expectedAntoraPrerelease + "' display_version: '"
|
||||
+ expectedAntoraDisplayVersion + "' defined in " + antoraYmlFile + " but got version: '"
|
||||
+ actualAntoraVersion + "' prerelease: '" + actualAntoraPrerelease + "' display_version: '" + actualAntoraDisplayVersion + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getAntoraYmlFile();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getAntoraVersion();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getAntoraPrerelease();
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
public abstract Property<String> getAntoraDisplayVersion();
|
||||
|
||||
public static class AntoraYml {
|
||||
private String version;
|
||||
|
||||
private String prerelease;
|
||||
|
||||
private String display_version;
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getPrerelease() {
|
||||
return prerelease;
|
||||
}
|
||||
|
||||
public void setPrerelease(String prerelease) {
|
||||
this.prerelease = prerelease;
|
||||
}
|
||||
|
||||
public String getDisplay_version() {
|
||||
return display_version;
|
||||
}
|
||||
|
||||
public void setDisplay_version(String display_version) {
|
||||
this.display_version = display_version;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2019-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.gradle.antora;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.yaml.snakeyaml.nodes.NodeTuple;
|
||||
import org.yaml.snakeyaml.nodes.Tag;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
public abstract class UpdateAntoraVersionTask extends DefaultTask {
|
||||
|
||||
@TaskAction
|
||||
public void update() throws IOException {
|
||||
String projectVersion = getProject().getVersion().toString();
|
||||
File antoraYmlFile = getAntoraYmlFile().getAsFile().get();
|
||||
String updatedAntoraVersion = AntoraVersionUtils.getDefaultAntoraVersion(projectVersion);
|
||||
String updatedAntoraPrerelease = AntoraVersionUtils.getDefaultAntoraPrerelease(projectVersion);
|
||||
String updatedAntoraDisplayVersion = AntoraVersionUtils.getDefaultAntoraDisplayVersion(projectVersion);
|
||||
|
||||
Representer representer = new Representer();
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
|
||||
Yaml yaml = new Yaml(new Constructor(AntoraYml.class), representer);
|
||||
AntoraYml antoraYml = yaml.load(new FileInputStream(antoraYmlFile));
|
||||
|
||||
System.out.println("Updating the version parameters in " + antoraYmlFile.getName() + " to version: "
|
||||
+ updatedAntoraVersion + ", prerelease: " + updatedAntoraPrerelease + ", display_version: "
|
||||
+ updatedAntoraDisplayVersion);
|
||||
antoraYml.setVersion(updatedAntoraVersion);
|
||||
antoraYml.setPrerelease(updatedAntoraPrerelease);
|
||||
antoraYml.setDisplay_version(updatedAntoraDisplayVersion);
|
||||
|
||||
FileWriter outputWriter = new FileWriter(antoraYmlFile);
|
||||
getYaml().dump(antoraYml, outputWriter);
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getAntoraYmlFile();
|
||||
|
||||
public static class AntoraYml {
|
||||
|
||||
private String name;
|
||||
|
||||
private String version;
|
||||
|
||||
private String prerelease;
|
||||
|
||||
private String display_version;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getPrerelease() {
|
||||
return prerelease;
|
||||
}
|
||||
|
||||
public void setPrerelease(String prerelease) {
|
||||
this.prerelease = prerelease;
|
||||
}
|
||||
|
||||
public String getDisplay_version() {
|
||||
return display_version;
|
||||
}
|
||||
|
||||
public void setDisplay_version(String display_version) {
|
||||
this.display_version = display_version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Yaml getYaml() {
|
||||
Representer representer = new Representer() {
|
||||
@Override
|
||||
protected NodeTuple representJavaBeanProperty(Object javaBean,
|
||||
org.yaml.snakeyaml.introspector.Property property, Object propertyValue, Tag customTag) {
|
||||
// Don't write out null values
|
||||
if (propertyValue == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
|
||||
}
|
||||
}
|
||||
};
|
||||
representer.addClassTag(AntoraYml.class, Tag.MAP);
|
||||
DumperOptions ymlOptions = new DumperOptions();
|
||||
ymlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
ymlOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
|
||||
return new Yaml(representer, ymlOptions);
|
||||
}
|
||||
|
||||
}
|
||||
135
git/hooks/forward-merge
Executable file
135
git/hooks/forward-merge
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/ruby
|
||||
require 'json'
|
||||
require 'net/http'
|
||||
require 'yaml'
|
||||
require 'logger'
|
||||
|
||||
$log = Logger.new(STDOUT)
|
||||
$log.level = Logger::WARN
|
||||
|
||||
class ForwardMerge
|
||||
attr_reader :issue, :milestone, :message, :line
|
||||
def initialize(issue, milestone, message, line)
|
||||
@issue = issue
|
||||
@milestone = milestone
|
||||
@message = message
|
||||
@line = line
|
||||
end
|
||||
end
|
||||
|
||||
def find_forward_merges(message_file)
|
||||
$log.debug "Searching for forward merge"
|
||||
rev=`git rev-parse -q --verify MERGE_HEAD`.strip
|
||||
$log.debug "Found #{rev} from git rev-parse"
|
||||
return nil unless rev
|
||||
message = File.read(message_file)
|
||||
forward_merges = []
|
||||
message.each_line do |line|
|
||||
$log.debug "Checking #{line} for message"
|
||||
match = /^(?:Fixes|Closes) gh-(\d+) in (\d\.\d\.[\dx](?:[\.\-](?:M|RC)\d)?)$/.match(line)
|
||||
if match then
|
||||
issue = match[1]
|
||||
milestone = match[2]
|
||||
$log.debug "Matched reference to issue #{issue} in milestone #{milestone}"
|
||||
forward_merges << ForwardMerge.new(issue, milestone, message, line)
|
||||
end
|
||||
end
|
||||
$log.debug "No match in merge message" unless forward_merges
|
||||
return forward_merges
|
||||
end
|
||||
|
||||
def get_issue(username, password, repository, number)
|
||||
$log.debug "Getting issue #{number} from GitHub repository #{repository}"
|
||||
uri = URI("https://api.github.com/repos/#{repository}/issues/#{number}")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.use_ssl=true
|
||||
request = Net::HTTP::Get.new(uri.path)
|
||||
request.basic_auth(username, password)
|
||||
response = http.request(request)
|
||||
$log.debug "Get HTTP response #{response.code}"
|
||||
return JSON.parse(response.body) unless response.code != '200'
|
||||
puts "Failed to retrieve issue #{number}: #{response.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
def find_milestone(username, password, repository, title)
|
||||
$log.debug "Finding milestone #{title} from GitHub repository #{repository}"
|
||||
uri = URI("https://api.github.com/repos/#{repository}/milestones")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.use_ssl=true
|
||||
request = Net::HTTP::Get.new(uri.path)
|
||||
request.basic_auth(username, password)
|
||||
response = http.request(request)
|
||||
milestones = JSON.parse(response.body)
|
||||
if title.end_with?(".x")
|
||||
prefix = title.delete_suffix('.x')
|
||||
$log.debug "Finding nearest milestone from candidates starting with #{prefix}"
|
||||
titles = milestones.map { |milestone| milestone['title'] }
|
||||
titles = titles.select{ |title| title.start_with?(prefix) unless title.end_with?('.x')}
|
||||
titles = titles.sort_by { |v| Gem::Version.new(v) }
|
||||
$log.debug "Considering candidates #{titles}"
|
||||
if(titles.empty?)
|
||||
puts "Cannot find nearest milestone for prefix #{title}"
|
||||
exit 1
|
||||
end
|
||||
title = titles.first
|
||||
$log.debug "Found nearest milestone #{title}"
|
||||
end
|
||||
milestones.each do |milestone|
|
||||
$log.debug "Considering #{milestone['title']}"
|
||||
return milestone['number'] if milestone['title'] == title
|
||||
end
|
||||
puts "Milestone #{title} not found in #{repository}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
def create_issue(username, password, repository, original, title, labels, milestone, milestone_name, dry_run)
|
||||
$log.debug "Finding forward-merge issue in GitHub repository #{repository} for '#{title}'"
|
||||
uri = URI("https://api.github.com/repos/#{repository}/issues")
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.use_ssl=true
|
||||
request = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
|
||||
request.basic_auth(username, password)
|
||||
request.body = {
|
||||
title: title,
|
||||
labels: labels,
|
||||
milestone: milestone.to_i,
|
||||
body: "Forward port of issue ##{original} to #{milestone_name}."
|
||||
}.to_json
|
||||
if dry_run then
|
||||
puts "Dry run"
|
||||
puts "POSTing to #{uri} with body #{request.body}"
|
||||
return "dry-run"
|
||||
end
|
||||
response = JSON.parse(http.request(request).body)
|
||||
$log.debug "Created new issue #{response['number']}"
|
||||
return response['number']
|
||||
end
|
||||
|
||||
$log.debug "Running forward-merge hook script"
|
||||
message_file=ARGV[0]
|
||||
|
||||
forward_merges = find_forward_merges(message_file)
|
||||
exit 0 unless forward_merges
|
||||
|
||||
$log.debug "Loading config from ~/.spring-boot/forward_merge.yml"
|
||||
config = YAML.load_file(File.join(Dir.home, '.spring-boot', 'forward-merge.yml'))
|
||||
username = config['github']['credentials']['username']
|
||||
password = config['github']['credentials']['password']
|
||||
dry_run = config['dry_run']
|
||||
repository = 'spring-projects/spring-session'
|
||||
|
||||
forward_merges.each do |forward_merge|
|
||||
existing_issue = get_issue(username, password, repository, forward_merge.issue)
|
||||
title = existing_issue['title']
|
||||
labels = existing_issue['labels'].map { |label| label['name'] }
|
||||
labels << "status: forward-port"
|
||||
$log.debug "Processing issue '#{title}'"
|
||||
|
||||
milestone = find_milestone(username, password, repository, forward_merge.milestone)
|
||||
new_issue_number = create_issue(username, password, repository, forward_merge.issue, title, labels, milestone, forward_merge.milestone, dry_run)
|
||||
|
||||
puts "Created gh-#{new_issue_number} for forward port of gh-#{forward_merge.issue} into #{forward_merge.milestone}"
|
||||
rewritten_message = forward_merge.message.sub(forward_merge.line, "Closes gh-#{new_issue_number}\n")
|
||||
File.write(message_file, rewritten_message)
|
||||
end
|
||||
71
git/hooks/prepare-forward-merge
Executable file
71
git/hooks/prepare-forward-merge
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/ruby
|
||||
require 'json'
|
||||
require 'net/http'
|
||||
require 'yaml'
|
||||
require 'logger'
|
||||
|
||||
$main_branch = "3.0.x"
|
||||
|
||||
$log = Logger.new(STDOUT)
|
||||
$log.level = Logger::WARN
|
||||
|
||||
def get_fixed_issues()
|
||||
$log.debug "Searching for for forward merge"
|
||||
rev=`git rev-parse -q --verify MERGE_HEAD`.strip
|
||||
$log.debug "Found #{rev} from git rev-parse"
|
||||
return nil unless rev
|
||||
fixed = []
|
||||
message = `git log -1 --pretty=%B #{rev}`
|
||||
message.each_line do |line|
|
||||
$log.debug "Checking #{line} for message"
|
||||
fixed << line.strip if /^(?:Fixes|Closes) gh-(\d+)/.match(line)
|
||||
end
|
||||
$log.debug "Found fixed issues #{fixed}"
|
||||
return fixed;
|
||||
end
|
||||
|
||||
def rewrite_message(message_file, fixed)
|
||||
current_branch = `git rev-parse --abbrev-ref HEAD`.strip
|
||||
if current_branch == "main"
|
||||
current_branch = $main_branch
|
||||
end
|
||||
rewritten_message = ""
|
||||
message = File.read(message_file)
|
||||
message.each_line do |line|
|
||||
match = /^Merge.*branch\ '(.*)'(?:\ into\ (.*))?$/.match(line)
|
||||
if match
|
||||
from_branch = match[1]
|
||||
if from_branch.include? "/"
|
||||
from_branch = from_branch.partition("/").last
|
||||
end
|
||||
to_brach = match[2]
|
||||
$log.debug "Rewriting merge message"
|
||||
line = "Merge branch '#{from_branch}'" + (to_brach ? " into #{to_brach}\n" : "\n")
|
||||
end
|
||||
if fixed and line.start_with?("#")
|
||||
$log.debug "Adding fixed"
|
||||
rewritten_message << "\n"
|
||||
fixed.each do |fixes|
|
||||
rewritten_message << "#{fixes} in #{current_branch}\n"
|
||||
end
|
||||
fixed = nil
|
||||
end
|
||||
rewritten_message << line
|
||||
end
|
||||
return rewritten_message
|
||||
end
|
||||
|
||||
$log.debug "Running prepare-forward-merge hook script"
|
||||
|
||||
message_file=ARGV[0]
|
||||
message_type=ARGV[1]
|
||||
|
||||
if message_type != "merge"
|
||||
$log.debug "Not a merge commit"
|
||||
exit 0;
|
||||
end
|
||||
|
||||
$log.debug "Searching for for forward merge"
|
||||
fixed = get_fixed_issues()
|
||||
rewritten_message = rewrite_message(message_file, fixed)
|
||||
File.write(message_file, rewritten_message)
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
version=3.0.0
|
||||
version=3.1.0-M1
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'io.projectreactor:reactor-bom:2022.0.0'
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.13.4.20221013'
|
||||
mavenBom 'io.projectreactor:reactor-bom:2022.0.5'
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.14.2'
|
||||
mavenBom 'org.junit:junit-bom:5.9.1'
|
||||
mavenBom 'org.mockito:mockito-bom:4.8.1'
|
||||
mavenBom 'org.springframework:spring-framework-bom:6.0.0'
|
||||
mavenBom 'org.springframework.data:spring-data-bom:2022.0.0'
|
||||
mavenBom 'org.springframework.security:spring-security-bom:6.0.0'
|
||||
mavenBom 'org.testcontainers:testcontainers-bom:1.17.3'
|
||||
mavenBom 'org.springframework:spring-framework-bom:6.0.7'
|
||||
mavenBom 'org.springframework.data:spring-data-bom:2022.0.4'
|
||||
mavenBom 'org.springframework.security:spring-security-bom:6.0.2'
|
||||
mavenBom 'org.testcontainers:testcontainers-bom:1.17.6'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
* Copyright 2014-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -98,7 +98,6 @@ public class HeaderHttpSessionIdResolver implements HttpSessionIdResolver {
|
||||
@Override
|
||||
public List<String> resolveSessionIds(HttpServletRequest request) {
|
||||
String headerValue = request.getHeader(this.headerName);
|
||||
System.out.println(headerValue);
|
||||
return (headerValue != null) ? Collections.singletonList(headerValue) : Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
site:
|
||||
title: Spring Session
|
||||
url: https://docs.spring.io/spring-session/reference/
|
||||
asciidoc:
|
||||
attributes:
|
||||
page-pagination: true
|
||||
content:
|
||||
sources:
|
||||
- url: https://github.com/spring-io/spring-generated-docs
|
||||
branches: [spring-projects/spring-session/*]
|
||||
- url: https://github.com/spring-projects/spring-session
|
||||
branches: [main,2.7.x,2.6.x]
|
||||
tags: [ '3.0.*', '2.7.*', '2.6.*','!2.6.0-M*','!2.6.0-RC*','!2.7.0-M1','!3.0.0-M1']
|
||||
start_path: spring-session-docs
|
||||
urls:
|
||||
latest_version_segment_strategy: redirect:to
|
||||
latest_version_segment: ''
|
||||
redirect_facility: httpd
|
||||
ui:
|
||||
bundle:
|
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/latest/ui-bundle.zip
|
||||
snapshot: true
|
||||
|
||||
antora:
|
||||
extensions:
|
||||
- require: ./antora/extensions/version-fix.js
|
||||
- require: ./antora/extensions/major-minor-segment.js
|
||||
@@ -1,2 +1,12 @@
|
||||
name: ROOT
|
||||
version: '3.0.0'
|
||||
version: true
|
||||
title: Documentation
|
||||
nav:
|
||||
- modules/ROOT/nav.adoc
|
||||
ext:
|
||||
collector:
|
||||
run:
|
||||
command: gradlew -q -PbuildSrc.skipTests=true "-Dorg.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError" :spring-session-docs:generateAntoraYml
|
||||
local: true
|
||||
scan:
|
||||
dir: ./build/generated-antora-resources
|
||||
|
||||
35
spring-session-docs/cached-antora-playbook.yml
Normal file
35
spring-session-docs/cached-antora-playbook.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
# PACKAGES antora@3.2.0-alpha.2 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springio/antora-extensions@1.0.0 @asciidoctor/tabs@1.0.0-beta.3 @opendevise/antora-release-line-extension@1.0.0
|
||||
#
|
||||
# The purpose of this Antora playbook is to build the docs in the current branch.
|
||||
antora:
|
||||
extensions:
|
||||
- '@antora/collector-extension'
|
||||
- id: '@antora/atlas-extension'
|
||||
require: '@antora/atlas-extension'
|
||||
enabled: false
|
||||
- '@opendevise/antora-release-line-extension'
|
||||
- require: '@springio/antora-extensions/tabs-migration-extension'
|
||||
unwrap_example_block: always
|
||||
site:
|
||||
title: Spring Session Reference
|
||||
content:
|
||||
sources:
|
||||
- url: ./..
|
||||
branches: HEAD
|
||||
start_path: spring-session-docs
|
||||
worktrees: true
|
||||
asciidoc:
|
||||
attributes:
|
||||
hide-uri-scheme: '@'
|
||||
page-pagination: ''
|
||||
primary-site-url: https://docs.spring.io/spring-session/reference
|
||||
tabs-sync-option: '@'
|
||||
extensions:
|
||||
- '@asciidoctor/tabs'
|
||||
sourcemap: true
|
||||
urls:
|
||||
latest_version_segment: ''
|
||||
ui:
|
||||
bundle:
|
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/latest/ui-bundle.zip
|
||||
snapshot: true
|
||||
@@ -1,26 +0,0 @@
|
||||
site:
|
||||
title: Spring
|
||||
url: https://docs.spring.io/spring-session/reference/
|
||||
asciidoc:
|
||||
attributes:
|
||||
page-pagination: true
|
||||
content:
|
||||
sources:
|
||||
- url: ../../spring-io/spring-generated-docs
|
||||
branches: [spring-projects/spring-session/*]
|
||||
- url: ../../spring-projects/spring-session
|
||||
branches: [main]
|
||||
start_path: spring-session-docs
|
||||
urls:
|
||||
latest_version_segment_strategy: redirect:to
|
||||
latest_version_segment: ''
|
||||
redirect_facility: httpd
|
||||
ui:
|
||||
bundle:
|
||||
url: https://github.com/spring-io/antora-ui-spring/releases/download/latest/ui-bundle.zip
|
||||
snapshot: true
|
||||
|
||||
antora:
|
||||
extensions:
|
||||
- require: ./antora/extensions/version-fix.js
|
||||
- require: ./antora/extensions/major-minor-segment.js
|
||||
@@ -75,9 +75,9 @@ For example, you can include the following in your application.properties:
|
||||
====
|
||||
.src/main/resources/application.properties
|
||||
----
|
||||
spring.redis.host=localhost # Redis server host.
|
||||
spring.redis.password= # Login password of the redis server.
|
||||
spring.redis.port=6379 # Redis server port.
|
||||
spring.data.redis.host=localhost # Redis server host.
|
||||
spring.data.redis.password= # Login password of the redis server.
|
||||
spring.data.redis.port=6379 # Redis server port.
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ Spring Session provides `PrincipalNameExtractor` for this purpose.
|
||||
is not set, Hazelcast will serialize sessions using native Java serialization.
|
||||
<4> We create a `HazelcastInstance` that connects Spring Session to Hazelcast.
|
||||
By default, the application starts and connects to an embedded instance of Hazelcast.
|
||||
For more information on configuring Hazelcast, see the https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
|
||||
For more information on configuring Hazelcast, see the https://docs.hazelcast.com/hazelcast/latest/[reference documentation].
|
||||
====
|
||||
|
||||
NOTE: If `HazelcastSessionSerializer` is preferred, it needs to be configured for all Hazelcast cluster members before they start.
|
||||
@@ -161,7 +161,7 @@ $ ./gradlew :spring-session-sample-javaconfig-hazelcast:tomcatRun
|
||||
====
|
||||
|
||||
NOTE: By default, Hazelcast runs in embedded mode with your application.
|
||||
However, if you want to connect to a standalone instance instead, you can configure it by following the instructions in the https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
|
||||
However, if you want to connect to a standalone instance instead, you can configure it by following the instructions in the https://docs.hazelcast.com/hazelcast/latest/getting-started/get-started-cli[reference documentation].
|
||||
|
||||
You should now be able to access the application at http://localhost:8080/
|
||||
|
||||
@@ -188,9 +188,9 @@ You can view the cookies (with https://developers.google.com/web/tools/chrome-de
|
||||
|
||||
=== Interacting with the Data Store
|
||||
|
||||
You can remove the session by using https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-java-client[a Java client],
|
||||
https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#other-client-implementations[one of the other clients], or the
|
||||
https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#management-center[management center].
|
||||
You can remove the session by using https://docs.hazelcast.com/hazelcast/latest/clients/java[a Java client],
|
||||
https://hazelcast.com/clients/[one of the other clients], or the
|
||||
https://docs.hazelcast.com/management-center/latest/getting-started/overview[management center].
|
||||
|
||||
==== Using the Console
|
||||
|
||||
@@ -203,7 +203,7 @@ For example, to remove the session by using the management center console after
|
||||
----
|
||||
====
|
||||
|
||||
TIP: The Hazelcast documentation has instructions for https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#executing-console-commands[the console].
|
||||
TIP: The Hazelcast documentation has instructions for https://docs.hazelcast.com/hazelcast/latest/clients/clc[the console].
|
||||
|
||||
Alternatively, you can also delete the explicit key. Enter the following into the console, being sure to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your `SESSION` cookie:
|
||||
|
||||
@@ -218,7 +218,7 @@ Now visit the application at http://localhost:8080/ and observe that we are no l
|
||||
==== Using the REST API
|
||||
|
||||
As described in the section of the documentation that cover other clients, there is a
|
||||
https://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#rest-client[REST API]
|
||||
https://docs.hazelcast.com/hazelcast/latest/clients/rest[REST API]
|
||||
provided by the Hazelcast node(s).
|
||||
|
||||
For example, you could delete an individual key as follows (being sure to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
id "io.github.rwinch.antora" version "0.0.2"
|
||||
id 'org.antora' version '1.0.0'
|
||||
id 'io.spring.antora.generate-antora-yml' version '0.0.1'
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.docs'
|
||||
@@ -29,16 +30,54 @@ dependencies {
|
||||
}
|
||||
|
||||
antora {
|
||||
antoraVersion = "3.1.0"
|
||||
arguments = ["--fetch"]
|
||||
playbook = 'cached-antora-playbook.yml'
|
||||
playbookProvider {
|
||||
repository = 'spring-projects/spring-session'
|
||||
branch = 'docs-build'
|
||||
path = 'lib/antora/templates/per-branch-antora-playbook.yml'
|
||||
checkLocalBranch = true
|
||||
}
|
||||
options = [clean: true, fetch: !project.gradle.startParameter.offline, stacktrace: true]
|
||||
}
|
||||
|
||||
tasks.antora {
|
||||
environment = [
|
||||
"ALGOLIA_API_KEY" : "82c7ead946afbac3cf98c32446154691",
|
||||
"ALGOLIA_APP_ID" : "244V8V9FGG",
|
||||
"ALGOLIA_INDEX_NAME" : "session-docs"
|
||||
]
|
||||
tasks.named("generateAntoraYml") {
|
||||
asciidocAttributes = project.provider( { generateAttributes() } )
|
||||
}
|
||||
|
||||
def generateAttributes() {
|
||||
def dollar = '$'
|
||||
def ghTag = snapshotBuild ? 'main' : project.version
|
||||
def ghUrl = "https://github.com/spring-projects/spring-session/tree/${ghTag.toString()}"
|
||||
def snapshotBuild = project.version.contains("SNAPSHOT")
|
||||
def milestoneBuild = project.version.contains("-M")
|
||||
def releaseBuild = (!snapshotBuild && !milestoneBuild)
|
||||
def springBootVersion = "2.7.0"
|
||||
def downloadUrl = "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip"
|
||||
def ghSamplesUrl = "$ghUrl/spring-session-samples/"
|
||||
def samplesDir = "example${dollar}spring-session-samples/"
|
||||
def sessionJdbcMainResourcesDir = "example${dollar.toString()}session-jdbc-main-resources-dir/"
|
||||
def springSessionDataMongoDbDir = "example${dollar.toString()}spring-session-data-mongodb-dir/"
|
||||
def docsTestDir = "example${dollar.toString()}java/"
|
||||
def websocketdocTestDir = "example${dollar.toString()}java/docs/websocket/"
|
||||
def docsTestResourcesDir = "example${dollar.toString()}resources/"
|
||||
def indexdocTests = "example${dollar.toString()}java/docs/IndexDocTests.java"
|
||||
|
||||
return [
|
||||
'download-url': downloadUrl.toString(),
|
||||
'gh-samples-url': ghSamplesUrl.toString(),
|
||||
'samples-dir': samplesDir.toString(),
|
||||
'session-jdbc-main-resources-dir': sessionJdbcMainResourcesDir.toString(),
|
||||
'spring-session-data-mongodb-dir': springSessionDataMongoDbDir.toString(),
|
||||
'docs-test-dir': docsTestDir.toString(),
|
||||
'websocketdoc-test-dir': websocketdocTestDir.toString(),
|
||||
'docs-test-resources-dir': docsTestResourcesDir.toString(),
|
||||
'indexdoc-tests': indexdocTests.toString(),
|
||||
'spring-session-version': project.version,
|
||||
'version-milestone': milestoneBuild,
|
||||
'version-release': releaseBuild,
|
||||
'version-snapshot': snapshotBuild,
|
||||
'spring-boot-version': springBootVersion
|
||||
] + resolvedVersions(project.configurations.testRuntimeClasspath)
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -52,58 +91,16 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("generateAntora") {
|
||||
group = "Documentation"
|
||||
description = "Generates the antora.yml for dynamic properties"
|
||||
doLast {
|
||||
def dollar = '$'
|
||||
def ghTag = snapshotBuild ? 'main' : project.version
|
||||
def ghUrl = "https://github.com/spring-projects/spring-session/tree/$ghTag"
|
||||
def versions = resolvedVersions(project.configurations.testRuntimeClasspath)
|
||||
def ymlVersions = ""
|
||||
versions.call().each { name, version ->
|
||||
ymlVersions += """
|
||||
${name}: ${version}"""
|
||||
}
|
||||
def outputFile = new File("$buildDir/generateAntora/antora.yml")
|
||||
outputFile.getParentFile().mkdirs()
|
||||
outputFile.createNewFile()
|
||||
def antoraYmlText = file("antora.yml").getText()
|
||||
outputFile.setText("""$antoraYmlText
|
||||
title: Spring Session
|
||||
start_page: ROOT:index.adoc
|
||||
nav:
|
||||
- modules/ROOT/nav.adoc
|
||||
|
||||
asciidoc:
|
||||
attributes:
|
||||
download-url: "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip"
|
||||
gh-samples-url: "$ghUrl/spring-session-samples/"
|
||||
samples-dir: "example${dollar}spring-session-samples/"
|
||||
session-jdbc-main-resources-dir: "example${dollar}session-jdbc-main-resources-dir/"
|
||||
spring-session-data-mongodb-dir: "example${dollar}spring-session-data-mongodb-dir/"
|
||||
docs-test-dir: "example${dollar}java/"
|
||||
websocketdoc-test-dir: 'example${dollar}java/docs/websocket/'
|
||||
docs-test-resources-dir: "example${dollar}resources/"
|
||||
indexdoc-tests: "example${dollar}java/docs/IndexDocTests.java"
|
||||
spring-session-version: ${project.version}
|
||||
version-milestone: $milestoneBuild
|
||||
version-release: $releaseBuild
|
||||
version-snapshot: $snapshotBuild
|
||||
spring-boot-version: ${springBootVersion}
|
||||
${ymlVersions}
|
||||
""")
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "https://repo.spring.io/release" }
|
||||
mavenCentral()
|
||||
maven { url 'https://repo.spring.io/release' }
|
||||
maven { url 'https://repo.spring.io/milestone' }
|
||||
maven { url 'https://repo.spring.io/snapshot' }
|
||||
}
|
||||
|
||||
def resolvedVersions(Configuration configuration) {
|
||||
return {
|
||||
configuration.resolvedConfiguration
|
||||
return configuration.resolvedConfiguration
|
||||
.resolvedArtifacts
|
||||
.collectEntries { [(it.name + "-version"): it.moduleVersion.id.version] }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2014-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.jdbc.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
|
||||
|
||||
/**
|
||||
* Utility class for schema files.
|
||||
*
|
||||
* @author Marcus da Coregio
|
||||
* @since 3.1
|
||||
*/
|
||||
public final class JdbcSchemaUtils {
|
||||
|
||||
private JdbcSchemaUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the content of the provided schema resource and replaces the
|
||||
* {@link JdbcIndexedSessionRepository#DEFAULT_TABLE_NAME} by the provided table name.
|
||||
* @param schemaResource the schema resource
|
||||
* @param tableName the table name to replace
|
||||
* @return the schema resource with the table name replaced
|
||||
*/
|
||||
public static Resource replaceDefaultTableName(Resource schemaResource, String tableName) throws IOException {
|
||||
try (InputStream inputStream = schemaResource.getInputStream()) {
|
||||
String schemaScript = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
String newSchema = schemaScript.replace(JdbcIndexedSessionRepository.DEFAULT_TABLE_NAME, tableName);
|
||||
return new ByteArrayResource(newSchema.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2014-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.jdbc.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JdbcSchemaUtils}.
|
||||
*
|
||||
* @author Marcus da Coregio
|
||||
*/
|
||||
class JdbcSchemaUtilsTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("getCreateSchemaFiles")
|
||||
void replaceCreateSchemaTableName(Resource schema) throws IOException {
|
||||
Resource newTableNameSchema = JdbcSchemaUtils.replaceDefaultTableName(schema, "NEW_TABLE_NAME");
|
||||
String schemaScript = new String(newTableNameSchema.getInputStream().readAllBytes());
|
||||
assertThat(schemaScript).doesNotContain("SPRING_SESSION", "SPRING_SESSION_ATTRIBUTES", "SPRING_SESSION_IX1",
|
||||
"SPRING_SESSION_IX2", "SPRING_SESSION_IX3");
|
||||
assertThat(schemaScript).contains("NEW_TABLE_NAME", "NEW_TABLE_NAME_ATTRIBUTES", "NEW_TABLE_NAME_IX1",
|
||||
"NEW_TABLE_NAME_IX2", "NEW_TABLE_NAME_IX3");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("getDropSchemaFiles")
|
||||
void replaceDropSchemaTableName(Resource schema) throws IOException {
|
||||
Resource newTableNameSchema = JdbcSchemaUtils.replaceDefaultTableName(schema, "NEW_TABLE_NAME");
|
||||
String schemaScript = new String(newTableNameSchema.getInputStream().readAllBytes());
|
||||
assertThat(schemaScript).doesNotContain("SPRING_SESSION", "SPRING_SESSION_ATTRIBUTES");
|
||||
assertThat(schemaScript).contains("NEW_TABLE_NAME", "NEW_TABLE_NAME_ATTRIBUTES");
|
||||
}
|
||||
|
||||
private static Stream<Resource> getCreateSchemaFiles() throws IOException {
|
||||
return getSchemaFiles().filter((resource) -> !resource.getFilename().contains("drop"));
|
||||
}
|
||||
|
||||
private static Stream<Resource> getDropSchemaFiles() throws IOException {
|
||||
return getSchemaFiles().filter((resource) -> resource.getFilename().contains("drop"));
|
||||
}
|
||||
|
||||
private static Stream<Resource> getSchemaFiles() throws IOException {
|
||||
return Arrays.stream(new PathMatchingResourcePatternResolver()
|
||||
.getResources("classpath*:org/springframework/session/jdbc/schema-*.sql"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,8 +13,9 @@ dependencies {
|
||||
implementation "ch.qos.logback:logback-classic"
|
||||
implementation "org.testcontainers:testcontainers"
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -16,6 +16,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -14,6 +14,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -15,6 +15,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -17,6 +17,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
|
||||
@@ -13,6 +13,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -13,7 +13,8 @@ dependencies {
|
||||
implementation "ch.qos.logback:logback-classic"
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
@@ -15,6 +15,7 @@ dependencies {
|
||||
|
||||
providedCompile "jakarta.servlet:jakarta.servlet-api"
|
||||
providedCompile "org.glassfish.web:jakarta.servlet.jsp.jstl"
|
||||
providedCompile "jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api"
|
||||
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
|
||||
Reference in New Issue
Block a user