Fix context (#19)

* Fix bean init

* Upd context structure + fix multivalue and params order
This commit is contained in:
Egor Cherniak 2023-07-05 14:20:52 +03:00 committed by GitHub
parent 016c0f49a9
commit 535876b5b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 112 additions and 54 deletions

View File

@ -1,11 +1,7 @@
package dev.vality.alert.tg.bot.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -9,6 +9,7 @@ import dev.vality.alert.tg.bot.service.MayDayService;
import dev.vality.alerting.mayday.UserAlert;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@ -25,6 +26,7 @@ import java.util.Set;
import static dev.vality.alert.tg.bot.utils.StringSearchUtils.*;
@Slf4j
@Component
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
@ -65,6 +67,7 @@ public class InlineHandler implements CommonHandler<AnswerInlineQuery> {
String paramId = substringParamId(inlineQuery);
ParametersData parametersData = parametersDao.getByAlertIdAndParamId(alertId, paramId);
Set<String> options = jsonMapper.toSet(parametersData.getOptionsValues());
log.info("Supported params: {}", options);
options.forEach(optionValue -> {
if (isParamInList(optionValue, inlineQuery, alertId, paramId)) {
queryResultArticleList.add(fillInlineQueryResultArticle(

View File

@ -5,6 +5,7 @@ import dev.vality.alert.tg.bot.dao.ParametersDao;
import dev.vality.alert.tg.bot.dao.StateDataDao;
import dev.vality.alert.tg.bot.domain.tables.pojos.ParametersData;
import dev.vality.alert.tg.bot.domain.tables.pojos.StateData;
import dev.vality.alert.tg.bot.model.Parameter;
import lombok.RequiredArgsConstructor;
import org.apache.thrift.TException;
import org.springframework.stereotype.Component;
@ -24,18 +25,14 @@ public class CreateParamsRequestMapper {
public SendMessage createRequest(Long userId, String paramName, String paramValue) throws TException {
StateData stateData = stateDataDao.getByUserId(userId);
Map<String, Set<String>> paramMap = jsonMapper.toMap(stateData.getMapParams());
List<Parameter> paramMap = jsonMapper.toMap(stateData.getMapParams());
ParametersData parametersData = parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), paramName);
if (isParamValueMatchToProcess(parametersData, paramValue, paramMap)) {
Set<String> values = new HashSet<>();
values.add(paramValue);
if (!paramMap.containsKey(paramName)) {
paramMap.put(paramName, values);
} else {
paramMap.get(paramName).addAll(values);
}
paramMap.stream()
.filter(parameter -> parameter.getName().equals(paramName))
.findFirst()
.orElseThrow()
.getValues().add(paramValue);
stateData.setMapParams(jsonMapper.toJson(paramMap));
stateDataDao.updateParams(userId, stateData.getMapParams());
}
@ -47,8 +44,8 @@ public class CreateParamsRequestMapper {
}
}
private boolean isParamValueMatchToProcess(ParametersData parametersData, String paramValue, Map<String,
Set<String>> providedParams) {
private boolean isParamValueMatchToProcess(ParametersData parametersData, String paramValue,
List<Parameter> parameters) {
return (!parametersData.getMandatory()
&& (isValuePattern(paramValue, parametersData)
|| paramValue.equals(TextConstants.EMPTY_PARAM.getText())))
@ -57,7 +54,9 @@ public class CreateParamsRequestMapper {
&& isValuePattern(paramValue, parametersData))
|| (parametersData.getMandatory()
&& paramValue.equals(TextConstants.EMPTY_PARAM.getText())
&& providedParams.containsKey(parametersData.getParamId()));
&& parameters.stream()
.anyMatch(parameter -> parameter.getId().equals(parametersData.getParamId())
&& !parameter.getValues().contains(TextConstants.EMPTY_PARAM.getText())));
}
private boolean isValuePattern(String value, ParametersData parametersData) {
@ -68,18 +67,26 @@ public class CreateParamsRequestMapper {
return true;
}
private static String getNextKeyForFill(Map<String, Set<String>> map, ParametersData parametersData) {
return map.entrySet().stream()
// Если у параметра вообще нет значения
.filter(entry -> null == entry.getValue()
//Если у параметр может принимать несколько значений, а
// пользователь продолжает вводить новые значения
|| !entry.getValue().contains(TextConstants.EMPTY_PARAM.getText())
&& parametersData.getMultipleValues()
//Если параметр обязательный, но пользователь передал только пустое значение
|| entry.getValue().contains(TextConstants.EMPTY_PARAM.getText())
&& parametersData.getMandatory() && entry.getValue().size() == 1)
.findFirst().map(Map.Entry::getKey)
private static String getNextKeyForFill(List<Parameter> parameters, ParametersData parametersData) {
Parameter lastParameter =
parameters.stream().filter(parameter -> parameter.getName().equals(parametersData.getParamName()))
.findFirst().orElseThrow();
//Если параметр может принимать несколько значений и пользователь не ввёл символ прекращения ввода
if (parametersData.getMultipleValues()
&& !lastParameter.getValues().contains(TextConstants.EMPTY_PARAM.getText())
//Если параметр обязательный, но пользователь так и не передал значение
|| parametersData.getMandatory()
&& lastParameter.getValues().contains(TextConstants.EMPTY_PARAM.getText())
&& lastParameter.getValues().size() == 1) {
return parametersData.getParamName();
}
return parameters.stream()
.sorted()
// Выбираем первый параметр без значений
.filter(parameter -> parameter.getValues().isEmpty())
.findFirst().map(Parameter::getName)
.orElse(null);
}
}

View File

@ -3,6 +3,7 @@ package dev.vality.alert.tg.bot.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.vality.alert.tg.bot.model.Parameter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
@ -23,7 +24,7 @@ public class JsonMapper {
}
@SneakyThrows(JsonProcessingException.class)
public Map<String, Set<String>> toMap(String json) {
public List<Parameter> toMap(String json) {
return objectMapper.readValue(json, new TypeReference<>() {
});
}

View File

@ -5,6 +5,7 @@ import dev.vality.alert.tg.bot.dao.ParametersDao;
import dev.vality.alert.tg.bot.dao.StateDataDao;
import dev.vality.alert.tg.bot.domain.tables.pojos.ParametersData;
import dev.vality.alert.tg.bot.domain.tables.pojos.StateData;
import dev.vality.alert.tg.bot.model.Parameter;
import dev.vality.alert.tg.bot.service.MayDayService;
import dev.vality.alert.tg.bot.utils.ParamKeyboardBuilder;
import dev.vality.alerting.mayday.AlertConfiguration;
@ -29,25 +30,35 @@ public class ParametersCallbackMapper {
AlertConfiguration alertConfiguration = mayDayService.getAlertConfiguration(callData);
String alertId = alertConfiguration.getId();
List<ParameterConfiguration> parameterConfigurations = alertConfiguration.getParameters();
parameterConfigurations.sort(ParameterConfiguration::compareTo);
fillStateDataAndSave(userId, alertId, parameterConfigurations);
List<Parameter> sortedParams = fillStateDataAndSave(userId, alertId, parameterConfigurations);
parameterConfigurations.forEach(param -> convertParameterConfigurationsAndSave(alertId, param));
return ParamKeyboardBuilder.buildParamKeyboard(
parameterConfigurations.get(0).isSetOptions(),
parameterConfigurations.stream()
.filter(parameterConfiguration ->
parameterConfiguration.getId().equals(sortedParams.get(0).getId()))
.findFirst()
.orElseThrow().isSetOptions(),
alertId,
parameterConfigurations.get(0).getId(),
parameterConfigurations.get(0).getName(),
parameterConfigurations.get(0).getName());
sortedParams.get(0).getId(),
sortedParams.get(0).getName(),
sortedParams.get(0).getName());
}
private void fillStateDataAndSave(long userId, String alertId,
List<ParameterConfiguration> parameterConfigurations) {
private List<Parameter> fillStateDataAndSave(long userId, String alertId,
List<ParameterConfiguration> parameterConfigurations) {
StateData stateData = stateDataDao.getByUserId(userId);
stateData.setAlertId(alertId);
Map<String, List<String>> mapParams = new HashMap<>();
parameterConfigurations.forEach(param -> mapParams.put(param.getName(), new ArrayList<>()));
stateData.setMapParams(jsonMapper.toJson(mapParams));
List<Parameter> parameters = new ArrayList<>();
parameterConfigurations.forEach(param -> {
Parameter parameter = new Parameter();
parameter.setId(param.getId());
parameter.setName(param.getName());
parameters.add(parameter);
});
parameters.sort(Parameter::compareTo);
stateData.setMapParams(jsonMapper.toJson(parameters));
stateDataDao.save(stateData);
return parameters;
}
private void convertParameterConfigurationsAndSave(String alertId, ParameterConfiguration param) {

View File

@ -5,6 +5,7 @@ import dev.vality.alert.tg.bot.dao.ParametersDao;
import dev.vality.alert.tg.bot.dao.StateDataDao;
import dev.vality.alert.tg.bot.domain.tables.pojos.ParametersData;
import dev.vality.alert.tg.bot.domain.tables.pojos.StateData;
import dev.vality.alert.tg.bot.model.Parameter;
import dev.vality.alert.tg.bot.service.MayDayService;
import dev.vality.alert.tg.bot.utils.ParamKeyboardBuilder;
import dev.vality.alerting.mayday.CreateAlertRequest;
@ -16,8 +17,6 @@ import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static dev.vality.alert.tg.bot.utils.MainMenuBuilder.buildMainInlineKeyboardMarkup;
@ -34,16 +33,16 @@ public class ReplyMessagesMapper {
public SendMessage createAlertRequest(long userId) throws TException {
StateData stateData = stateDataDao.getByUserId(userId);
log.info("Start create alert with stateData {}", stateData);
Map<String, Set<String>> paramMap = jsonMapper.toMap(stateData.getMapParams());
List<Parameter> parameters = jsonMapper.toMap(stateData.getMapParams());
CreateAlertRequest createAlertRequest = new CreateAlertRequest();
createAlertRequest.setAlertId(stateData.getAlertId());
createAlertRequest.setUserId(String.valueOf(userId));
List<ParameterInfo> parameterInfos =
paramMap.entrySet().stream()
.flatMap(entry -> {
parameters.stream()
.flatMap(parameter -> {
ParametersData parametersData =
parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), entry.getKey());
return entry.getValue().stream()
parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), parameter.getName());
return parameter.getValues().stream()
.map(value -> {
ParameterInfo parameterInfo = new ParameterInfo();
parameterInfo.setId(parametersData.getParamId());

View File

@ -0,0 +1,42 @@
package dev.vality.alert.tg.bot.model;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashSet;
import java.util.Set;
@Data
@NoArgsConstructor
public class Parameter implements Comparable<Parameter> {
private final Set<String> values = new HashSet<>();
private String id;
private String name;
@Override
public int compareTo(Parameter o) {
return Integer.valueOf(this.id)
.compareTo(Integer.valueOf(o.getId()));
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Parameter parameter = (Parameter) o;
return name.equals(parameter.name);
}
}

View File

@ -15,14 +15,14 @@ public abstract class TestObjectFactory {
StateData stateData = new StateData();
stateData.setUserId(122233L);
stateData.setAlertId("45");
stateData.setMapParams("{\"Процент\":[34],\"Имя Терминала\":[56]}");
stateData.setMapParams("[{\"values\":[34],\"id\":\"1\",\"name\":\"Процент\"}]");
return stateData;
}
public static ParametersData testParameters() {
ParametersData params = new ParametersData();
params.setAlertId("32");
params.setParamName("Терминал");
params.setParamName("Процент");
params.setParamId("14");
params.setOptionsValues("[\"test1\",\"test2\"]");
params.setMandatory(false);
@ -74,7 +74,7 @@ public abstract class TestObjectFactory {
Chat chat = new Chat();
chat.setId(123L);
Message message = new Message();
message.setText("Введите в ответе параметр: test");
message.setText("Введите в ответе параметр: Процент");
message.setReplyToMessage(message);
message.setChat(chat);
message.setFrom(user);
@ -104,7 +104,7 @@ public abstract class TestObjectFactory {
Chat chat = new Chat();
chat.setId(123L);
Message message = new Message();
message.setText("selectParam{32}<14>");
message.setText("selectParam{Процент}<14>");
message.setReplyToMessage(message);
message.setChat(chat);
message.setFrom(user);

View File

@ -102,7 +102,6 @@ public class CallbackHandlerTest {
verify(stateDataDao, times(1)).getByUserId(any());
verify(stateDataDao, times(1)).save(any());
verify(parametersDao, times(1)).save(any());
}
}

View File

@ -66,7 +66,7 @@ public class ReplyMessageMapperTest {
SendMessage sendMessage = replyMessagesMapper.createNextParameterRequest("test", testStateData());
assertNotNull(sendMessage);
assertNotNull(sendMessage.getReplyMarkup());
assertEquals("Выберите из списка параметр: Терминал", sendMessage.getText());
assertEquals("Выберите из списка параметр: Процент", sendMessage.getText());
}
@Test