Sfoglia il codice sorgente

стейты наконец-то заработали нормально, отвечают нормально, в нужной последовательности

kpmy 8 anni fa
parent
commit
2b8bdee274

+ 1 - 1
.drone.yml

@@ -3,7 +3,7 @@ pipeline:
     image: plugins/git
     links:
       - gogs
-  test:
+  build:
     image: maven:3.3.9-jdk-8
     commands:
       - mvn package

+ 1 - 1
README.md

@@ -1,3 +1,3 @@
-# these-days-backend
+# these-days-backend [![Build Status](http://o.ocsf.in:18000/api/badges/these-days/these-days-backend/status.svg)](http://o.ocsf.in:18000/these-days/these-days-backend)
 
 0) монга `docker run --name these_days_mongo -d -p 127.0.0.1:27017:27017 mongo:3.4`

+ 2 - 2
src/main/java/in/ocsf/these/days/app/messaging/ChatListener.java

@@ -67,7 +67,7 @@ public class ChatListener {
         });
     }
 
-    @Scheduled(fixedDelay = 1000)
+    @Scheduled(fixedDelay = 500)
     protected void doRequest() {
         TelegramBot bot = TelegramBotAdapter.build(token);
 
@@ -83,10 +83,10 @@ public class ChatListener {
                         response.updates().stream().forEach(u -> {
                             if (u.updateId() > state.getUpdateId()) {
                                 state.setUpdateId(Long.valueOf(u.updateId()));
+                                stateRepo.save(state);
                                 update(u);
                             }
                         });
-                    stateRepo.save(state);
                 } else {
                     throw new RuntimeException("response not ok");
                 }

+ 4 - 1
src/main/java/in/ocsf/these/days/app/object/Card.java

@@ -1,14 +1,17 @@
 package in.ocsf.these.days.app.object;/* kpmy 20.02.2017 */
 
+import org.bson.types.ObjectId;
 import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
 
 @Document(collection = "card")
 public class Card {
 
     @Id
-    private Long id;
+    private ObjectId id;
 
+    @DBRef
     private User user;
 
     public User getUser() {

+ 2 - 1
src/main/java/in/ocsf/these/days/app/repo/CardRepositrory.java

@@ -1,12 +1,13 @@
 package in.ocsf.these.days.app.repo;/* kpmy 20.02.2017 */
 
 import in.ocsf.these.days.app.object.Card;
+import org.bson.types.ObjectId;
 import org.springframework.data.mongodb.repository.MongoRepository;
 import org.springframework.data.rest.core.annotation.RepositoryRestResource;
 
 import java.util.Optional;
 
 @RepositoryRestResource(exported = false)
-public interface CardRepositrory extends MongoRepository<Card, Long> {
+public interface CardRepositrory extends MongoRepository<Card, ObjectId> {
     Optional<Card> findFirstByUserId(Long id);
 }

+ 1 - 1
src/main/java/in/ocsf/these/days/app/service/UpdateService.java

@@ -62,7 +62,7 @@ public class UpdateService {
             Optional<Chat> chat0 = chatRepo.findByUserIdAndStateThenActualize(user.getId());
             chat0.ifPresent(c -> {
                 StateMachine chatState = stateService.getChatStateFor(c);
-                stateService.put(chatState, upd);
+                stateService.inherit(state, chatState);
                 stateService.put(chatState, IChat.CHAT, c.getId());
                 IChat chat = context.getBean(c.getType().getBean());
                 chat.handle(chatState);

+ 1 - 0
src/main/java/in/ocsf/these/days/app/state/IChat.java

@@ -7,6 +7,7 @@ public interface IChat<S, E> {
     String CHAT = "CHAT";
     String MESSAGE = "CHATMESSAGE";
     String USER = "USER";
+    String ENTITY = "ENTITY";
 
     default <T> T get(StateMachine machine, String key) {
         return machine.getExtendedState().get(key, (Class<T>) Object.class);

+ 9 - 2
src/main/java/in/ocsf/these/days/app/state/StateService.java

@@ -7,6 +7,7 @@ import in.ocsf.these.days.app.state.account.Accounted;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.ApplicationContext;
+import org.springframework.statemachine.StateContext;
 import org.springframework.statemachine.StateMachine;
 import org.springframework.statemachine.config.StateMachineFactory;
 import org.springframework.statemachine.persist.DefaultStateMachinePersister;
@@ -40,7 +41,6 @@ public class StateService {
     public void setChatStateFor(Chat chat, StateMachine state) {
         StateMachinePersister persist = new DefaultStateMachinePersister(new InChatStateMachinePersist());
         try {
-            state.getExtendedState().getVariables().clear();
             persist.persist(state, chat);
         } catch (Exception e) {
             throw new RuntimeException(e);
@@ -66,7 +66,6 @@ public class StateService {
         StateMachinePersister<Accounted.State, Accounted.Event, User> persist = new DefaultStateMachinePersister<>(new AccountStateMachineFactoryConfig.InUserStateMachinePersist());
 
         try {
-            state.getExtendedState().getVariables().clear();
             persist.persist(state, user);
         } catch (Exception e) {
             throw new RuntimeException(e);
@@ -80,4 +79,12 @@ public class StateService {
     public void put(StateMachine state, String key, Object value) {
         state.getExtendedState().getVariables().put(key, value);
     }
+
+    public void inherit(StateContext old, StateMachine that) {
+        that.getExtendedState().getVariables().putAll(old.getExtendedState().getVariables());
+    }
+
+    public void inherit(StateMachine old, StateMachine that) {
+        that.getExtendedState().getVariables().putAll(old.getExtendedState().getVariables());
+    }
 }

+ 27 - 2
src/main/java/in/ocsf/these/days/app/state/account/Accounted.java

@@ -1,10 +1,13 @@
 package in.ocsf.these.days.app.state.account;/* kpmy 25.02.2017 */
 
+import in.ocsf.these.days.app.object.Card;
 import in.ocsf.these.days.app.object.User;
+import in.ocsf.these.days.app.repo.CardRepositrory;
 import in.ocsf.these.days.app.repo.UserRepository;
 import in.ocsf.these.days.app.state.IChat;
 import in.ocsf.these.days.app.state.IState;
 import in.ocsf.these.days.app.state.StateService;
+import in.ocsf.these.days.app.state.chat.WelcomeChat;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.statemachine.StateContext;
@@ -24,12 +27,19 @@ public class Accounted implements IChat<Accounted.State, Accounted.Event> {
     @Autowired
     private StateService stateService;
 
+    @Autowired
+    private WelcomeChat welcomeChat;
+
+    @Autowired
+    private CardRepositrory cardRepo;
+
     public void unknown(StateContext<State, Event> ctx) {
         //do nothing
     }
 
     public void newbie(StateContext<State, Event> ctx) {
-        log.info("newbie");
+        User user = userRepo.findOne((Long) get(ctx, USER));
+        welcomeChat.startWith(user, get(ctx, MESSAGE));
     }
 
     public void client(StateContext<State, Event> ctx) {
@@ -43,7 +53,7 @@ public class Accounted implements IChat<Accounted.State, Accounted.Event> {
                     case unknown:
                         User user = userRepo.findOne((Long) get(state0, USER));
                         StateMachine<State, Event> state = stateService.getStateFor(user);
-                        stateService.put(state, get(state0, MESSAGE));
+                        stateService.inherit(state0, state);
                         state.sendEvent(Event.start);
                         stateService.setStateFor(user, state);
                         userRepo.save(user);
@@ -52,6 +62,21 @@ public class Accounted implements IChat<Accounted.State, Accounted.Event> {
                         // throw new RuntimeException();
                 }
                 break;
+            case "/_register":
+                switch (state0.getState().getId()) {
+                    case newbie:
+                        User user = userRepo.findOne((Long) get(state0, USER));
+                        StateMachine<State, Event> state = stateService.getStateFor(user);
+                        stateService.inherit(state0, state);
+                        state.sendEvent(Event.init);
+                        stateService.setStateFor(user, state);
+                        userRepo.save(user);
+
+                        Card card = new Card();
+                        card.setUser(user);
+                        cardRepo.save(card);
+                }
+                break;
             default:
                 // throw new RuntimeException();
         }

+ 57 - 3
src/main/java/in/ocsf/these/days/app/state/chat/WelcomeChat.java

@@ -2,15 +2,26 @@ package in.ocsf.these.days.app.state.chat;/* kpmy 22.02.2017 */
 
 import in.ocsf.these.days.app.messaging.ChatHelper;
 import in.ocsf.these.days.app.messaging.UpdateHelper;
+import in.ocsf.these.days.app.object.Chat;
+import in.ocsf.these.days.app.object.ChatState;
+import in.ocsf.these.days.app.object.User;
+import in.ocsf.these.days.app.repo.ChatRepository;
+import in.ocsf.these.days.app.state.ChatType;
 import in.ocsf.these.days.app.state.IChat;
 import in.ocsf.these.days.app.state.IState;
+import in.ocsf.these.days.app.state.StateService;
+import in.ocsf.these.days.app.state.account.Accounted;
 import in.ocsf.these.days.app.state.utils.MessageTemplate;
 import org.apache.log4j.Logger;
+import org.bson.types.ObjectId;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.statemachine.StateContext;
 import org.springframework.statemachine.StateMachine;
 import org.springframework.stereotype.Service;
 
+import java.util.Arrays;
+
 @Service
 public class WelcomeChat implements IChat<WelcomeChat.State, WelcomeChat.Event> {
 
@@ -21,23 +32,66 @@ public class WelcomeChat implements IChat<WelcomeChat.State, WelcomeChat.Event>
     @Autowired
     private ChatHelper chatHelper;
 
+    @Autowired
+    private StateService stateService;
+
+    @Autowired
+    private ChatRepository chatRepo;
+
+    @Autowired
+    @Lazy
+    private Accounted accounted;
+
     public void hello(StateContext<State, Event> ctx) {
-        UpdateHelper upd = ctx.getExtendedState().get(IChat.MESSAGE, UpdateHelper.class);
+        UpdateHelper upd = get(ctx, IChat.MESSAGE);
         chatHelper.sendSimpleTextMessage(upd.getChatId(), helloMsg.render());
     }
 
     public void ask(StateContext<State, Event> ctx) {
-        UpdateHelper upd = ctx.getExtendedState().get(IChat.MESSAGE, UpdateHelper.class);
+        UpdateHelper upd = get(ctx, IChat.MESSAGE);
         chatHelper.sendSimpleTextMessage(upd.getChatId(), "Как дела?");
     }
 
     public void goodbye(StateContext<State, Event> ctx) {
-        log.info("hello");
+        UpdateHelper upd = get(ctx, IChat.MESSAGE);
+        chatHelper.sendSimpleTextMessage(upd.getChatId(), "Ну пока...");
+        Chat chat = get(ctx, IChat.ENTITY);
+        chat.setState(ChatState.closed);
+
+        StateMachine userState = stateService.getStateFor(chat.getUser());
+        stateService.inherit(ctx, userState);
+        accounted.handleCommand(Arrays.asList("/_register"), userState);
     }
 
     @Override
     public void handle(StateMachine<State, Event> state) {
+        Chat chat = chatRepo.findOne(new ObjectId((String) get(state, CHAT)));
+        StateMachine<WelcomeChat.State, WelcomeChat.Event> chatState = stateService.getChatStateFor(chat);
+        stateService.inherit(state, chatState);
+        stateService.put(chatState, IChat.ENTITY, chat);
+        switch (chatState.getState().getId()) {
+            case hello:
+                chatState.sendEvent(Event.reply);
+                break;
+            case ask:
+                chatState.sendEvent(Event.answer);
+            default:
+
+        }
+        stateService.setChatStateFor(chat, chatState);
+        chatRepo.save(chat);
+    }
 
+    public void startWith(User user, UpdateHelper upd) {
+        Chat chat = new Chat();
+        chat.setUser(user);
+        chat.setType(ChatType.welcome);
+        StateMachine<WelcomeChat.State, WelcomeChat.Event> chatState = stateService.getChatStateFor(chat);
+        stateService.put(chatState, upd);
+        stateService.put(chatState, IChat.ENTITY, chat);
+        chatState.start();
+        stateService.setChatStateFor(chat, chatState);
+        chatRepo.save(chat);
     }
 
     public enum Event {

+ 4 - 0
src/main/java/in/ocsf/these/days/app/state/utils/BeanMapPersist.java

@@ -4,14 +4,18 @@ import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.statemachine.StateMachineContext;
 
+import java.util.HashMap;
 import java.util.Map;
 
 public interface BeanMapPersist {
 
     default Map<String, Object> toMap(StateMachineContext context) throws Exception {
         ObjectMapper oMapper = new ObjectMapper();
+        Map tmp = new HashMap(context.getExtendedState().getVariables());
+        context.getExtendedState().getVariables().clear();
         Map<String, Object> map = oMapper.convertValue(context, Map.class);
         map.remove("extendedState");
+        context.getExtendedState().getVariables().putAll(tmp);
         return map;
     }
 

+ 1 - 0
src/main/java/in/ocsf/these/days/app/state/utils/InvokeBeanMethodAction.java

@@ -32,6 +32,7 @@ public class InvokeBeanMethodAction<S, E> implements Action<S, E> {
             invokingBean.prepare();
             invokingBean.invoke();
         } catch (Exception e) {
+            e.printStackTrace();
             throw new RuntimeException(e);
         }
     }

+ 3 - 0
src/main/resources/application-prod.properties

@@ -0,0 +1,3 @@
+spring.data.mongodb.uri=mongodb://localhost:27017/these-days
+spring.data.rest.base-path=/api
+these-days.bot.token=369702745:AAG12AwPVNT1lA2ZePFNOrqlqj48VamYKSc