mirror of
https://github.com/valitydev/wb-list-manager.git
synced 2024-11-06 01:35:17 +00:00
Add logic fir check lists
This commit is contained in:
parent
7ac69e6f6e
commit
90f227a7ce
80
.gitignore
vendored
80
.gitignore
vendored
@ -1,42 +1,56 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.DS_Store
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
.eunit
|
||||
deps
|
||||
*.o
|
||||
*.beam
|
||||
*.plt
|
||||
erl_crash.dump
|
||||
ebin/*.beam
|
||||
rel/example_project
|
||||
.concrete/DEV_MODE
|
||||
.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:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
.idea/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
*.ipr
|
||||
*.iml
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
@ -48,9 +62,17 @@ atlassian-ide-plugin.xml
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
*.class
|
||||
|
||||
# Target folder
|
||||
target
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Target ant folder
|
||||
build
|
||||
# Package Files #
|
||||
*.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
4
.gitmodules
vendored
Normal 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
16
Jenkinsfile
vendored
Normal 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
1
build_utils
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 269686d735abef363f9f40a1bf4e1b7c751f3722
|
190
pom.xml
Normal file
190
pom.xml
Normal 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>
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
17
src/main/java/com/rbkmoney/wb/list/manager/model/Row.java
Normal file
17
src/main/java/com/rbkmoney/wb/list/manager/model/Row.java
Normal 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;
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
16
src/main/resources/application.yml
Normal file
16
src/main/resources/application.yml
Normal 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"
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
2
src/test/resources/app/start.sh
Normal file
2
src/test/resources/app/start.sh
Normal file
@ -0,0 +1,2 @@
|
||||
riak-admin bucket-type create type
|
||||
riak-admin bucket-type activate type
|
10
src/test/resources/logback-test.xml
Normal file
10
src/test/resources/logback-test.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user