JavaRush /Java блогы /Random-KK /Мақалаға клиент қосу - «A-дан Я-ға дейінгі Java жобасы»
Roman Beekeeper
Деңгей

Мақалаға клиент қосу - «A-дан Я-ға дейінгі Java жобасы»

Топта жарияланған
Баршаңызға сәлем, қымбатты достарым. Біз бірте-бірте мақсатымызға жақындап келеміз - жобамыздың MVP - JavaRush Telegram боты болу. Өткен мақалада айтқанымдай, бар болғаны 5 тапсырма қалды. Бүгін біз олардың екеуін қарастырамыз. «А-дан Я-ға Java жобасы»: Мақалаға клиент қосу – 1Тағы да айтқым келеді, жоба мұнымен бітпейді. Менде бұл жобаның қалай дамуы керек, оған қандай жаңа нәрселер қосуға болады, нені жақсырақ жасауға болады деген көптеген идеялар мен көзқарастар бар. MVP алдында біз рефакторинг тақырыбына жеке мақала жасаймыз, яғни codeтың сапасын оның функционалдығын өзгертпей жақсарту туралы. Осы уақытқа дейін бүкіл жоба көрініп, нені және қай жерде жақсартуға болатыны белгілі болады. Біздің жағдайда біз функционалдылықты бұзудан барынша қорғалған боламыз, өйткені көптеген сынақтар жазылған. Біз сондай-ақ біз не қалайтынымыз және соңында не алғанымыз туралы ретроспективаны жазамыз. Бұл өте пайдалы нәрсе: алты ай бұрын бәрі қаншалықты дұрыс көрінгенін көрейік. Кем дегенде, бұл маған өте қызықты. Егер кімде-кім өзін қолмен сынаушы ретінде сынап көргісі келсе, бізге жазыңыз, біз бірлесіп жұмыс істейміз. Бұл жобаны бірге жақсартайық! Сонымен, олар мыналар: алты ай бұрын сипатталған екі тапсырма: JRTB-8 және JRTB-9 . Мен осы тапсырмаларды орындау үшін не қажет екенін қарастыра бастадым және командаларды іске қосу тұрғысынан бәрі дайын екенін түсіндім. Бұл орын алады...) Мұнда StartCommand , орындау әдісін қарауға болады :
@Override
public void execute(Update update) {
   String chatId = update.getMessage().getChatId().toString();

   telegramUserService.findByChatId(chatId).ifPresentOrElse(
           user -> {
               user.setActive(true);
               telegramUserService.save(user);
           },
           () -> {
               TelegramUser telegramUser = new TelegramUser();
               telegramUser.setActive(true);
               telegramUser.setChatId(chatId);
               telegramUserService.save(telegramUser);
           });

   sendBotMessageService.sendMessage(chatId, START_MESSAGE);
}
Логика осында жұмыс істейді: егер біздің дерекқорымызда chatId бойынша мұндай пайдаланушы бар болса, біз оған жай ғана белсенді = шын өрісін орнатамыз. Ал егер ондай пайдаланушы болмаса, біз жаңасын жасаймыз. StopCommand ішіндегі /stop пәрмені үшін бірдей :
@Override
public void execute(Update update) {
   telegramUserService.findByChatId(update.getMessage().getChatId().toString())
           .ifPresent(it -> {
               it.setActive(false);
               telegramUserService.save(it);
           });
   sendBotMessageService.sendMessage(update.getMessage().getChatId().toString(), STOP_MESSAGE);
}
Бұл пәрменді шақырған кезде пайдаланушы үшін тек белсенді = жалған өріс орнатылғанын көруге болады. Мұның бәрі: оның жазылымдары өмір сүреді және пайдаланушы ботпен чатты белсендіруді шешкен кезде қанаттарында күтеді. Және бұл тапсырма орындалған және жабуға болатын сияқты. Бірақ ол жерде болмады. Ең маңызды міндет - жазылымдағы жаңа мақалалар туралы ескерту жасау. Міне, осы тапсырмалар толығымен жаңартылып, аяқталады. Яғни, біз жаңа мақалалар туралы хабарландыруды жүзеге асырмайынша, оны жабу мүмкін емес. Сондықтан JRTB-4 тапсырмасын орындайық - әр 20 minutes сайын чек жасау және жаңа мақалалар туралы хабарландырулар. Достар! Жобаның жаңа codeы қашан шыққанын бірден білгіңіз келе ме? Жаңа мақала қашан шығады? Менің tg каналыма қосылыңыз . Онда мен өзімнің мақалаларымды, ойларымды, ашық дереккөзді дамытуымды бірге жинаймын.

Біз JRTB-4 енгіземіз

Бұл тапсырманың бөлігі ретінде не істеуіміз керек:
  1. Дерекқорда жазылымы бар барлық топтарға мерзімді түрде өтетін жұмыс жасаңыз, мақалаларды жарияланған күні бойынша сұрыптаңыз және соңғы жарияланымның идентификаторының GroupSub ішіндегі мәнге сәйкес келетінін тексеріңіз. Егер ол сәйкес келмесе, соңғы уақыттан бері қанша мақала жарияланғанын түсінуіңіз керек. Біз GroupSub7 ішіндегі last_article_id codeын ағымдағы күйге жаңартамыз.

  2. Жарияланған мақалалар тізімін тапқан кезде біз осы топтар үшін барлық БЕЛСЕНДІ пайдаланушыларды табамыз және оларға жаңа мақалалар туралы хабарландырулар жібереміз.

Ол үшін көктемгі жоспарлаушы сияқты нәрсені қолданамыз. Бұл Spring Framework механизміндегі механизм, оның көмегімен белгілі бір уақытта орындалатын тапсырмаларды жасауға болады. Әр 15-20-40 minutes сайын, немесе әр бейсенбіде 15:30 немесе басқа нұсқа. Оларды ағылшын тілінен калька деп те атайды - joba. Біз бұл тапсырманы орындап жатқанда, мен жаңа мақалаларды іздеуде әдейі бір кемшілік қалдырамын. Бұл өте сирек және мен осы тапсырманың жұмысын қолмен тексерген кезде ғана пайда болды. Мұны істеу үшін сізге мақалаларды іздеу үшін клиент жазу керек. Ол үшін бізге бұрыннан таныс Swagger API қолданамыз . Пост-контроллер бар. Біз тек белгілі бір сүзгілер арқылы мақалалар жинағын іздеуге мүдделіміз:
/api/1.0/rest/posts Жазбаларды сүзгілер бойынша алыңыз
Біз бұл сұраныспен жұмыс істейміз. Онда бізге не керек? Белгілі бір топқа жататын мақалалар тізімін алыңыз және олар жарияланған күні бойынша сұрыпталуы керек. Осылайша біз соңғы 15 мақаланы алып, дерекқорымыздағы lastArticleId негізінде жаңа жарияланымдардың жарияланғанын тексере аламыз . Егер бар болса, біз оларды өңдеуге және пайдаланушыға жіберуге жібереміз. Сондықтан JavaRushPostClient жазуымыз керек .

Біз JavaRushPostClient жазамыз

Бұл жерде біз API-де бізге жіберілген барлық сұрауларды қамтуға тырыспаймыз және тек бізге керектісін жасаймыз. Осылайша біз бірден екі мақсатқа қол жеткіземіз:
  1. Біз өтінімді жазу процесін тездетеміз.

  2. Біз бұл жұмысты біздің қауымдастыққа көмектескісі келетіндерге қалдырамыз және өздерін әзірлеуші ​​ретінде сынап көргісі келеді. Мен бұл үшін MVP-ден кейін орындауға болатын тапсырмаларды жасаймын.

Ендеше жасайық. Swagger UI жүйесіндегі Үлгілер бөлімін сұрау үшін біз келесі DTO-ларды жасаймыз:«А-дан Я-ға Java жобасы»: Мақалаға клиент қосу – 2

BaseUserInfo:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

import lombok.Data;

/**
* DTO, which represents base user information.
*/
@Data
public class BaseUserInfo {
   private String city;
   private String country;
   private String displayName;
   private Integer id;
   private String job;
   private String key;
   private Integer level;
   private String pictureUrl;
   private String position;
   private UserPublicStatus publicStatus;
   private String publicStatusMessage;
   private Integer rating;
   private Integer userId;
}

Тіл:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents languages.
*/
public enum Language {
   UNKNOWN,
   ENGLISH,
   GERMAN,
   SPANISH,
   HINDI,
   FRENCH,
   PORTUGUESE,
   POLISH,
   BENGALI,
   PUNJABI,
   CHINESE,
   ITALIAN,
   INDONESIAN,
   MARATHI,
   TAMIL,
   TELUGU,
   JAPANESE,
   KOREAN,
   URDU,
   TAIWANESE,
   NETHERLANDS,
   RUSSIAN,
   UKRAINIAN
}

Ұнату туралы ақпарат:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents like's information.
*/
public class LikesInfo {

   private Integer count;
   private LikeStatus status;
}

LikeStatus:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents like's status.
*/
public enum LikeStatus {

   UNKNOWN,
   LIKE,
   HOT,
   FOLLOW,
   FAVORITE,
   SOLUTION,
   HELPFUL,
   ARTICLE,
   OSCAR,
   DISLIKE,
   WRONG,
   SPAM,
   ABUSE,
   FOUL,
   TROLLING,
   OFFTOPIC,
   DUPLICATE,
   DIRTY,
   OUTDATED,
   BORING,
   UNCLEAR,
   HARD,
   EASY,
   FAKE,
   SHAM,
   AWFUL
}

Пост түрі:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents post types.
*/
public enum PostType {
   UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}

UserPublicStatus:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents user public status.
*/
public enum UserPublicStatus {
   UNKNOWN,
   BEGINNER,
   ACTIVE,
   STRONG,
   GRADUATED,
   INTERNSHIP_IN_PROGRESS,
   INTERNSHIP_COMPLETED,
   RESUME_COMPLETED,
   LOOKING_FOR_JOB,
   HAVE_JOB;
}

VisibilityStatus:
package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents visibility status.
*/
public enum VisibilityStatus {
   UNKNOWN,
   RESTRICTED,
   PUBLIC,
   PROTECTED,
   PRIVATE,
   DISABLED,
   DELETED
}
Осы DTO-лардың барлығына сүйене отырып, мақалаларды алу үшін негізгі класс жазайық:

Пошта ақпараты:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

import lombok.Data;

/**
* DTO, which represents post information.
*/
@Data
public class PostInfo {

   private BaseUserInfo authorInfo;
   private Integer commentsCount;
   private String content;
   private Long createdTime;
   private String description;
   private GroupInfo groupInfo;
   private Integer id;
   private String key;
   private Language language;
   private LikesInfo likesInfo;
   private GroupInfo originalGroupInfo;
   private String pictureUrl;
   private Double rating;
   private Integer ratingCount;
   private String title;
   private PostType type;
   private Long updatedTime;
   private UserDiscussionInfo userDiscussionInfo;
   private Integer views;
   private VisibilityStatus visibilityStatus;

}
Енді жұмыс істеу үшін интерфейсті және оны жүзеге асыруды жасайық. Мақалалармен жұмыс істеу үшін бізге бір ғана әдіс қажет:

JavaRushPostClient:

package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;

import java.util.List;

/**
* Client for Javarush Open API corresponds to Posts.
*/
public interface JavaRushPostClient {

   /**
    * Find new posts since lastPostId in provided group.
    *
    * @param groupId provided group ID.
    * @param lastPostId provided last post ID.
    * @return the collection of the new {@link PostInfo}.
    */
   List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId);
}
findNewPosts екі дәлелді қабылдайды: топ идентификаторы және бот жариялаған мақаланың соңғы идентификаторы. Сондықтан lastPostId бар мақаладан кейінірек жарияланған барлық мақалалар жіберіледі . Және оны жүзеге асыру:
package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import kong.unirest.GenericType;
import kong.unirest.Unirest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class JavaRushPostClientImpl implements JavaRushPostClient {

   private final String javarushApiPostPath;

   public JavaRushPostClientImpl(@Value("${javarush.api.path}") String javarushApi) {
       this.javarushApiPostPath = javarushApi + "/posts";
   }

   @Override
   public List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId) {
       List<PostInfo> lastPostsByGroup = Unirest.get(javarushApiPostPath)
               .queryString("order", "NEW")
               .queryString("groupKid", groupId)
               .queryString("limit", 15)
               .asObject(new GenericType<List<PostInfo>>() {
               }).getBody();
       List<PostInfo> newPosts = new ArrayList<>();
       for (PostInfo post : lastPostsByGroup) {
           if (lastPostId.equals(post.getId())) {
               return newPosts;
           }
           newPosts.add(post);
       }
       return newPosts;
   }
}
Біз сұрауға бірнеше сүзгілерді қосамыз:
  • тапсырыс = ЖАҢА - тізімде алдымен жаңалары болуы үшін;
  • groupKid = groupId - тек белгілі бір топтарды іздеу;
  • лимит = 15 — біз сұраныс бойынша мақалалар санын шектейміз. Біздің жиілігіміз 15-20 minutes және осы уақыт ішінде 15 (!) АРТЫҚ жазылмайды деп күтеміз.
Әрі қарай, біз мақалаларды тапқан кезде тізімді қарап шығып, жаңаларын іздейміз. Алгоритм қарапайым және интуитивті. Оны жақсартқыңыз келсе жазыңыз). Осы клиент үшін қарапайым тест жазайық:
package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;

import static com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClientTest.JAVARUSH_API_PATH;

@DisplayName("Integration-level testing for JavaRushPostClient")
class JavaRushPostClientTest {

   private final JavaRushPostClient postClient = new JavaRushPostClientImpl(JAVARUSH_API_PATH);

   @Test
   public void shouldProperlyGetNew15Posts() {
       //when
       List<PostInfo> newPosts = postClient.findNewPosts(30, 2935);

       //then
       Assertions.assertEquals(15, newPosts.size());
   }
}
Бұл клиентпен байланыс бар-жоғын тексеретін өте қарапайым сынақ. Ол Java жобалары тобында 15 жаңа мақаланы табады, өйткені мен оған осы топтағы бірінші мақаланың идентификаторын беремін және олардың саны 15-тен астам... Олардың 22-сі бар! Мен олардың соншалықты көп болатынын ойламадым да. Мен қалай тез білдім? Қалай ойлайсың, ол оларды санауға барды ма? Жоқ) Мен свагерді қолдандым және белгілі бір топқа арналған мақалалар санын қарадым. Айтпақшы, басқаларға осылай қарауға болады... Ал RANDOM тобында қанша мақала бар?... Мен қазір айтайын: олардың 1062-сі бар! Ауыр сома.

Бірінші бөлімнің соңы

Мұнда біз клиентпен жұмысты мақалалар бойынша қостық. Біз бәрін жасадық, бұл жолы бәрі қарапайым және жылдам болуы керек деп ойлаймын. Келесі мақалада Spring Scheduler қосамыз және FindNewArticleService жазамыз . Әдеттегідей, лайк басыңыз - жазылыңыз - қоңырауды басыңыз , жобамызға жұлдызша беріңіз , пікір қалдырыңыз және мақаланы бағалаңыз! Оқығандарыңызға рахмет - жақын арада кездескенше!

Сериядағы барлық материалдардың тізімі осы мақаланың басында.

Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION