Add logic fir check lists

This commit is contained in:
k.struzhkin 2019-01-15 13:45:06 +03:00
parent 7ac69e6f6e
commit 90f227a7ce
25 changed files with 908 additions and 29 deletions

80
.gitignore vendored
View File

@ -1,42 +1,56 @@
# Created by .ignore support plugin (hsz.mobi) # Created by .ignore support plugin (hsz.mobi)
### JetBrains template .eunit
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm deps
*.o
*.DS_Store *.beam
*.plt
*.iml erl_crash.dump
ebin/*.beam
## Directory-based project format: rel/example_project
.idea/ .concrete/DEV_MODE
# if you remove the above rule, at least ignore the following: .rebar
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff: # User-specific stuff:
# .idea/workspace.xml .idea/
# .idea/tasks.xml .idea/workspace.xml
# .idea/dictionaries .idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files: # Sensitive or high-churn files:
# .idea/dataSources.ids .idea/dataSources.ids
# .idea/dataSources.xml .idea/dataSources.xml
# .idea/sqlDataSources.xml .idea/dataSources.local.xml
# .idea/dynamic.xml .idea/sqlDataSources.xml
# .idea/uiDesigner.xml .idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle: # Gradle:
# .idea/gradle.xml .idea/gradle.xml
# .idea/libraries .idea/libraries
# Mongo Explorer plugin: # Mongo Explorer plugin:
# .idea/mongoSettings.xml .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws *.iws
*.ipr
*.iml
## Plugin-specific files:
# IntelliJ # IntelliJ
out/ /out/
# mpeltonen/sbt-idea plugin # mpeltonen/sbt-idea plugin
.idea_modules/ .idea_modules/
@ -48,9 +62,17 @@ atlassian-ide-plugin.xml
com_crashlytics_export_strings.xml com_crashlytics_export_strings.xml
crashlytics.properties crashlytics.properties
crashlytics-build.properties crashlytics-build.properties
fabric.properties
*.class
# Target folder # Mobile Tools for Java (J2ME)
target .mtj.tmp/
# Target ant folder # Package Files #
build *.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
env.list

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "build_utils"]
path = build_utils
url = git@github.com:rbkmoney/build_utils.git
branch = master

16
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,16 @@
#!groovy
build('wb-list-manager', 'java-maven') {
checkoutRepo()
loadBuildUtils()
def javaServicePipeline
runStage('load JavaService pipeline') {
javaServicePipeline = load("build_utils/jenkins_lib/pipeJavaService.groovy")
}
def serviceName = env.REPO_NAME
def mvnArgs = '-DjvmArgs="-Xmx256m"'
def useJava11 = true
javaServicePipeline(serviceName, useJava11, mvnArgs)
}

1
build_utils Submodule

@ -0,0 +1 @@
Subproject commit 269686d735abef363f9f40a1bf4e1b7c751f3722

190
pom.xml Normal file
View File

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rbkmoney</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<artifactId>wb-list-manager</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>wb-list-manager</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<server.port>8022</server.port>
<exposed.ports>${server.port}</exposed.ports>
<dockerfile.base.service.tag>81f57f9ef5e5854c27659c9f56f59cdb2b7c43e5</dockerfile.base.service.tag>
<shared.resources.version>0.3.2</shared.resources.version>
</properties>
<dependencies>
<dependency>
<groupId>com.rbkmoney</groupId>
<artifactId>shared-resources</artifactId>
<version>${shared.resources.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.rbkmoney.woody</groupId>
<artifactId>woody-thrift</artifactId>
<version>1.1.15</version>
</dependency>
<dependency>
<groupId>com.rbkmoney</groupId>
<artifactId>spring-boot-starter-metrics-statsd</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.10.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.basho.riak</groupId>
<artifactId>riak-client</artifactId>
<version>2.1.1</version>
</dependency>
<!--kafka-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.2.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>kafka</artifactId>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.rbkmoney</groupId>
<artifactId>wb-list-proto</artifactId>
<version>1.8-36aed97</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${project.build.directory}/maven-shared-archive-resources</directory>
<targetPath>${project.build.directory}</targetPath>
<includes>
<include>Dockerfile</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>${project.build.directory}/maven-shared-archive-resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>Dockerfile</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.6.0</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-filtering</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<configuration>
<resourceBundles>
<resourceBundle>com.rbkmoney:shared-resources:${shared.resources.version}</resourceBundle>
</resourceBundles>
<attachToMain>false</attachToMain>
<attachToTest>false</attachToTest>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Sonar-JaCoCo integration plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package com.rbkmoney.wb.list.manager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class WbListManagerApplication extends SpringApplication {
public static void main(String[] args) {
SpringApplication.run(WbListManagerApplication.class);
}
}

View File

@ -0,0 +1,48 @@
package com.rbkmoney.wb.list.manager.config;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class KafkaConfig {
private static final String GROUP_ID = "CommandListener";
private static final String EARLIEST = "earliest";
@Value("${kafka.bootstrap.servers}")
private String bootstrapServers;
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.GROUP_ID_CONFIG, GROUP_ID);
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, EARLIEST);
return props;
}
@Bean
public ConsumerFactory<String, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}
@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
return factory;
}
}

View File

@ -0,0 +1,17 @@
package com.rbkmoney.wb.list.manager.config;
import com.rbkmoney.damsel.wb_list.WbListServiceSrv;
import com.rbkmoney.wb.list.manager.handler.WbListServiceHandler;
import com.rbkmoney.wb.list.manager.repository.ListRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ResourceConfig {
@Bean
public WbListServiceSrv.Iface fraudInspectorHandler(ListRepository listRepository) {
return new WbListServiceHandler(listRepository);
}
}

View File

@ -0,0 +1,35 @@
package com.rbkmoney.wb.list.manager.config;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.core.RiakCluster;
import com.basho.riak.client.core.RiakNode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RiakConfig {
@Value("${riak.port}")
public int riakPort;
@Value("${riak.address}")
public String riakAddress;
@Bean
public RiakCluster riakCluster() {
RiakNode node = new RiakNode.Builder()
.withRemoteAddress(riakAddress)
.withRemotePort(riakPort)
.build();
RiakCluster cluster = new RiakCluster.Builder(node)
.build();
cluster.start();
return cluster;
}
@Bean
public RiakClient riakClient() {
return new RiakClient(riakCluster());
}
}

View File

@ -0,0 +1,23 @@
package com.rbkmoney.wb.list.manager.exception;
public class RiakExecutionException extends RuntimeException {
public RiakExecutionException() {
}
public RiakExecutionException(String message) {
super(message);
}
public RiakExecutionException(String message, Throwable cause) {
super(message, cause);
}
public RiakExecutionException(Throwable cause) {
super(cause);
}
public RiakExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,29 @@
package com.rbkmoney.wb.list.manager.handler;
import com.rbkmoney.damsel.wb_list.ListNotFound;
import com.rbkmoney.damsel.wb_list.WbListServiceSrv;
import com.rbkmoney.wb.list.manager.exception.RiakExecutionException;
import com.rbkmoney.wb.list.manager.repository.ListRepository;
import com.rbkmoney.wb.list.manager.utils.KeyGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
@Slf4j
@RequiredArgsConstructor
public class WbListServiceHandler implements WbListServiceSrv.Iface {
private final ListRepository listRepository;
@Override
public boolean isExist(String partyId, String shopId, String listName, String value) throws ListNotFound, TException {
String bucket = KeyGenerator.generateBucket(partyId, shopId);
String key = KeyGenerator.generateKey(listName, value);
try {
return listRepository.get(bucket, key).isPresent();
} catch (RiakExecutionException e) {
throw new TException(e);
}
}
}

View File

@ -0,0 +1,22 @@
package com.rbkmoney.wb.list.manager.listener;
import com.rbkmoney.wb.list.manager.model.Row;
import com.rbkmoney.wb.list.manager.repository.ListRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class WbListListener {
private final ListRepository listRepository;
@KafkaListener(topics = "${kafka.wblist.topic}", containerFactory = "kafkaListenerContainerFactory")
public void listen(Row row) {
log.info("TemplateListener ruleTemplate: {}", row);
listRepository.create(row);
}
}

View File

@ -0,0 +1,17 @@
package com.rbkmoney.wb.list.manager.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Row {
private String bucketName;
private String key;
private String value;
}

View File

@ -0,0 +1,15 @@
package com.rbkmoney.wb.list.manager.repository;
import com.rbkmoney.wb.list.manager.model.Row;
import java.util.Optional;
public interface CrudRepository<T, K> {
void create(T row);
void remove(T row);
Optional<Row> get(String bucket, K key);
}

View File

@ -0,0 +1,91 @@
package com.rbkmoney.wb.list.manager.repository;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.cap.Quorum;
import com.basho.riak.client.api.commands.kv.DeleteValue;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.StoreValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import com.basho.riak.client.core.query.RiakObject;
import com.basho.riak.client.core.util.BinaryValue;
import com.rbkmoney.wb.list.manager.exception.RiakExecutionException;
import com.rbkmoney.wb.list.manager.model.Row;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
@Slf4j
@Service
@RequiredArgsConstructor
public class ListRepository implements CrudRepository<Row, String> {
private static final String TEXT_PLAIN = "text/plain";
private final RiakClient client;
@Override
public void create(Row row) {
try {
RiakObject quoteObject = new RiakObject()
.setContentType(TEXT_PLAIN)
.setValue(BinaryValue.create(row.getValue()));
Location quoteObjectLocation = createLocation(row.getBucketName(), row.getKey());
StoreValue storeOp = new StoreValue.Builder(quoteObject)
.withOption(StoreValue.Option.W, Quorum.oneQuorum())
.withLocation(quoteObjectLocation)
.build();
client.execute(storeOp);
} catch (ExecutionException e) {
log.error("Exception in ListRepository when create e: ", e);
throw new RiakExecutionException();
} catch (InterruptedException e) {
log.error("InterruptedException in ListRepository when get e: ", e);
Thread.currentThread().interrupt();
throw new RiakExecutionException(e);
}
}
@Override
public void remove(Row row) {
try {
Location quoteObjectLocation = createLocation(row.getBucketName(), row.getKey());
DeleteValue delete = new DeleteValue.Builder(quoteObjectLocation).build();
client.execute(delete);
} catch (ExecutionException e) {
log.error("Exception in ListRepository when remove e: ", e);
throw new RiakExecutionException(e);
} catch (InterruptedException e) {
log.error("InterruptedException in ListRepository when get e: ", e);
Thread.currentThread().interrupt();
throw new RiakExecutionException(e);
}
}
@Override
public Optional<Row> get(String bucket, String key) {
try {
Location quoteObjectLocation = createLocation(bucket, key);
FetchValue fetch = new FetchValue.Builder(quoteObjectLocation)
.withOption(FetchValue.Option.R, new Quorum(3))
.build();
FetchValue.Response response = client.execute(fetch);
RiakObject obj = response.getValue(RiakObject.class);
return Optional.of(new Row(bucket, key, obj.getValue().toString()));
} catch (ExecutionException e) {
log.error("Exception in ListRepository when get e: ", e);
throw new RiakExecutionException(e);
} catch (InterruptedException e) {
log.error("InterruptedException in ListRepository when get e: ", e);
Thread.currentThread().interrupt();
throw new RiakExecutionException(e);
}
}
private Location createLocation(String bucketName, String key) {
Namespace quotesBucket = new Namespace(bucketName);
return new Location(quotesBucket, key);
}
}

View File

@ -0,0 +1,30 @@
package com.rbkmoney.wb.list.manager.resource;
import com.rbkmoney.damsel.wb_list.WbListServiceSrv;
import com.rbkmoney.woody.thrift.impl.http.THServiceBuilder;
import lombok.RequiredArgsConstructor;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/v1/wb_list")
@RequiredArgsConstructor
public class FraudInspectorServlet extends GenericServlet {
private Servlet thriftServlet;
private final WbListServiceSrv.Iface fraudInspectorHandler;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
thriftServlet = new THServiceBuilder()
.build(WbListServiceSrv.Iface.class, fraudInspectorHandler);
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
thriftServlet.service(req, res);
}
}

View File

@ -0,0 +1,46 @@
package com.rbkmoney.wb.list.manager.serializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.common.errors.SerializationException;
import org.apache.kafka.common.serialization.Deserializer;
import java.util.Map;
public class JsonPOJODeserializer<T> implements Deserializer<T> {
private ObjectMapper objectMapper = new ObjectMapper();
private Class<T> tClass;
/**
* Default constructor needed by Kafka
*/
public JsonPOJODeserializer() {
}
@SuppressWarnings("unchecked")
@Override
public void configure(Map<String, ?> props, boolean isKey) {
tClass = (Class<T>) props.get("JsonPOJOClass");
}
@Override
public T deserialize(String topic, byte[] bytes) {
if (bytes == null)
return null;
T data;
try {
data = objectMapper.readValue(bytes, tClass);
} catch (Exception e) {
throw new SerializationException(e);
}
return data;
}
@Override
public void close() {
}
}

View File

@ -0,0 +1,38 @@
package com.rbkmoney.wb.list.manager.serializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.common.errors.SerializationException;
import org.apache.kafka.common.serialization.Serializer;
import java.util.Map;
public class JsonPOJOSerializer<T> implements Serializer<T> {
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* Default constructor needed by Kafka
*/
public JsonPOJOSerializer() {
}
@Override
public void configure(Map<String, ?> props, boolean isKey) {
}
@Override
public byte[] serialize(String topic, T data) {
if (data == null)
return null;
try {
return objectMapper.writeValueAsBytes(data);
} catch (Exception e) {
throw new SerializationException("Error serializing JSON message", e);
}
}
@Override
public void close() {
}
}

View File

@ -0,0 +1,19 @@
package com.rbkmoney.wb.list.manager.utils;
public class KeyGenerator {
public static final String DELIMITER = "_";
public static String generateBucket(String partyId, String shopId) {
return generateKeySecondField(partyId, shopId);
}
public static String generateKey(String type, String key) {
return generateKeySecondField(type, key);
}
private static String generateKeySecondField(String first, String second) {
return first + DELIMITER + second;
}
}

View File

@ -0,0 +1,16 @@
server.port: @server.port@
management.security.flag: false
spring.application.name: @project.name@
info.version: @project.version@
info.stage: dev
management.metrics.export.statsd:
flavor: etsy
riak:
address: localhost
port: 8087
kafka:
bootstrap.servers: "localhost:9092"
wblist.topic: "wblist"

View File

@ -0,0 +1,34 @@
package com.rbkmoney.wb.list.manager;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.KafkaContainer;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ContextConfiguration(initializers = KafkaAbstractTest.Initializer.class)
public abstract class KafkaAbstractTest {
@ClassRule
public static KafkaContainer kafka = new KafkaContainer("5.0.1").withEmbeddedZookeeper();
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("kafka.bootstrap.servers=" + kafka.getBootstrapServers())
.applyTo(configurableApplicationContext.getEnvironment());
}
}
}

View File

@ -0,0 +1,96 @@
package com.rbkmoney.wb.list.manager;
import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;
import com.basho.riak.client.core.query.RiakObject;
import com.rbkmoney.wb.list.manager.config.KafkaConfig;
import com.rbkmoney.wb.list.manager.model.Row;
import com.rbkmoney.wb.list.manager.repository.ListRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.WaitAllStrategy;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ContextConfiguration(classes = WbListManagerApplication.class, initializers = WbListManagerApplicationTest.Initializer.class)
public class WbListManagerApplicationTest extends KafkaAbstractTest {
public static final String TYPE = "type";
public static final String BUCKET_NAME = "bucketName";
public static final String VALUE = "value";
public static final String KEY = "key";
@Autowired
private ListRepository listRepository;
@Autowired
private RiakClient client;
@ClassRule
public static GenericContainer riak = new GenericContainer("basho/riak-kv")
.waitingFor(new WaitAllStrategy());
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("riak.port=" + riak.getMappedPort(8087))
.applyTo(configurableApplicationContext.getEnvironment());
}
}
@Before
public void init() throws InterruptedException {
riak.start();
// TODO add cycle for up check
Thread.sleep(8000L);
}
@Test
public void contextLoads() throws ExecutionException, InterruptedException {
Row row = new Row();
row.setKey(KEY);
row.setBucketName(BUCKET_NAME);
row.setValue(VALUE);
listRepository.create(row);
Namespace ns = new Namespace(BUCKET_NAME);
Location location = new Location(ns, KEY);
FetchValue fv = new FetchValue.Builder(location).build();
FetchValue.Response response = client.execute(fv);
RiakObject obj = response.getValue(RiakObject.class);
String result = obj.getValue().toString();
Assert.assertEquals(VALUE, result);
Optional<Row> resultGet = listRepository.get(BUCKET_NAME, KEY);
Assert.assertFalse(resultGet.isEmpty());
Assert.assertEquals(VALUE, resultGet.get().getValue());
listRepository.remove(row);
response = client.execute(fv);
obj = response.getValue(RiakObject.class);
Assert.assertNull(obj);
}
}

View File

@ -0,0 +1,43 @@
package com.rbkmoney.wb.list.manager.handler;
import com.rbkmoney.wb.list.manager.model.Row;
import com.rbkmoney.wb.list.manager.repository.ListRepository;
import org.apache.thrift.TException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
import static org.mockito.ArgumentMatchers.anyString;
public class WbListServiceHandlerTest {
public static final String VALUE = "value";
WbListServiceHandler wbListServiceHandler;
@Mock
ListRepository listRepository;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
wbListServiceHandler = new WbListServiceHandler(listRepository);
}
@Test
public void isExist() throws TException {
Row value = new Row();
value.setValue(VALUE);
Mockito.when(listRepository.get(anyString(), anyString())).thenReturn(Optional.of(value));
boolean exist = wbListServiceHandler.isExist("partyId", "shopId", "listName", "value");
Assert.assertTrue(exist);
Mockito.when(listRepository.get(anyString(), anyString())).thenReturn(Optional.empty());
exist = wbListServiceHandler.isExist("partyId", "shopId", "listName", "value");
Assert.assertFalse(exist);
}
}

View File

@ -0,0 +1,2 @@
riak-admin bucket-type create type
riak-admin bucket-type activate type

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<root level="warn">
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.rbkmoney.woody" level="ALL"/>
</configuration>