SPRING_BOOT_HOME=<extracted path>/spring-1.3.0.M1 PATH=$SPRING_BOOT_HOME/bin:$PATH
<extracted-path>/spring-1.3.0.M1/shell-completion/bash/spring
spring init -dweb,data-mongodb,flapdoodle-mongo --groupId com.justiceleague --artifactId justiceleaguemodule --build maven justiceleaguesystem
package com.justiceleague.justiceleaguemodule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Основное приложение spring boot, которое запустит веб-контейнер и подключит все * необходимые компоненты * * @author dinuka * */ @SpringBootApplication public class JusticeLeagueManagementApplication { public static void main(String[] args) { SpringApplication.run(JusticeLeagueManagementApplication.class, args); } }
package com.justiceleague.justiceleaguemodule.domain; import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.Indexed; import org.springframework.data.mongodb.core.mapping.Document; /** * В этом классе содержатся подробности о членах Лиги Справедливости, которые * будут храниться в MongoDB * * @author dinuka * */ @Document(collection = "justiceLeagueMembers") public class JusticeLeagueMemberDetail { @Id private ObjectId id; @Indexed private String name; private String superPower; private String location; public JusticeLeagueMemberDetail(String name, String superPower, String location) { this.name = name; this.superPower = superPower; this.location = location; } public String getId() { return id.toString(); } public void setId(String id) { this.id = new ObjectId(id); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSuperPower() { return superPower; } public void setSuperPower(String superPower) { this.superPower = superPower; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
@Document
package com.justiceleague.justiceleaguemodule.dao; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; import com.justiceleague.justiceleaguemodule.domain.JusticeLeagueMemberDetail; public interface JusticeLeagueRepository extends MongoRepository < JusticeLeagueMemberDetail, String > { /** * Этот метод извлекает подробности об участнике лиги справедливости, связанным с . * переданным именем. * * @param superHeroName * имя участника лиги справедливости для поиска и извлечения. * @return возвращает инстанс {@link JusticeLeagueMemberDetail} с подробностями * об участнике. */ @Query("{ 'name' : {$regex: ?0, $options: 'i' }}") JusticeLeagueMemberDetail findBySuperHeroName(final String superHeroName); }
@Query
annotation @Query
we are looking for a superhero using regular expressions. The “i” option means that you need to ignore the case when trying to find a match in MongoDB. package com.justiceleague.justiceleaguemodule.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.justiceleague.justiceleaguemodule.constants.MessageConstants.ErrorMessages; import com.justiceleague.justiceleaguemodule.dao.JusticeLeagueRepository; import com.justiceleague.justiceleaguemodule.domain.JusticeLeagueMemberDetail; import com.justiceleague.justiceleaguemodule.exception.JusticeLeagueManagementException; import com.justiceleague.justiceleaguemodule.service.JusticeLeagueMemberService; import com.justiceleague.justiceleaguemodule.web.dto.JusticeLeagueMemberDTO; import com.justiceleague.justiceleaguemodule.web.transformer.DTOToDomainTransformer; /** * Этот класс сервиса реализует {@link JusticeLeagueMemberService} для обеспечения * функциональности, необходимой системе лиги справедливости * * @author dinuka * */ @Service public class JusticeLeagueMemberServiceImpl implements JusticeLeagueMemberService { @Autowired private JusticeLeagueRepository justiceLeagueRepo; /** * {@inheritDoc} */ public void addMember(JusticeLeagueMemberDTO justiceLeagueMember) { JusticeLeagueMemberDetail dbMember = justiceLeagueRepo.findBySuperHeroName(justiceLeagueMember.getName()); if (dbMember != null) { throw new JusticeLeagueManagementException(ErrorMessages.MEMBER_ALREDY_EXISTS); } JusticeLeagueMemberDetail memberToPersist = DTOToDomainTransformer.transform(justiceLeagueMember); justiceLeagueRepo.insert(memberToPersist); } }
package com.justiceleague.justiceleaguemodule.web.rest.controller; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import com.justiceleague.justiceleaguemodule.constants.MessageConstants; import com.justiceleague.justiceleaguemodule.service.JusticeLeagueMemberService; import com.justiceleague.justiceleaguemodule.web.dto.JusticeLeagueMemberDTO; import com.justiceleague.justiceleaguemodule.web.dto.ResponseDTO; /** * Этот класс открывает REST API системе. * * @author dinuka * */ @RestController @RequestMapping("/justiceleague") public class JusticeLeagueManagementController { @Autowired private JusticeLeagueMemberService memberService; /** * Этот метод будет использоваться для добавления новых участников лиги справедливости в систему * * @param justiceLeagueMember * участник лиги для добавления. * @return an instance of {@link ResponseDTO} который уведомит об успешности * добавления нового члена. */ @ResponseBody @ResponseStatus(value = HttpStatus.CREATED) @RequestMapping(method = RequestMethod.POST, path = "/addMember", produces = { MediaType.APPLICATION_JSON_VALUE }, consumes = { MediaType.APPLICATION_JSON_VALUE }) public ResponseDTO addJusticeLeagueMember(@Valid @RequestBody JusticeLeagueMemberDTO justiceLeagueMember) { ResponseDTO responseDTO = new ResponseDTO(ResponseDTO.Status.SUCCESS, MessageConstants.MEMBER_ADDED_SUCCESSFULLY); try { memberService.addMember(justiceLeagueMember); } catch (Exception e) { responseDTO.setStatus(ResponseDTO.Status.FAIL); responseDTO.setMessage(e.getMessage()); } return responseDTO; } }
package com.justiceleague.justiceleaguemodule.test.util; import java.io.IOException; import java.net.UnknownHostException; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import com.fasterxml.jackson.databind.ObjectMapper; import com.justiceleague.justiceleaguemodule.domain.JusticeLeagueMemberDetail; import de.flapdoodle.embed.mongo.MongodExecutable; import de.flapdoodle.embed.mongo.MongodStarter; import de.flapdoodle.embed.mongo.config.IMongodConfig; import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; import de.flapdoodle.embed.mongo.config.Net; import de.flapdoodle.embed.mongo.distribution.Version; /** * В этом классе будет функциональность, необходимая для запуска интеграционных тестов, * чтобы не реализовывать одно и то же несколько раз в индивидуальных классах. * * @author dinuka * */ @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public abstract class BaseIntegrationTest { @Autowired protected MockMvc mockMvc; protected ObjectMapper mapper; private static MongodExecutable mongodExecutable; @Autowired protected MongoTemplate mongoTemplate; @Before public void setUp() { mapper = new ObjectMapper(); } @After public void after() { mongoTemplate.dropCollection(JusticeLeagueMemberDetail.class); } /** * Здесь мы настраиваем встроенный инстанс mongodb для запуска с нашими * интеграционными тестами. * * @throws UnknownHostException * @throws IOException */ @BeforeClass public static void beforeClass() throws UnknownHostException, IOException { MongodStarter starter = MongodStarter.getDefaultInstance(); IMongodConfig mongoConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION) .net(new Net(27017, false)).build(); mongodExecutable = starter.prepare(mongoConfig); try { mongodExecutable.start(); } catch (Exception e) { closeMongoExecutable(); } } @AfterClass public static void afterClass() { closeMongoExecutable(); } private static void closeMongoExecutable() { if (mongodExecutable != null) { mongodExecutable.stop(); } } }
package com.justiceleague.justiceleaguemodule.web.rest.controller; import org.hamcrest.beans.SamePropertyValuesAs; import org.junit.Assert; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import com.justiceleague.justiceleaguemodule.constants.MessageConstants; import com.justiceleague.justiceleaguemodule.constants.MessageConstants.ErrorMessages; import com.justiceleague.justiceleaguemodule.domain.JusticeLeagueMemberDetail; import com.justiceleague.justiceleaguemodule.test.util.BaseIntegrationTest; import com.justiceleague.justiceleaguemodule.web.dto.JusticeLeagueMemberDTO; import com.justiceleague.justiceleaguemodule.web.dto.ResponseDTO; import com.justiceleague.justiceleaguemodule.web.dto.ResponseDTO.Status; /** * Этот класс протестирует работу уровня REST-контроллера, встроенного * {@link JusticeLeagueManagementController} * * @author dinuka * */ public class JusticeLeagueManagementControllerTest extends BaseIntegrationTest { /** * Этот метод протестирует успешность добавления участника лиги справедливости при * передаче корректных данных. * * @throws Exception */ @Test public void testAddJusticeLeagueMember() throws Exception { JusticeLeagueMemberDTO flash = new JusticeLeagueMemberDTO("Barry Allen", "super speed", "Central City"); String jsonContent = mapper.writeValueAsString(flash); String response = mockMvc .perform(MockMvcRequestBuilders.post("/justiceleague/addMember") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON).content(jsonContent)) .andExpect(MockMvcResultMatchers.status().isCreated()).andReturn().getResponse().getContentAsString(); ResponseDTO expected = new ResponseDTO(Status.SUCCESS, MessageConstants.MEMBER_ADDED_SUCCESSFULLY); ResponseDTO receivedResponse = mapper.readValue(response, ResponseDTO.class); Assert.assertThat(receivedResponse, SamePropertyValuesAs.samePropertyValuesAs(expected)); } /** * Этот метод проверит, будет ли получен ответ об ошибке * при попытке добавить члена, который уже существует в системе. * * @throws Exception */ @Test public void testAddJusticeLeagueMemberWhenMemberAlreadyExists() throws Exception { JusticeLeagueMemberDetail flashDetail = new JusticeLeagueMemberDetail("Barry Allen", "super speed","Central City"); mongoTemplate.save(flashDetail); JusticeLeagueMemberDTO flash = new JusticeLeagueMemberDTO("Barry Allen", "super speed", "Central City"); String jsonContent = mapper.writeValueAsString(flash); String response = mockMvc .perform(MockMvcRequestBuilders.post("/justiceleague/addMember"). accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON).content(jsonContent)) .andExpect(MockMvcResultMatchers.status().isCreated()).andReturn().getResponse() .getContentAsString(); ResponseDTO expected = new ResponseDTO(Status.FAIL, ErrorMessages.MEMBER_ALREDY_EXISTS); ResponseDTO receivedResponse = mapper.readValue(response, ResponseDTO.class); Assert.assertThat(receivedResponse, SamePropertyValuesAs.samePropertyValuesAs(expected)); } /** * Этот метод проверит, будет ли получена валидная ошибка клиента, * если не будут переданы необходимые данные с полезной нагрузкой JSON запроса. * В нашем случае - имя супергероя. * * @throws Exception */ @Test public void testAddJusticeLeagueMemberWhenNameNotPassedIn() throws Exception { // Здесь передается пустое имя супергероя, чтобы проверить // начинается ли обработка ошибки валидации. JusticeLeagueMemberDTO flash = new JusticeLeagueMemberDTO (null, "super speed", "Central City"); String jsonContent = mapper.writeValueAsString(flash); mockMvc.perform(MockMvcRequestBuilders.post("/justiceleague/addMember") .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON).content(jsonContent)) .andExpect(MockMvcResultMatchers.status().is4xxClientError()); } }
Source: https://habr.com/ru/post/437410/