您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ChangelogActionTest.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.qualityprofile.ws;
  21. import com.google.common.collect.ImmutableMap;
  22. import java.util.Arrays;
  23. import java.util.Map;
  24. import java.util.function.Consumer;
  25. import javax.annotation.Nullable;
  26. import org.junit.Rule;
  27. import org.junit.Test;
  28. import org.junit.rules.ExpectedException;
  29. import org.sonar.api.resources.Languages;
  30. import org.sonar.api.rule.RuleKey;
  31. import org.sonar.api.server.ws.WebService;
  32. import org.sonar.api.utils.DateUtils;
  33. import org.sonar.api.utils.internal.TestSystem2;
  34. import org.sonar.db.DbTester;
  35. import org.sonar.db.organization.OrganizationDto;
  36. import org.sonar.db.qualityprofile.QProfileChangeDto;
  37. import org.sonar.db.qualityprofile.QProfileDto;
  38. import org.sonar.db.rule.RuleDefinitionDto;
  39. import org.sonar.db.user.UserDto;
  40. import org.sonar.server.exceptions.ForbiddenException;
  41. import org.sonar.server.exceptions.NotFoundException;
  42. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  43. import org.sonar.server.qualityprofile.ActiveRuleChange;
  44. import org.sonar.server.qualityprofile.ActiveRuleInheritance;
  45. import org.sonar.server.tester.UserSessionRule;
  46. import org.sonar.server.ws.WsActionTester;
  47. import static java.lang.String.format;
  48. import static java.lang.String.valueOf;
  49. import static org.assertj.core.api.Assertions.assertThat;
  50. import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
  51. import static org.sonar.test.JsonAssert.assertJson;
  52. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
  53. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
  54. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
  55. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
  56. import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SINCE;
  57. public class ChangelogActionTest {
  58. private static final String DATE = "2011-04-25T01:15:42+0100";
  59. private TestSystem2 system2 = new TestSystem2().setNow(DateUtils.parseDateTime(DATE).getTime());
  60. @Rule
  61. public DbTester db = DbTester.create(system2);
  62. @Rule
  63. public UserSessionRule userSession = UserSessionRule.standalone();
  64. @Rule
  65. public ExpectedException expectedException = ExpectedException.none();
  66. private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, TestDefaultOrganizationProvider.from(db));
  67. private WsActionTester ws = new WsActionTester(
  68. new ChangelogAction(wsSupport, new Languages(), db.getDbClient()));
  69. @Test
  70. public void return_change_with_all_fields() {
  71. OrganizationDto organization = db.organizations().insert();
  72. QProfileDto profile = db.qualityProfiles().insert(organization);
  73. UserDto user = db.users().insertUser();
  74. RuleDefinitionDto rule = db.rules().insert(RuleKey.of("java", "S001"));
  75. insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user, ImmutableMap.of(
  76. "ruleId", valueOf(rule.getId()),
  77. "severity", "MINOR",
  78. "inheritance", ActiveRuleInheritance.INHERITED.name(),
  79. "param_foo", "foo_value",
  80. "param_bar", "bar_value"));
  81. String response = ws.newRequest()
  82. .setParam(PARAM_KEY, profile.getKee())
  83. .execute()
  84. .getInput();
  85. assertJson(response).isSimilarTo("{\n" +
  86. " \"total\": 1,\n" +
  87. " \"p\": 1,\n" +
  88. " \"ps\": 50,\n" +
  89. " \"events\": [\n" +
  90. " {\n" +
  91. " \"date\": \"" + DATE + "\",\n" +
  92. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  93. " \"authorName\": \"" + user.getName() + "\",\n" +
  94. " \"action\": \"ACTIVATED\",\n" +
  95. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  96. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  97. " \"params\": {\n" +
  98. " \"severity\": \"MINOR\",\n" +
  99. " \"bar\": \"bar_value\",\n" +
  100. " \"foo\": \"foo_value\"\n" +
  101. " }\n" +
  102. " }\n" +
  103. " ]\n" +
  104. "}");
  105. }
  106. @Test
  107. public void find_changelog_by_profile_key() {
  108. OrganizationDto organization = db.organizations().insert();
  109. QProfileDto profile = db.qualityProfiles().insert(organization);
  110. RuleDefinitionDto rule = db.rules().insert();
  111. UserDto user = db.users().insertUser();
  112. insertChange(profile, ActiveRuleChange.Type.ACTIVATED, user,
  113. ImmutableMap.of(
  114. "ruleId", valueOf(rule.getId()),
  115. "severity", "MINOR"));
  116. String response = ws.newRequest()
  117. .setParam(PARAM_KEY, profile.getKee())
  118. .execute()
  119. .getInput();
  120. assertJson(response).isSimilarTo("{\n" +
  121. " \"events\": [\n" +
  122. " {\n" +
  123. " \"date\": \"" + DATE + "\",\n" +
  124. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  125. " \"action\": \"ACTIVATED\",\n" +
  126. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  127. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  128. " \"params\": {\n" +
  129. " \"severity\": \"MINOR\"\n" +
  130. " }\n" +
  131. " }\n" +
  132. " ]\n" +
  133. "}");
  134. }
  135. @Test
  136. public void find_changelog_by_language_and_name() {
  137. QProfileDto qualityProfile = db.qualityProfiles().insert(db.getDefaultOrganization());
  138. RuleDefinitionDto rule = db.rules().insert();
  139. UserDto user = db.users().insertUser();
  140. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
  141. ImmutableMap.of(
  142. "ruleId", valueOf(rule.getId()),
  143. "severity", "MINOR"));
  144. String response = ws.newRequest()
  145. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  146. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  147. .execute()
  148. .getInput();
  149. assertJson(response).isSimilarTo("{\n" +
  150. " \"events\": [\n" +
  151. " {\n" +
  152. " \"date\": \"" + DATE + "\",\n" +
  153. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  154. " \"action\": \"ACTIVATED\",\n" +
  155. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  156. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  157. " \"params\": {\n" +
  158. " \"severity\": \"MINOR\"\n" +
  159. " }\n" +
  160. " }\n" +
  161. " ]\n" +
  162. "}");
  163. }
  164. @Test
  165. public void find_changelog_by_organization_and_language_and_name() {
  166. OrganizationDto organization = db.organizations().insert();
  167. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  168. RuleDefinitionDto rule = db.rules().insert();
  169. UserDto user = db.users().insertUser();
  170. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
  171. ImmutableMap.of(
  172. "ruleId", valueOf(rule.getId()),
  173. "severity", "MINOR"));
  174. String response = ws.newRequest()
  175. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  176. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  177. .setParam(PARAM_ORGANIZATION, organization.getKey())
  178. .execute()
  179. .getInput();
  180. assertJson(response).isSimilarTo("{\n" +
  181. " \"events\": [\n" +
  182. " {\n" +
  183. " \"date\": \"" + DATE + "\",\n" +
  184. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  185. " \"action\": \"ACTIVATED\",\n" +
  186. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  187. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  188. " \"params\": {\n" +
  189. " \"severity\": \"MINOR\"\n" +
  190. " }\n" +
  191. " }\n" +
  192. " ]\n" +
  193. "}");
  194. }
  195. @Test
  196. public void changelog_empty() {
  197. OrganizationDto organization = db.organizations().insert();
  198. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  199. String response = ws.newRequest()
  200. .setParam(PARAM_KEY, qualityProfile.getKee())
  201. .execute()
  202. .getInput();
  203. assertJson(response).isSimilarTo("{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}");
  204. }
  205. @Test
  206. public void changelog_filter_by_since() {
  207. OrganizationDto organization = db.organizations().insert();
  208. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  209. system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
  210. RuleDefinitionDto rule = db.rules().insert();
  211. UserDto user = db.users().insertUser();
  212. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
  213. ImmutableMap.of(
  214. "ruleId", valueOf(rule.getId()),
  215. "severity", "MINOR"));
  216. assertJson(ws.newRequest()
  217. .setParam(PARAM_KEY, qualityProfile.getKee())
  218. .setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100")
  219. .execute()
  220. .getInput()).isSimilarTo("{\n" +
  221. " \"events\": [\n" +
  222. " {\n" +
  223. " \"date\": \"2011-04-25T01:15:42+0100\",\n" +
  224. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  225. " \"action\": \"ACTIVATED\",\n" +
  226. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  227. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  228. " }\n" +
  229. " ]\n" +
  230. "}");
  231. assertJson(ws.newRequest()
  232. .setParam(PARAM_KEY, qualityProfile.getKee())
  233. .setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100")
  234. .execute()
  235. .getInput()).isSimilarTo("{\n" +
  236. " \"events\": []\n" +
  237. "}");
  238. }
  239. @Test
  240. public void sort_changelog_events_in_reverse_chronological_order() {
  241. OrganizationDto organization = db.organizations().insert();
  242. QProfileDto profile = db.qualityProfiles().insert(organization);
  243. system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
  244. RuleDefinitionDto rule1 = db.rules().insert();
  245. insertChange(profile, ActiveRuleChange.Type.ACTIVATED, null,
  246. ImmutableMap.of(
  247. "ruleId", valueOf(rule1.getId()),
  248. "severity", "MINOR"));
  249. system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:43+0100").getTime());
  250. UserDto user = db.users().insertUser();
  251. RuleDefinitionDto rule2 = db.rules().insert();
  252. insertChange(profile, ActiveRuleChange.Type.DEACTIVATED, user,
  253. ImmutableMap.of("ruleId", valueOf(rule2.getId())));
  254. String response = ws.newRequest()
  255. .setParam(PARAM_KEY, profile.getKee())
  256. .execute()
  257. .getInput();
  258. assertJson(response).isSimilarTo("{\n" +
  259. "\"events\": [\n" +
  260. " {\n" +
  261. " \"date\": \"2011-04-25T02:15:43+0200\",\n" +
  262. " \"action\": \"DEACTIVATED\",\n" +
  263. " \"authorLogin\": \"" + user.getLogin() + "\",\n" +
  264. " \"ruleKey\": \"" + rule2.getKey() + "\",\n" +
  265. " \"ruleName\": \"" + rule2.getName() + "\",\n" +
  266. " \"params\": {}\n" +
  267. " },\n" +
  268. " {\n" +
  269. " \"date\": \"2011-04-25T02:15:42+0200\",\n" +
  270. " \"action\": \"ACTIVATED\",\n" +
  271. " \"ruleKey\": \"" + rule1.getKey() + "\",\n" +
  272. " \"ruleName\": \"" + rule1.getName() + "\",\n" +
  273. " \"params\": {\n" +
  274. " \"severity\": \"MINOR\"\n" +
  275. " }\n" +
  276. " }\n" +
  277. " ]" +
  278. "}");
  279. }
  280. @Test
  281. public void changelog_on_no_more_existing_rule() {
  282. OrganizationDto organization = db.organizations().insert();
  283. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  284. UserDto user = db.users().insertUser();
  285. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
  286. ImmutableMap.of("ruleId", "123"));
  287. String response = ws.newRequest()
  288. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  289. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  290. .setParam(PARAM_ORGANIZATION, organization.getKey())
  291. .execute()
  292. .getInput();
  293. assertJson(response).isSimilarTo("{\n" +
  294. " \"events\": [\n" +
  295. " {\n" +
  296. " \"date\": \"" + DATE + "\",\n" +
  297. " \"action\": \"ACTIVATED\",\n" +
  298. " \"params\": {}\n" +
  299. " }\n" +
  300. " ]\n" +
  301. "}");
  302. assertThat(response).doesNotContain("ruleKey", "ruleName");
  303. }
  304. @Test
  305. public void changelog_on_no_more_existing_user() {
  306. OrganizationDto organization = db.organizations().insert();
  307. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  308. RuleDefinitionDto rule = db.rules().insert();
  309. insertChange(c -> c.setRulesProfileUuid(qualityProfile.getRulesProfileUuid())
  310. .setUserUuid("UNKNOWN")
  311. .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
  312. .setData(ImmutableMap.of("ruleId", rule.getId())));
  313. String response = ws.newRequest()
  314. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  315. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  316. .setParam(PARAM_ORGANIZATION, organization.getKey())
  317. .execute()
  318. .getInput();
  319. assertJson(response).isSimilarTo("{\n" +
  320. " \"events\": [\n" +
  321. " {\n" +
  322. " \"date\": \"" + DATE + "\",\n" +
  323. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  324. " \"ruleName\": \"" + rule.getName() + "\",\n" +
  325. " \"action\": \"ACTIVATED\",\n" +
  326. " \"params\": {}\n" +
  327. " }\n" +
  328. " ]\n" +
  329. "}");
  330. assertThat(response).doesNotContain("authorLogin", "authorName");
  331. }
  332. @Test
  333. public void changelog_on_paid_organization() {
  334. OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
  335. UserDto user = db.users().insertUser();
  336. userSession.logIn(user).addMembership(organization);
  337. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  338. RuleDefinitionDto rule = db.rules().insert();
  339. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, db.users().insertUser(),
  340. ImmutableMap.of(
  341. "ruleId", valueOf(rule.getId()),
  342. "severity", "MINOR"));
  343. String response = ws.newRequest()
  344. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  345. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  346. .setParam(PARAM_ORGANIZATION, organization.getKey())
  347. .execute()
  348. .getInput();
  349. assertJson(response).isSimilarTo("{\n" +
  350. " \"events\": [\n" +
  351. " {\n" +
  352. " \"ruleKey\": \"" + rule.getKey() + "\",\n" +
  353. " }\n" +
  354. " ]\n" +
  355. "}");
  356. }
  357. @Test
  358. public void do_not_find_changelog_by_wrong_organization_and_language_and_name() {
  359. OrganizationDto organization1 = db.organizations().insert();
  360. OrganizationDto organization2 = db.organizations().insert();
  361. QProfileDto qualityProfile = db.qualityProfiles().insert(organization1);
  362. RuleDefinitionDto rule = db.rules().insert();
  363. UserDto user = db.users().insertUser();
  364. insertChange(qualityProfile, ActiveRuleChange.Type.ACTIVATED, user,
  365. ImmutableMap.of(
  366. "ruleId", valueOf(rule.getId()),
  367. "severity", "MINOR"));
  368. expectedException.expect(NotFoundException.class);
  369. ws.newRequest()
  370. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  371. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  372. .setParam(PARAM_ORGANIZATION, organization2.getKey())
  373. .execute();
  374. }
  375. @Test
  376. public void fail_on_paid_organization_when_not_member() {
  377. OrganizationDto organization = db.organizations().insert(o -> o.setSubscription(PAID));
  378. QProfileDto qualityProfile = db.qualityProfiles().insert(organization);
  379. expectedException.expect(ForbiddenException.class);
  380. expectedException.expectMessage(format("You're not member of organization '%s'", organization.getKey()));
  381. ws.newRequest()
  382. .setParam(PARAM_LANGUAGE, qualityProfile.getLanguage())
  383. .setParam(PARAM_QUALITY_PROFILE, qualityProfile.getName())
  384. .setParam(PARAM_ORGANIZATION, organization.getKey())
  385. .execute();
  386. }
  387. @Test
  388. public void example() {
  389. OrganizationDto organization = db.organizations().insert();
  390. QProfileDto profile = db.qualityProfiles().insert(organization);
  391. String profileUuid = profile.getRulesProfileUuid();
  392. system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:39+0100").getTime());
  393. RuleDefinitionDto rule1 = db.rules().insert(RuleKey.of("squid", "S2438"), r -> r.setName("\"Threads\" should not be used where \"Runnables\" are expected"));
  394. UserDto user1 = db.users().insertUser(u -> u.setLogin("anakin.skywalker").setName("Anakin Skywalker"));
  395. insertChange(c -> c.setRulesProfileUuid(profileUuid)
  396. .setUserUuid(user1.getUuid())
  397. .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
  398. .setData(ImmutableMap.of("severity", "CRITICAL", "ruleId", valueOf(rule1.getId()))));
  399. system2.setNow(DateUtils.parseDateTime("2015-02-23T17:58:18+0100").getTime());
  400. RuleDefinitionDto rule2 = db.rules().insert(RuleKey.of("squid", "S2162"), r -> r.setName("\"equals\" methods should be symmetric and work for subclasses"));
  401. UserDto user2 = db.users().insertUser(u -> u.setLogin("padme.amidala").setName("Padme Amidala"));
  402. QProfileChangeDto change2 = insertChange(c -> c.setRulesProfileUuid(profileUuid)
  403. .setUserUuid(user2.getUuid())
  404. .setChangeType(ActiveRuleChange.Type.DEACTIVATED.name())
  405. .setData(ImmutableMap.of("ruleId", valueOf(rule2.getId()))));
  406. system2.setNow(DateUtils.parseDateTime("2014-09-12T15:20:46+0200").getTime());
  407. RuleDefinitionDto rule3 = db.rules().insert(RuleKey.of("squid", "S00101"), r -> r.setName("Class names should comply with a naming convention"));
  408. UserDto user3 = db.users().insertUser(u -> u.setLogin("obiwan.kenobi").setName("Obiwan Kenobi"));
  409. QProfileChangeDto change3 = insertChange(c -> c.setRulesProfileUuid(profileUuid)
  410. .setUserUuid(user3.getUuid())
  411. .setChangeType(ActiveRuleChange.Type.ACTIVATED.name())
  412. .setData(ImmutableMap.of("severity", "MAJOR", "param_format", "^[A-Z][a-zA-Z0-9]*$", "ruleId", valueOf(rule3.getId()))));
  413. String response = ws.newRequest()
  414. .setMethod("GET")
  415. .setParam(PARAM_KEY, profile.getKee())
  416. .setParam("ps", "10")
  417. .execute()
  418. .getInput();
  419. assertJson(response).isSimilarTo(getClass().getResource("changelog-example.json"));
  420. }
  421. @Test
  422. public void definition() {
  423. WebService.Action definition = ws.getDef();
  424. assertThat(definition.isPost()).isFalse();
  425. assertThat(definition.responseExampleAsString()).isNotEmpty();
  426. assertThat(definition.params()).extracting(WebService.Param::key)
  427. .containsExactlyInAnyOrder("key", "qualityProfile", "language", "organization", "since", "to", "p", "ps");
  428. WebService.Param profileName = definition.param("qualityProfile");
  429. assertThat(profileName.deprecatedSince()).isNullOrEmpty();
  430. WebService.Param language = definition.param("language");
  431. assertThat(language.deprecatedSince()).isNullOrEmpty();
  432. }
  433. private QProfileChangeDto insertChange(QProfileDto profile, ActiveRuleChange.Type type, @Nullable UserDto user, @Nullable Map<String, Object> data) {
  434. return insertChange(c -> c.setRulesProfileUuid(profile.getRulesProfileUuid())
  435. .setUserUuid(user == null ? null : user.getUuid())
  436. .setChangeType(type.name())
  437. .setData(data));
  438. }
  439. @SafeVarargs
  440. private final QProfileChangeDto insertChange(Consumer<QProfileChangeDto>... consumers) {
  441. QProfileChangeDto dto = new QProfileChangeDto();
  442. Arrays.stream(consumers).forEach(c -> c.accept(dto));
  443. db.getDbClient().qProfileChangeDao().insert(db.getSession(), dto);
  444. db.commit();
  445. return dto;
  446. }
  447. }