aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorLukasz Jarocki <lukasz.jarocki@sonarsource.com>2021-07-14 15:54:51 +0200
committersonartech <sonartech@sonarsource.com>2021-07-27 20:03:02 +0000
commit9519c05d2ca5d3df513ab322baa9a3f23e93d6b7 (patch)
tree724db6875c570ee6af6cd2e42e9a568efe58b03d /server
parent09d8569209aade0e3b4cbd21c6dee9da025b245b (diff)
downloadsonarqube-9519c05d2ca5d3df513ab322baa9a3f23e93d6b7.tar.gz
sonarqube-9519c05d2ca5d3df513ab322baa9a3f23e93d6b7.zip
SONAR-15143 created api/audit_logs/download endpoint
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditDao.java28
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditMapper.java9
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/audit/AuditMapper.xml29
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/audit/AuditDaoTest.java95
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java7
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditDbTester.java43
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditTesting.java18
7 files changed, 128 insertions, 101 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditDao.java
index 5279b63575b..7c2b2d67979 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditDao.java
@@ -19,12 +19,12 @@
*/
package org.sonar.db.audit;
+import java.util.List;
import org.sonar.api.utils.System2;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
-
-import java.util.List;
+import org.sonar.db.Pagination;
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.MAX_SIZE;
@@ -45,23 +45,19 @@ public class AuditDao implements Dao {
return dbSession.getMapper(AuditMapper.class);
}
- public List<AuditDto> selectAll(DbSession dbSession) {
- return getMapper(dbSession).selectAll();
- }
-
- public List<AuditDto> selectByPeriod(DbSession dbSession, long beginning, long end) {
- return getMapper(dbSession).selectByPeriod(beginning, end);
- }
-
- public List<AuditDto> selectIfBeforeSelectedDate(DbSession dbSession, long end) {
- return getMapper(dbSession).selectIfBeforeSelectedDate(end);
+ public List<AuditDto> selectByPeriodPaginated(DbSession dbSession, long start, long end, int page) {
+ return getMapper(dbSession).selectByPeriodPaginated(start, end, Pagination.forPage(page).andSize(DEFAULT_PAGE_SIZE));
}
public void insert(DbSession dbSession, AuditDto auditDto) {
- long now = system2.now();
- auditDto.setUuid(uuidFactory.create());
- auditDto.setCreatedAt(now);
- if (auditDto.getNewValue().length() > MAX_SIZE) {
+ if (auditDto.getUuid() == null) {
+ auditDto.setUuid(uuidFactory.create());
+ }
+ if (auditDto.getCreatedAt() == 0) {
+ long now = system2.now();
+ auditDto.setCreatedAt(now);
+ }
+ if(auditDto.getNewValue().length() > MAX_SIZE) {
auditDto.setNewValue(EXCEEDED_LENGTH);
}
getMapper(dbSession).insert(auditDto);
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditMapper.java
index 22c7ea2ef53..f5a45d34ba6 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/audit/AuditMapper.java
@@ -20,21 +20,18 @@
package org.sonar.db.audit;
import org.apache.ibatis.annotations.Param;
+import org.sonar.db.Pagination;
import java.util.List;
public interface AuditMapper {
- List<AuditDto> selectAll();
-
- List<AuditDto> selectByPeriod(@Param("start") long start, @Param("end") long end);
-
- List<AuditDto> selectIfBeforeSelectedDate(@Param("end") long end);
-
void insert(@Param("dto") AuditDto auditDto);
void delete(@Param("uuids") List<String> uuids);
void deleteIfBeforeSelectedDate(@Param("timestamp") long timestamp);
+ List<AuditDto> selectByPeriodPaginated(@Param("start")long start, @Param("end") long end, @Param("pagination") Pagination pagination);
+
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/audit/AuditMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/audit/AuditMapper.xml
index 31ab08d8a71..a2a6347c333 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/audit/AuditMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/audit/AuditMapper.xml
@@ -13,27 +13,16 @@
a.created_at as "createdAt"
</sql>
- <select id="selectAll" resultType="org.sonar.db.audit.AuditDto">
- select <include refid="sqlColumns"/>
- from
- audits a
- </select>
-
- <select id="selectByPeriod" parameterType="map" resultType="org.sonar.db.audit.AuditDto">
- select <include refid="sqlColumns"/>
- from
- audits a
- where
- a.created_at &gt; #{start, jdbcType=BIGINT} AND
- a.created_at &lt; #{end, jdbcType=BIGINT}
- </select>
-
- <select id="selectIfBeforeSelectedDate" parameterType="map" resultType="org.sonar.db.audit.AuditDto">
- select <include refid="sqlColumns"/>
- from
- audits a
+ <select id="selectByPeriodPaginated" parameterType="map" resultType="org.sonar.db.audit.AuditDto">
+ select <include refid="sqlColumns"/> from (
+ select
+ row_number() over(order by created_at, uuid) as row_number, *
+ from audits
+ where created_at &gt;= #{start} and created_at &lt; #{end}
+ ) as a
where
- a.created_at &gt; #{end, jdbcType=BIGINT}
+ a.row_number between #{pagination.startRowNumber,jdbcType=INTEGER} and #{pagination.endRowNumber,jdbcType=INTEGER}
+ order by a.row_number asc
</select>
<insert id="insert" parameterType="Map" useGeneratedKeys="false">
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/AuditDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/AuditDaoTest.java
index fcde499416c..b338b23132d 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/audit/AuditDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/audit/AuditDaoTest.java
@@ -23,110 +23,94 @@ import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.impl.utils.TestSystem2;
-import org.sonar.core.util.UuidFactory;
import org.sonar.core.util.UuidFactoryImpl;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import static org.sonar.db.audit.AuditDao.EXCEEDED_LENGTH;
public class AuditDaoTest {
private static final long NOW = 1000000L;
- private static final String A_UUID = "SOME_UUID";
private final TestSystem2 system2 = new TestSystem2().setNow(NOW);
@Rule
public final DbTester db = DbTester.create(system2);
private final DbSession dbSession = db.getSession();
- private final UuidFactory uuidFactory = mock(UuidFactory.class);
private final AuditDao testAuditDao = new AuditDao(system2, UuidFactoryImpl.INSTANCE);
@Test
- public void selectAll_oneEntryInserted_returnThisEntry() {
- AuditDao auditDaoDeterministicUUID = new AuditDao(system2, uuidFactory);
- when(uuidFactory.create()).thenReturn(A_UUID);
- AuditDto auditDto = AuditTesting.newAuditDto();
- auditDaoDeterministicUUID.insert(dbSession, auditDto);
+ public void selectByPeriodPaginated_10001EntriesInserted_defaultPageSizeEntriesReturned() {
+ prepareRowsWithDeterministicCreatedAt(10001);
- List<AuditDto> auditDtos = auditDaoDeterministicUUID.selectAll(dbSession);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1, 20000, 1);
- assertThat(auditDtos.size()).isEqualTo(1);
- assertThat(auditDtos.get(0))
- .extracting(AuditDto::getUuid, AuditDto::getUserLogin,
- AuditDto::getUserUuid, AuditDto::getCategory,
- AuditDto::getOperation, AuditDto::getNewValue,
- AuditDto::getCreatedAt)
- .containsExactly(A_UUID, auditDto.getUserLogin(),
- auditDto.getUserUuid(), auditDto.getCategory(),
- auditDto.getOperation(), auditDto.getNewValue(),
- auditDto.getCreatedAt());
+ assertThat(auditDtos.size()).isEqualTo(10000);
}
@Test
- public void selectAll_100EntriesInserted_100EntriesReturned() {
- AuditDao auditDao = new AuditDao(system2, UuidFactoryImpl.INSTANCE);
- for(int i=0; i<100; i++) {
- AuditDto auditDto = AuditTesting.newAuditDto();
- auditDto.setUuid(randomAlphanumeric(20));
- auditDao.insert(dbSession, auditDto);
- }
+ public void selectByPeriodPaginated_10001EntriesInserted_querySecondPageReturns1Item() {
+ prepareRowsWithDeterministicCreatedAt(10001);
- List<AuditDto> auditDtos = auditDao.selectAll(dbSession);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1, 20000, 2);
- assertThat(auditDtos.size()).isEqualTo(100);
+ assertThat(auditDtos.size()).isEqualTo(1);
}
@Test
- public void selectByPeriod_selectOneRowFromTheMiddle() {
- prepareThreeRowsWithDeterministicCreatedAt();
+ public void deleteIfBeforeSelectedDate_deleteTwoRows() {
+ prepareRowsWithDeterministicCreatedAt(3);
- List<AuditDto> auditDtos = testAuditDao.selectByPeriod(dbSession, 1, 3);
+ testAuditDao.deleteIfBeforeSelectedDate(dbSession, 2);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1, 4, 1);
assertThat(auditDtos.size()).isEqualTo(1);
- assertThat(auditDtos.get(0).getCreatedAt()).isEqualTo(2);
}
@Test
- public void selectByPeriod_selectOneRowFromTheEnd() {
- prepareThreeRowsWithDeterministicCreatedAt();
+ public void selectByPeriodPaginated_100EntriesInserted_100EntriesReturned() {
+ prepareRowsWithDeterministicCreatedAt(100);
- List<AuditDto> auditDtos = testAuditDao.selectByPeriod(dbSession, 2, 4);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1, 101, 1);
- assertThat(auditDtos.size()).isEqualTo(1);
- assertThat(auditDtos.get(0).getCreatedAt()).isEqualTo(3);
+ assertThat(auditDtos.size()).isEqualTo(100);
}
@Test
- public void selectByPeriod_selectAllRows() {
- prepareThreeRowsWithDeterministicCreatedAt();
+ public void insert_doNotSetACreatedAtIfAlreadySet() {
+ AuditDto auditDto = AuditTesting.newAuditDto();
+ auditDto.setCreatedAt(1041375600000L);
- List<AuditDto> auditDtos = testAuditDao.selectByPeriod(dbSession, 0, 4);
+ testAuditDao.insert(dbSession, auditDto);
- assertThat(auditDtos.size()).isEqualTo(3);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1041375500000L, 1041375700000L, 1);
+ AuditDto storedAuditDto = auditDtos.get(0);
+ assertThat(storedAuditDto.getCreatedAt()).isEqualTo(auditDto.getCreatedAt());
}
@Test
- public void selectIfBeforeSelectedDate_select1Row() {
- prepareThreeRowsWithDeterministicCreatedAt();
+ public void insert_setACreatedAtIfAlreadySet() {
+ AuditDto auditDto = AuditTesting.newAuditDto();
+ auditDto.setCreatedAt(0);
- List<AuditDto> auditDtos = testAuditDao.selectIfBeforeSelectedDate(dbSession, 2);
+ testAuditDao.insert(dbSession, auditDto);
- assertThat(auditDtos.size()).isEqualTo(1);
+ assertThat(auditDto.getCreatedAt()).isNotZero();
}
@Test
- public void deleteIfBeforeSelectedDate_deleteTwoRows() {
- prepareThreeRowsWithDeterministicCreatedAt();
+ public void insert_doNotSetAUUIDIfAlreadySet() {
+ AuditDto auditDto = AuditTesting.newAuditDto();
+ auditDto.setUuid("myuuid");
+ auditDto.setCreatedAt(1041375600000L);
- testAuditDao.deleteIfBeforeSelectedDate(dbSession, 2);
+ testAuditDao.insert(dbSession, auditDto);
- List<AuditDto> auditDtos = testAuditDao.selectAll(dbSession);
- assertThat(auditDtos.size()).isEqualTo(1);
+ List<AuditDto> auditDtos = testAuditDao.selectByPeriodPaginated(dbSession, 1041375500000L, 1041375700000L, 1);
+ AuditDto storedAuditDto = auditDtos.get(0);
+ assertThat(storedAuditDto.getUuid()).isEqualTo(auditDto.getUuid());
}
@Test
@@ -140,10 +124,9 @@ public class AuditDaoTest {
assertThat(auditDto.getNewValue()).isEqualTo(EXCEEDED_LENGTH);
}
- private void prepareThreeRowsWithDeterministicCreatedAt() {
- for(int i=1; i<=3; i++) {
- AuditDto auditDto = AuditTesting.newAuditDto();
- system2.setNow(i);
+ private void prepareRowsWithDeterministicCreatedAt(int size) {
+ for (int i = 1; i <= size; i++) {
+ AuditDto auditDto = AuditTesting.newAuditDto(i);
testAuditDao.insert(dbSession, auditDto);
}
}
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
index 8d795b2411c..b4733ef57be 100644
--- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
@@ -34,6 +34,7 @@ import org.sonar.core.util.SequenceUuidFactory;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.alm.integration.pat.AlmPatsDbTester;
import org.sonar.db.almsettings.AlmSettingsDbTester;
+import org.sonar.db.audit.AuditDbTester;
import org.sonar.db.audit.AuditPersister;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ProjectLinkDbTester;
@@ -88,6 +89,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> {
private final InternalComponentPropertyDbTester internalComponentPropertyTester;
private final AlmSettingsDbTester almSettingsDbTester;
private final AlmPatsDbTester almPatsDbtester;
+ private final AuditDbTester auditDbTester;
private DbTester(System2 system2, @Nullable String schemaPath, AuditPersister auditPersister, MyBatisConfExtension... confExtensions) {
super(TestDbImpl.create(schemaPath, confExtensions));
@@ -116,6 +118,7 @@ public class DbTester extends AbstractDbTester<TestDbImpl> {
this.newCodePeriodTester = new NewCodePeriodDbTester(this);
this.almSettingsDbTester = new AlmSettingsDbTester(this);
this.almPatsDbtester = new AlmPatsDbTester(this);
+ this.auditDbTester = new AuditDbTester(this);
}
public static DbTester create() {
@@ -244,6 +247,10 @@ public class DbTester extends AbstractDbTester<TestDbImpl> {
return almPatsDbtester;
}
+ public AuditDbTester audits() {
+ return auditDbTester;
+ }
+
@Override
protected void after() {
if (session != null) {
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditDbTester.java
new file mode 100644
index 00000000000..2d34d325108
--- /dev/null
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditDbTester.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.audit;
+
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+
+public class AuditDbTester {
+
+ private final DbTester db;
+ private final DbClient dbClient;
+ private final DbSession dbSession;
+
+ public AuditDbTester(DbTester db) {
+ this.db = db;
+ this.dbClient = db.getDbClient();
+ this.dbSession = db.getSession();
+ }
+
+ public final void insertRandomAuditEntry(long createdAt) {
+ AuditDto auditDto = AuditTesting.newAuditDto(createdAt);
+ dbClient.auditDao().insert(dbSession, auditDto);
+ db.commit();
+ }
+}
diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditTesting.java
index 094ae46db49..1cc60162c32 100644
--- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditTesting.java
+++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/audit/AuditTesting.java
@@ -28,14 +28,26 @@ public class AuditTesting {
private static final Random random = new Random();
public static AuditDto newAuditDto() {
+ return newAuditDto(random.nextLong(), "operation");
+ }
+
+ public static AuditDto newAuditDto(String operation) {
+ return newAuditDto(random.nextLong(), operation);
+ }
+
+ public static AuditDto newAuditDto(long createdAt) {
+ return newAuditDto(createdAt, "operation");
+ }
+
+ public static AuditDto newAuditDto(long createdAt, String operation) {
AuditDto auditDto = new AuditDto();
auditDto.setUuid(randomAlphanumeric(20));
auditDto.setUserUuid(randomAlphanumeric(40));
auditDto.setUserLogin(randomAlphanumeric(40));
- auditDto.setNewValue(randomAlphanumeric(2000));
- auditDto.setOperation("operation");
+ auditDto.setNewValue("{ \"someKey\": \"someValue\" }");
+ auditDto.setOperation(operation);
auditDto.setCategory("category");
- auditDto.setCreatedAt(random.nextLong());
+ auditDto.setCreatedAt(createdAt);
return auditDto;
}
}