You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RuleDaoTest.java 56KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.db.rule;
  21. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.Collections;
  24. import java.util.Iterator;
  25. import java.util.List;
  26. import java.util.Optional;
  27. import java.util.Set;
  28. import java.util.function.Consumer;
  29. import org.apache.ibatis.exceptions.PersistenceException;
  30. import org.apache.ibatis.session.ResultHandler;
  31. import org.junit.Before;
  32. import org.junit.Rule;
  33. import org.junit.Test;
  34. import org.junit.rules.ExpectedException;
  35. import org.sonar.api.rule.RuleKey;
  36. import org.sonar.api.rule.RuleStatus;
  37. import org.sonar.api.rule.Severity;
  38. import org.sonar.api.rules.RuleQuery;
  39. import org.sonar.api.rules.RuleType;
  40. import org.sonar.api.server.debt.DebtRemediationFunction;
  41. import org.sonar.api.utils.DateUtils;
  42. import org.sonar.api.utils.System2;
  43. import org.sonar.db.DbTester;
  44. import org.sonar.db.RowNotFoundException;
  45. import org.sonar.db.es.RuleExtensionId;
  46. import org.sonar.db.organization.OrganizationDto;
  47. import org.sonar.db.organization.OrganizationTesting;
  48. import org.sonar.db.rule.RuleDto.Scope;
  49. import static com.google.common.collect.Sets.newHashSet;
  50. import static java.util.Arrays.asList;
  51. import static java.util.Collections.emptyList;
  52. import static java.util.Collections.singletonList;
  53. import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
  54. import static org.assertj.core.api.Assertions.assertThat;
  55. import static org.assertj.core.api.Assertions.tuple;
  56. import static org.sonar.api.rule.RuleStatus.REMOVED;
  57. import static org.sonar.db.rule.RuleTesting.newRuleMetadata;
  58. public class RuleDaoTest {
  59. private static final String ORGANIZATION_UUID = "org-1";
  60. private static final String UNKNOWN_RULE_UUID = "unknown-uuid";
  61. @Rule
  62. public ExpectedException thrown = ExpectedException.none();
  63. @Rule
  64. public DbTester db = DbTester.create(System2.INSTANCE);
  65. private RuleDao underTest = db.getDbClient().ruleDao();
  66. private OrganizationDto organization;
  67. @Before
  68. public void before() {
  69. organization = db.organizations().insert(o -> o.setUuid(ORGANIZATION_UUID));
  70. }
  71. @Test
  72. public void selectByKey() {
  73. RuleDefinitionDto ruleDefinition = db.rules().insert();
  74. OrganizationDto organization = db.organizations().insert();
  75. RuleMetadataDto metadata = newRuleMetadata(ruleDefinition, organization);
  76. db.rules().insertRule(ruleDefinition, metadata);
  77. assertThat(underTest.selectByKey(db.getSession(), organization.getUuid(), RuleKey.of("foo", "bar")))
  78. .isEmpty();
  79. RuleDto rule = underTest.selectByKey(db.getSession(), organization.getUuid(), ruleDefinition.getKey()).get();
  80. assertEquals(rule.getDefinition(), ruleDefinition);
  81. verifyMetadata(rule.getMetadata(), ruleDefinition, metadata);
  82. }
  83. @Test
  84. public void selectByKey_return_rule_even_if_organization_does_not_exist() {
  85. RuleDefinitionDto ruleDefinition = db.rules().insert();
  86. assertThat(underTest.selectByKey(db.getSession(), OrganizationTesting.newOrganizationDto().getUuid(), ruleDefinition.getKey()))
  87. .isNotEmpty();
  88. }
  89. @Test
  90. public void selectByKey_populates_organizationUuid_even_when_organization_has_no_metadata() {
  91. OrganizationDto organization = db.organizations().insert();
  92. RuleDefinitionDto ruleDefinition = db.rules().insert();
  93. RuleDto rule = underTest.selectByKey(db.getSession(), organization.getUuid(), ruleDefinition.getKey()).get();
  94. verifyNoMetadata(rule.getMetadata(), organization);
  95. }
  96. @Test
  97. public void selectByKey_returns_metadata_of_specified_organization() {
  98. RuleDefinitionDto ruleDefinition = db.rules().insert();
  99. OrganizationDto organization1 = db.organizations().insert();
  100. RuleMetadataDto expectedOrg1 = newRuleMetadata(ruleDefinition, organization1);
  101. db.rules().insertRule(ruleDefinition, expectedOrg1);
  102. OrganizationDto organization2 = db.organizations().insert();
  103. RuleMetadataDto expectedOrg2 = newRuleMetadata(ruleDefinition, organization2);
  104. db.rules().insertRule(ruleDefinition, expectedOrg2);
  105. RuleDto rule = underTest.selectByKey(db.getSession(), organization1.getUuid(), ruleDefinition.getKey()).get();
  106. verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg1);
  107. rule = underTest.selectByKey(db.getSession(), organization2.getUuid(), ruleDefinition.getKey()).get();
  108. verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg2);
  109. }
  110. @Test
  111. public void selectDefinitionByKey() {
  112. RuleDefinitionDto rule = db.rules().insert();
  113. assertThat(underTest.selectDefinitionByKey(db.getSession(), RuleKey.of("NOT", "FOUND")).isPresent()).isFalse();
  114. Optional<RuleDefinitionDto> reloaded = underTest.selectDefinitionByKey(db.getSession(), rule.getKey());
  115. assertThat(reloaded.isPresent()).isTrue();
  116. }
  117. @Test
  118. public void selectByUuid() {
  119. RuleDefinitionDto ruleDefinition = db.rules().insert();
  120. OrganizationDto organization = db.organizations().insert();
  121. RuleMetadataDto metadata = newRuleMetadata(ruleDefinition, organization);
  122. RuleDto expected = db.rules().insertRule(ruleDefinition, metadata);
  123. assertThat(underTest.selectByUuid(expected.getUuid() + 500, organization.getUuid(), db.getSession()))
  124. .isEmpty();
  125. RuleDto rule = underTest.selectByUuid(expected.getUuid(), organization.getUuid(), db.getSession()).get();
  126. assertEquals(rule.getDefinition(), ruleDefinition);
  127. verifyMetadata(rule.getMetadata(), ruleDefinition, metadata);
  128. }
  129. @Test
  130. public void selectByUuid_return_rule_even_if_organization_does_not_exist() {
  131. RuleDefinitionDto ruleDefinition = db.rules().insert();
  132. assertThat(underTest.selectByUuid(ruleDefinition.getUuid(), "dfdfdf", db.getSession()))
  133. .isNotEmpty();
  134. }
  135. @Test
  136. public void selectByUuid_populates_organizationUuid_even_when_organization_has_no_metadata() {
  137. OrganizationDto organization = db.organizations().insert();
  138. RuleDefinitionDto ruleDefinition = db.rules().insert();
  139. RuleDto rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization.getUuid(), db.getSession()).get();
  140. verifyNoMetadata(rule.getMetadata(), organization);
  141. }
  142. @Test
  143. public void selectByUuid_returns_metadata_of_specified_organization() {
  144. RuleDefinitionDto ruleDefinition = db.rules().insert();
  145. OrganizationDto organization1 = db.organizations().insert();
  146. RuleMetadataDto expectedOrg1 = newRuleMetadata(ruleDefinition, organization1);
  147. db.rules().insertRule(ruleDefinition, expectedOrg1);
  148. OrganizationDto organization2 = db.organizations().insert();
  149. RuleMetadataDto expectedOrg2 = newRuleMetadata(ruleDefinition, organization2);
  150. db.rules().insertRule(ruleDefinition, expectedOrg2);
  151. RuleDto rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization1.getUuid(), db.getSession()).get();
  152. verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg1);
  153. rule = underTest.selectByUuid(ruleDefinition.getUuid(), organization2.getUuid(), db.getSession()).get();
  154. verifyMetadata(rule.getMetadata(), ruleDefinition, expectedOrg2);
  155. }
  156. @Test
  157. public void selectDefinitionByUuid() {
  158. RuleDefinitionDto rule = db.rules().insert();
  159. assertThat(underTest.selectDefinitionByUuid(UNKNOWN_RULE_UUID, db.getSession())).isEmpty();
  160. Optional<RuleDefinitionDto> ruleDtoOptional = underTest.selectDefinitionByUuid(rule.getUuid(), db.getSession());
  161. assertThat(ruleDtoOptional).isPresent();
  162. }
  163. @Test
  164. public void selectByUuids() {
  165. OrganizationDto organization = db.organizations().insert();
  166. RuleDefinitionDto rule1 = db.rules().insert();
  167. db.rules().insertOrUpdateMetadata(rule1, organization);
  168. RuleDefinitionDto rule2 = db.rules().insert();
  169. db.rules().insertOrUpdateMetadata(rule2, organization);
  170. RuleDefinitionDto removedRule = db.rules().insert(r -> r.setStatus(REMOVED));
  171. db.rules().insertOrUpdateMetadata(removedRule, organization);
  172. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), singletonList(rule1.getUuid()))).hasSize(1);
  173. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid()))).hasSize(2);
  174. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid(), UNKNOWN_RULE_UUID))).hasSize(2);
  175. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid(), removedRule.getUuid()))).hasSize(3);
  176. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), singletonList(UNKNOWN_RULE_UUID))).isEmpty();
  177. }
  178. @Test
  179. public void selectByUuids_populates_organizationUuid_even_when_organization_has_no_metadata() {
  180. OrganizationDto organization = db.organizations().insert();
  181. RuleDefinitionDto rule1 = db.rules().insert();
  182. RuleDefinitionDto rule2 = db.rules().insert();
  183. assertThat(underTest.selectByUuids(db.getSession(), organization.getUuid(), asList(rule1.getUuid(), rule2.getUuid())))
  184. .extracting(RuleDto::getOrganizationUuid)
  185. .containsExactly(organization.getUuid(), organization.getUuid());
  186. }
  187. @Test
  188. public void selectDefinitionByUuids() {
  189. RuleDefinitionDto rule1 = db.rules().insert();
  190. RuleDefinitionDto rule2 = db.rules().insert();
  191. assertThat(underTest.selectDefinitionByUuids(db.getSession(), singletonList(rule1.getUuid()))).hasSize(1);
  192. assertThat(underTest.selectDefinitionByUuids(db.getSession(), asList(rule1.getUuid(), rule2.getUuid()))).hasSize(2);
  193. assertThat(underTest.selectDefinitionByUuids(db.getSession(), asList(rule1.getUuid(), rule2.getUuid(), UNKNOWN_RULE_UUID))).hasSize(2);
  194. assertThat(underTest.selectDefinitionByUuids(db.getSession(), singletonList(UNKNOWN_RULE_UUID))).isEmpty();
  195. }
  196. @Test
  197. public void selectOrFailByKey() {
  198. OrganizationDto organization = db.organizations().insert();
  199. RuleDefinitionDto rule1 = db.rules().insert();
  200. db.rules().insert();
  201. RuleDto rule = underTest.selectOrFailByKey(db.getSession(), organization, rule1.getKey());
  202. assertThat(rule.getUuid()).isEqualTo(rule1.getUuid());
  203. }
  204. @Test
  205. public void selectOrFailByKey_fails_if_rule_not_found() {
  206. OrganizationDto organization = db.organizations().insert();
  207. thrown.expect(RowNotFoundException.class);
  208. thrown.expectMessage("Rule with key 'NOT:FOUND' does not exist");
  209. underTest.selectOrFailByKey(db.getSession(), organization, RuleKey.of("NOT", "FOUND"));
  210. }
  211. @Test
  212. public void selectOrFailByKey_populates_organizationUuid_even_when_organization_has_no_metadata() {
  213. OrganizationDto organization = db.organizations().insert();
  214. RuleDefinitionDto rule = db.rules().insert();
  215. assertThat(underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey()).getOrganizationUuid())
  216. .isEqualTo(organization.getUuid());
  217. }
  218. @Test
  219. public void selectOrFailDefinitionByKey_fails_if_rule_not_found() {
  220. thrown.expect(RowNotFoundException.class);
  221. thrown.expectMessage("Rule with key 'NOT:FOUND' does not exist");
  222. underTest.selectOrFailDefinitionByKey(db.getSession(), RuleKey.of("NOT", "FOUND"));
  223. }
  224. @Test
  225. public void selectByKeys() {
  226. OrganizationDto organization = db.organizations().insert();
  227. RuleDefinitionDto rule1 = db.rules().insert();
  228. db.rules().insertOrUpdateMetadata(rule1, organization);
  229. RuleDefinitionDto rule2 = db.rules().insert();
  230. db.rules().insertOrUpdateMetadata(rule2, organization);
  231. assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), Collections.emptyList())).isEmpty();
  232. assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), singletonList(RuleKey.of("NOT", "FOUND")))).isEmpty();
  233. List<RuleDto> rules = underTest.selectByKeys(db.getSession(), organization.getUuid(), asList(rule1.getKey(), RuleKey.of("java", "OTHER")));
  234. assertThat(rules).hasSize(1);
  235. assertThat(rules.get(0).getUuid()).isEqualTo(rule1.getUuid());
  236. }
  237. @Test
  238. public void selectByKeys_populates_organizationUuid_even_when_organization_has_no_metadata() {
  239. OrganizationDto organization = db.organizations().insert();
  240. RuleDefinitionDto rule = db.rules().insert();
  241. assertThat(underTest.selectByKeys(db.getSession(), organization.getUuid(), singletonList(rule.getKey())))
  242. .extracting(RuleDto::getOrganizationUuid)
  243. .containsExactly(organization.getUuid());
  244. }
  245. @Test
  246. public void selectDefinitionByKeys() {
  247. RuleDefinitionDto rule = db.rules().insert();
  248. assertThat(underTest.selectDefinitionByKeys(db.getSession(), Collections.emptyList())).isEmpty();
  249. assertThat(underTest.selectDefinitionByKeys(db.getSession(), singletonList(RuleKey.of("NOT", "FOUND")))).isEmpty();
  250. List<RuleDefinitionDto> rules = underTest.selectDefinitionByKeys(db.getSession(), asList(rule.getKey(), RuleKey.of("java", "OTHER")));
  251. assertThat(rules).hasSize(1);
  252. assertThat(rules.get(0).getUuid()).isEqualTo(rule.getUuid());
  253. }
  254. @Test
  255. public void selectAll() {
  256. OrganizationDto organization = db.organizations().insert();
  257. RuleDto rule1 = db.rules().insertRule(organization);
  258. RuleDto rule2 = db.rules().insertRule(organization);
  259. RuleDto rule3 = db.rules().insertRule(organization);
  260. assertThat(underTest.selectAll(db.getSession(), organization.getUuid()))
  261. .extracting(RuleDto::getUuid)
  262. .containsOnly(rule1.getUuid(), rule2.getUuid(), rule3.getUuid());
  263. }
  264. @Test
  265. public void selectAll_returns_all_rules_even_if_organization_does_not_exist() {
  266. RuleDefinitionDto rule1 = db.rules().insert();
  267. RuleDefinitionDto rule2 = db.rules().insert();
  268. RuleDefinitionDto rule3 = db.rules().insert();
  269. assertThat(underTest.selectAll(db.getSession(), "dfdfdf"))
  270. .extracting(RuleDto::getUuid)
  271. .containsOnly(rule1.getUuid(), rule2.getUuid(), rule3.getUuid());
  272. }
  273. @Test
  274. public void selectAll_populates_organizationUuid_even_when_organization_has_no_metadata() {
  275. OrganizationDto organization = db.organizations().insert();
  276. RuleDefinitionDto ruleDefinition1 = db.rules().insert();
  277. RuleDefinitionDto ruleDefinition2 = db.rules().insert();
  278. List<RuleDto> rules = underTest.selectAll(db.getSession(), organization.getUuid());
  279. assertThat(rules)
  280. .extracting(RuleDto::getUuid)
  281. .containsOnly(ruleDefinition1.getUuid(), ruleDefinition2.getUuid());
  282. assertThat(rules)
  283. .extracting(RuleDto::getOrganizationUuid)
  284. .containsExactly(organization.getUuid(), organization.getUuid());
  285. }
  286. @Test
  287. public void selectAll_returns_metadata_of_specified_organization() {
  288. RuleDefinitionDto ruleDefinition = db.rules().insert();
  289. OrganizationDto organization = db.organizations().insert();
  290. RuleMetadataDto expected = newRuleMetadata(ruleDefinition, organization);
  291. db.rules().insertRule(ruleDefinition, expected);
  292. List<RuleDto> rules = underTest.selectAll(db.getSession(), organization.getUuid());
  293. assertThat(rules).hasSize(1);
  294. verifyMetadata(rules.iterator().next().getMetadata(), ruleDefinition, expected);
  295. }
  296. private void assertEquals(RuleDefinitionDto actual, RuleDefinitionDto expected) {
  297. assertThat(actual.getUuid()).isEqualTo(expected.getUuid());
  298. assertThat(actual.getRepositoryKey()).isEqualTo(expected.getRepositoryKey());
  299. assertThat(actual.getRuleKey()).isEqualTo(expected.getRuleKey());
  300. assertThat(actual.getKey()).isEqualTo(expected.getKey());
  301. assertThat(actual.getDescription()).isEqualTo(expected.getDescription());
  302. assertThat(actual.getDescriptionFormat()).isEqualTo(expected.getDescriptionFormat());
  303. assertThat(actual.getStatus()).isEqualTo(expected.getStatus());
  304. assertThat(actual.getName()).isEqualTo(expected.getName());
  305. assertThat(actual.getConfigKey()).isEqualTo(expected.getConfigKey());
  306. assertThat(actual.getSeverity()).isEqualTo(expected.getSeverity());
  307. assertThat(actual.getSeverityString()).isEqualTo(expected.getSeverityString());
  308. assertThat(actual.isExternal()).isEqualTo(expected.isExternal());
  309. assertThat(actual.isTemplate()).isEqualTo(expected.isTemplate());
  310. assertThat(actual.getLanguage()).isEqualTo(expected.getLanguage());
  311. assertThat(actual.getTemplateUuid()).isEqualTo(expected.getTemplateUuid());
  312. assertThat(actual.getDefRemediationFunction()).isEqualTo(expected.getDefRemediationFunction());
  313. assertThat(actual.getDefRemediationGapMultiplier()).isEqualTo(expected.getDefRemediationGapMultiplier());
  314. assertThat(actual.getDefRemediationBaseEffort()).isEqualTo(expected.getDefRemediationBaseEffort());
  315. assertThat(actual.getGapDescription()).isEqualTo(expected.getGapDescription());
  316. assertThat(actual.getSystemTags()).isEqualTo(expected.getSystemTags());
  317. assertThat(actual.getSecurityStandards()).isEqualTo(expected.getSecurityStandards());
  318. assertThat(actual.getType()).isEqualTo(expected.getType());
  319. }
  320. private static void verifyMetadata(RuleMetadataDto metadata, RuleDefinitionDto ruleDefinition, RuleMetadataDto expected) {
  321. assertThat(metadata.getOrganizationUuid()).isEqualTo(expected.getOrganizationUuid());
  322. assertThat(metadata.getRemediationBaseEffort()).isEqualTo(expected.getRemediationBaseEffort());
  323. assertThat(metadata.getRemediationFunction()).isEqualTo(expected.getRemediationFunction());
  324. assertThat(metadata.getRemediationGapMultiplier()).isEqualTo(expected.getRemediationGapMultiplier());
  325. assertThat(metadata.getTags()).isEqualTo(expected.getTags());
  326. assertThat(metadata.getNoteData()).isEqualTo(expected.getNoteData());
  327. assertThat(metadata.getNoteCreatedAt()).isEqualTo(expected.getNoteCreatedAt());
  328. assertThat(metadata.getNoteUpdatedAt()).isEqualTo(expected.getNoteUpdatedAt());
  329. assertThat(metadata.getAdHocName()).isEqualTo(expected.getAdHocName());
  330. assertThat(metadata.getAdHocDescription()).isEqualTo(expected.getAdHocDescription());
  331. assertThat(metadata.getAdHocSeverity()).isEqualTo(expected.getAdHocSeverity());
  332. assertThat(metadata.getAdHocType()).isEqualTo(expected.getAdHocType());
  333. }
  334. private static void verifyNoMetadata(RuleMetadataDto metadata, OrganizationDto organization) {
  335. assertThat(metadata.getOrganizationUuid()).isEqualTo(organization.getUuid());
  336. assertThat(metadata.getRemediationBaseEffort()).isNull();
  337. assertThat(metadata.getRemediationFunction()).isNull();
  338. assertThat(metadata.getRemediationGapMultiplier()).isNull();
  339. assertThat(metadata.getTags()).isEmpty();
  340. assertThat(metadata.getNoteData()).isNull();
  341. assertThat(metadata.getNoteCreatedAt()).isNull();
  342. assertThat(metadata.getNoteUpdatedAt()).isNull();
  343. assertThat(metadata.getAdHocName()).isNull();
  344. assertThat(metadata.getAdHocDescription()).isNull();
  345. assertThat(metadata.getAdHocSeverity()).isNull();
  346. assertThat(metadata.getAdHocType()).isNull();
  347. }
  348. @Test
  349. public void selectAllDefinitions() {
  350. RuleDefinitionDto rule1 = db.rules().insert();
  351. RuleDefinitionDto rule2 = db.rules().insert();
  352. RuleDefinitionDto removedRule = db.rules().insert(r -> r.setStatus(REMOVED));
  353. List<RuleDefinitionDto> ruleDtos = underTest.selectAllDefinitions(db.getSession());
  354. assertThat(ruleDtos).extracting(RuleDefinitionDto::getUuid).containsOnly(rule1.getUuid(), rule2.getUuid(), removedRule.getUuid());
  355. }
  356. @Test
  357. public void selectEnabled_with_ResultHandler() {
  358. RuleDefinitionDto rule = db.rules().insert();
  359. db.rules().insert(r -> r.setStatus(REMOVED));
  360. final List<RuleDefinitionDto> rules = new ArrayList<>();
  361. ResultHandler<RuleDefinitionDto> resultHandler = resultContext -> rules.add(resultContext.getResultObject());
  362. underTest.selectEnabled(db.getSession(), resultHandler);
  363. assertThat(rules.size()).isEqualTo(1);
  364. RuleDefinitionDto ruleDto = rules.get(0);
  365. assertThat(ruleDto.getUuid()).isEqualTo(rule.getUuid());
  366. }
  367. @Test
  368. public void selectByTypeAndLanguages() {
  369. OrganizationDto organization = db.organizations().insert();
  370. OrganizationDto organization2 = db.organizations().insert();
  371. RuleDefinitionDto rule1 = db.rules().insert(
  372. r -> r.setKey(RuleKey.of("java", "S001"))
  373. .setConfigKey("S1")
  374. .setType(RuleType.VULNERABILITY)
  375. .setLanguage("java"));
  376. db.rules().insertOrUpdateMetadata(rule1, organization);
  377. RuleDefinitionDto rule2 = db.rules().insert(
  378. r -> r.setKey(RuleKey.of("js", "S002"))
  379. .setType(RuleType.SECURITY_HOTSPOT)
  380. .setLanguage("js"));
  381. db.rules().insertOrUpdateMetadata(rule2, organization);
  382. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
  383. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  384. .containsExactly(tuple(organization.getUuid(), rule1.getUuid(), "java", RuleType.VULNERABILITY.getDbConstant()));
  385. // Rule available also on organization2
  386. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization2.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
  387. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  388. .containsExactly(tuple(organization2.getUuid(), rule1.getUuid(), "java", RuleType.VULNERABILITY.getDbConstant()));
  389. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("js")))
  390. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  391. .containsExactly(tuple(organization.getUuid(), rule2.getUuid(), "js", RuleType.SECURITY_HOTSPOT.getDbConstant()));
  392. // Rule available also on organization2
  393. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization2.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("js")))
  394. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  395. .containsExactly(tuple(organization2.getUuid(), rule2.getUuid(), "js", RuleType.SECURITY_HOTSPOT.getDbConstant()));
  396. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.SECURITY_HOTSPOT.getDbConstant()), singletonList("java")))
  397. .isEmpty();
  398. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("js")))
  399. .isEmpty();
  400. }
  401. @Test
  402. public void selectByTypeAndLanguages_return_nothing_when_no_rule_on_languages() {
  403. OrganizationDto organization = db.organizations().insert();
  404. RuleDefinitionDto rule1 = db.rules().insert(
  405. r -> r.setKey(RuleKey.of("java", "S001"))
  406. .setConfigKey("S1")
  407. .setType(RuleType.VULNERABILITY)
  408. .setLanguage("java"));
  409. db.rules().insertOrUpdateMetadata(rule1, organization);
  410. RuleDefinitionDto rule2 = db.rules().insert(
  411. r -> r.setKey(RuleKey.of("js", "S002"))
  412. .setType(RuleType.VULNERABILITY)
  413. .setLanguage("js"));
  414. db.rules().insertOrUpdateMetadata(rule2, organization);
  415. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("cpp")))
  416. .isEmpty();
  417. }
  418. @Test
  419. public void selectByTypeAndLanguages_return_nothing_when_no_rule_with_type() {
  420. OrganizationDto organization = db.organizations().insert();
  421. RuleDefinitionDto rule1 = db.rules().insert(
  422. r -> r.setKey(RuleKey.of("java", "S001"))
  423. .setConfigKey("S1")
  424. .setType(RuleType.VULNERABILITY)
  425. .setLanguage("java"));
  426. db.rules().insertOrUpdateMetadata(rule1, organization);
  427. RuleDefinitionDto rule2 = db.rules().insert(
  428. r -> r.setKey(RuleKey.of("java", "S002"))
  429. .setType(RuleType.SECURITY_HOTSPOT)
  430. .setLanguage("java"));
  431. db.rules().insertOrUpdateMetadata(rule2, organization);
  432. RuleDefinitionDto rule3 = db.rules().insert(
  433. r -> r.setKey(RuleKey.of("java", "S003"))
  434. .setType(RuleType.CODE_SMELL)
  435. .setLanguage("java"));
  436. db.rules().insertOrUpdateMetadata(rule3, organization);
  437. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.BUG.getDbConstant()), singletonList("java")))
  438. .isEmpty();
  439. }
  440. @Test
  441. public void selectByTypeAndLanguages_ignores_external_rules() {
  442. OrganizationDto organization = db.organizations().insert();
  443. RuleDefinitionDto rule1 = db.rules().insert(
  444. r -> r.setKey(RuleKey.of("java", "S001"))
  445. .setConfigKey("S1")
  446. .setType(RuleType.VULNERABILITY)
  447. .setIsExternal(true)
  448. .setLanguage("java"));
  449. db.rules().insertOrUpdateMetadata(rule1, organization);
  450. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
  451. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  452. .isEmpty();
  453. }
  454. @Test
  455. public void selectByTypeAndLanguages_ignores_template_rules() {
  456. OrganizationDto organization = db.organizations().insert();
  457. RuleDefinitionDto rule1 = db.rules().insert(
  458. r -> r.setKey(RuleKey.of("java", "S001"))
  459. .setConfigKey("S1")
  460. .setType(RuleType.VULNERABILITY)
  461. .setIsTemplate(true)
  462. .setLanguage("java"));
  463. db.rules().insertOrUpdateMetadata(rule1, organization);
  464. assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java")))
  465. .extracting(RuleDto::getOrganizationUuid, RuleDto::getUuid, RuleDto::getLanguage, RuleDto::getType)
  466. .isEmpty();
  467. }
  468. @Test
  469. public void select_by_query() {
  470. OrganizationDto organization = db.organizations().insert();
  471. RuleDefinitionDto rule1 = db.rules().insert(r -> r.setKey(RuleKey.of("java", "S001")).setConfigKey("S1"));
  472. db.rules().insertOrUpdateMetadata(rule1, organization);
  473. RuleDefinitionDto rule2 = db.rules().insert(r -> r.setKey(RuleKey.of("java", "S002")));
  474. db.rules().insertOrUpdateMetadata(rule2, organization);
  475. RuleDefinitionDto removedRule = db.rules().insert(r -> r.setStatus(REMOVED));
  476. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create())).hasSize(2);
  477. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withKey("S001"))).hasSize(1);
  478. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withConfigKey("S1"))).hasSize(1);
  479. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create().withRepositoryKey("java"))).hasSize(2);
  480. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(),
  481. RuleQuery.create().withKey("S001").withConfigKey("S1").withRepositoryKey("java"))).hasSize(1);
  482. }
  483. @Test
  484. public void select_by_query_populates_organizationUuid_even_when_organization_has_no_metadata() {
  485. OrganizationDto organization = db.organizations().insert();
  486. db.rules().insert();
  487. db.rules().insert();
  488. assertThat(underTest.selectByQuery(db.getSession(), organization.getUuid(), RuleQuery.create()))
  489. .extracting(RuleDto::getOrganizationUuid)
  490. .containsExactly(organization.getUuid(), organization.getUuid());
  491. }
  492. @Test
  493. public void insert() {
  494. RuleDefinitionDto newRule = new RuleDefinitionDto()
  495. .setUuid("rule-uuid")
  496. .setRuleKey("NewRuleKey")
  497. .setRepositoryKey("plugin")
  498. .setName("new name")
  499. .setDescription("new description")
  500. .setDescriptionFormat(RuleDto.Format.MARKDOWN)
  501. .setStatus(RuleStatus.DEPRECATED)
  502. .setConfigKey("NewConfigKey")
  503. .setSeverity(Severity.INFO)
  504. .setIsTemplate(true)
  505. .setIsExternal(true)
  506. .setIsAdHoc(true)
  507. .setLanguage("dart")
  508. .setTemplateUuid("uuid-3")
  509. .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString())
  510. .setDefRemediationGapMultiplier("5d")
  511. .setDefRemediationBaseEffort("10h")
  512. .setGapDescription("squid.S115.effortToFix")
  513. .setSystemTags(newHashSet("systag1", "systag2"))
  514. .setSecurityStandards(newHashSet("owaspTop10:a1", "cwe:123"))
  515. .setType(RuleType.BUG)
  516. .setScope(Scope.ALL)
  517. .setCreatedAt(1_500_000_000_000L)
  518. .setUpdatedAt(2_000_000_000_000L);
  519. underTest.insert(db.getSession(), newRule);
  520. db.getSession().commit();
  521. RuleDefinitionDto ruleDto = underTest.selectOrFailDefinitionByKey(db.getSession(), RuleKey.of("plugin", "NewRuleKey"));
  522. assertThat(ruleDto.getUuid()).isNotNull();
  523. assertThat(ruleDto.getName()).isEqualTo("new name");
  524. assertThat(ruleDto.getDescription()).isEqualTo("new description");
  525. assertThat(ruleDto.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN);
  526. assertThat(ruleDto.getStatus()).isEqualTo(RuleStatus.DEPRECATED);
  527. assertThat(ruleDto.getRuleKey()).isEqualTo("NewRuleKey");
  528. assertThat(ruleDto.getRepositoryKey()).isEqualTo("plugin");
  529. assertThat(ruleDto.getConfigKey()).isEqualTo("NewConfigKey");
  530. assertThat(ruleDto.getSeverity()).isEqualTo(0);
  531. assertThat(ruleDto.getLanguage()).isEqualTo("dart");
  532. assertThat(ruleDto.isTemplate()).isTrue();
  533. assertThat(ruleDto.isExternal()).isTrue();
  534. assertThat(ruleDto.isAdHoc()).isTrue();
  535. assertThat(ruleDto.getTemplateUuid()).isEqualTo("uuid-3");
  536. assertThat(ruleDto.getDefRemediationFunction()).isEqualTo("LINEAR_OFFSET");
  537. assertThat(ruleDto.getDefRemediationGapMultiplier()).isEqualTo("5d");
  538. assertThat(ruleDto.getDefRemediationBaseEffort()).isEqualTo("10h");
  539. assertThat(ruleDto.getGapDescription()).isEqualTo("squid.S115.effortToFix");
  540. assertThat(ruleDto.getSystemTags()).containsOnly("systag1", "systag2");
  541. assertThat(ruleDto.getSecurityStandards()).containsOnly("owaspTop10:a1", "cwe:123");
  542. assertThat(ruleDto.getScope()).isEqualTo(Scope.ALL);
  543. assertThat(ruleDto.getType()).isEqualTo(RuleType.BUG.getDbConstant());
  544. assertThat(ruleDto.getCreatedAt()).isEqualTo(1_500_000_000_000L);
  545. assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L);
  546. }
  547. @Test
  548. public void update_RuleDefinitionDto() {
  549. RuleDefinitionDto rule = db.rules().insert();
  550. RuleDefinitionDto ruleToUpdate = new RuleDefinitionDto()
  551. .setUuid(rule.getUuid())
  552. .setRuleKey("NewRuleKey")
  553. .setRepositoryKey("plugin")
  554. .setName("new name")
  555. .setDescription("new description")
  556. .setDescriptionFormat(RuleDto.Format.MARKDOWN)
  557. .setStatus(RuleStatus.DEPRECATED)
  558. .setConfigKey("NewConfigKey")
  559. .setSeverity(Severity.INFO)
  560. .setIsTemplate(true)
  561. .setIsExternal(true)
  562. .setIsAdHoc(true)
  563. .setLanguage("dart")
  564. .setTemplateUuid("uuid-3")
  565. .setDefRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString())
  566. .setDefRemediationGapMultiplier("5d")
  567. .setDefRemediationBaseEffort("10h")
  568. .setGapDescription("squid.S115.effortToFix")
  569. .setSystemTags(newHashSet("systag1", "systag2"))
  570. .setSecurityStandards(newHashSet("owaspTop10:a1", "cwe:123"))
  571. .setScope(Scope.ALL)
  572. .setType(RuleType.BUG)
  573. .setUpdatedAt(2_000_000_000_000L);
  574. underTest.update(db.getSession(), ruleToUpdate);
  575. db.getSession().commit();
  576. RuleDefinitionDto ruleDto = underTest.selectOrFailDefinitionByKey(db.getSession(), RuleKey.of("plugin", "NewRuleKey"));
  577. assertThat(ruleDto.getName()).isEqualTo("new name");
  578. assertThat(ruleDto.getDescription()).isEqualTo("new description");
  579. assertThat(ruleDto.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN);
  580. assertThat(ruleDto.getStatus()).isEqualTo(RuleStatus.DEPRECATED);
  581. assertThat(ruleDto.getRuleKey()).isEqualTo("NewRuleKey");
  582. assertThat(ruleDto.getRepositoryKey()).isEqualTo("plugin");
  583. assertThat(ruleDto.getConfigKey()).isEqualTo("NewConfigKey");
  584. assertThat(ruleDto.getSeverity()).isEqualTo(0);
  585. assertThat(ruleDto.getLanguage()).isEqualTo("dart");
  586. assertThat(ruleDto.isTemplate()).isTrue();
  587. assertThat(ruleDto.isExternal()).isTrue();
  588. assertThat(ruleDto.isAdHoc()).isTrue();
  589. assertThat(ruleDto.getTemplateUuid()).isEqualTo("uuid-3");
  590. assertThat(ruleDto.getDefRemediationFunction()).isEqualTo("LINEAR_OFFSET");
  591. assertThat(ruleDto.getDefRemediationGapMultiplier()).isEqualTo("5d");
  592. assertThat(ruleDto.getDefRemediationBaseEffort()).isEqualTo("10h");
  593. assertThat(ruleDto.getGapDescription()).isEqualTo("squid.S115.effortToFix");
  594. assertThat(ruleDto.getSystemTags()).containsOnly("systag1", "systag2");
  595. assertThat(ruleDto.getSecurityStandards()).containsOnly("owaspTop10:a1", "cwe:123");
  596. assertThat(ruleDto.getScope()).isEqualTo(Scope.ALL);
  597. assertThat(ruleDto.getType()).isEqualTo(RuleType.BUG.getDbConstant());
  598. assertThat(ruleDto.getCreatedAt()).isEqualTo(rule.getCreatedAt());
  599. assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L);
  600. }
  601. @Test
  602. public void update_RuleMetadataDto_inserts_row_in_RULE_METADATA_if_not_exists_yet() {
  603. RuleDefinitionDto rule = db.rules().insert();
  604. String organizationUuid = "org-1";
  605. RuleMetadataDto metadataToUpdate = new RuleMetadataDto()
  606. .setRuleUuid(rule.getUuid())
  607. .setOrganizationUuid(organizationUuid)
  608. .setNoteData("My note")
  609. .setNoteUserUuid("admin")
  610. .setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime())
  611. .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime())
  612. .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString())
  613. .setRemediationGapMultiplier("1h")
  614. .setRemediationBaseEffort("5min")
  615. .setTags(newHashSet("tag1", "tag2"))
  616. .setAdHocName("ad hoc name")
  617. .setAdHocDescription("ad hoc desc")
  618. .setAdHocSeverity(Severity.BLOCKER)
  619. .setAdHocType(RuleType.CODE_SMELL)
  620. .setCreatedAt(3_500_000_000_000L)
  621. .setUpdatedAt(4_000_000_000_000L);
  622. underTest.insertOrUpdate(db.getSession(), metadataToUpdate);
  623. db.getSession().commit();
  624. OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
  625. RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
  626. assertThat(ruleDto.getNoteData()).isEqualTo("My note");
  627. assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin");
  628. assertThat(ruleDto.getNoteCreatedAt()).isNotNull();
  629. assertThat(ruleDto.getNoteUpdatedAt()).isNotNull();
  630. assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR");
  631. assertThat(ruleDto.getRemediationGapMultiplier()).isEqualTo("1h");
  632. assertThat(ruleDto.getRemediationBaseEffort()).isEqualTo("5min");
  633. assertThat(ruleDto.getTags()).containsOnly("tag1", "tag2");
  634. assertThat(ruleDto.getAdHocName()).isEqualTo("ad hoc name");
  635. assertThat(ruleDto.getAdHocDescription()).isEqualTo("ad hoc desc");
  636. assertThat(ruleDto.getAdHocSeverity()).isEqualTo(Severity.BLOCKER);
  637. assertThat(ruleDto.getAdHocType()).isEqualTo(RuleType.CODE_SMELL.getDbConstant());
  638. assertThat(ruleDto.getSecurityStandards()).isEmpty();
  639. assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L);
  640. assertThat(ruleDto.getUpdatedAt()).isEqualTo(4_000_000_000_000L);
  641. // Info from rule definition
  642. assertThat(ruleDto.getDefRemediationFunction()).isEqualTo(rule.getDefRemediationFunction());
  643. assertThat(ruleDto.getDefRemediationGapMultiplier()).isEqualTo(rule.getDefRemediationGapMultiplier());
  644. assertThat(ruleDto.getDefRemediationBaseEffort()).isEqualTo(rule.getDefRemediationBaseEffort());
  645. assertThat(ruleDto.getGapDescription()).isEqualTo(rule.getGapDescription());
  646. assertThat(ruleDto.getSystemTags()).containsAll(rule.getSystemTags());
  647. assertThat(ruleDto.getType()).isEqualTo(rule.getType());
  648. }
  649. @Test
  650. public void update_RuleMetadataDto_updates_row_in_RULE_METADATA_if_already_exists() {
  651. RuleDefinitionDto rule = db.rules().insert();
  652. String organizationUuid = "org-1";
  653. OrganizationDto organization = OrganizationTesting.newOrganizationDto().setUuid(organizationUuid);
  654. RuleMetadataDto metadataV1 = new RuleMetadataDto()
  655. .setRuleUuid(rule.getUuid())
  656. .setOrganizationUuid(organizationUuid)
  657. .setCreatedAt(3_500_000_000_000L)
  658. .setUpdatedAt(4_000_000_000_000L);
  659. RuleMetadataDto metadataV2 = new RuleMetadataDto()
  660. .setRuleUuid(rule.getUuid())
  661. .setOrganizationUuid(organizationUuid)
  662. .setNoteData("My note")
  663. .setNoteUserUuid("admin")
  664. .setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime())
  665. .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime())
  666. .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString())
  667. .setRemediationGapMultiplier("1h")
  668. .setRemediationBaseEffort("5min")
  669. .setTags(newHashSet("tag1", "tag2"))
  670. .setAdHocName("ad hoc name")
  671. .setAdHocDescription("ad hoc desc")
  672. .setAdHocSeverity(Severity.BLOCKER)
  673. .setAdHocType(RuleType.CODE_SMELL)
  674. .setCreatedAt(6_500_000_000_000L)
  675. .setUpdatedAt(7_000_000_000_000L);
  676. underTest.insertOrUpdate(db.getSession(), metadataV1);
  677. db.commit();
  678. assertThat(db.countRowsOfTable("RULES_METADATA")).isEqualTo(1);
  679. RuleDto ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
  680. assertThat(ruleDto.getNoteData()).isNull();
  681. assertThat(ruleDto.getNoteUserUuid()).isNull();
  682. assertThat(ruleDto.getNoteCreatedAt()).isNull();
  683. assertThat(ruleDto.getNoteUpdatedAt()).isNull();
  684. assertThat(ruleDto.getRemediationFunction()).isNull();
  685. assertThat(ruleDto.getRemediationGapMultiplier()).isNull();
  686. assertThat(ruleDto.getRemediationBaseEffort()).isNull();
  687. assertThat(ruleDto.getTags()).isEmpty();
  688. assertThat(ruleDto.getAdHocName()).isNull();
  689. assertThat(ruleDto.getAdHocDescription()).isNull();
  690. assertThat(ruleDto.getAdHocSeverity()).isNull();
  691. assertThat(ruleDto.getAdHocType()).isNull();
  692. assertThat(ruleDto.getSecurityStandards()).isEmpty();
  693. assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L);
  694. assertThat(ruleDto.getUpdatedAt()).isEqualTo(4_000_000_000_000L);
  695. underTest.insertOrUpdate(db.getSession(), metadataV2);
  696. db.commit();
  697. ruleDto = underTest.selectOrFailByKey(db.getSession(), organization, rule.getKey());
  698. assertThat(ruleDto.getNoteData()).isEqualTo("My note");
  699. assertThat(ruleDto.getNoteUserUuid()).isEqualTo("admin");
  700. assertThat(ruleDto.getNoteCreatedAt()).isNotNull();
  701. assertThat(ruleDto.getNoteUpdatedAt()).isNotNull();
  702. assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR");
  703. assertThat(ruleDto.getRemediationGapMultiplier()).isEqualTo("1h");
  704. assertThat(ruleDto.getRemediationBaseEffort()).isEqualTo("5min");
  705. assertThat(ruleDto.getTags()).containsOnly("tag1", "tag2");
  706. assertThat(ruleDto.getAdHocName()).isEqualTo("ad hoc name");
  707. assertThat(ruleDto.getAdHocDescription()).isEqualTo("ad hoc desc");
  708. assertThat(ruleDto.getAdHocSeverity()).isEqualTo(Severity.BLOCKER);
  709. assertThat(ruleDto.getAdHocType()).isEqualTo(RuleType.CODE_SMELL.getDbConstant());
  710. assertThat(ruleDto.getSecurityStandards()).isEmpty();
  711. assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L);
  712. assertThat(ruleDto.getUpdatedAt()).isEqualTo(7_000_000_000_000L);
  713. }
  714. @Test
  715. public void select_parameters_by_rule_key() {
  716. RuleDefinitionDto rule = db.rules().insert();
  717. RuleParamDto ruleParam = db.rules().insertRuleParam(rule);
  718. List<RuleParamDto> ruleDtos = underTest.selectRuleParamsByRuleKey(db.getSession(), rule.getKey());
  719. assertThat(ruleDtos.size()).isEqualTo(1);
  720. RuleParamDto ruleDto = ruleDtos.get(0);
  721. assertThat(ruleDto.getUuid()).isEqualTo(ruleParam.getUuid());
  722. assertThat(ruleDto.getName()).isEqualTo(ruleParam.getName());
  723. assertThat(ruleDto.getDescription()).isEqualTo(ruleParam.getDescription());
  724. assertThat(ruleDto.getType()).isEqualTo(ruleParam.getType());
  725. assertThat(ruleDto.getRuleUuid()).isEqualTo(rule.getUuid());
  726. }
  727. @Test
  728. public void select_parameters_by_rule_keys() {
  729. RuleDefinitionDto rule1 = db.rules().insert();
  730. db.rules().insertRuleParam(rule1);
  731. RuleDefinitionDto rule2 = db.rules().insert();
  732. db.rules().insertRuleParam(rule2);
  733. assertThat(underTest.selectRuleParamsByRuleKeys(db.getSession(),
  734. Arrays.asList(rule1.getKey(), rule2.getKey()))).hasSize(2);
  735. assertThat(underTest.selectRuleParamsByRuleKeys(db.getSession(),
  736. singletonList(RuleKey.of("unknown", "Unknown")))).isEmpty();
  737. }
  738. @Test
  739. public void insert_parameter() {
  740. RuleDefinitionDto ruleDefinitionDto = db.rules().insert();
  741. RuleParamDto orig = RuleParamDto.createFor(ruleDefinitionDto)
  742. .setName("max")
  743. .setType("INTEGER")
  744. .setDefaultValue("30")
  745. .setDescription("My Parameter");
  746. underTest.insertRuleParam(db.getSession(), ruleDefinitionDto, orig);
  747. List<RuleParamDto> ruleParamDtos = underTest.selectRuleParamsByRuleKey(db.getSession(), ruleDefinitionDto.getKey());
  748. assertThat(ruleParamDtos).hasSize(1);
  749. RuleParamDto loaded = ruleParamDtos.get(0);
  750. assertThat(loaded.getRuleUuid()).isEqualTo(orig.getRuleUuid());
  751. assertThat(loaded.getName()).isEqualTo(orig.getName());
  752. assertThat(loaded.getType()).isEqualTo(orig.getType());
  753. assertThat(loaded.getDefaultValue()).isEqualTo(orig.getDefaultValue());
  754. assertThat(loaded.getDescription()).isEqualTo(orig.getDescription());
  755. }
  756. @Test
  757. public void should_fail_to_insert_duplicate_parameter() {
  758. RuleDefinitionDto ruleDefinitionDto = db.rules().insert();
  759. RuleParamDto param = RuleParamDto.createFor(ruleDefinitionDto)
  760. .setName("max")
  761. .setType("INTEGER")
  762. .setDefaultValue("30")
  763. .setDescription("My Parameter");
  764. underTest.insertRuleParam(db.getSession(), ruleDefinitionDto, param);
  765. thrown.expect(PersistenceException.class);
  766. underTest.insertRuleParam(db.getSession(), ruleDefinitionDto, param);
  767. }
  768. @Test
  769. public void update_parameter() {
  770. RuleDefinitionDto rule = db.rules().insert();
  771. RuleParamDto ruleParam = db.rules().insertRuleParam(rule);
  772. List<RuleParamDto> params = underTest.selectRuleParamsByRuleKey(db.getSession(), rule.getKey());
  773. assertThat(params).hasSize(1);
  774. RuleParamDto param = new RuleParamDto()
  775. .setUuid(ruleParam.getUuid())
  776. .setRuleUuid(rule.getUuid())
  777. // Name will not be updated
  778. .setName("format")
  779. .setType("STRING")
  780. .setDefaultValue("^[a-z]+(\\.[a-z][a-z0-9]*)*$")
  781. .setDescription("Regular expression used to check the package names against.");
  782. underTest.updateRuleParam(db.getSession(), rule, param);
  783. assertThat(underTest.selectRuleParamsByRuleKey(db.getSession(), rule.getKey()))
  784. .extracting(RuleParamDto::getName, RuleParamDto::getType, RuleParamDto::getDefaultValue, RuleParamDto::getDescription)
  785. .containsExactlyInAnyOrder(tuple(ruleParam.getName(), "STRING", "^[a-z]+(\\.[a-z][a-z0-9]*)*$", "Regular expression used to check the package names against."));
  786. }
  787. @Test
  788. public void delete_parameter() {
  789. RuleDefinitionDto rule = db.rules().insert();
  790. RuleParamDto ruleParam = db.rules().insertRuleParam(rule);
  791. assertThat(underTest.selectRuleParamsByRuleKey(db.getSession(), rule.getKey())).hasSize(1);
  792. underTest.deleteRuleParam(db.getSession(), ruleParam.getUuid());
  793. assertThat(underTest.selectRuleParamsByRuleKey(db.getSession(), rule.getKey())).isEmpty();
  794. }
  795. @Test
  796. public void scrollIndexingRules_on_empty_table() {
  797. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  798. underTest.scrollIndexingRules(db.getSession(), accumulator);
  799. assertThat(accumulator.list).isEmpty();
  800. }
  801. @Test
  802. public void scrollIndexingRules() {
  803. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  804. RuleDefinitionDto r1 = db.rules().insert();
  805. RuleDefinitionDto r2 = db.rules().insert(r -> r.setIsExternal(true));
  806. underTest.scrollIndexingRules(db.getSession(), accumulator);
  807. assertThat(accumulator.list)
  808. .extracting(RuleForIndexingDto::getUuid, RuleForIndexingDto::getRuleKey)
  809. .containsExactlyInAnyOrder(tuple(r1.getUuid(), r1.getKey()), tuple(r2.getUuid(), r2.getKey()));
  810. Iterator<RuleForIndexingDto> it = accumulator.list.iterator();
  811. RuleForIndexingDto firstRule = it.next();
  812. assertThat(firstRule.getRepository()).isEqualTo(r1.getRepositoryKey());
  813. assertThat(firstRule.getPluginRuleKey()).isEqualTo(r1.getRuleKey());
  814. assertThat(firstRule.getName()).isEqualTo(r1.getName());
  815. assertThat(firstRule.getDescription()).isEqualTo(r1.getDescription());
  816. assertThat(firstRule.getDescriptionFormat()).isEqualTo(r1.getDescriptionFormat());
  817. assertThat(firstRule.getSeverity()).isEqualTo(r1.getSeverity());
  818. assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus());
  819. assertThat(firstRule.isExternal()).isFalse();
  820. assertThat(firstRule.isTemplate()).isEqualTo(r1.isTemplate());
  821. assertThat(firstRule.getSystemTags()).isEqualTo(r1.getSystemTags());
  822. assertThat(firstRule.getSecurityStandards()).isEqualTo(r1.getSecurityStandards());
  823. assertThat(firstRule.getTemplateRuleKey()).isNull();
  824. assertThat(firstRule.getTemplateRepository()).isNull();
  825. assertThat(firstRule.getInternalKey()).isEqualTo(r1.getConfigKey());
  826. assertThat(firstRule.getLanguage()).isEqualTo(r1.getLanguage());
  827. assertThat(firstRule.getType()).isEqualTo(r1.getType());
  828. assertThat(firstRule.getCreatedAt()).isEqualTo(r1.getCreatedAt());
  829. assertThat(firstRule.getUpdatedAt()).isEqualTo(r1.getUpdatedAt());
  830. RuleForIndexingDto secondRule = it.next();
  831. assertThat(secondRule.isExternal()).isTrue();
  832. }
  833. @Test
  834. public void scrollIndexingRules_maps_rule_definition_fields_for_regular_rule_and_template_rule() {
  835. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  836. RuleDefinitionDto r1 = db.rules().insert();
  837. RuleDefinitionDto r2 = db.rules().insert(rule -> rule.setTemplateUuid(r1.getUuid()));
  838. underTest.scrollIndexingRules(db.getSession(), accumulator);
  839. assertThat(accumulator.list).hasSize(2);
  840. RuleForIndexingDto firstRule = accumulator.list.get(0);
  841. RuleForIndexingDto secondRule = accumulator.list.get(1);
  842. assertRuleDefinitionFieldsAreEquals(r1, firstRule);
  843. assertThat(firstRule.getTemplateRuleKey()).isNull();
  844. assertThat(firstRule.getTemplateRepository()).isNull();
  845. assertRuleDefinitionFieldsAreEquals(r2, secondRule);
  846. assertThat(secondRule.getTemplateRuleKey()).isEqualTo(r1.getRuleKey());
  847. assertThat(secondRule.getTemplateRepository()).isEqualTo(r1.getRepositoryKey());
  848. }
  849. @Test
  850. public void scrollIndexingRulesByKeys() {
  851. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  852. RuleDefinitionDto r1 = db.rules().insert();
  853. db.rules().insert();
  854. underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(r1.getUuid()), accumulator);
  855. assertThat(accumulator.list)
  856. .extracting(RuleForIndexingDto::getUuid, RuleForIndexingDto::getRuleKey)
  857. .containsExactlyInAnyOrder(tuple(r1.getUuid(), r1.getKey()));
  858. }
  859. @Test
  860. public void scrollIndexingRulesByKeys_maps_rule_definition_fields_for_regular_rule_and_template_rule() {
  861. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  862. RuleDefinitionDto r1 = db.rules().insert();
  863. RuleDefinitionDto r2 = db.rules().insert(rule -> rule.setTemplateUuid(r1.getUuid()));
  864. underTest.scrollIndexingRulesByKeys(db.getSession(), Arrays.asList(r1.getUuid(), r2.getUuid()), accumulator);
  865. assertThat(accumulator.list).hasSize(2);
  866. RuleForIndexingDto firstRule = accumulator.list.stream().filter(t -> t.getUuid().equals(r1.getUuid())).findFirst().get();
  867. RuleForIndexingDto secondRule = accumulator.list.stream().filter(t -> t.getUuid().equals(r2.getUuid())).findFirst().get();
  868. assertRuleDefinitionFieldsAreEquals(r1, firstRule);
  869. assertThat(firstRule.getTemplateRuleKey()).isNull();
  870. assertThat(firstRule.getTemplateRepository()).isNull();
  871. assertRuleDefinitionFieldsAreEquals(r2, secondRule);
  872. assertThat(secondRule.getTemplateRuleKey()).isEqualTo(r1.getRuleKey());
  873. assertThat(secondRule.getTemplateRepository()).isEqualTo(r1.getRepositoryKey());
  874. }
  875. private void assertRuleDefinitionFieldsAreEquals(RuleDefinitionDto r1, RuleForIndexingDto firstRule) {
  876. assertThat(firstRule.getUuid()).isEqualTo(r1.getUuid());
  877. assertThat(firstRule.getRuleKey()).isEqualTo(r1.getKey());
  878. assertThat(firstRule.getRepository()).isEqualTo(r1.getRepositoryKey());
  879. assertThat(firstRule.getPluginRuleKey()).isEqualTo(r1.getRuleKey());
  880. assertThat(firstRule.getName()).isEqualTo(r1.getName());
  881. assertThat(firstRule.getDescription()).isEqualTo(r1.getDescription());
  882. assertThat(firstRule.getDescriptionFormat()).isEqualTo(r1.getDescriptionFormat());
  883. assertThat(firstRule.getSeverity()).isEqualTo(r1.getSeverity());
  884. assertThat(firstRule.getSeverityAsString()).isEqualTo(SeverityUtil.getSeverityFromOrdinal(r1.getSeverity()));
  885. assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus());
  886. assertThat(firstRule.isTemplate()).isEqualTo(r1.isTemplate());
  887. assertThat(firstRule.getSystemTags()).isEqualTo(r1.getSystemTags());
  888. assertThat(firstRule.getSecurityStandards()).isEqualTo(r1.getSecurityStandards());
  889. assertThat(firstRule.getInternalKey()).isEqualTo(r1.getConfigKey());
  890. assertThat(firstRule.getLanguage()).isEqualTo(r1.getLanguage());
  891. assertThat(firstRule.getType()).isEqualTo(r1.getType());
  892. assertThat(firstRule.getTypeAsRuleType()).isEqualTo(RuleType.valueOf(r1.getType()));
  893. assertThat(firstRule.getCreatedAt()).isEqualTo(r1.getCreatedAt());
  894. assertThat(firstRule.getUpdatedAt()).isEqualTo(r1.getUpdatedAt());
  895. }
  896. @Test
  897. public void scrollIndexingRulesByKeys_scrolls_nothing_if_key_does_not_exist() {
  898. Accumulator<RuleForIndexingDto> accumulator = new Accumulator<>();
  899. db.rules().insert();
  900. String nonExistingRuleUuid = "non-existing-uuid";
  901. underTest.scrollIndexingRulesByKeys(db.getSession(), singletonList(nonExistingRuleUuid), accumulator);
  902. assertThat(accumulator.list).isEmpty();
  903. }
  904. @Test
  905. public void scrollIndexingRuleExtensions() {
  906. Accumulator<RuleExtensionForIndexingDto> accumulator = new Accumulator<>();
  907. RuleDefinitionDto r1 = db.rules().insert();
  908. RuleMetadataDto r1Extension = db.rules().insertOrUpdateMetadata(r1, organization, r -> r.setTagsField("t1,t2"));
  909. RuleDefinitionDto r2 = db.rules().insert();
  910. RuleMetadataDto r2Extension = db.rules().insertOrUpdateMetadata(r2, organization, r -> r.setTagsField("t1,t3"));
  911. underTest.scrollIndexingRuleExtensions(db.getSession(), accumulator);
  912. assertThat(accumulator.list)
  913. .extracting(RuleExtensionForIndexingDto::getRuleUuid,
  914. RuleExtensionForIndexingDto::getRuleKey,
  915. RuleExtensionForIndexingDto::getOrganizationUuid, RuleExtensionForIndexingDto::getTags)
  916. .containsExactlyInAnyOrder(
  917. tuple(r1.getUuid(), r1.getKey(), organization.getUuid(), r1Extension.getTagsAsString()),
  918. tuple(r2.getUuid(), r2.getKey(), organization.getUuid(), r2Extension.getTagsAsString()));
  919. }
  920. @Test
  921. public void scrollIndexingRuleExtensionsByIds() {
  922. Accumulator<RuleExtensionForIndexingDto> accumulator = new Accumulator<>();
  923. RuleDefinitionDto r1 = db.rules().insert();
  924. RuleMetadataDto r1Extension = db.rules().insertOrUpdateMetadata(r1, organization, r -> r.setTagsField("t1,t2"));
  925. RuleExtensionId r1ExtensionId = new RuleExtensionId(organization.getUuid(), r1.getUuid());
  926. RuleDefinitionDto r2 = db.rules().insert();
  927. db.rules().insertOrUpdateMetadata(r2, organization, r -> r.setTagsField("t1,t3"));
  928. underTest.scrollIndexingRuleExtensionsByIds(db.getSession(), singletonList(r1ExtensionId), accumulator);
  929. assertThat(accumulator.list)
  930. .extracting(RuleExtensionForIndexingDto::getRuleUuid,
  931. RuleExtensionForIndexingDto::getRuleKey,
  932. RuleExtensionForIndexingDto::getOrganizationUuid, RuleExtensionForIndexingDto::getTags)
  933. .containsExactlyInAnyOrder(
  934. tuple(r1.getUuid(), r1.getKey(), organization.getUuid(), r1Extension.getTagsAsString()));
  935. }
  936. @Test
  937. public void selectAllDeprecatedRuleKeys() {
  938. RuleDefinitionDto r1 = db.rules().insert();
  939. RuleDefinitionDto r2 = db.rules().insert();
  940. db.rules().insertDeprecatedKey(r -> r.setRuleUuid(r1.getUuid()));
  941. db.rules().insertDeprecatedKey(r -> r.setRuleUuid(r2.getUuid()));
  942. db.getSession().commit();
  943. Set<DeprecatedRuleKeyDto> deprecatedRuleKeyDtos = underTest.selectAllDeprecatedRuleKeys(db.getSession());
  944. assertThat(deprecatedRuleKeyDtos).hasSize(2);
  945. }
  946. @Test
  947. public void selectAllDeprecatedRuleKeys_return_values_even_if_there_is_no_rule() {
  948. db.rules().insertDeprecatedKey();
  949. db.rules().insertDeprecatedKey();
  950. Set<DeprecatedRuleKeyDto> deprecatedRuleKeyDtos = underTest.selectAllDeprecatedRuleKeys(db.getSession());
  951. assertThat(deprecatedRuleKeyDtos).hasSize(2);
  952. assertThat(deprecatedRuleKeyDtos)
  953. .extracting(DeprecatedRuleKeyDto::getNewRepositoryKey, DeprecatedRuleKeyDto::getNewRuleKey)
  954. .containsExactly(
  955. tuple(null, null),
  956. tuple(null, null));
  957. }
  958. @Test
  959. public void deleteDeprecatedRuleKeys_with_empty_list_has_no_effect() {
  960. db.rules().insertDeprecatedKey();
  961. db.rules().insertDeprecatedKey();
  962. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(2);
  963. underTest.deleteDeprecatedRuleKeys(db.getSession(), emptyList());
  964. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(2);
  965. }
  966. @Test
  967. public void deleteDeprecatedRuleKeys_with_non_existing_uuid_has_no_effect() {
  968. db.rules().insertDeprecatedKey(d -> d.setUuid("A1"));
  969. db.rules().insertDeprecatedKey(d -> d.setUuid("A2"));
  970. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(2);
  971. underTest.deleteDeprecatedRuleKeys(db.getSession(), asList("B1", "B2"));
  972. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(2);
  973. }
  974. @Test
  975. public void deleteDeprecatedRuleKeys() {
  976. DeprecatedRuleKeyDto deprecatedRuleKeyDto1 = db.rules().insertDeprecatedKey();
  977. db.rules().insertDeprecatedKey();
  978. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(2);
  979. underTest.deleteDeprecatedRuleKeys(db.getSession(), singletonList(deprecatedRuleKeyDto1.getUuid()));
  980. assertThat(underTest.selectAllDeprecatedRuleKeys(db.getSession())).hasSize(1);
  981. }
  982. @Test
  983. public void insertDeprecatedRuleKey() {
  984. RuleDefinitionDto r1 = db.rules().insert();
  985. DeprecatedRuleKeyDto deprecatedRuleKeyDto = db.rules().insertDeprecatedKey(d -> d.setRuleUuid(r1.getUuid()));
  986. db.getSession().commit();
  987. Set<DeprecatedRuleKeyDto> deprecatedRuleKeyDtos = underTest.selectAllDeprecatedRuleKeys(db.getSession());
  988. assertThat(deprecatedRuleKeyDtos).hasSize(1);
  989. DeprecatedRuleKeyDto deprecatedRuleKeyDto1 = deprecatedRuleKeyDtos.iterator().next();
  990. assertThat(deprecatedRuleKeyDto1.getOldRepositoryKey()).isEqualTo(deprecatedRuleKeyDto.getOldRepositoryKey());
  991. assertThat(deprecatedRuleKeyDto1.getOldRuleKey()).isEqualTo(deprecatedRuleKeyDto.getOldRuleKey());
  992. assertThat(deprecatedRuleKeyDto1.getNewRepositoryKey()).isEqualTo(r1.getRepositoryKey());
  993. assertThat(deprecatedRuleKeyDto1.getNewRuleKey()).isEqualTo(r1.getRuleKey());
  994. assertThat(deprecatedRuleKeyDto1.getUuid()).isEqualTo(deprecatedRuleKeyDto.getUuid());
  995. assertThat(deprecatedRuleKeyDto1.getCreatedAt()).isEqualTo(deprecatedRuleKeyDto.getCreatedAt());
  996. assertThat(deprecatedRuleKeyDto1.getRuleUuid()).isEqualTo(r1.getUuid());
  997. }
  998. @Test
  999. public void insertDeprecatedRuleKey_with_same_RuleKey_should_fail() {
  1000. String repositoryKey = randomAlphanumeric(50);
  1001. String ruleKey = randomAlphanumeric(50);
  1002. db.rules().insertDeprecatedKey(d -> d.setOldRepositoryKey(repositoryKey)
  1003. .setOldRuleKey(ruleKey));
  1004. thrown.expect(PersistenceException.class);
  1005. db.rules().insertDeprecatedKey(d -> d.setOldRepositoryKey(repositoryKey)
  1006. .setOldRuleKey(ruleKey));
  1007. }
  1008. private static class Accumulator<T> implements Consumer<T> {
  1009. private final List<T> list = new ArrayList<>();
  1010. @Override
  1011. public void accept(T dto) {
  1012. list.add(dto);
  1013. }
  1014. }
  1015. }