diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml
new file mode 100644
index 0000000..dbad7f8
--- /dev/null
+++ b/.github/workflows/github-actions.yml
@@ -0,0 +1,37 @@
+name: Build project
+
+on:
+ push:
+ branches:
+ - "*"
+ pull_request:
+ branches:
+ - "*"
+
+jobs:
+ Explore-GitHub-Actions:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 17 for x64
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'corretto'
+ architecture: 'x64'
+
+ - name: Build & Test
+ run: mvn -B clean package
+
+ - name: Install Docker Compose
+ run: sudo apt-get update && sudo apt-get install -y docker-compose
+
+ - name: Create & run Docker image
+ run: docker-compose up -d --build
+
+ - name: Clean up Docker resources
+ run: |
+ docker-compose down
+ docker system prune -af
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..8640475
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+mBuild:
+ mvn clean -Dmaven.test.skip package -e
+run:
+ java -jar target/knowBot-1.0-SNAPSHOT-jar-with-dependencies.jar
+doc:
+ docker-compose up -d --build
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index dc98105..6429811 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,12 +2,9 @@ services:
bot:
build: .
environment:
- - SPRING_DATA_MONGODB_URI=${SPRING_DATA_MONGODB_URI}
- TELEGRAM_USER_TOKEN=${TELEGRAM_USER_TOKEN}
- - TELEGRAM_ADMIN_TOKEN=${TELEGRAM_ADMIN_TOKEN}
- SPRING_DATA_MONGODB_DATABASE=${SPRING_DATA_MONGODB_DATABASE}
- - REDIS_PORT=${REDIS_PORT}
- - REDIS_HOSTNAME=${REDIS_HOSTNAME}
+ - SPRING_DATA_MONGODB_URI=${SPRING_DATA_MONGODB_URI}
grafana:
image: "grafana/grafana-enterprise:10.4.2"
diff --git a/pom.xml b/pom.xml
index 2dc2381..928e019 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,18 +18,10 @@
4.11.1
2.16.1
2.17.2
+ 5.10.2
+ 1.6.0.Final
-
- org.springframework.data
- spring-data-redis
- 3.2.5
-
-
- redis.clients
- jedis
- 5.1.2
-
com.github.pengrad
java-telegram-bot-api
@@ -51,15 +43,15 @@
${jackson-databind.version}
- org.junit-pioneer
- junit-pioneer
- 2.2.0
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter-api.version}
test
org.cache2k
cache2k-base-bom
- 1.6.0.Final
+ ${cache2k-base-bom.version}
pom
@@ -70,19 +62,6 @@
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.2.0
-
-
-
- org.example.Main
-
-
-
-
-
maven-assembly-plugin
3.7.1
diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java
index 9dc714b..e86ad42 100644
--- a/src/main/java/org/example/Main.java
+++ b/src/main/java/org/example/Main.java
@@ -3,10 +3,12 @@
import com.pengrad.telegrambot.TelegramBot;
import org.example.configs.MongoDBConfig;
import org.example.services.QuizService;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
@PropertySource("classpath:application.properties")
public class Main {
diff --git a/src/main/java/org/example/QuizBotListener.java b/src/main/java/org/example/QuizBotListener.java
index 65999e0..0c70533 100644
--- a/src/main/java/org/example/QuizBotListener.java
+++ b/src/main/java/org/example/QuizBotListener.java
@@ -26,10 +26,7 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Random;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
public class QuizBotListener implements UpdatesListener {
@@ -41,10 +38,14 @@ public class QuizBotListener implements UpdatesListener {
public QuizBotListener(TelegramBot bot, QuizService quizService) {
this.bot = bot;
this.quizService = quizService;
- this.sessionCache = Cache2kBuilder.of(Long.class, QuizBotSession.class).expireAfterWrite(120, TimeUnit.SECONDS).addListener((CacheEntryExpiredListener) (cache, entry) -> {
- clearLastMessageKeyboard(cache.get(entry.getKey()), entry.getKey());
- sendMessage(entry.getKey(), "You've been thinking too long, so you'll have to start over." + " Write /start or /choice.");
- }).addListener((CacheEntryCreatedListener) (cache, entry) -> sendMessage(entry.getKey(), UserBotConstants.STARTING_MESSAGE)).build();
+ this.sessionCache = Cache2kBuilder.of(Long.class, QuizBotSession.class)
+ .expireAfterWrite(120, TimeUnit.SECONDS)
+ .addListener((CacheEntryExpiredListener) (cache, entry) -> {
+ clearLastMessageKeyboard(cache.get(entry.getKey()), entry.getKey());
+ sendMessage(entry.getKey(), "You've been thinking too long, so you'll have " +
+ "to start over." + " Write /start or /choice.");
+ })
+ .build();
}
@Override
@@ -60,73 +61,84 @@ public int process(List updates) throws NullPointerException {
Message message = update.message();
Long userId = message.chat().id();
String messageText = message.text();
- QuizBotSession quizBotSession = sessionCache.computeIfAbsent(userId, () -> new QuizBotSession(QuizBotSessionMode.SESSION_CREATED));
- //todo start here
+ QuizBotSession quizBotSession = sessionCache.computeIfAbsent(userId,
+ () -> new QuizBotSession(QuizBotSessionMode.SESSION_CREATED));
+ switch (quizBotSession.getBotSessionMode()) {
+ case TOPIC_CHOICE -> {
+ if (messageText.equals(UserBotConstants.CANCEL_COMMAND)) {
+ quizBotSession.setBotSessionMode(QuizBotSessionMode.SESSION_CREATED);
+ sendMessage(userId, UserBotConstants.STARTING_MESSAGE);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+ choiceTopic(messageText, quizBotSession, userId);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+ case QUIZ -> {
+ if (messageText.equals(UserBotConstants.CANCEL_COMMAND)) {
+ clearLastMessageKeyboard(quizBotSession, userId);
+ sendStatsCanceledQuiz(userId, quizBotSession);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+ sendMessage(userId, "Please finish this quiz");
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+
+ case QUESTION_COUNT_CHOICE -> {
+ if (messageText.equals(UserBotConstants.CANCEL_COMMAND)) {
+ quizBotSession.setBotSessionMode(QuizBotSessionMode.SESSION_CREATED);
+ sendMessage(userId, UserBotConstants.STARTING_MESSAGE);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+ setCountOfQuiz(messageText, userId, quizBotSession);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
+ }
+ }
+
switch (messageText) {
case UserBotConstants.START_BOT_COMMAND -> {
clearLastMessageKeyboard(quizBotSession, userId);
+ sendMessage(userId, UserBotConstants.STARTING_MESSAGE);
sessionCache.remove(userId);
sessionCache.put(userId, new QuizBotSession(QuizBotSessionMode.SESSION_CREATED));
return UpdatesListener.CONFIRMED_UPDATES_ALL;
}
- case UserBotConstants.CHOOSE_TOPIC_COMMAND -> {
- UserQuizSession userQuizSession = quizBotSession.getUserQuizSession();
- if (userQuizSession != null) {
- sendMessage(userId, "Please finish this quiz");
- break;
- }
- sendTopics(userId, quizBotSession);
- }
+ case UserBotConstants.CHOOSE_TOPIC_COMMAND -> sendTopics(userId, quizBotSession);
case UserBotConstants.START_QUIZ_COMMAND -> {
- UserQuizSession userQuizSession = quizBotSession.getUserQuizSession();
- if (userQuizSession != null) {
- sendMessage(userId, "Please finish this quiz");
- break;
- }
String currentTopicName = quizBotSession.getCurrentTopicName();
- if (currentTopicName == null) {
- sendMessage(userId, "Topic is not chosen, please use " + UserBotConstants.CHOOSE_TOPIC_COMMAND + " command to choose");
- break;
- }
- if (quizBotSession.getBotSessionMode().equals(QuizBotSessionMode.QUESTION_COUNT_CHOICE)) {
- sendMessage(userId, "You are not chosen quiz");
- break;
+ if (currentTopicName.isEmpty()) {
+ sendMessage(userId, "Pleas choice topic " + UserBotConstants.CHOOSE_TOPIC_COMMAND);
+ return UpdatesListener.CONFIRMED_UPDATES_ALL;
}
-
- userQuizSession = new UserQuizSession(getGeneratedQuiz(currentTopicName, quizBotSession));
+ int countOfQuestion = quizBotSession.getCountOfQuestion();
+ QuizQuestions quizQuestions = quizService.findRandomQuestionsByTopicName(currentTopicName, countOfQuestion);
+ UserQuizSession userQuizSession = new UserQuizSession(quizQuestions);
+ sendMessage(userId, "Quiz: " + currentTopicName);
quizBotSession.setUserQuizSession(userQuizSession);
- sendMessage(userId, "Quiz: " + quizBotSession.getCurrentTopicName());
- quizBotSession.setBotSessionMode(QuizBotSessionMode.QUIZ);
sendQuestion(userId, quizBotSession);
+ quizBotSession.setBotSessionMode(QuizBotSessionMode.QUIZ);
}
- case UserBotConstants.CANCEL_COMMAND -> {
- UserQuizSession userQuizSession = quizBotSession.getUserQuizSession();
- if (userQuizSession == null) {
- sendMessage(userId, "You aren't begin quiz");
- break;
- }
- clearLastMessageKeyboard(quizBotSession, userId);
- sendStatsCanceledQuiz(userId, quizBotSession);
- }
- }
-
- if (messageText.matches("^[1-9][0-9]*$")) {
- if (quizBotSession.getBotSessionMode().equals(QuizBotSessionMode.QUESTION_COUNT_CHOICE)) {
- setCountOfQuiz(messageText, userId, quizBotSession);
- }
- if (quizBotSession.getBotSessionMode().equals(QuizBotSessionMode.TOPIC_CHOICE)) {
- choiceTopic(messageText, quizBotSession, userId);
- }
+ case UserBotConstants.CANCEL_COMMAND -> sendMessage(userId, "Nothing canceled");
+ default -> sendMessage(userId, "Input a valid command");
}
- return UpdatesListener.CONFIRMED_UPDATES_ALL;
} catch (Exception e) {
log.error(e.getMessage());
}
-
return UpdatesListener.CONFIRMED_UPDATES_ALL;
}
+ private static String getQuizStatText(int quizAmount, int rightAnswerCounter) {
+ return String.format("❓ Question number: %d" + "\n\n" + "✅ Right answers: %d\\%d" + "\n\n" + "Input " + UserBotConstants.START_QUIZ_COMMAND + " to start quiz or chose quiz another quiz " + UserBotConstants.CHOOSE_TOPIC_COMMAND, quizAmount, rightAnswerCounter, quizAmount);
+ }
+
+ private static String getCanceledQuizStatText(int questionCount, int rightAnswerCounter) {
+ return String.format("❓You canceled quiz\n" + "\n" + "The questions were: %d\n\n" + "✅ Right answers: %d\\%d\n" + "\n" + "Input " + UserBotConstants.START_QUIZ_COMMAND + " to start quiz or chose quiz another quiz " + UserBotConstants.CHOOSE_TOPIC_COMMAND, questionCount, rightAnswerCounter, questionCount);
+ }
+
private void setCountOfQuiz(String messageText, Long userId, QuizBotSession quizBotSession) {
+ if (!messageText.matches("^[1-9][0-9]*$")) {
+ sendMessage(userId, "Input a number or input " + UserBotConstants.CANCEL_COMMAND + " for cancel count of question choice");
+ return;
+ }
int countOfQuestions = Integer.parseInt(messageText);
if (countOfQuestions > 20 || countOfQuestions < 5) {
sendMessage(userId, "Input valid count of question");
@@ -136,33 +148,6 @@ private void setCountOfQuiz(String messageText, Long userId, QuizBotSession quiz
quizBotSession.setBotSessionMode(QuizBotSessionMode.SESSION_CREATED);
}
- private QuizQuestions getGeneratedQuiz(String currentTopicName, QuizBotSession quizBotSession) {
- QuizQuestions quizQuestions = quizService.findByTopicName(currentTopicName);
- List questionList = quizQuestions.getQuestionList();
- int countOfQuestion = quizBotSession.getCountOfQuestion();
- if (questionList.size() <= countOfQuestion) {
- return quizQuestions;
- }
- QuizQuestions generatedQuizQuestions = new QuizQuestions();
- List generatedQuestionList = new ArrayList<>();
- Set uniqueNumbers = getUniqueNums(questionList.size() - 1, countOfQuestion);
- for (Integer i : uniqueNumbers) {
- generatedQuestionList.add(questionList.get(i));
- }
- generatedQuizQuestions.setQuestionList(generatedQuestionList);
- generatedQuizQuestions.setTopicName(quizQuestions.getTopicName());
- return generatedQuizQuestions;
- }
-
- private Set getUniqueNums(int max, int count) {
- Set uniqueNums = new HashSet<>();
- Random random = new Random();
- while (count > uniqueNums.size()) {
- uniqueNums.add(random.nextInt(max));
- }
- return uniqueNums;
- }
-
private void sendMessage(Long userId, String s) {
bot.execute(new SendMessage(userId, s));
}
@@ -289,26 +274,24 @@ private InlineKeyboardMarkup buildInlineKeyboard(int keyboardLength) {
}
private void choiceTopic(String messageText, QuizBotSession quizBotSession, Long userId) {
+ if (!messageText.matches("^[1-9][0-9]*$")) {
+ sendMessage(userId, "Input a number or input " + UserBotConstants.CANCEL_COMMAND + " for cancel topic choice");
+ return;
+ }
int topicIndex = Integer.parseInt(messageText) - 1;
List allTopicName = quizService.getTopics();
if (allTopicName.isEmpty()) {
-
quizBotSession.setBotSessionMode(QuizBotSessionMode.SESSION_CREATED);
sendMessage(userId, "Sorry nothing quiz, send " + UserBotConstants.CHOOSE_TOPIC_COMMAND + " for choice quiz");
return;
}
- if (topicIndex >= allTopicName.size()) {
- sendMessage(userId, "You input over large digital, send me correct digital");
- sendTopics(userId, quizBotSession);
- return;
- } else if (topicIndex < 0) {
- sendMessage(userId, "You input so small digital, send me correct digital");
+ if (topicIndex >= allTopicName.size() || topicIndex < 0) {
+ sendMessage(userId, "Send me correct digital from 1 to " + allTopicName.size());
sendTopics(userId, quizBotSession);
return;
}
String currentTopicName = allTopicName.get(topicIndex);
quizBotSession.setCurrentTopicName(currentTopicName);
- quizBotSession.setCurrentQuiz(quizService.findByTopicName(currentTopicName));
quizBotSession.setBotSessionMode(QuizBotSessionMode.QUESTION_COUNT_CHOICE);
sendMessage(userId, "Input count to your quiz (at 5 to 20)");
}
@@ -322,14 +305,6 @@ private void clearLastMessageKeyboard(QuizBotSession quizBotSession, Long userId
bot.execute(editMessage);
}
- private static String getQuizStatText(int quizAmount, int rightAnswerCounter) {
- return String.format("❓ Question number: %d" + "\n\n" + "✅ Right answers: %d\\%d" + "\n\n" + "Input " + UserBotConstants.START_QUIZ_COMMAND + " to start quiz or chose quiz another quiz " + UserBotConstants.CHOOSE_TOPIC_COMMAND, quizAmount, rightAnswerCounter, quizAmount);
- }
-
- private static String getCanceledQuizStatText(int questionCount, int rightAnswerCounter) {
- return String.format("❓You canceled quiz\n" + "\n" + "The questions were: %d\n\n" + "✅ Right answers: %d\\%d\n" + "\n" + "Input " + UserBotConstants.START_QUIZ_COMMAND + " to start quiz or chose quiz another quiz " + UserBotConstants.CHOOSE_TOPIC_COMMAND, questionCount, rightAnswerCounter, questionCount);
- }
-
private String getAnswerText(UserQuizSession userQuizSession, int userAnswerNum) {
Question question = userQuizSession.getCurrentQuestion();
List optionsList = question.getOptionList();
diff --git a/src/main/java/org/example/configs/MongoDBConfig.java b/src/main/java/org/example/configs/MongoDBConfig.java
index de2d7af..432a600 100644
--- a/src/main/java/org/example/configs/MongoDBConfig.java
+++ b/src/main/java/org/example/configs/MongoDBConfig.java
@@ -1,8 +1,16 @@
package org.example.configs;
+
import com.mongodb.ConnectionString;
+import com.mongodb.client.ChangeStreamIterable;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Aggregates;
+import com.mongodb.client.model.Filters;
+import org.bson.Document;
+import org.bson.conversions.Bson;
+import org.example.services.QuizService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@@ -10,20 +18,25 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
+import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+import java.util.Arrays;
+import java.util.List;
+
@Configuration
@ComponentScan(basePackages = "org.example")
@PropertySource("classpath:application.properties")
@EnableMongoRepositories("org.example.repositories")
public class MongoDBConfig extends AbstractMongoClientConfiguration {
-
@Value("${spring.data.mongodb.database}")
private String databaseName;
+
@Value("${spring.data.mongodb.uri}")
private String connectionUri;
+
@NotNull
@Override
protected String getDatabaseName() {
@@ -37,9 +50,28 @@ public MongoClient mongoClient() {
return MongoClients.create(new ConnectionString(connectionUri));
}
- public MongoClient reconnectToDB() {
- MongoClient currentClient = mongoClient();
- currentClient.close();
- return MongoClients.create(new ConnectionString(connectionUri));
+ @Bean
+ public ChangeStreamIterable runEventListener(MongoTemplate mongoTemplate, QuizService quizService) {
+ MongoCollection collection = mongoTemplate.getCollection("quizQuestions");
+ List pipeline = List.of(
+ Aggregates.match(Filters.in("operationType", Arrays.asList("insert", "delete"))));
+ ChangeStreamIterable changeStream = collection.watch(pipeline);
+ changeStream.forEach(event -> {
+ String operationType = event.getOperationTypeString();
+ if (operationType == null) {
+ return;
+ }
+
+ switch (operationType) {
+ case "insert" -> {
+ Document document = event.getFullDocument();
+ if (document != null && document.containsKey("topicName")) {
+ quizService.addTopic(document.getString("topicName"));
+ }
+ }
+ case "delete" -> quizService.updateTopics();
+ }
+ });
+ return changeStream;
}
}
diff --git a/src/main/java/org/example/model/PermanentUserInfo.java b/src/main/java/org/example/model/PermanentUserInfo.java
index 582c5e3..30024e7 100644
--- a/src/main/java/org/example/model/PermanentUserInfo.java
+++ b/src/main/java/org/example/model/PermanentUserInfo.java
@@ -3,25 +3,21 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
-import org.springframework.data.redis.core.RedisHash;
@Document
public class PermanentUserInfo {
@Id
@Field(name = "userId")
- private Long userId;
+ private Long userId = 0L;
@Field(name = "userName")
- private String userName;
- @Field(name = "isAdmin")
- private boolean isAdmin = false;
+ private String userName = "";
public PermanentUserInfo() {
}
- public PermanentUserInfo(String userName, Long userId, boolean isAdmin) {
+ public PermanentUserInfo(String userName, Long userId) {
this.userName = userName;
this.userId = userId;
- this.isAdmin = isAdmin;
}
public String getUserName() {
@@ -40,11 +36,4 @@ public void setUserId(Long userId) {
this.userId = userId;
}
- public boolean getIsAdmin() {
- return isAdmin;
- }
-
- public void setAdmin(boolean admin) {
- isAdmin = admin;
- }
}
diff --git a/src/main/java/org/example/model/Question.java b/src/main/java/org/example/model/Question.java
index 421b7fa..ab30262 100644
--- a/src/main/java/org/example/model/Question.java
+++ b/src/main/java/org/example/model/Question.java
@@ -12,7 +12,7 @@
public class Question {
@Id
@JsonIgnore
- private ObjectId id;
+ private ObjectId id = new ObjectId();
private String question = "";
private String answerDescription = "";
private List optionList = new ArrayList<>();
diff --git a/src/main/java/org/example/model/QuizBotSession.java b/src/main/java/org/example/model/QuizBotSession.java
index 9d31329..65fff0e 100644
--- a/src/main/java/org/example/model/QuizBotSession.java
+++ b/src/main/java/org/example/model/QuizBotSession.java
@@ -5,11 +5,10 @@
public class QuizBotSession {
private QuizBotSessionMode botSessionMode;
- private QuizQuestions currentQuizQuestions;
private UserQuizSession userQuizSession;
- private String currentTopicName;
+ private String currentTopicName = "";
private int lastKeyboardBotMessageId = 0;
- private String lastKeyboardBotMessageText;
+ private String lastKeyboardBotMessageText ="";
private int countOfQuestion = 0;
public QuizBotSession(QuizBotSessionMode botSessionMode) {
@@ -48,13 +47,6 @@ public void setLastKeyboardBotMessageText(String lastKeyboardBotMessageText) {
this.lastKeyboardBotMessageText = lastKeyboardBotMessageText;
}
- public QuizQuestions getCurrentQuiz() {
- return currentQuizQuestions;
- }
-
- public void setCurrentQuiz(QuizQuestions currentQuizQuestions) {
- this.currentQuizQuestions = currentQuizQuestions;
- }
public int getCountOfQuestion() {
return countOfQuestion;
diff --git a/src/main/java/org/example/repositories/QuizRepo.java b/src/main/java/org/example/repositories/QuizRepo.java
index 07336eb..5c2d55b 100644
--- a/src/main/java/org/example/repositories/QuizRepo.java
+++ b/src/main/java/org/example/repositories/QuizRepo.java
@@ -1,27 +1,29 @@
package org.example.repositories;
-import org.example.model.Question;
import org.example.model.QuizQuestions;
-import org.springframework.data.mongodb.repository.DeleteQuery;
+import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
-import org.springframework.data.mongodb.repository.Update;
import org.springframework.stereotype.Repository;
-import java.util.List;
-
@Repository
public interface QuizRepo extends MongoRepository {
- @Query(value = "{}", fields = "{ 'topicName' : 1, '_id' : 0 }")
- List findAllTopicName();
@Query("{'topicName' : ?0}")
QuizQuestions findByTopicName(String topicName);
- @DeleteQuery("{'topicName' : ?0}")
- void deleteByTopicName(String topicName);
+ @Aggregation({"{ $match: { topicName: ?0 } }",
+ "{ $project: {topicName: 1,questionList: 1,_class: 1} }",
+ "{ $unwind: \"$questionList\" }",
+ "{ $sample: { size: ?1 } }",
+ "{ $group: {_id: \"$_id\", topicName:{$first:\"$topicName\"},questionList: { $push: \"$questionList\" },_class:{$first:\"$_class\"}} }",
+ })
+ QuizQuestions findRandomQuestionsByTopicName(String topicName, int n);
- @Query("{'topicName' : ?0}")
- @Update("{$push : {'questionList' : {$each : ?1}}}")
- void addByTopic(String topicName, List questionList);
+ @Aggregation({
+ "{$project: {_id: 0,topicName: 1}}",
+ "{$group: {_id: 0,topicName: { $push: \"$topicName\" }}}",
+ "{$project: {topicName: 1,_id: 0}}"
+ })
+ String findAllTopic();
}
diff --git a/src/main/java/org/example/services/QuizService.java b/src/main/java/org/example/services/QuizService.java
index 4dbb92d..d1ba491 100644
--- a/src/main/java/org/example/services/QuizService.java
+++ b/src/main/java/org/example/services/QuizService.java
@@ -1,51 +1,55 @@
package org.example.services;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import org.cache2k.Cache;
+import org.cache2k.Cache2kBuilder;
import org.example.model.QuizQuestions;
import org.example.repositories.QuizRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
-import java.util.stream.Collectors;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
@Service
public class QuizService {
- private static List topics = new ArrayList<>();
+ private final Lock lock = new ReentrantLock();
+ private final Cache> topicsCache;
private final QuizRepo quizRepo;
@Autowired
public QuizService(QuizRepo quizRepo) {
this.quizRepo = quizRepo;
- topics = quizRepo.findAllTopicName();
+ topicsCache = new Cache2kBuilder>() {}
+ .eternal(true)
+ .build();
+ List topics = Arrays.stream(quizRepo.findAllTopic().split(",")).toList();
+ topicsCache.put("topics", topics);
}
public List getTopics() {
- ObjectMapper objectMapper = new ObjectMapper();
- List topic = quizRepo.findAllTopicName();
- if (topic == null) {
- return List.of();
- }
- return topics = topic.stream().map(string -> {
- try {
- JsonNode jsonNode = objectMapper.readTree(string);
- return jsonNode.get("topicName").asText();
- } catch (JsonProcessingException e) {
- throw new RuntimeException(e);
- }
- }).collect(Collectors.toList());
+ return topicsCache.get("topics");
}
- public void deleteAllQuiz() {
- topics = new ArrayList<>();
- quizRepo.deleteAll();
+ public void addTopic(String topicName){
+ lock.lock();
+ try {
+ List topics = new ArrayList<>(topicsCache.get("topics"));
+ topics.add(topicName);
+ topicsCache.put("topics", topics);
+ } finally {
+ lock.unlock();
+ }
}
- public QuizQuestions findByTopicName(String topicName) {
- return quizRepo.findByTopicName(topicName);
+ public QuizQuestions findRandomQuestionsByTopicName(String topicName, int count) {
+ return quizRepo.findRandomQuestionsByTopicName(topicName, count);
}
+ public void updateTopics(){
+ List topics = Arrays.stream(quizRepo.findAllTopic().split(",")).toList();
+ topicsCache.put("topics", topics);
+ }
}
diff --git a/src/main/java/org/example/services/UsersService.java b/src/main/java/org/example/services/UsersService.java
index 5d3f4dd..aa7d407 100644
--- a/src/main/java/org/example/services/UsersService.java
+++ b/src/main/java/org/example/services/UsersService.java
@@ -15,7 +15,7 @@ public UsersService(UserRepo userRepo) {
}
public PermanentUserInfo addNewUser(String userName, Long userId) {
- PermanentUserInfo permanentUserInfo = new PermanentUserInfo(userName, userId, false);
+ PermanentUserInfo permanentUserInfo = new PermanentUserInfo(userName, userId);
userRepo.insert(permanentUserInfo);
return permanentUserInfo;
}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 23c259b..50077b1 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -8,7 +8,7 @@
-
+
@@ -17,6 +17,5 @@
-
diff --git a/src/main/resources/topics b/src/main/resources/topics
deleted file mode 100644
index 72581d0..0000000
--- a/src/main/resources/topics
+++ /dev/null
@@ -1,4 +0,0 @@
-Python Programming
-Spring Framework
-Java Programming
-CSS (Cascading Style Sheets)
diff --git a/src/test/java/org/example/QuizQuestionsBotListenerTest.java b/src/test/java/org/example/QuizQuestionsBotListenerTest.java
deleted file mode 100644
index 29d8443..0000000
--- a/src/test/java/org/example/QuizQuestionsBotListenerTest.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.example;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-class QuizQuestionsBotListenerTest {
- private QuizBotListener quizBotListener;
-
- @BeforeEach
- void setUp() {
- }
-
- @Test
- void process() {
-
- }
-
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/model/QuestionOptionTest.java b/src/test/java/org/example/model/QuestionOptionTest.java
deleted file mode 100644
index 30890be..0000000
--- a/src/test/java/org/example/model/QuestionOptionTest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.example.model;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class QuestionOptionTest {
-
- @Test
- void getOptionText() {
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/model/QuestionTest.java b/src/test/java/org/example/model/QuestionTest.java
deleted file mode 100644
index 4b5c04c..0000000
--- a/src/test/java/org/example/model/QuestionTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.example.model;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-class QuestionTest {
- private Question question;
-
- @BeforeEach
- void setUp() {
- question = new Question();
- }
-
- @Test
- void getQuestion() {
- Assertions.assertNotNull(question.getQuestion());
- }
-
- @Test
- void getAnswerDescription() {
- Assertions.assertNotNull(question.getAnswerDescription());
- }
-
- @Test
- void getOptionList() {
- Assertions.assertNotNull(question.getOptionList());
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/model/QuizQuestionsSessionTest.java b/src/test/java/org/example/model/QuizQuestionsSessionTest.java
deleted file mode 100644
index 71aae85..0000000
--- a/src/test/java/org/example/model/QuizQuestionsSessionTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.example.model;
-
-import org.junit.jupiter.api.BeforeEach;
-
-class QuizQuestionsSessionTest {
- private QuizBotSession quizBotSession;
-
- @BeforeEach
- void setUp() {
- quizBotSession = new QuizBotSession();
- }
-
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/model/QuizQuestionsTest.java b/src/test/java/org/example/model/QuizQuestionsTest.java
deleted file mode 100644
index e1cc12b..0000000
--- a/src/test/java/org/example/model/QuizQuestionsTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.example.model;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-class QuizQuestionsTest {
- private QuizQuestions quizQuestions;
-
- @BeforeEach
- void setUp() {
- quizQuestions = new QuizQuestions();
- }
-
- @Test
- void getTopicName() {
- assertNotNull(quizQuestions.getTopicName());
- }
-
- @Test
- void setTopicName() {
- quizQuestions.setTopicName(null);
- Assertions.assertNotNull(quizQuestions.getTopicName());
- quizQuestions.setTopicName("java");
- Assertions.assertEquals(quizQuestions.getTopicName(),"java");
- }
-
- @Test
- void getQuestionList() {
- assertNotNull(quizQuestions.getQuestionList());
- }
-
- @Test
- void setQuestionList() {
- List questionList = new ArrayList<>();
- quizQuestions.setQuestionList(questionList);
- Assertions.assertEquals(quizQuestions.getQuestionList(),questionList);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/example/model/UserQuizQuestionsSessionTest.java b/src/test/java/org/example/model/UserQuizQuestionsSessionTest.java
deleted file mode 100644
index 08f0e89..0000000
--- a/src/test/java/org/example/model/UserQuizQuestionsSessionTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.example.model;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-class UserQuizQuestionsSessionTest {
- private UserQuizSession userQuizSession;
- private Question question1;
- private Question question2;
-
- @BeforeEach
- public void setUp() {
- List questionList = new ArrayList<>();
- question1 = new Question("asddsasda",new ArrayList<>(),"asdsdasd");
- question2 = new Question("asddsasdsssa",new ArrayList<>(),"asdsdasd");
- questionList.add(question1);
- questionList.add(question2);
- QuizQuestions quizQuestions = new QuizQuestions();
- quizQuestions.setQuestionList(questionList);
- userQuizSession = new UserQuizSession(quizQuestions);
- }
-
- @Test
- void isNextQuestionAvailable(){
- Assertions.assertTrue(userQuizSession.isNextQuestionAvailable());
- }
-
- @Test
- void isNextQuestionNotAvailable() {
- userQuizSession = new UserQuizSession(new QuizQuestions());
- Assertions.assertFalse(userQuizSession.isNextQuestionAvailable());
- }
-
- @Test
- void incRightCounter() {
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),0);
- userQuizSession.incRightCounter();
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),1);
- }
-
- @Test
- void getCurrentQuestion() {
- Assertions.assertNull(userQuizSession.getCurrentQuestionIndex());
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getCurrentQuestionIndex(), question1);
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getCurrentQuestionIndex(), question2);
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getCurrentQuestionIndex(), question2);
- }
-
- @Test
- void getNextQuestion() {
- Assertions.assertEquals(userQuizSession.getNextQuestion(), question1);
- Assertions.assertEquals(userQuizSession.getNextQuestion(), question2);
- }
-
- @Test
- void getQuestionCounter() {
- Assertions.assertEquals(userQuizSession.getQuestionCounter(),0);
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getQuestionCounter(),1);
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getQuestionCounter(),2);
- userQuizSession.getNextQuestion();
- Assertions.assertEquals(userQuizSession.getQuestionCounter(),2);
- }
-
- @Test
- void getQuestionAmount() {
- Assertions.assertEquals(userQuizSession.getQuestionAmount(),2);
- }
-
- @Test
- void getRightAnswerCounter() {
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),0);
- userQuizSession.incRightCounter();
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),1);
- userQuizSession.incRightCounter();
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),2);
- userQuizSession.incRightCounter();
- Assertions.assertEquals(userQuizSession.getRightAnswerCounter(),2);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/services/QuizServiceTest.java b/src/test/java/services/QuizServiceTest.java
new file mode 100644
index 0000000..04e00ed
--- /dev/null
+++ b/src/test/java/services/QuizServiceTest.java
@@ -0,0 +1,5 @@
+package services;
+
+public class QuizServiceTest {
+
+}
diff --git a/src/test/java/services/UsersService.java b/src/test/java/services/UsersService.java
new file mode 100644
index 0000000..9842eee
--- /dev/null
+++ b/src/test/java/services/UsersService.java
@@ -0,0 +1,4 @@
+package services;
+
+public class UsersService {
+}