this.getclass().getresource 空指针异常_Optional有效避免空指针异常

本文详细介绍了 Java 8 中的 Optional 类,用于避免空指针异常。通过创建、操作 API、示例代码展示了如何使用 Optional 进行值的判断、处理和转换。此外,还通过 flatMap 实战展示了如何在多层对象导航中优雅地处理空指针问题。
874df660f4d8f4388636efcd311a7278.png

一、是什么

可以理解成是个容器类,是java8诞生的,可以有效的避免空指针异常。

二、API

1、创建Optional

Optional.empty():创建一个空的Optional实例。new Optional<>();Optional.of(T t):创建一个包含t值的Optional实例。若t==null,则get的时候会出现空指针。Optional.ofNullable(T t):是empty和of的结合体,创建一个包含t值的Optional实例。不会出现空指针,若t==null则返回空的Optional实例

2、操作API

isPresent():判断此值是否是null。true:不是null;false:是nullifPresent(Consumer consumer):如果值不是空,则执行consumer代码片段逻辑get():获取此值,若值是null,则会抛出NoSuchElementException("No value present");orElse(T other):若值不是null则返回当前值,否则返回other,有效避免空指针。orElseGet(Supplier s):若值不是null则返回当前值,否则返回s获取的值。有效避免空指针。orElseThrow(Supplier extends X> exceptionSupplier):若值不是null则返回当前值,否则抛出异常。filter(Predicate super T> predicate):根据某种规则进行过滤。map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()flatMap(Function mapper):与map类似,要求返回值必须是Optional

三、Demo

package com.chentongwei.java8.optional;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.util.Optional;/*** @author chentongwei@baidu-mgame.com 2018-12-14 18:28:07* @Desc Optional api测试*/public class OptionalTest { public static void main(String[] args) { testEmpty(); testOf(); testOfNullable(); testIsPresent(); testIfPresent(); testGet(); testOrElse(); testOrElseGet(); testOrElseThrow(); testFilter(); testMap(); } /** * Optional.empty():创建一个空的Optional实例。new Optional<>(); */ private static void testEmpty() { Optional optionalObj = Optional.empty(); // Optional.empty // 为什么输出这个,不多BB,自己去看Optional类的toString()方法源码好吧? System.out.println(optionalObj); } /** * Optional.of(T t):创建一个包含t值的Optional实例。若t==null,则get的时候会出现空指针。 */ private static void testOf() { /* * java.lang.NullPointerException * 为什么抛空指针?我求你了,自己看源码好吧?就一两句话,从这刻起锻炼自己读源码的意识。 */ Optional optionalNull = Optional.of(null); System.out.println(optionalNull); Optional optionalObj = Optional.of(new Obj("test")); // Optional[Obj(name=test)] System.out.println(optionalObj); } /** * Optional.ofNullable(T t):是empty和of的结合体,创建一个包含t值的Optional实例。不会出现空指针,若t==null则返回空的Optional实例 */ private static void testOfNullable() { /* * Optional.empty * 为什么这里就不抛空指针?我求你了,自己看源码好吧?就一两句话,从这刻起锻炼自己读源码的意识。 */ Optional optionalNull = Optional.ofNullable(null); System.out.println(optionalNull); Optional optionalObj = Optional.ofNullable(newObj("test")); // Optional[Obj(name=test)] System.out.println(optionalObj); } /** * isPresent():判断此值是否是null。true:不是null;false:是null */ private static void testIsPresent() { Optional optionalObj = Optional.ofNullable(null); boolean present = optionalObj.isPresent(); // false System.out.println(present); Optional optionalObj2 = Optional.ofNullable(newObj("test")); boolean present2 = optionalObj2.isPresent(); // true System.out.println(present2); } /** * ifPresent(Consumer consumer):如果值不是空,则执行consumer代码片段逻辑 */ private static void testIfPresent() { Optional optionalObj = Optional.ofNullable(null); /* * 什么都没输出,想了解底层看源码。 */ optionalObj.ifPresent(o -> System.out.println(o.getName())); Optional optionalObj2 = Optional.ofNullable(newObj("test")); // test optionalObj2.ifPresent(o -> System.out.println(o.getName())); } /** * get():获取此值,若值是null,则会抛出NoSuchElementException("No value present"); */ private static void testGet() { Optional optionalObj = Optional.ofNullable(null); // java.util.NoSuchElementException: No value present Obj obj = optionalObj.get(); System.out.println(obj); Optional optionalObj2 = Optional.ofNullable(newObj("test")); Obj obj2 = optionalObj2.get(); // Obj(name=test) System.out.println(obj2); } /** * orElse(T other):若值不是null则返回当前值,否则返回other,有效避免空指针。 */ private static void testOrElse() { Optional optionalObj = Optional.ofNullable(null); // 如果optionalObj==null,则创建Obj("haha") Obj obj = optionalObj.orElse(new Obj("haha")); // Obj(name=haha) System.out.println(obj); Optional optionalObj2 = Optional.ofNullable(newObj("test")); Obj obj2 = optionalObj2.orElse(new Obj("haha")); // Obj(name=test) System.out.println(obj2); } /** * orElseGet(Supplier s):若值不是null则返回当前值,否则返回s获取的值。有效避免空指针。 */ private static void testOrElseGet() { Optional optionalObj = Optional.ofNullable(null); // 如果optionalObj==null,则创建Obj("") Obj obj = optionalObj.orElseGet(Obj::new); // Obj(name=null) System.out.println(obj); Optional optionalObj2 = Optional.ofNullable(newObj("test")); Obj obj2 = optionalObj2.orElseGet(Obj::new); // Obj(name=test) System.out.println(obj2); } /** * orElseThrow(Supplier extends X> exceptionSupplier):若值不是null则返回当前值,否则抛出异常。 */ private static void testOrElseThrow() { Optional optionalObj = Optional.ofNullable(null); // 如果optionalObj==null,则抛出指定异常 // java.lang.ArithmeticException Obj obj = optionalObj.orElseThrow(ArithmeticException::new); System.out.println(obj); // 和上面一样,只是不同写法 Optional optionalObj2 = Optional.ofNullable(null); // java.lang.RuntimeException: exception Obj obj2 = optionalObj2.orElseThrow(() -> newRuntimeException("exception")); System.out.println(obj2); Optional optionalObj3 = Optional.ofNullable(newObj("test")); Obj obj3 =optionalObj3.orElseThrow(NullPointerException::new); // Obj(name=test) System.out.println(obj3); } /** * filter(Predicate super T> predicate):根据某种规则进行过滤。 */ private static void testFilter() { Optional optionalObj = Optional.ofNullable(newObj("test")); Obj obj1 = optionalObj.filter(obj -> obj.getName() != null).get(); // Obj(name=test) System.out.println(obj1); Optional optionalObj2 = Optional.ofNullable(newObj("test")); // java.util.NoSuchElementException: No value present,因为filter没找到满足的条件,返回了empty(),然后针对empty()做个get操作。 // 当然我们可以用orElse来避免 Obj obj2 = optionalObj2.filter(obj -> !obj.getName().equals("test")).get(); System.out.println(obj2); } /** * map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty() */ private static void testMap() { String test = Optional.ofNullable(new Obj()).map(obj ->obj.getName()).orElse("test"); // test System.out.println(test); } /** * flatMap(Function mapper):与map类似,要求返回值必须是Optional。下面的flatMap实战中讲解。 */}@NoArgsConstructor@AllArgsConstructor@Dataclass Obj { private String name;}

四、flatMap实战

常规处理空指针方式

@Datapublic class Person { private Car car;}@Datapublic class Car { private Insurance insurance;}@Datapublic class Insurance { private String name;}package com.chentongwei.java8.optional;/*** @author chentongwei@baidu-mgame.com 2018-12-14 16:11:37* @Desc*/public class Null { public static void main(String[] args) { // 空指针异常,没悬念。因为我们没new Car()也没有newInsurance() getInsuranceName(new Person()); // 虽然不报错,但是代码完全不可读。 getInsuranceNameByDeepDoubts(new Person()); // 虽然不报错,但是也很啰嗦了。 getInsuranceNameByMulitExit(new Person()); } /** * 常见解决null问题的方案之一 * * @param person:人 * @return */ private static String getInsuranceNameByDeepDoubts(Personperson) { if (null != person) { Car car = person.getCar(); if (null != car) { Insurance insurance = car.getInsurance(); if (null != insurance) { return insurance.getName(); } } } return "null"; } /** * 常见解决null问题的方案之二 * * @param person:人 * @return */ private static String getInsuranceNameByMulitExit(Person person) { final String defaultValue = "null"; if (null == person) { return defaultValue; } Car car = person.getCar(); if (null == car) { return defaultValue; } Insurance insurance = car.getInsurance(); if (null == insurance) { return defaultValue; } return insurance.getName(); } /** * 获取某人的车险名称 * * @param person:人 * @return */ private static String getInsuranceName(Person person) { return person.getCar().getInsurance().getName(); }}

Optional处理空指针方式

@Datapublic class Person2 { private Optional car;}@Datapublic class Car2 { private Optional insurance;}@Datapublic class Insurance { private String name;}package com.chentongwei.java8.optional;import java.util.Optional;/*** @author chentongwei@baidu-mgame.com 2018-12-14 19:16:49* @Desc*/public class FlatMapTest { public static void main(String[] args) { // unkonwn Optional.ofNullable(test(null)).ifPresent(System.out::println); } private static String test(Person2 person2) { return Optional.ofNullable(person2) // Person2::getCar返回Optional,所以用flatMap而不是map .flatMap(Person2::getCar) // Car2::getInsurance返回Optional,所以用flatMap而不是map .flatMap(Car2::getInsurance) // 用map拿到name .map(Insurance::getName) // 若name是空的,则输出unknown,防止空指针 .orElse("unkonwn"); }}

五、注意

  • 巧妙运用各个API,比如orElse避免空指针等。会让你代码更好看更安全。
  • 一定要去阅读此类源码,因为你会发现及其的简单,一看就懂。
以下是onlineReportServiceImplTest的代码:package com.jd.jacp.unit.report; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.jd.jacp.client.service.ICicdClient; import com.jd.jacp.client.service.ICmdbClient; import com.jd.jacp.client.service.ItsmClientService; import com.jd.jacp.common.service.UserHelper; import com.jd.jacp.common.vo.UserVO; import com.jd.jacp.common.vo.enums.YesOrNoEnum; import com.jd.jacp.demand.entity.BizDemandUser; import com.jd.jacp.demand.service.IBizDemandUserService; import com.jd.jacp.notify.entity.BizNotifyRule; import com.jd.jacp.notify.entity.BizNotifySetting; import com.jd.jacp.notify.enums.BizNotifySendWayEnum; import com.jd.jacp.notify.service.IBizNotifyRuleService; import com.jd.jacp.notify.service.IBizNotifySettingService; import com.jd.jacp.report.dto.*; import com.jd.jacp.report.entity.BizReport; import com.jd.jacp.report.entity.BizReportItem; import com.jd.jacp.report.enums.AcceptanceReportEnum; import com.jd.jacp.report.service.IBizReportItemService; import com.jd.jacp.report.service.IBizReportService; import com.jd.jacp.report.service.impl.OnlineReportServiceImpl; import com.jd.jacp.report.vo.SprintOnlineReportInfoVO; import com.jd.jacp.space.dto.CardQuery; import com.jd.jacp.space.dto.SubSystemByParamsDTO; import com.jd.jacp.space.entity.BizSpace; import com.jd.jacp.space.entity.BizSpaceCard; import com.jd.jacp.space.entity.BizSpaceSprint; import com.jd.jacp.space.service.IBizSpaceCardService; import com.jd.jacp.space.service.IBizSpaceService; import com.jd.jacp.space.service.IBizSpaceSettingService; import com.jd.jacp.space.service.IBizSpaceSprintService; import com.jd.jacp.space.vo.DetailVO; import com.jd.jacp.space.vo.QueryReportVO; import com.jd.jacp.unit.MockitoBasedTest; import com.msxf.devops.common.PageResult; import com.msxf.fcid.xmsg.reponse.ChatInfoDataResp; import org.apache.velocity.script.VelocityScriptEngine; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; import static org.mockito.Mockito.*; import javax.script.ScriptEngineManager; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; public class OnlineReportServiceImplTest extends MockitoBasedTest { @Spy @InjectMocks private OnlineReportServiceImpl onlineReportService; @Mock private IBizSpaceSprintService bizSpaceSprintService; @Mock private IBizSpaceSettingService spaceSettingService; @Mock private ScriptEngineManager scriptEngineManager; @Mock private IBizSpaceService bizSpaceService; @Mock private IBizReportService bizReportService; @Mock private IBizNotifySettingService bizNotifySettingService; @Mock private IBizNotifyRuleService bizNotifyRuleService; @Mock private ItsmClientService itsmClientService; @Mock private ICmdbClient cmdbClient; @Mock private ICicdClient cicdClient; @Mock private IBizSpaceCardService spaceCardService; @Mock private IBizDemandUserService demandUserService; @Mock private IBizReportItemService reportItemService; @Mock private UserHelper userHelper; @Test(expected = Exception.class) public void selectOnlineReportInfo_SprintNotExist_ThrowsException() { when(bizSpaceSprintService.getById(1)).thenReturn(null); onlineReportService.selectOnlineReportInfo(1); } @Test(expected = Exception.class) public void selectOnlineReportInfo_SpaceNotExist_ThrowsException() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setSpaceId(1); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(bizSpaceService.getById(1)).thenReturn(null); onlineReportService.selectOnlineReportInfo(1); } @Test public void selectOnlineReportInfo_Successful() { // Mock data BizSpaceSprint sprint = new BizSpaceSprint().setId(1).setSpaceId(1); BizSpace space = new BizSpace().setId(1).setKey("key"); BizReport report = new BizReport().setId(1).setExtendInfo("{\"reportName\":\"Test Report\"}"); BizNotifySetting notifySetting = new BizNotifySetting().setId(1); BizNotifyRule notifyRule = new BizNotifyRule(); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(bizSpaceService.getById(1)).thenReturn(space); when(bizReportService.selectReport(any(), any(), anyInt())).thenReturn(report); when(bizNotifySettingService.getOneBy(anyString(), anyString())).thenReturn(notifySetting); when(bizNotifyRuleService.getOneByNotifyId(anyInt())).thenReturn(notifyRule); SprintOnlineReportInfoVO result = onlineReportService.selectOnlineReportInfo(1); assertNotNull(result); assertEquals("Test Report", result.getOnlineReport().getReportName()); assertNotNull(result.getNotifySetting()); } @Test public void selectOnlineReportInfo_NoNotifySetting() { // Mock data BizSpaceSprint sprint = new BizSpaceSprint().setId(1).setSpaceId(1); BizSpace space = new BizSpace().setId(1).setKey("key"); BizReport report = new BizReport().setId(1).setExtendInfo("{\"reportName\":\"Test Report\"}"); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(bizSpaceService.getById(1)).thenReturn(space); when(bizReportService.selectReport(any(), any(), anyInt())).thenReturn(report); when(bizNotifySettingService.getOneBy(anyString(), anyString())).thenReturn(null); SprintOnlineReportInfoVO result = onlineReportService.selectOnlineReportInfo(1); assertNotNull(result); assertEquals("Test Report", result.getOnlineReport().getReportName()); assertNull(result.getNotifySetting()); } @Test public void getOnlineReportBaseInfoDTO_test() { when(bizReportService.selectReport(any(), any(), any())).thenReturn(new BizReport()); when(bizNotifySettingService.getOneBy(any(), any())).thenReturn(null); onlineReportService.getOnlineReportBaseInfoDTO(new BizSpaceSprint(), "1"); } @Test public void saveSprintNotifySetting_Test() { SprintOnlineReportInfoVO reportInfoVO = new SprintOnlineReportInfoVO(); reportInfoVO.setNotifySetting(new NotifySettingDTO()); onlineReportService.saveSprintNotifySetting(reportInfoVO); } @Test(expected = Exception.class) public void saveSpaceNotifySetting_test() { onlineReportService.saveSpaceNotifySetting(new SprintOnlineReportInfoVO()); } @Test public void saveSpaceNotifySetting_test1() { when(bizSpaceSprintService.getById(any())).thenReturn(new BizSpaceSprint().setSpaceId(1)); SprintOnlineReportInfoVO reportInfoVO = new SprintOnlineReportInfoVO(); reportInfoVO.setNotifySetting(new NotifySettingDTO()); reportInfoVO.setOnlineReport(new OnlineReportBaseInfoDTO()); onlineReportService.saveSpaceNotifySetting(reportInfoVO); } @Test public void selectSprintCardPage_NoRecords_ReturnEmptyPage() { CardQuery query = new CardQuery(); query.setPageNum(1); query.setPageSize(10); Page<BizSpaceCard> emptyPage = new Page<>(); emptyPage.setRecords(Collections.emptyList()); when(spaceCardService.queryCardByCondition(any(CardQuery.class))).thenReturn(emptyPage); PageResult<OnlineReportCardDTO> result = onlineReportService.selectSprintCardPage(query); assertTrue(result.getRecords().isEmpty()); assertEquals(1, result.getCurrent()); assertEquals(10, result.getSize()); } @Test public void selectSprintCardPage_WithRecords_ReturnFilledPage() { CardQuery query = new CardQuery(); query.setPageNum(1); query.setPageSize(10); query.setSprintId(1); // Mock card page BizSpaceCard card = new BizSpaceCard(); card.setId(1); Page<BizSpaceCard> cardPage = new Page<>(); cardPage.setRecords(Arrays.asList(card)); when(spaceCardService.queryCardByCondition(any(CardQuery.class))).thenReturn(cardPage); // Mock demand users List<BizDemandUser> demandUsers = Collections.emptyList(); when(demandUserService.selectByDemandIds(anyList(), any(Integer.class))).thenReturn(demandUsers); // Mock report map BizReport uatReport = new BizReport(); BizReport gradationReport = new BizReport(); Map<String, BizReport> reportMap = new java.util.HashMap<>(); reportMap.put(AcceptanceReportEnum.reportType.UAT.name(), uatReport); reportMap.put(AcceptanceReportEnum.reportType.GRADATION.name(), gradationReport); when(bizReportService.selectReportMap(anyList(), any(AcceptanceReportEnum.relationBizType.class), any(Integer.class))).thenReturn(reportMap); // Mock report items List<BizReportItem> reportItems = Collections.emptyList(); when(reportItemService.listReportItemByReportIds(anyList())).thenReturn(reportItems); // Mock user map Map<String, UserVO> userVOMap = new java.util.HashMap<>(); when(userHelper.getUserVoMapWithFSNameByErps(anyList(), any(Function.class), any(Function.class))).thenReturn(userVOMap); PageResult<OnlineReportCardDTO> result = onlineReportService.selectSprintCardPage(query); assertEquals(1, result.getRecords().size()); } @Test public void selectSprintCardPage_WithRecords_ReturnFilledPage2() { CardQuery query = new CardQuery(); query.setPageNum(1); query.setPageSize(10); query.setSprintId(1); // Mock card page BizSpaceCard card = new BizSpaceCard(); card.setId(1); Page<BizSpaceCard> cardPage = new Page<>(); cardPage.setRecords(Arrays.asList(card)); when(spaceCardService.queryCardByCondition(any(CardQuery.class))).thenReturn(cardPage); // Mock demand users List<BizDemandUser> demandUsers = Collections.emptyList(); when(demandUserService.selectByDemandIds(anyList(), any(Integer.class))).thenReturn(demandUsers); // Mock report map BizReport uatReport = new BizReport(); BizReport gradationReport = new BizReport(); Map<String, BizReport> reportMap = new java.util.HashMap<>(); when(bizReportService.selectReportMap(anyList(), any(AcceptanceReportEnum.relationBizType.class), any(Integer.class))).thenReturn(reportMap); // Mock report items List<BizReportItem> reportItems = Collections.emptyList(); when(reportItemService.listReportItemByReportIds(anyList())).thenReturn(reportItems); // Mock user map Map<String, UserVO> userVOMap = new java.util.HashMap<>(); when(userHelper.getUserVoMapWithFSNameByErps(anyList(), any(Function.class), any(Function.class))).thenReturn(userVOMap); PageResult<OnlineReportCardDTO> result = onlineReportService.selectSprintCardPage(query); assertEquals(1, result.getRecords().size()); } @Test public void selectSprintAppList_SprintNotExist_ReturnEmptyList() { when(bizSpaceSprintService.getById(anyInt())).thenReturn(null); List<OnlineReportAppDTO> result = onlineReportService.selectSprintAppList(1); assertEquals(Collections.emptyList(), result); } @Test public void selectSprintAppList_SpaceNotExist_ReturnEmptyList() { BizSpaceSprint bizSpaceSprint = new BizSpaceSprint(); bizSpaceSprint.setId(1); bizSpaceSprint.setSpaceId(1); when(bizSpaceSprintService.getById(anyInt())).thenReturn(bizSpaceSprint); when(bizSpaceService.getById(anyInt())).thenReturn(null); List<OnlineReportAppDTO> result = onlineReportService.selectSprintAppList(1); assertEquals(Collections.emptyList(), result); } @Test public void selectSprintAppList_SprintAndSpaceExist_ReturnAppList() { BizSpaceSprint bizSpaceSprint = new BizSpaceSprint(); bizSpaceSprint.setId(1); bizSpaceSprint.setSpaceId(1); BizSpace bizSpace = new BizSpace(); bizSpace.setId(1); bizSpace.setKey("key"); when(bizSpaceSprintService.getById(anyInt())).thenReturn(bizSpaceSprint); when(bizSpaceService.getById(anyInt())).thenReturn(bizSpace); List<OnlineReportAppDTO> result = onlineReportService.selectSprintAppList(1); } @Test public void selectSprintAppList_test1() { onlineReportService.selectSprintAppList(1, "2"); } @Test public void selectSprintAppList_test2() { QueryReportVO queryReportVO = new QueryReportVO(); queryReportVO.setDetail(Arrays.asList(new DetailVO())); when(itsmClientService.getQueryReport(any(), any())).thenReturn(queryReportVO); onlineReportService.selectSprintAppList(1, "2"); } @Test public void sendOnlineReportNow_SprintNotExist_ShouldThrowException() { SprintOnlineReportInfoVO param = new SprintOnlineReportInfoVO(); param.setSprintId(1); when(bizSpaceSprintService.getById(1)).thenReturn(null); assertThrows(IllegalArgumentException.class, () -> { onlineReportService.sendOnlineReportNow(param); }); } @Test public void sendOnlineReportNow_SpaceNotConfigured_ShouldThrowException() { SprintOnlineReportInfoVO param = new SprintOnlineReportInfoVO(); param.setSprintId(1); BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setSpaceId(1); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(onlineReportService.selectSpaceSwitch(1)).thenReturn(false); assertThrows(IllegalArgumentException.class, () -> { onlineReportService.sendOnlineReportNow(param); }); } @Test public void sendOnlineReportNow_ValidConditions_ShouldSendReport() { SprintOnlineReportInfoVO param = new SprintOnlineReportInfoVO(); param.setSprintId(1); param.setNotifySetting(new NotifySettingDTO()); param.setOnlineReport(new OnlineReportBaseInfoDTO()); BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setSpaceId(1); sprint.setArchived(1); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(onlineReportService.selectSpaceSwitch(1)).thenReturn(true); onlineReportService.sendOnlineReportNow(param); } @Test public void genDefaultOnlineReportName_test() { onlineReportService.genDefaultOnlineReportName(new BizSpaceSprint(), "1", "2"); } @Test public void genDefaultOnlineReportName_test2() { SubSystemByParamsDTO subSystemByParamsDTO = new SubSystemByParamsDTO(); subSystemByParamsDTO.setDepartment("11"); when(cmdbClient.queryProjectByCode(any())).thenReturn(subSystemByParamsDTO); onlineReportService.genDefaultOnlineReportName(new BizSpaceSprint(), "1", ""); } @Test public void sendOnlineReportByNotifySetting_SprintNotArchived_ShouldThrowException() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(YesOrNoEnum.NO.getNumCode()); NotifySettingDTO notifySetting = new NotifySettingDTO(); OnlineReportBaseInfoDTO reportBaseInfoDTO = new OnlineReportBaseInfoDTO(); onlineReportService.sendOnlineReportByNotifySetting(sprint, notifySetting, reportBaseInfoDTO); } @Test public void sendOnlineReportByNotifySetting_SpaceNotExist_ShouldLogWarning() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(YesOrNoEnum.YES.getNumCode()); sprint.setSpaceId(1); NotifySettingDTO notifySetting = new NotifySettingDTO(); OnlineReportBaseInfoDTO reportBaseInfoDTO = new OnlineReportBaseInfoDTO(); when(bizSpaceService.getById(1)).thenReturn(null); onlineReportService.sendOnlineReportByNotifySetting(sprint, notifySetting, reportBaseInfoDTO); verify(bizSpaceService).getById(1); } @Test public void sendOnlineReportByNotifySetting_ReportBaseInfoIsNull_ShouldCreateNew() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(YesOrNoEnum.YES.getNumCode()); sprint.setSpaceId(1); sprint.setId(1); sprint.setName("sprintName"); BizSpace space = new BizSpace(); space.setId(1); space.setKey("key"); NotifySettingDTO notifySetting = new NotifySettingDTO(); notifySetting.setSendWays(Arrays.asList()); OnlineReportBaseInfoDTO reportBaseInfoDTO = null; when(bizSpaceService.getById(1)).thenReturn(space); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(spaceCardService.queryCardByCondition(any())).thenReturn(new Page<>()); onlineReportService.sendOnlineReportByNotifySetting(sprint, notifySetting, reportBaseInfoDTO); verify(bizSpaceService).getById(1); } @Test public void sendOnlineReportByNotifySetting_SendWayIsLark_ShouldCallWKMethod() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(YesOrNoEnum.YES.getNumCode()); sprint.setSpaceId(1); sprint.setId(1); sprint.setName("sprintName"); BizSpace space = new BizSpace(); space.setId(1); space.setKey("key"); NotifySettingDTO notifySetting = new NotifySettingDTO(); notifySetting.setSendWays(Arrays.asList(BizNotifySendWayEnum.LARK.getCode())); ChatInfoDataResp.ChatData chatData = new ChatInfoDataResp.ChatData(); chatData.setChatId("chatId"); notifySetting.setLarks(Arrays.asList(chatData)); OnlineReportBaseInfoDTO reportBaseInfoDTO = new OnlineReportBaseInfoDTO(); when(bizSpaceService.getById(1)).thenReturn(space); when(spaceCardService.queryCardByCondition(any())).thenReturn(new Page<>()); onlineReportService.sendOnlineReportByNotifySetting(sprint, notifySetting, reportBaseInfoDTO); } @Test public void sendOnlineReportByNotifySetting_SendWayIsEmail_ShouldCallEmailMethod() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(YesOrNoEnum.YES.getNumCode()); sprint.setSpaceId(1); sprint.setId(1); sprint.setName("sprintName"); BizSpace space = new BizSpace(); space.setId(1); space.setKey("key"); NotifySettingDTO notifySetting = new NotifySettingDTO(); notifySetting.setSendWays(Arrays.asList(BizNotifySendWayEnum.EMAIL.getCode())); notifySetting.setEmails("test@example.com"); OnlineReportBaseInfoDTO reportBaseInfoDTO = new OnlineReportBaseInfoDTO(); when(bizSpaceService.getById(1)).thenReturn(space); when(spaceCardService.queryCardByCondition(any())).thenReturn(new Page<>()); when(scriptEngineManager.getEngineByName(any())).thenReturn(new VelocityScriptEngine()); onlineReportService.sendOnlineReportByNotifySetting(sprint, notifySetting, reportBaseInfoDTO); } @Test public void sendOnlineReportForSprints_test() { BizSpaceSprint sprint = new BizSpaceSprint(); when(spaceSettingService.checkRequireKeyIsYesCode(any(), any())).thenReturn(true); when(bizSpaceSprintService.listByIds(any())).thenReturn(Arrays.asList(sprint)); onlineReportService.sendOnlineReportForSprints(Arrays.asList(1)); } @Test public void sendOnlineReportForSprints_test1() { BizSpaceSprint sprint = new BizSpaceSprint(); when(bizSpaceSprintService.listByIds(any())).thenReturn(Arrays.asList(sprint)); onlineReportService.sendOnlineReportForSprints(Arrays.asList(1)); } @Test public void sendOnlineReportForSprints_test2() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(0); when(spaceSettingService.checkRequireKeyIsYesCode(any(), any())).thenReturn(true); when(bizSpaceSprintService.listByIds(any())).thenReturn(Arrays.asList(sprint)); onlineReportService.sendOnlineReportForSprints(Arrays.asList(1)); } @Test public void sendOnlineReportForSprints_test3() { BizSpaceSprint sprint = new BizSpaceSprint(); sprint.setArchived(1); when(spaceSettingService.checkRequireKeyIsYesCode(any(), any())).thenReturn(true); BizNotifySetting bizNotifySetting = new BizNotifySetting(); when(bizNotifySettingService.getOneBy(any(), any())).thenReturn(bizNotifySetting); when(bizSpaceSprintService.listByIds(any())).thenReturn(Arrays.asList(sprint)); onlineReportService.sendOnlineReportForSprints(Arrays.asList(1)); } @Test public void selectSpaceNotifySetting_test() { onlineReportService.selectSpaceNotifySetting(1); } @Test public void selectSpaceNotifySetting_test2() { when(bizSpaceSprintService.getSpaceBySprintId(any())).thenReturn(new BizSpace().setId(1)); onlineReportService.selectSpaceNotifySetting(1); } @Test public void selectSpaceNotifySetting_test3() { when(bizSpaceSprintService.getSpaceBySprintId(any())).thenReturn(new BizSpace().setId(1)); when(bizNotifySettingService.getOneBy(any(), any())).thenReturn(new BizNotifySetting().setId(1)); onlineReportService.selectSpaceNotifySetting(1); } @Test public void queryCheckTest() { BizReport bizReport = new BizReport(); bizReport.setExtendInfo("{\"checkPoint\":\"Test CheckPoint\",\"checkPointResult\":\"Test CheckPointResult\",\"omittedIssuesForRecord\":\"Test OmittedIssuesForRecord\"}"); when(bizReportService.selectReport(AcceptanceReportEnum.reportType.ONLINE, AcceptanceReportEnum.relationBizType.SPRINT, 1)).thenReturn(bizReport); OnlineReportCheckDTO result = onlineReportService.queryCheck(1); assertNotNull(result); assertEquals("Test CheckPoint", result.getCheckPoint()); assertEquals("Test CheckPointResult", result.getCheckPointResult()); assertEquals("Test OmittedIssuesForRecord", result.getOmittedIssuesForRecord()); } @Test public void updateCheckTest() { // Mock data BizSpaceSprint sprint = new BizSpaceSprint().setId(1).setSpaceId(1); BizSpace space = new BizSpace().setId(1).setKey("key"); OnlineReportCheckDTO onlineReportCheckDTO = new OnlineReportCheckDTO() .setCheckPoint("Test CheckPoint") .setCheckPointResult("Test CheckPointResult") .setOmittedIssuesForRecord("Test OmittedIssuesForRecord"); when(bizSpaceSprintService.getById(1)).thenReturn(sprint); when(bizSpaceService.getById(1)).thenReturn(space); when(onlineReportService.getOnlineReportBaseInfoDTO(eq(sprint), eq("key"))) .thenReturn(new OnlineReportBaseInfoDTO()); // Act onlineReportService.updateCheck(onlineReportCheckDTO, 1); // Verify verify(bizReportService, times(1)).saveOrUpdateOnlineReport(1, any(OnlineReportBaseInfoDTO.class)); } } 以下是onlineReportService对应类的代码:package com.jd.jacp.report.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.jd.jacp.client.dto.CICDAppGrayscaleDeployInfo; import com.jd.jacp.client.dto.GetCiCdTaskQuery; import com.jd.jacp.client.service.ICicdClient; import com.jd.jacp.client.service.ICmdbClient; import com.jd.jacp.client.service.ItsmClientService; import com.jd.jacp.common.feishu.FeiShuMessageSender; import com.jd.jacp.common.service.UserHelper; import com.jd.jacp.common.vo.UserVO; import com.jd.jacp.common.vo.enums.YesOrNoEnum; import com.jd.jacp.demand.entity.BizDemandUser; import com.jd.jacp.demand.service.IBizDemandUserService; import com.jd.jacp.demand.vo.DemandUserTypeEnum; import com.jd.jacp.notify.entity.BizNotifyRule; import com.jd.jacp.notify.entity.BizNotifySetting; import com.jd.jacp.notify.enums.BizNotifySendWayEnum; import com.jd.jacp.notify.enums.BizNotifyTypeEnum; import com.jd.jacp.notify.service.IBizNotifyRuleService; import com.jd.jacp.notify.service.IBizNotifySettingService; import com.jd.jacp.report.dto.*; import com.jd.jacp.report.entity.BizReport; import com.jd.jacp.report.entity.BizReportItem; import com.jd.jacp.report.enums.AcceptanceReportEnum; import com.jd.jacp.report.service.IBizReportItemService; import com.jd.jacp.report.service.IBizReportService; import com.jd.jacp.report.service.IOnlineReportService; import com.jd.jacp.report.vo.SprintOnlineReportInfoVO; import com.jd.jacp.space.dto.CardQuery; import com.jd.jacp.space.dto.SubSystemByParamsDTO; import com.jd.jacp.space.entity.BizSpace; import com.jd.jacp.space.entity.BizSpaceCard; import com.jd.jacp.space.entity.BizSpaceSprint; import com.jd.jacp.space.service.IBizSpaceCardService; import com.jd.jacp.space.service.IBizSpaceService; import com.jd.jacp.space.service.IBizSpaceSettingService; import com.jd.jacp.space.service.IBizSpaceSprintService; import com.jd.jacp.space.service.impl.BizSpaceSettingServiceImpl; import com.jd.jacp.space.vo.DetailVO; import com.jd.jacp.space.vo.QueryReportVO; import com.jd.jacp.util.AssertUtil; import com.jd.jacp.util.EmailSender; import com.msxf.devops.common.PageResult; import com.msxf.fcid.xmsg.reponse.ChatInfoDataResp; import com.msxf.fcid.xmsg.sdk.response.FeishuMessageSendResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import java.io.InputStream; import java.io.StringWriter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author ke.feng-n */ @Slf4j @Service public class OnlineReportServiceImpl implements IOnlineReportService { @Autowired private IBizSpaceSprintService bizSpaceSprintService; @Autowired private ItsmClientService itsmClientService; @Autowired private IBizReportService bizReportService; @Autowired private ICmdbClient cmdbClient; @Autowired private IBizSpaceService bizSpaceService; @Autowired private IBizNotifySettingService bizNotifySettingService; @Autowired private IBizNotifyRuleService bizNotifyRuleService; @Autowired private IBizSpaceCardService spaceCardService; @Autowired private IBizDemandUserService demandUserService; @Autowired private IBizReportItemService reportItemService; @Autowired private UserHelper userHelper; @Resource(name = "scriptEngineManager") private ScriptEngineManager scriptEngineManager; @Autowired private FeiShuMessageSender feiShuMessageSender; @Autowired private ICicdClient cicdClient; @Autowired private IBizSpaceSettingService spaceSettingService; @Value("${env.domain.name}") private String domain; @Resource EmailSender emailSender; @Override public SprintOnlineReportInfoVO selectOnlineReportInfo(Integer sprintId) { BizSpaceSprint sprint = bizSpaceSprintService.getById(sprintId); Assert.notNull(sprint, "迭代不存在"); BizSpace space = bizSpaceService.getById(sprint.getSpaceId()); Assert.notNull(space, "迭代所属子系统不存在"); //获取报告名称和遗漏问题 OnlineReportBaseInfoDTO onlineReportBaseInfoDTO = getOnlineReportBaseInfoDTO(sprint, space.getKey()); SprintOnlineReportInfoVO reportInfoVO = new SprintOnlineReportInfoVO(); reportInfoVO.setOnlineReport(onlineReportBaseInfoDTO); //获取迭代的通知配置信息 BizNotifySetting sprintNotifySetting = getSprintNotifySetting(sprint); if (ObjectUtil.isEmpty(sprintNotifySetting)) { return reportInfoVO; } BizNotifyRule notifyRule = bizNotifyRuleService.getOneByNotifyId(sprintNotifySetting.getId()); NotifySettingDTO notifySetting = NotifySettingDTO.of(sprintNotifySetting, notifyRule); reportInfoVO.setNotifySetting(notifySetting); return reportInfoVO; } /** * 获取迭代的基础配置信息(报告名称,) * * @param sprint * @param spaceKey * @return */ public OnlineReportBaseInfoDTO getOnlineReportBaseInfoDTO(BizSpaceSprint sprint, String spaceKey) { BizReport bizReport = bizReportService.selectReport(AcceptanceReportEnum.reportType.ONLINE, AcceptanceReportEnum.relationBizType.SPRINT, sprint.getId()); OnlineReportBaseInfoDTO onlineReportBaseInfoDTO; if (ObjectUtil.isNotEmpty(bizReport) && StrUtil.isNotBlank(bizReport.getExtendInfo())) { onlineReportBaseInfoDTO = JSONUtil.toBean(bizReport.getExtendInfo(), OnlineReportBaseInfoDTO.class); } else { BizNotifySetting spaceNotifySetting = bizNotifySettingService.getOneBy(String.valueOf(sprint.getSpaceId()), BizNotifyTypeEnum.SPACE_SPRINT_ONLINE_REPORT.getCode()); onlineReportBaseInfoDTO = genDefaultOnlineReportName(sprint, spaceKey, ObjectUtil.isEmpty(spaceNotifySetting) ? null : spaceNotifySetting.getRelatedObjName()); } return onlineReportBaseInfoDTO; } @Override @Transactional(rollbackFor = Exception.class) public void saveSprintNotifySetting(SprintOnlineReportInfoVO param) { bizReportService.saveOrUpdateOnlineReport(param.getSprintId(), param.getOnlineReport()); Integer notifyId = bizNotifySettingService.saveOrUpdateNotifySetting(BizNotifyTypeEnum.SPRINT_ONLINE_REPORT, String.valueOf(param.getSprintId()), param.getNotifySetting(), null); bizNotifyRuleService.saveOrUpdateNotifyRule(notifyId, param.getNotifySetting().getSendTime()); } @Override @Transactional(rollbackFor = Exception.class) public void saveSpaceNotifySetting(SprintOnlineReportInfoVO param) { BizSpaceSprint sprint = bizSpaceSprintService.getById(param.getSprintId()); Assert.notNull(sprint, "迭代不存在"); Integer notifyId = bizNotifySettingService.saveOrUpdateNotifySetting(BizNotifyTypeEnum.SPACE_SPRINT_ONLINE_REPORT, String.valueOf(sprint.getSpaceId()), param.getNotifySetting(), param.getOnlineReport().getDepartment()); bizNotifyRuleService.saveOrUpdateNotifyRule(notifyId, param.getNotifySetting().getSendTime()); } @Override public PageResult<OnlineReportCardDTO> selectSprintCardPage(CardQuery query) { Page<BizSpaceCard> cardPage = spaceCardService.queryCardByCondition(query); List<OnlineReportCardDTO> cardDTOList = OnlineReportCardDTO.buildFromCardEntity(cardPage.getRecords()); if (CollectionUtil.isEmpty(cardDTOList)) { return PageResult.newEmptyPage(Long.valueOf(query.getPageNum()), Long.valueOf(query.getPageSize())); } //获取需求提报人列表 List<Integer> demandIds = cardDTOList.stream().map(OnlineReportCardDTO::getDemandId).distinct().collect(Collectors.toList()); List<BizDemandUser> bizDemandUsers = demandUserService.selectFeishuUserByDemandIds(demandIds, DemandUserTypeEnum.CONTACT_TYPE_BIZ.getId()); Map<Integer, List<BizDemandUser>> submitterMap = bizDemandUsers.stream().collect(Collectors.groupingBy(BizDemandUser::getDemandId)); List<String> cardErps = cardDTOList.stream() .flatMap(cardDTO -> Stream.of( cardDTO.getProductManagerErp(), cardDTO.getProcessorErp(), cardDTO.getTestLeaderErp() )).distinct() .collect(Collectors.toList()); Map<String, BizReport> reportMap = bizReportService.selectReportMap(Arrays.asList(AcceptanceReportEnum.reportType.UAT, AcceptanceReportEnum.reportType.GRADATION), AcceptanceReportEnum.relationBizType.SPRINT, query.getSprintId()); List<Integer> reportIds = reportMap.values().stream().map(BizReport::getId).collect(Collectors.toList()); //获取验收报告信息 List<String> acceptorErps = Collections.emptyList(); Map<Integer, Map<String, BizReportItem>> reportItemMap = new HashMap<>(); if(CollectionUtil.isNotEmpty(reportIds)) { List<BizReportItem> reportItems = reportItemService.listReportItemByReportIds(reportIds); acceptorErps = reportItems.stream().map(BizReportItem::getAccepters) .flatMap(erp -> JSONUtil.toList(erp, String.class).stream()) .filter(StrUtil::isNotBlank) .distinct() .collect(Collectors.toList()); //报告id-卡片id-报告项 reportItemMap = reportItems.stream().collect(Collectors.groupingBy(BizReportItem::getReportId, Collectors.toMap(BizReportItem::getRelationItemIdentifier, Function.identity(), (v1, v2) -> v1))); } cardErps.addAll(acceptorErps); Map<String, UserVO> userVOMap = userHelper.getUserVoMapWithFSNameByErps(cardErps.stream().filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList()), UserVO::getErp, Function.identity()); for (OnlineReportCardDTO cardDTO : cardDTOList) { //填充需求提报人 cardDTO.setSubmitter(BizDemandUser.buildUserVOList(submitterMap.get(cardDTO.getDemandId()))); //填充卡片相关人信息 cardDTO.setProductManager(userVOMap.get(cardDTO.getProductManagerErp())); cardDTO.setProcessor(userVOMap.get(cardDTO.getProcessorErp())); cardDTO.setTestLeader(userVOMap.get(cardDTO.getTestLeaderErp())); //填充UAT验收信息 BizReport uatReport = reportMap.get(AcceptanceReportEnum.reportType.UAT.name()); cardDTO.fillUATAcceptanceInfo(reportItemMap, uatReport, userVOMap); //填充灰度验收信息 BizReport gradationReport = reportMap.get(AcceptanceReportEnum.reportType.GRADATION.name()); cardDTO.fillGradationAcceptanceInfo(reportItemMap, gradationReport, userVOMap); } return PageResult.newInstance(cardDTOList, cardPage.getPages(), cardPage.getTotal(), cardPage.getCurrent(), cardPage.getSize()); } @Override public List<OnlineReportAppDTO> selectSprintAppList(Integer sprintId) { BizSpaceSprint sprint = bizSpaceSprintService.getById(sprintId); if (ObjectUtil.isEmpty(sprint)) { return Collections.emptyList(); } BizSpace space = bizSpaceService.getById(sprint.getSpaceId()); if (ObjectUtil.isEmpty(space)) { return Collections.emptyList(); } return this.selectSprintAppList(sprintId, space.getKey()); } @Override public List<OnlineReportAppDTO> selectSprintAppList(Integer sprintId, String spaceKey) { DetailVO itsmDetail = getSprintItsmOnlineDetail(sprintId, spaceKey); if (ObjectUtil.isEmpty(itsmDetail) || ObjectUtil.isEmpty(itsmDetail.getApplyCode())) { return Collections.emptyList(); } List<CICDAppGrayscaleDeployInfo> cicdAppGrayscaleDeployInfos = Collections.emptyList(); try { cicdAppGrayscaleDeployInfos = cicdClient.getTaskListByParam(GetCiCdTaskQuery.buildQueryProdTaskQuery(itsmDetail.getApplyCode())); } catch (Exception e) { log.warn("调用CICD接口查询迭代部署完成应用列表失败:", e); } return OnlineReportAppDTO.buildList(cicdAppGrayscaleDeployInfos); } @Override public void sendOnlineReportNow(SprintOnlineReportInfoVO param) { BizSpaceSprint sprint = bizSpaceSprintService.getById(param.getSprintId()); Assert.notNull(sprint, "迭代不存在"); boolean sendSwitch = this.selectSpaceSwitch(sprint.getSpaceId()); Assert.isTrue(sendSwitch, "空间未开启上线报告发送配置"); this.sendOnlineReportByNotifySetting(sprint, param.getNotifySetting(), param.getOnlineReport()); } /** * 查询迭代卡片列表 * * @param sprintId */ public List<OnlineReportCardDTO> selectSprintCardList(Integer sprintId) { CardQuery cardQuery = new CardQuery(); cardQuery.setSprintId(sprintId); cardQuery.setPageNum(1); cardQuery.setPageSize(10000); PageResult<OnlineReportCardDTO> sprintCardPage = this.selectSprintCardPage(cardQuery); return sprintCardPage.getRecords(); } /** * 生成默认的上线报告名称 * * @return */ public OnlineReportBaseInfoDTO genDefaultOnlineReportName(BizSpaceSprint sprint, String spaceKey, String department) { if (StrUtil.isBlank(department)) { SubSystemByParamsDTO subSystemByParamsDTO = cmdbClient.queryProjectByCode(spaceKey); department = ObjectUtil.isNotEmpty(subSystemByParamsDTO) ? subSystemByParamsDTO.getDepartment() : "暂无部门"; } //获取迭代上线流程信息 DetailVO detailVO = getSprintItsmOnlineDetail(sprint.getId(), spaceKey); String deployType = Optional.ofNullable(detailVO).map(DetailVO::getDeployType).orElse(""); String sprintEndDate = ObjectUtil.isNotEmpty(sprint.getEndDate()) ? DateUtil.format(sprint.getEndDate(), DatePattern.PURE_DATE_FORMAT) : ""; String reportName = "版本发布" + "-" + department + "-" + deployType + "-" + sprintEndDate; return new OnlineReportBaseInfoDTO().setReportName(reportName).setDepartment(department).setDeployType(deployType).setSprintEndDate(sprintEndDate); } /** * 获取迭代上线流程信息 * * @param sprintId * @param spaceKey * @return */ private DetailVO getSprintItsmOnlineDetail(Integer sprintId, String spaceKey) { QueryReportVO queryReport = itsmClientService.getQueryReport(sprintId, spaceKey); DetailVO detailVO = null; if (ObjectUtil.isNotEmpty(queryReport) && CollectionUtil.isNotEmpty(queryReport.getDetail())) { detailVO = queryReport.getDetail().get(0); } return detailVO; } @Override public String sprintDeployReportWK(SprintOnlineReportInfoDTO sprintOnlineReportInfoDTO, List<String> chats, boolean acceptanceReportEnable) { SprintDeployReportDTO dto = SprintDeployReportDTO.convertFromSprintOnlineReportInfoDTO(sprintOnlineReportInfoDTO, domain, BizNotifySendWayEnum.LARK.getCode(), acceptanceReportEnable); try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream( acceptanceReportEnable ? "templates/SprintDeployReport.json" : "templates/SprintDeployReport-NoAcceptance.json")) { String content = IOUtils.toString(inputStream); ScriptEngine engine = scriptEngineManager.getEngineByName("velocity"); JSONObject wkParam = JSON.parseObject(JSON.toJSONString(dto)); ScriptContext scriptContext = engine.getContext(); wkParam.keySet().forEach(key -> scriptContext.setAttribute(key, wkParam.get(key), ScriptContext.ENGINE_SCOPE)); scriptContext.setWriter(new StringWriter()); String contentText = engine.eval(content).toString(); FeishuMessageSendResponse response = feiShuMessageSender.withCustomTemplate(contentText, "global-template-notice", chats, null, null); AssertUtil.notNull(response, "no response"); AssertUtil.isTrue(Objects.equals(response.getCode(), "0"), response.getMsg()); AssertUtil.notEmpty(response.getData(), "wk message send fault"); return response.getData().get(0); } catch (Exception e) { log.error("sprint deploy report wk message send error", e); } return null; } @Override public void sendOnlineReportByNotifySetting(BizSpaceSprint sprint, NotifySettingDTO notifySetting, OnlineReportBaseInfoDTO reportBaseInfoDTO) { BizSpace space = bizSpaceService.getById(sprint.getSpaceId()); if (ObjectUtil.isEmpty(space)) { log.warn("【发送上线报告】迭代所属子系统不存在:{}", sprint.getSpaceId()); return; } if(ObjectUtil.isEmpty(reportBaseInfoDTO)) { reportBaseInfoDTO = this.getOnlineReportBaseInfoDTO(sprint, space.getKey()); } List<OnlineReportCardDTO> cardList = this.selectSprintCardList(sprint.getId()); List<OnlineReportAppDTO> appList = this.selectSprintAppList(sprint.getId(), space.getKey()); SprintOnlineReportInfoDTO reportInfoDTO = new SprintOnlineReportInfoDTO() .setSprintId(sprint.getId()) .setSprintName(sprint.getName()) .setSpaceKey(space.getKey()) .setOnlineReportBaseInfo(reportBaseInfoDTO) .setOnlineReportCardList(cardList) .setOnlineReportAppList(appList); List<String> sendWays = notifySetting.getSendWays(); boolean acceptanceReportEnable = spaceSettingService.acceptanceReportEnable(space.getId()); if (sendWays.contains(BizNotifySendWayEnum.LARK.getCode())) { List<String> chatIds = notifySetting.getLarks().stream().map(ChatInfoDataResp.ChatData::getChatId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); this.sprintDeployReportWK(reportInfoDTO, chatIds, acceptanceReportEnable); } if (sendWays.contains(BizNotifySendWayEnum.EMAIL.getCode())) { this.sprintDeployReportEmail(reportInfoDTO, Arrays.asList(notifySetting.getEmails().split(",")), null, acceptanceReportEnable); } } @Override public NotifySettingDTO selectSpaceNotifySetting(Integer sprintId) { BizSpace space = bizSpaceSprintService.getSpaceBySprintId(sprintId); if (ObjectUtil.isEmpty(space)) { return null; } BizNotifySetting spaceNotifySetting = bizNotifySettingService.getOneBy(String.valueOf(space.getId()), BizNotifyTypeEnum.SPACE_SPRINT_ONLINE_REPORT.getCode()); if (ObjectUtil.isEmpty(spaceNotifySetting)) { return null; } BizNotifyRule notifyRule = bizNotifyRuleService.getOneByNotifyId(spaceNotifySetting.getId()); return NotifySettingDTO.of(spaceNotifySetting, notifyRule); } @Override public void sendOnlineReportForSprints(List<Integer> sprintIds) { List<BizSpaceSprint> sprints = bizSpaceSprintService.listByIds(sprintIds); for (BizSpaceSprint sprint : sprints) { if(!this.selectSpaceSwitch(sprint.getSpaceId())) { continue; } if (YesOrNoEnum.NO.getNumCode().equals(sprint.getArchived())) { continue; } BizNotifySetting notifySetting = getSprintNotifySetting(sprint); if (ObjectUtil.isEmpty(notifySetting)) { return; } this.sendOnlineReportByNotifySetting(sprint, NotifySettingDTO.of(notifySetting), null); } } @Override public void sprintDeployReportEmail(SprintOnlineReportInfoDTO sprintOnlineReportInfoDTO, List<String> receiver, List<String> carbon, boolean acceptanceReportEnable) { SprintDeployReportDTO dto = SprintDeployReportDTO.convertFromSprintOnlineReportInfoDTO(sprintOnlineReportInfoDTO, domain, BizNotifySendWayEnum.EMAIL.getCode(), acceptanceReportEnable); try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("templates/SprintDeployReport.html")) { String content = IOUtils.toString(inputStream); ScriptEngine engine = scriptEngineManager.getEngineByName("velocity"); JSONObject htmlParam = JSON.parseObject(JSON.toJSONString(dto)); ScriptContext scriptContext = engine.getContext(); htmlParam.keySet().forEach(key -> { scriptContext.setAttribute(key, htmlParam.get(key), ScriptContext.ENGINE_SCOPE); }); scriptContext.setAttribute("acceptance_report_enable", acceptanceReportEnable, ScriptContext.ENGINE_SCOPE); scriptContext.setWriter(new StringWriter()); String contentText = engine.eval(content).toString(); emailSender.dcpSendEmail(receiver, carbon, String.format("%s一上线报告", dto.getSprintTitle()), contentText); } catch (Exception e) { log.error("sprint deploy report email message send error", e); } } /** * 获取迭代可用的通知配置信息 * * @param sprint * @return */ @Override public BizNotifySetting getSprintNotifySetting(BizSpaceSprint sprint) { if(ObjectUtil.isEmpty(sprint)) { return null; } BizNotifySetting sprintNotifySetting = bizNotifySettingService.getOneBy(String.valueOf(sprint.getId()), BizNotifyTypeEnum.SPRINT_ONLINE_REPORT.getCode()); if (ObjectUtil.isEmpty(sprintNotifySetting)) { sprintNotifySetting = bizNotifySettingService.getOneBy(String.valueOf(sprint.getSpaceId()), BizNotifyTypeEnum.SPACE_SPRINT_ONLINE_REPORT.getCode()); } return sprintNotifySetting; } @Override public boolean selectSpaceSwitch(Integer spaceId) { return spaceSettingService.checkRequireKeyIsYesCode(spaceId, BizSpaceSettingServiceImpl.REQUIRED_SEND_REPORT_AFTER_SPRINT_ARCHIVED); } /** * 根据迭代id查询生产验证情况 * @param sprintId * @return */ @Override public OnlineReportCheckDTO queryCheck(Integer sprintId) { BizReport bizReport = bizReportService.selectReport(AcceptanceReportEnum.reportType.ONLINE, AcceptanceReportEnum.relationBizType.SPRINT, sprintId); OnlineReportBaseInfoDTO onlineReportBaseInfoDTO; OnlineReportCheckDTO onlineReportCheckDTO = new OnlineReportCheckDTO(); if (ObjectUtil.isNotEmpty(bizReport) && StrUtil.isNotBlank(bizReport.getExtendInfo())) { onlineReportBaseInfoDTO = JSONUtil.toBean(bizReport.getExtendInfo(), OnlineReportBaseInfoDTO.class); onlineReportCheckDTO.setCheckPoint(onlineReportBaseInfoDTO.getCheckPoint()); onlineReportCheckDTO.setCheckPointResult(onlineReportBaseInfoDTO.getCheckPointResult()); onlineReportCheckDTO.setOmittedIssuesForRecord(onlineReportBaseInfoDTO.getOmittedIssuesForRecord()); } return onlineReportCheckDTO; } /** * 更新生产验证情况 * @param onlineReportCheckDTO * @param sprintId */ @Override public void updateCheck(OnlineReportCheckDTO onlineReportCheckDTO, Integer sprintId) { BizSpaceSprint sprint = bizSpaceSprintService.getById(sprintId); Assert.notNull(sprint, "迭代不存在"); BizSpace space = bizSpaceService.getById(sprint.getSpaceId()); Assert.notNull(space, "迭代所属子系统不存在"); //获取报告名称和遗漏问题 OnlineReportBaseInfoDTO onlineReportBaseInfoDTO = getOnlineReportBaseInfoDTO(sprint, space.getKey()); //设置数据 onlineReportBaseInfoDTO.setCheckPoint(onlineReportCheckDTO.getCheckPoint()); onlineReportBaseInfoDTO.setCheckPointResult(onlineReportCheckDTO.getCheckPointResult()); onlineReportBaseInfoDTO.setOmittedIssuesForRecord(onlineReportCheckDTO.getOmittedIssuesForRecord()); //如果有数据直接更新,没有生成新数据 bizReportService.saveOrUpdateOnlineReport(sprintId, onlineReportBaseInfoDTO); } } 当运行updateCheckTest时,报错:java.lang.NullPointerException at com.jd.jacp.report.service.impl.OnlineReportServiceImpl.getOnlineReportBaseInfoDTO(OnlineReportServiceImpl.java:163) at com.jd.jacp.unit.report.OnlineReportServiceImplTest.updateCheckTest(OnlineReportServiceImplTest.java:567) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) Process finished with exit code -1
最新发布
09-04
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值