Skip to content

Commit

Permalink
Демо-приложение для вебинара по Tarantool Cartridge.
Browse files Browse the repository at this point in the history
  • Loading branch information
peneksglazami committed Feb 24, 2021
0 parents commit eb4eaca
Show file tree
Hide file tree
Showing 48 changed files with 3,375 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/
117 changes: 117 additions & 0 deletions .mvn/wrapper/MavenWrapperDownloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2007-present 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.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;

public class MavenWrapperDownloader {

private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";

/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";

/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";

/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";

public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());

// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);

File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}

private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}

}
Binary file added .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
4 changes: 4 additions & 0 deletions Dockerfile-app
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM bellsoft/liberica-openjdk-alpine:8
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
15 changes: 15 additions & 0 deletions Dockerfile-tarantool
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Moscow

# Install tarantool and cartridge
RUN apt-get update && apt-get install curl -y
RUN curl -L https://tarantool.io/qCLQYP/release/2.6/installer.sh --output installer.sh
RUN chmod +x ./installer.sh
RUN ./installer.sh
RUN apt-get -y install tarantool
RUN apt-get -y install cartridge-cli
RUN apt-get -y install unzip

COPY ./tarantool/cartridge-app /opt/cartridge-app
RUN cartridge build /opt/cartridge-app
113 changes: 113 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Демо-приложение для вебинара "Tarantool Cartridge: разработка отказоустойчивого кластера"

В данном репозитории хранится исходный код демо-приложения, являющегося примером работы Java-приложения
с кластером [Tarantool](http://tarantool.io).

## Запуск демонстративного кластера через docker-compose
На схеме ниже показан вариант развертывания демо-приложения в виде набора docker-контейнеров
(см. файл [docker-compose.yml](./docker-compose.yml)).
![deployment_schema](./deployment-schema.png)

Для запуска демо-приложения в виде набора docker-контейнеров необходимо выполнить следующие шаги:

1. Выполнить сборку веб-приложения через команду

```shell
mvnw clean package
```
или
```shell
sh mvnw clean package
```

2. Запустить сеть docker-контейнеров через команду

```shell
docker-compose up --build --detach
```

3. Подключиться к консоли одного из контейнеров, например, к `tarantool-server1` через команду

```shell
docker-compose exec tarantool-server1 /bin/bash
```

4. Подключитесь с использованием `tarantoolctl` к экземпляру Tarantool.

```shell
tarantoolctl connect http://admin:admin@127.0.0.1:3301
```

5. Затем в командной строке tarantool выполните следующий lua-скрипт
(см. файл [tarantool/init-script-demo.lua](./tarantool/init-script-demo.lua)).
Он выполнит объединение экземпляров Tarantool в replica sets и назначение экземплярам определённых ролей.

```lua
cartridge = require('cartridge')
replicasets = { {
alias = 'router1',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = 'tarantool-server1:3301' } }
}, {
alias = 'router2',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = 'tarantool-server2:3301' } }
}, {
alias = 'router3',
roles = { 'router', 'vshard-router', 'failover-coordinator' },
join_servers = { { uri = 'tarantool-server3:3301' } }
}, {
alias = 'storage1',
roles = { 'storage', 'vshard-storage' },
join_servers = { { uri = 'tarantool-server4:3301' },
{ uri = 'tarantool-server5:3301' },
{ uri = 'tarantool-server6:3301' } }
}, {
alias = 'storage2',
roles = { 'storage', 'vshard-storage' },
join_servers = { { uri = 'tarantool-server7:3301' },
{ uri = 'tarantool-server8:3301' },
{ uri = 'tarantool-server9:3301' } }
}}
cartridge.admin_edit_topology({ replicasets = replicasets })
```

Если произойдёт отключение от консоли Tarantool, то снова выполните подключение к ней

```shell
tarantoolctl connect http://admin:admin@127.0.0.1:3301
```

В командной строке tarantool выполните следующий lua-скрипт, который выполнит инициализацию шардинга БД и включение
режима аварийного восстановления с использованием etcd для хранения информации о состоянии кластера.

```lua
cartridge.admin_bootstrap_vshard()
cartridge.failover_set_params({
mode = 'stateful',
state_provider = 'etcd2',
failover_timeout = 10,
etcd2_params = {
prefix = '/',
lock_delay = 10,
endpoints = { '172.20.0.12:2379', '172.20.0.13:2379', '172.20.0.14:2379' }
}
})
```
6. Корректности настройки кластера можно проверить через веб-приложение Tarantool Cartridge
`http://<IP-адрес хоста, где запускается docker>:8081/admin` (например, http://localhost:8081/admin или
http://192.168.99.100:8081/admin).

7. Для получения доступа к Swagger-UI демо-приложения переходите по ссылке http://localhost:8080/swagger-ui или
http://192.168.99.100/swagger-ui.

## Запуск демонстративного кластера в Gitpod
Для запуска демо-приложения в облаке [gitpod.io](https://gitpod.io) необходимо выполнить следующие действия:
1. Создайте учётную запись на [gitpod.io](https://gitpod.io).
2. Необходимо в личном кабинете gitpod.io зайти в раздел Settings и проставить галочку напротив настойки
"Enable Feature Preview". Это позволит запускать docker-контейнеры внутри docker-контейнера с облачной IDE.
3. Запустить workspace с приложением. Создать workspace можно, перейдя по ссылке https://gitpod.io/#https://github.com/peneksglazami/tarantool-cartridge-webinar.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/peneksglazami/tarantool-cartridge-webinar)
4. В терминале выполните команду `sudo docker-up`. Эта команда запустит демон docker.
5. Откройте новое окно терминала и далее выполните команды запуска кластера, описанные выше в разделе
"Запуск демонстративного кластера через docker-compose".
50 changes: 50 additions & 0 deletions api/api-request-example.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
POST http://192.168.99.100:8080/user
Content-Type: application/json

{
"login": "login",
"password": "password1",
"groups": [
"group1", "group2", "group3"
],
"status": "ACTIVE"
}

###
GET http://192.168.99.100:8080/user/{uuid}
###

PUT http://192.168.99.100:8080/user/{uuid}
Content-Type: application/json

{
"login": "login2",
"password": "password2",
"groups": [
"group4", "group5", "group6"
],
"status": "BLOCKED"
}

###

POST http://192.168.99.100:8080/login
Content-Type: application/json

{
"login": "login",
"password": "1"
}

###
DELETE http://192.168.99.100:8080/user/{uuid}

###

PUT http://192.168.99.100:8080/user/update-group
Content-Type: application/json

{
"groupId": "group4",
"newStatus": "ACTIVE"
}
Loading

0 comments on commit eb4eaca

Please sign in to comment.