JavaRush /جاوا بلاگ /Random-UR /مضامین میں کلائنٹ کو شامل کرنا - "A سے Z تک جاوا پروجیکٹ"...

مضامین میں کلائنٹ کو شامل کرنا - "A سے Z تک جاوا پروجیکٹ"

گروپ میں شائع ہوا۔
سب کو سلام، میرے پیارے دوستو۔ قدم بہ قدم ہم اپنے مقصد کے قریب پہنچ رہے ہیں - اپنے پروجیکٹ کا MVP بننے کے لیے - JavaRush Telegram Bot۔ جیسا کہ میں نے پچھلے مضمون میں کہا تھا، اب صرف 5 کام باقی ہیں۔ آج ہم ان میں سے دو کا احاطہ کریں گے۔ "A سے Z تک جاوا پروجیکٹ": آرٹیکلز میں کلائنٹ کو شامل کرنا - 1میں دہرانا چاہتا ہوں کہ یہ منصوبہ یہاں ختم نہیں ہوگا۔ میرے پاس اب بھی بہت سارے خیالات اور وژن ہیں کہ اس پروجیکٹ کو کیسے ترقی کرنی چاہیے، اس میں کون سی نئی چیزیں شامل کی جا سکتی ہیں، کیا بہتر کیا جا سکتا ہے۔ MVP سے پہلے، ہم ری فیکٹرنگ کے موضوع پر ایک الگ مضمون بنائیں گے - یعنی کوڈ کی فعالیت کو تبدیل کیے بغیر اس کے معیار کو بہتر بنانے کے بارے میں۔ اس وقت تک پورا منصوبہ نظر آ جائے گا اور یہ واضح ہو جائے گا کہ کیا اور کہاں بہتر کیا جا سکتا ہے۔ ہمارے معاملے میں، ہم فعالیت کو توڑنے سے زیادہ سے زیادہ محفوظ رہیں گے، کیونکہ بہت سے ٹیسٹ لکھے جا چکے ہیں۔ ہم اس پر بھی ایک سابقہ ​​تحریر کریں گے کہ ہم کیا چاہتے تھے اور آخر میں ہمیں کیا ملا۔ یہ ایک بہت ہی کارآمد چیز ہے: آئیے دیکھتے ہیں کہ چھ ماہ پہلے ہر چیز کو کس حد تک درست طریقے سے دیکھا گیا تھا۔ کم از کم یہ میرے لیے بہت دلچسپ ہے۔ اگر کوئی خود کو دستی ٹیسٹر کے طور پر آزمانا چاہتا ہے تو ہمیں لکھیں اور ہم تعاون کریں گے۔ آئیے مل کر اس پروجیکٹ کو بہتر بنائیں! تو، وہ یہ ہیں: چھ مہینے پہلے بیان کیے گئے دو کام: JRTB-8 اور JRTB-9 ۔ میں نے یہ دیکھنا شروع کیا کہ ان کاموں کے لیے کس چیز کو لاگو کرنے کی ضرورت ہے، اور محسوس ہوا کہ کمانڈ لانچ کرنے کے معاملے میں، سب کچھ پہلے سے ہی تیار تھا۔ ایسا ہوتا ہے...) یہاں، آپ دیکھ سکتے ہیں StartCommand ، execute طریقہ :
@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 کے ذریعے ایسا صارف موجود ہے، تو ہم اس کے لیے فعال = true فیلڈ سیٹ کرتے ہیں۔ اور اگر ایسا کوئی صارف نہیں ہے تو ہم ایک نیا بناتے ہیں۔ 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);
}
یہ دیکھا جا سکتا ہے کہ اس کمانڈ کو کال کرتے وقت، صارف کے لیے صرف Active = false فیلڈ سیٹ ہوتی ہے۔ اور بس: اس کی سبسکرپشنز زندہ رہیں گی اور انتظار کریں گی جب صارف دوبارہ بوٹ کے ساتھ چیٹ کو چالو کرنے کا فیصلہ کرے گا۔ اور ایسا لگتا ہے کہ کام پہلے ہی مکمل ہوچکا ہے اور اسے بند کیا جاسکتا ہے۔ لیکن یہ وہاں نہیں تھا۔ سب سے اہم کام سبسکرپشن میں نئے مضامین کے بارے میں الرٹ بنانا ہے۔ یہ وہ جگہ ہے جہاں ان کاموں کو مکمل طور پر اپ ڈیٹ اور مکمل کیا جائے گا۔ یعنی جب تک ہم نئے مضامین کے نوٹیفکیشن پر عمل درآمد نہیں کر لیتے، اسے بند نہیں کیا جا سکتا۔ لہذا، آئیے کام JRTB-4 کا خیال رکھیں - ہر 20 منٹ میں ایک چیک بنانا اور نئے مضامین کے بارے میں اطلاعات۔ دوستو! کیا آپ فوری طور پر جاننا چاہتے ہیں کہ پروجیکٹ کے لیے نیا کوڈ کب جاری کیا جائے گا؟ نیا مضمون کب آتا ہے؟ میرے ٹی جی چینل کو جوائن کریں ۔ وہاں میں اپنے مضامین، اپنے خیالات، اپنی اوپن سورس ڈیولپمنٹ کو اکٹھا کرتا ہوں۔

ہم JRTB-4 نافذ کرتے ہیں۔

اس کام کے حصے کے طور پر ہمیں کیا کرنے کی ضرورت ہے:
  1. ایک ایسی جاب بنائیں جو وقتاً فوقتاً ان تمام گروپس میں جائے جن کے لیے ہمارے پاس ڈیٹا بیس میں سبسکرپشنز ہیں، مضامین کو اشاعت کی تاریخ کے مطابق ترتیب دیں اور چیک کریں کہ آخری اشاعت کی ID GroupSub میں موجود قدر سے میل کھاتی ہے۔ اگر یہ مماثل نہیں ہے، تو آپ کو یہ سمجھنا ہوگا کہ آخری بار سے اب تک کتنے مضامین شائع ہوئے ہیں۔ ہم گروپسب7 میں آخری_آرٹیکل_آئی ڈی کو موجودہ حالت میں اپ ڈیٹ کرتے ہیں۔

  2. جب ہمیں شائع شدہ مضامین کی فہرست مل جاتی ہے، تو ہم ان گروپس کے لیے تمام فعال صارفین تلاش کرتے ہیں اور انہیں نئے مضامین کے بارے میں اطلاعات بھیجتے ہیں۔

ایسا کرنے کے لیے، ہم اسپرنگ شیڈیولر جیسی چیز استعمال کریں گے۔ یہ اسپرنگ فریم ورک میں ایک طریقہ کار ہے، اس کی مدد سے آپ ایسے کام بنا سکتے ہیں جو ایک مخصوص وقت پر انجام دیے جائیں گے۔ یا تو ہر 15-20-40 منٹ پر، یا ہر جمعرات کو 15:30 پر یا کوئی اور آپشن۔ انہیں انگریزی سے ٹریسنگ پیپر بھی کہا جاتا ہے - joba. جب ہم یہ کام کر رہے ہیں، میں جان بوجھ کر نئے مضامین کی تلاش میں ایک عیب چھوڑوں گا۔ یہ کافی نایاب ہے اور صرف اس صورت حال میں ظاہر ہوتا ہے جب میں نے دستی طور پر اس کام کے آپریشن کا تجربہ کیا۔ ایسا کرنے کے لیے آپ کو مضامین کی تلاش کے لیے ایک کلائنٹ لکھنا ہوگا۔ ایسا کرنے کے لیے، ہم Swagger API استعمال کریں گے جو ہمارے لیے پہلے سے واقف ہے ۔ ایک پوسٹ کنٹرولر ہے۔ ہم صرف مخصوص فلٹرز کا استعمال کرتے ہوئے مضامین کا مجموعہ تلاش کرنے میں دلچسپی رکھتے ہیں:
/api/1.0/rest/posts فلٹرز کے ذریعے پوسٹس حاصل کریں۔
ہم اس درخواست پر کام کریں گے۔ اس میں ہمیں کیا چاہیے؟ ایک مخصوص گروپ سے تعلق رکھنے والے مضامین کی فہرست حاصل کریں، اور انہیں اشاعت کی تاریخ کے مطابق ترتیب دیا جانا چاہیے۔ اس طرح ہم آخری 15 مضامین لے سکتے ہیں اور چیک کر سکتے ہیں کہ آیا ہمارے ڈیٹا بیس سے lastArticleId کی بنیاد پر نئی اشاعتیں شائع ہوئی ہیں۔ اگر کوئی ہے تو، ہم انہیں پروسیسنگ اور صارف کو بھیجنے کے لیے بھیجیں گے۔ لہذا ہمیں JavaRushPostClient لکھنے کی ضرورت ہے ۔

ہم JavaRushPostClient لکھتے ہیں۔

یہاں ہم ان تمام درخواستوں کا احاطہ کرنے کی کوشش نہیں کریں گے جو ہمیں API میں بھیجی گئی تھیں اور صرف وہی بنائیں گے جس کی ہمیں ضرورت ہے۔ ایسا کرنے سے، ہم ایک ساتھ دو مقاصد حاصل کرتے ہیں:
  1. ہم اپنی درخواست لکھنے کے عمل کو تیز کرتے ہیں۔

  2. ہم یہ کام ان لوگوں پر چھوڑ دیتے ہیں جو ہماری کمیونٹی کی مدد کرنا چاہتے ہیں اور خود کو ایک ڈویلپر کے طور پر آزمانے کا فیصلہ کرتے ہیں۔ میں اس کے لیے کام بناؤں گا جو ایم وی پی کے بعد مکمل ہو سکتے ہیں۔

تو آئیے یہ کرتے ہیں۔ Swagger UI میں ماڈلز سیکشن سے استفسار کرنے کے لیے ، ہم درج ذیل DTOs بنائیں گے:"A سے Z تک جاوا پروجیکٹ": آرٹیکلز میں کلائنٹ کو شامل کرنا - 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;
}

پسند کی حیثیت:

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
}

صارف کی عوامی حیثیت:

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
}
ان تمام ڈی ٹی اوز کی بنیاد پر، آئیے مضامین حاصل کرنے کے لیے ایک مرکزی کلاس لکھتے ہیں:

پوسٹ کی معلومات:

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 دو دلائل لیتا ہے: گروپ ID اور مضمون کی آخری ID جسے بوٹ پہلے ہی پوسٹ کر چکا ہے۔ لہٰذا، وہ تمام مضامین جو 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;
   }
}
ہم درخواست میں کئی فلٹرز شامل کرتے ہیں:
  • آرڈر = نیا - تاکہ فہرست میں پہلے نئے شامل ہوں؛
  • گروپ کِڈ = گروپ آئی ڈی - صرف مخصوص گروپس کے لیے تلاش کریں؛
  • حد = 15 — ہم فی درخواست مضامین کی تعداد کو محدود کرتے ہیں۔ ہماری فریکوئنسی 15-20 منٹ ہے اور ہم توقع کرتے ہیں کہ اس دوران 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());
   }
}
یہ ایک بہت آسان ٹیسٹ ہے جو چیک کرتا ہے کہ آیا کلائنٹ کے ساتھ کوئی بات چیت ہے یا نہیں۔ اسے جاوا پروجیکٹس گروپ میں 15 نئے مضامین ملے، کیونکہ میں اسے اس گروپ میں پہلے آرٹیکل کی آئی ڈی دیتا ہوں، اور ان میں سے 15 سے زیادہ پہلے ہی موجود ہیں... ان میں سے 22 پہلے ہی موجود ہیں! میں نے سوچا بھی نہیں تھا کہ ان میں سے اتنے ہوں گے۔ مجھے جلدی کیسے پتہ چلا؟ کیا آپ کو لگتا ہے کہ وہ ان کو گننے گیا تھا؟ نہیں۔ ویسے، آپ دوسروں میں اس طرح دیکھ سکتے ہیں... اور رینڈم گروپ میں کتنے مضامین ہیں؟... میں آپ کو اب بتاتا ہوں: ان میں سے 1062 ہیں! سنجیدہ رقم۔

پہلے حصے کا اختتام

یہاں ہم نے مضمون کے لحاظ سے کلائنٹ کے ساتھ کام شامل کیا ہے۔ ہم نے پہلے ہی سب کچھ کر لیا ہے، اس بار میرے خیال میں سب کچھ آسان اور تیز ہونا چاہیے۔ اگلے مضمون میں ہم Spring Scheduler شامل کریں گے اور FindNewArticleService لکھیں گے ۔ ٹھیک ہے، ہمیشہ کی طرح، جیسے - سبسکرائب کریں - گھنٹی بجائیں ، ہمارے پروجیکٹ کو ستارہ دیں ، تبصرے لکھیں اور مضمون کی درجہ بندی کریں! پڑھنے کے لئے آپ سب کا شکریہ - جلد ہی ملیں گے!

سیریز کے تمام مواد کی فہرست اس مضمون کے شروع میں ہے۔

تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION