Микросервисная архитектура - практическая SOA

В этой главе мы разработаем приложение на основе CRUD с архитектурой SOA. Позже, в следующих главах, мы разделим этот сервис на микросервисы и узнаем основные различия между SOA и микросервисной архитектурой.

Конфигурация и настройка системы

В этом разделе мы создадим образец приложения CRUD, которое будет возвращать объект JSON в качестве ответа всякий раз, когда мы вызываем нашу службу. Мы будем использовать фреймворк Джерси для разработки того же самого. Ниже приведены шаги по настройке локальной системной среды.

Разработка приложения CRUD

Step 1- Мы будем использовать NetBeans как среду разработки. Загрузите и установите последнюю версию, доступную на официальном сайте NetBeans.https://netbeans.org/downloads/.

Step 2- Откройте среду IDE NetBeans. Перейдите в «Файл -> Новый проект». Появится следующий снимок экрана. Выберите «Maven» в качестве категории, выберите «Проект из ArchType» в качестве проекта и нажмите «Далее».

Это загрузит все необходимые файлы jar для создания вашего первого проекта Maven и веб-службы RESTful.

Step 3- При нажатии кнопки Далее на предыдущем шаге появляется следующий снимок экрана. Здесь вам нужно будет указать Maven Archetype.

В поле поиска найдите «Jersey-archType-Webapp (2.16)» и установите флажок «Показать старые».

Step 4- После того, как вы выбрали то же самое, вы будете перенаправлены на следующий экран. Выберите желаемую банку из списка и нажмите «Далее», чтобы продолжить.

Step 5- На этом этапе вам необходимо указать имя вашего проекта и его идентификатор группы, а также сведения о пакете. После предоставления всей этой информации нажмите «Готово», чтобы продолжить.

Step 6- Вы закончили настройку рабочего места. Каталог проекта будет выглядеть следующим образом.

Загляните в свою папку «Зависимости», и вы обнаружите, что Maven автоматически загрузил все необходимые файлы jar для этого проекта.

Step 7- Ваше рабочее пространство настроено, и вы можете начать кодирование. Идите вперед и создайте четыре класса и пакета, как указано на следующем снимке экрана. Вы можете обнаружить, что MyResource.java уже создан Maven, поскольку Maven достаточно умен, чтобы определить, что вы собираетесь создать свой собственный веб-сервис.

Step 8 - После выполнения вышеуказанного шага мы создадим наш класс POJO, который является UserProfile.java, следующим образом.

package com.tutorialspoint.userprofile.Model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class UserProfile {
   private long ProId;
   private String FName;
   private String LName;
   private String Add;
   public UserProfile(){}
   
   public UserProfile(long Proid, String Fname, String Lname,String Add) {
      this.ProId = Proid;
      this.FName = Fname;
      this.LName = Lname;
      this.Add = Add;
   }
   public long getProId() {
      return ProId;
   }
   public void setProId(long ProId) {
      this.ProId = ProId;
   }
   public String getFName() {
      return FName;
   }
   public void setFName(String FName) {
      this.FName = FName;
   }
   public String getLName() {
      return LName;
   }
   public void setLName(String LName) {
      this.LName = LName;
   }
   public String getAdd() {
      return Add;
   }
   public void setAdd(String Add) {
      this.Add = Add;
   }
}

Step 9- Теперь мы создадим наш класс базы данных. Поскольку это часть учебного материала, мы не будем использовать какую-либо БД в качестве нашей базы данных. Мы будем использовать встроенную память Java в качестве нашей временной памяти. Как вы можете видеть в следующем наборе кода, мы будем использовать MAP в качестве нашей базы данных. Все операции веб-сервиса, которые мы выполняем, мы будем работать с этой MAP, определенной в классе.

package com.tutorialspoint.userprofile.DAO;

import com.tutorialspoint.userprofile.Model.UserProfile;

import java.util.HashMap;
import java.util.Map;

public class DatabaseClass {
   private static Map<Long,UserProfile> messages = new HashMap<Long,UserProfile>();
   public static Map<Long,UserProfile> getUsers() {
      return messages; 
      // Each time this method will return entire map as an instance of database
   }
}

Step 10- А теперь давайте построим наш класс обслуживания. Скопируйте и вставьте следующий набор кода в класс «ProfileService.java». Это класс, в котором мы объявим все методы наших веб-сервисов, которые будут доступны внешнему миру. Нам нужно создать одну ссылку на наш DatabaseClass, чтобы наша временная база данных была доступна в этом классе.

package com.tutorialspoint.userprofile.service;

import com.tutorialspoint.userprofile.DAO.DatabaseClass;
import com.tutorialspoint.userprofile.Model.UserProfile;

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

public class ProfileService {
   private Map<Long,UserProfile> Userprofiles = DatabaseClass.getUsers();
   
   // Creating some predefine profile and populating the same in the map
   public ProfileService() {
      UserProfile m1 = new UserProfile(1L,"Tutorials1","Point1","TutorialsPoint.com");
      UserProfile m2 = new UserProfile(2L,"Tutorials2","Point2","TutorialsPoint.com2");
      UserProfile m3 = new UserProfile(3L,"Tutorials3","Point3","TutorialsPoint.com3");
      UserProfile m4 = new UserProfile(4L,"Tutorials4","Point4","TutorialsPoint.com4");
      
      Userprofiles.put(1L, m1);
      Userprofiles.put(2L, m2);
      Userprofiles.put(1L, m3);
      Userprofiles.put(2L, m4);
   }
   
   //Method to fetch all profile
   public List<UserProfile> getAllProfile() {
      List<UserProfile> list = new ArrayList<UserProfile>(Userprofiles.values());
      return list;
   }  // Method to fetch only one profile depending on the ID provided
   
   public UserProfile getProfile(long id) {
      return Userprofiles.get(id);
   }  //Method to add profile
   
   public UserProfile addProfile(UserProfile UserProfile) {
      UserProfile.setProId(Userprofiles.size()+1);
      Userprofiles.put(UserProfile.getProId(), UserProfile);
      return UserProfile;
   }  //method to update Profile

   public UserProfile UpdateProfile(UserProfile UserProfile) {
      if(UserProfile.getProId()<=0) { 
         return null;
      } else { 
         Userprofiles.put(UserProfile.getProId(), UserProfile);
         return UserProfile;
      }
   } //method to delete profile
   
   public void RemoveProfile(long Id) {
      Userprofiles.remove(Id);
   }
}

Step 11 - На этом этапе мы создадим наш класс ресурсов, который будет связан с URL-адресом, и будет вызвана соответствующая служба.

package com.tutorialspoint.userprofile.Resource;

import com.tutorialspoint.userprofile.Model.UserProfile;
import com.tutorialspoint.userprofile.service.ProfileService;

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/Profile")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)

public class ProfileResource {
   ProfileService messageService = new ProfileService();
   
   @GET
   public List<UserProfile> getProfile() {
      return messageService.getAllProfile();
   }

   @GET
   @Path("/{ProID}")
   public UserProfile getProfile(@PathParam("ProID")long Id) {
      return messageService.getProfile(Id);
   }

   @POST
   public UserProfile addProfile(UserProfile profile) {
      return messageService.addProfile(profile);
   }

   @PUT
   @Path("/{proID}")
   public UserProfile UpdateProfile(@PathParam("proID")long Id,UserProfile UserProfile) {
      UserProfile.setProId(Id);
      return messageService.UpdateProfile(UserProfile);
   }
   
   @DELETE
   @Path("/{ProID}")
   public void deleteProfile(@PathParam("ProID")long Id) {
      messageService.RemoveProfile(Id);
   }
}

Step 12- Чистая сборка проекта и запуск. Если все пойдет хорошо, вы должны получить следующий вывод в браузере при доступе кhttp://localhost:8080/UserProfile/webapi/Profile” URL.

Вы можете видеть, что разные записи заполняются с использованием XML-представления.

Другой метод можно протестировать с помощью Postman, применив соответствующий URL-адрес метода.

@GET method - На следующем снимке экрана показано, как мы можем получить желаемый результат для запроса на получение, который возвращает все данные пользователя.

@POST- Следующий запрос можно использовать для тестирования нашего метода Post. Обратите внимание, как proId был создан автоматически.

@PUT- Этот метод обновит записи. На следующем снимке экрана показано, как Джерси берет proId из URL-адреса запроса и обновляет тот же ответ профиля пользователя.

Таким же образом вы можете проверить другие методы, доступные в ваших веб-службах.

В предыдущем разделе мы разработали одну службу, которая будет предоставлять функциональные возможности CRUD. Теперь всякий раз, когда мы пытаемся реализовать эту службу в нашем приложении, нам нужно создать клиента этого приложения и присоединить его к нашему приложению. В этой главе мы узнаем, как создать эту функциональность, используя концепцию микросервиса. Ниже приведено схематическое представление нашего приложения, созданного с использованием описанных выше шагов.

Актер должен быть точкой входа в нашу службу. В этом случае «ProfileResource.java» выполняет обязанности актера. Этот класс будет вызывать разные методы для выполнения различных операций, таких как добавление, обновление и удаление.

Разложение CRUD-приложения

Согласно основному принципу микросервиса, у нас должна быть только одна бизнес-задача для каждого из модулей, поэтому один субъект не должен отвечать за все четыре функции CRUD. Рассмотрим следующий пример, в котором мы ввели несколько новых ролей, так что вам будет концептуально ясно, что микросервис - это архитектурное представление SOA.

«Главный пользователь» - это пользователь, который общается с «Контроллером приложения» для удовлетворения своих потребностей. «Контроллер приложения» - это тот, кто просто вызывает разных «менеджеров ресурсов» в зависимости от запроса от конечного пользователя. «Диспетчер ресурсов» выполняет необходимую работу. Давайте кратко рассмотрим различные роли разных модулей приложения.

  • End User/Main Users - Запросы некоторых ресурсов к Application Controller.

  • Application - Получает запрос и пересылает его конкретному диспетчеру ресурсов.

  • Resource Manager - Выполняет фактическую работу по обновлению, удалению и добавлению пользователей.

Посмотрите, как общая ответственность одного класса распределяется между разными другими классами.