import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import org.jetbrains.annotations.NotNull;
import org.sonar.api.Startable;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Loggers;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.project.ProjectDto;
import org.sonar.db.pushevent.PushEventDto;
import org.sonar.server.pushapi.sonarlint.SonarLintClient;
import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
lastPullTimestamp = getLastPullTimestamp();
}
- var projectKeys = getClientsProjectKeys(clients);
+ var projectUuids = getClientsProjectUuids(clients);
try (DbSession dbSession = dbClient.openSession(false)) {
- var projectKeysByUuids = getProjectKeysByUuids(dbSession, projectKeys);
- Deque<PushEventDto> events = getPushEvents(dbSession, projectKeysByUuids.keySet());
+ Deque<PushEventDto> events = getPushEvents(dbSession, projectUuids);
LOG.debug("Received {} push events, attempting to broadcast to {} registered clients.", events.size(),
clients.size());
- events.forEach(pushEventDto -> mapToSonarLintPushEvent(pushEventDto, projectKeysByUuids)
+ events.forEach(pushEventDto -> mapToSonarLintPushEvent(pushEventDto)
.ifPresent(clientsRegistry::broadcastMessage));
if (!events.isEmpty()) {
}
}
- private static Optional<SonarLintPushEvent> mapToSonarLintPushEvent(PushEventDto pushEventDto, Map<String, String> projectKeysByUuids) {
- var resolvedProjectKey = projectKeysByUuids.get(pushEventDto.getProjectUuid());
- if (resolvedProjectKey == null) {
- LOG.debug("Could not find key for project with uuid [{}]", pushEventDto.getProjectUuid());
- return Optional.empty();
- }
- return Optional.of(new SonarLintPushEvent(pushEventDto.getName(), pushEventDto.getPayload(), resolvedProjectKey,
+ private static Optional<SonarLintPushEvent> mapToSonarLintPushEvent(PushEventDto pushEventDto) {
+ return Optional.of(new SonarLintPushEvent(pushEventDto.getName(), pushEventDto.getPayload(), pushEventDto.getProjectUuid(),
pushEventDto.getLanguage()));
}
- private static Set<String> getClientsProjectKeys(List<SonarLintClient> clients) {
+ private static Set<String> getClientsProjectUuids(List<SonarLintClient> clients) {
return clients.stream()
- .map(SonarLintClient::getClientProjectKeys)
+ .map(SonarLintClient::getClientProjectUuids)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
return dbClient.pushEventDao().selectChunkByProjectUuids(dbSession, projectUuids, lastPullTimestamp, lastSeenUuid, getPageSize());
}
- @NotNull
- private Map<String, String> getProjectKeysByUuids(DbSession dbSession, Set<String> projectKeys) {
- return dbClient.projectDao().selectProjectsByKeys(dbSession, projectKeys)
- .stream()
- .collect(Collectors.toMap(ProjectDto::getUuid, ProjectDto::getKey));
- }
-
public long getInitialDelay() {
// two minutes default initial delay
return config.getLong(INITIAL_DELAY_IN_SECONDS).orElse(2 * 60L);
private static final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
private final Set<String> languages;
- private final Set<String> projectKeys;
+ private final Set<String> projectUuids;
private final String userUuid;
- public SonarLintClient(AsyncContext asyncContext, Set<String> projectKeys, Set<String> languages, String userUuid) {
+ public SonarLintClient(AsyncContext asyncContext, Set<String> projectUuids, Set<String> languages, String userUuid) {
super(scheduledExecutorService, asyncContext);
- this.projectKeys = projectKeys;
+ this.projectUuids = projectUuids;
this.languages = languages;
this.userUuid = userUuid;
}
return languages;
}
- public Set<String> getClientProjectKeys() {
- return projectKeys;
+ public Set<String> getClientProjectUuids() {
+ return projectUuids;
}
@Override
}
SonarLintClient that = (SonarLintClient) o;
return languages.equals(that.languages)
- && projectKeys.equals(that.projectKeys)
+ && projectUuids.equals(that.projectUuids)
&& asyncContext.equals(that.asyncContext);
}
@Override
public int hashCode() {
- return Objects.hash(languages, projectKeys);
+ return Objects.hash(languages, projectUuids);
}
public String getUserUuid() {
this.userSessionFactory = userSessionFactory;
}
- public void validateUserCanReceivePushEventForProjects(UserSession userSession, Set<String> projectKeys) {
+ public List<ProjectDto> validateUserCanReceivePushEventForProjects(UserSession userSession, Set<String> projectKeys) {
List<ProjectDto> projectDtos;
try (DbSession dbSession = dbClient.openSession(false)) {
projectDtos = dbClient.projectDao().selectProjectsByKeys(dbSession, projectKeys);
}
- validateUsersDeactivationStatus(userSession);
- for (ProjectDto projectDto : projectDtos) {
- userSession.checkProjectPermission(UserRole.USER, projectDto);
- }
+ validateProjectPermissions(userSession, projectDtos);
+ return projectDtos;
}
- public void validateUserCanReceivePushEventForProjects(String userUUID, Set<String> projectKeys) {
+ public void validateUserCanReceivePushEventForProjectUuids(String userUuid, Set<String> projectUuids) {
UserDto userDto;
try (DbSession dbSession = dbClient.openSession(false)) {
- userDto = dbClient.userDao().selectByUuid(dbSession, userUUID);
+ userDto = dbClient.userDao().selectByUuid(dbSession, userUuid);
}
if (userDto == null) {
throw new ForbiddenException("User does not exist");
}
- validateUserCanReceivePushEventForProjects(userSessionFactory.create(userDto), projectKeys);
+ UserSession userSession = userSessionFactory.create(userDto);
+ List<ProjectDto> projectDtos;
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ projectDtos = dbClient.projectDao().selectByUuids(dbSession, projectUuids);
+ }
+ validateProjectPermissions(userSession, projectDtos);
+ }
+
+ private static void validateProjectPermissions(UserSession userSession, List<ProjectDto> projectDtos) {
+ validateUsersDeactivationStatus(userSession);
+ for (ProjectDto projectDto : projectDtos) {
+ userSession.checkProjectPermission(UserRole.USER, projectDto);
+ }
}
private static void validateUsersDeactivationStatus(UserSession userSession) {
public void broadcastMessage(SonarLintPushEvent event) {
clients.stream().filter(client -> isRelevantEvent(event, client))
.forEach(c -> {
- Set<String> clientProjectKeys = new HashSet<>(c.getClientProjectKeys());
- clientProjectKeys.retainAll(Set.of(event.getProjectKey()));
+ Set<String> clientProjectUuids = new HashSet<>(c.getClientProjectUuids());
+ clientProjectUuids.retainAll(Set.of(event.getProjectUuid()));
try {
- sonarLintClientPermissionsValidator.validateUserCanReceivePushEventForProjects(c.getUserUuid(), clientProjectKeys);
+ sonarLintClientPermissionsValidator.validateUserCanReceivePushEventForProjectUuids(c.getUserUuid(), clientProjectUuids);
c.writeAndFlush(event.serialize());
} catch (ForbiddenException forbiddenException) {
logClientUnauthenticated(forbiddenException);
}
private static boolean isRelevantEvent(SonarLintPushEvent event, SonarLintClient client) {
- return client.getClientProjectKeys().contains(event.getProjectKey())
+ return client.getClientProjectUuids().contains(event.getProjectUuid())
&& (!event.getName().equals("RuleSetChanged") || client.getLanguages().contains(event.getLanguage()));
}
import java.io.IOException;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;
import org.sonar.api.server.ws.Request;
var params = new SonarLintPushActionParamsValidator(request);
params.validateParams();
- permissionsValidator.validateUserCanReceivePushEventForProjects(userSession, params.projectKeys);
+ List<ProjectDto> projectDtos = permissionsValidator.validateUserCanReceivePushEventForProjects(userSession, params.projectKeys);
if (!isServerSideEventsRequest(servletRequest)) {
servletResponse.stream().setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
AsyncContext asyncContext = servletRequest.startAsync();
asyncContext.setTimeout(0);
- SonarLintClient sonarLintClient = new SonarLintClient(asyncContext, params.getProjectKeys(), params.getLanguages(), userSession.getUuid());
+ Set<String> projectUuids = projectDtos.stream().map(ProjectDto::getUuid).collect(Collectors.toSet());
+
+ SonarLintClient sonarLintClient = new SonarLintClient(asyncContext, projectUuids, params.getLanguages(), userSession.getUuid());
clientsRegistry.registerClient(sonarLintClient);
}
this.languages = parseParam(LANGUAGE_PARAM_KEY);
}
- Set<String> getProjectKeys() {
- return projectKeys;
- }
-
Set<String> getLanguages() {
return languages;
}
private final String name;
private final byte[] data;
- private final String projectKey;
+ private final String projectUuid;
private final String language;
- public SonarLintPushEvent(String name, byte[] data, String projectKey, @Nullable String language) {
+ public SonarLintPushEvent(String name, byte[] data, String projectUuid, @Nullable String language) {
this.name = name;
this.data = data;
- this.projectKey = projectKey;
+ this.projectUuid = projectUuid;
this.language = language;
}
- public String getProjectKey() {
- return projectKey;
+ public String getProjectUuid() {
+ return projectUuid;
}
@CheckForNull
var project = db.components().insertPrivateProject();
var sonarLintClient = mock(SonarLintClient.class);
- when(sonarLintClient.getClientProjectKeys()).thenReturn(Set.of(project.getDbKey()));
+ when(sonarLintClient.getClientProjectUuids()).thenReturn(Set.of(project.uuid()));
when(clientsRegistry.getClients()).thenReturn(List.of(sonarLintClient));
var underTest = new PushEventPollScheduler(executorService, clientsRegistry, db.getDbClient(), system2, config);
system2.setNow(1L);
var sonarLintClient = mock(SonarLintClient.class);
- when(sonarLintClient.getClientProjectKeys()).thenReturn(Set.of("not-existing-project-key"));
+ when(sonarLintClient.getClientProjectUuids()).thenReturn(Set.of("not-existing-project-uuid"));
when(clientsRegistry.getClients()).thenReturn(List.of(sonarLintClient));
var underTest = new PushEventPollScheduler(executorService, clientsRegistry, db.getDbClient(), system2, config);
system2.setNow(1L);
var sonarLintClient = mock(SonarLintClient.class);
- when(sonarLintClient.getClientProjectKeys()).thenReturn(Set.of(project.getDbKey()));
+ when(sonarLintClient.getClientProjectUuids()).thenReturn(Set.of(project.uuid()));
when(clientsRegistry.getClients()).thenReturn(List.of(sonarLintClient));
var underTest = new PushEventPollScheduler(executorService, clientsRegistry, db.getDbClient(), system2, config);
system2.setNow(1L);
var sonarLintClient = mock(SonarLintClient.class);
- when(sonarLintClient.getClientProjectKeys()).thenReturn(Set.of(project.getDbKey()));
+ when(sonarLintClient.getClientProjectUuids()).thenReturn(Set.of(project.uuid()));
when(clientsRegistry.getClients()).thenReturn(List.of(sonarLintClient), emptyList());
var underTest = new PushEventPollScheduler(executorService, clientsRegistry, db.getDbClient(), system2, config);
import java.util.List;
import java.util.Set;
-import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.sonar.db.DbClient;
private final static String USER_UUID = "USER_UUID";
- private final Set<String> exampleProjectKeys = Set.of("project1", "project2");
+ private final Set<String> exampleProjectuuids = Set.of("project1", "project2");
private final List<ProjectDto> projectDtos = List.of(mock(ProjectDto.class), mock(ProjectDto.class));
private final DbClient dbClient = mock(DbClient.class);
private final UserSessionFactory userSessionFactory = mock(UserSessionFactory.class);
when(dbClient.projectDao()).thenReturn(projectDao);
when(userSessionFactory.create(any())).thenReturn(userSession);
when(projectDao.selectProjectsByKeys(any(), any())).thenReturn(projectDtos);
+ when(projectDao.selectByUuids(any(), any())).thenReturn(projectDtos);
}
@Test
when(userDao.selectByUuid(any(), any())).thenReturn(userDto);
when(userSession.isActive()).thenReturn(true);
- assertThatCode(() -> underTest.validateUserCanReceivePushEventForProjects(USER_UUID, exampleProjectKeys))
+ assertThatCode(() -> underTest.validateUserCanReceivePushEventForProjectUuids(USER_UUID, exampleProjectuuids))
.doesNotThrowAnyException();
}
when(userSession.isActive()).thenReturn(false);
assertThrows(ForbiddenException.class,
- () -> underTest.validateUserCanReceivePushEventForProjects(USER_UUID, exampleProjectKeys));
+ () -> underTest.validateUserCanReceivePushEventForProjectUuids(USER_UUID, exampleProjectuuids));
}
@Test
when(userSession.checkProjectPermission(any(), any())).thenThrow(ForbiddenException.class);
assertThrows(ForbiddenException.class,
- () -> underTest.validateUserCanReceivePushEventForProjects(USER_UUID, exampleProjectKeys));
+ () -> underTest.validateUserCanReceivePushEventForProjectUuids(USER_UUID, exampleProjectuuids));
}
}
}
@Test
- public void equals_twoClientsWithDifferentProjectKeys() {
+ public void equals_twoClientsWithDifferentProjectUuids() {
SonarLintClient first = new SonarLintClient(firstContext, Set.of("project1", "project2"), Set.of(), USER_UUID);
SonarLintClient second = new SonarLintClient(firstContext, Set.of("project1"), Set.of(), USER_UUID);
private final AsyncContext defaultAsyncContext = mock(AsyncContext.class);
- private final Set<String> exampleKeys = Set.of("project1", "project2", "project3");
+ private final Set<String> exampleProjectUuids = Set.of("project1", "project2", "project3");
private final Set<String> languageKeys = Set.of("language1", "language2", "language3");
private final String USER_UUID = "userUuid";
private final ServletResponse response = mock(ServletResponse.class);
public void registering10Clients_10ClientsAreRegistered() {
for (int i = 0; i < 10; i++) {
AsyncContext newAsyncContext = mock(AsyncContext.class);
- SonarLintClient sonarLintClient = new SonarLintClient(newAsyncContext, exampleKeys, languageKeys, USER_UUID);
+ SonarLintClient sonarLintClient = new SonarLintClient(newAsyncContext, exampleProjectUuids, languageKeys, USER_UUID);
underTest.registerClient(sonarLintClient);
}
Set<String> javaLanguageKey = Set.of("java");
when(defaultAsyncContext.getResponse()).thenReturn(response);
when(response.getOutputStream()).thenReturn(outputStream);
- SonarLintClient sonarLintClient = new SonarLintClient(defaultAsyncContext, exampleKeys, javaLanguageKey, USER_UUID);
+ SonarLintClient sonarLintClient = new SonarLintClient(defaultAsyncContext, exampleProjectUuids, javaLanguageKey, USER_UUID);
underTest.registerClient(sonarLintClient);
Set<String> jsLanguageKey = Set.of("js");
when(defaultAsyncContext.getResponse()).thenReturn(response);
when(response.getOutputStream()).thenReturn(outputStream);
- SonarLintClient sonarLintClient = new SonarLintClient(defaultAsyncContext, exampleKeys, jsLanguageKey, USER_UUID);
+ SonarLintClient sonarLintClient = new SonarLintClient(defaultAsyncContext, exampleProjectUuids, jsLanguageKey, USER_UUID);
underTest.registerClient(sonarLintClient);
underTest.broadcastMessage(event1);
underTest.broadcastMessage(event2);
- verify(permissionsValidator, times(1)).validateUserCanReceivePushEventForProjects(anyString(), argument.capture());
+ verify(permissionsValidator, times(1)).validateUserCanReceivePushEventForProjectUuids(anyString(), argument.capture());
assertThat(argument.getValue()).hasSize(1).contains("projA");
}
public void listen_givenUserNotPermittedToReceiveEvent_closeConnection() {
SonarLintClient sonarLintClient = createSampleSLClient();
underTest.registerClient(sonarLintClient);
- doThrow(new ForbiddenException("Access forbidden")).when(permissionsValidator).validateUserCanReceivePushEventForProjects(anyString(), anySet());
+ doThrow(new ForbiddenException("Access forbidden")).when(permissionsValidator).validateUserCanReceivePushEventForProjectUuids(anyString(), anySet());
SonarLintPushEvent event = new SonarLintPushEvent(EVENT_NAME, "data".getBytes(StandardCharsets.UTF_8), "project1", "java");
underTest.broadcastMessage(event);
- verify(permissionsValidator, times(1)).validateUserCanReceivePushEventForProjects(anyString(), anySet());
+ verify(permissionsValidator, times(1)).validateUserCanReceivePushEventForProjectUuids(anyString(), anySet());
verify(sonarLintClient, times(1)).writeAndFlush(anyString());
}
underTest.broadcastMessage(event);
- verify(permissionsValidator, times(0)).validateUserCanReceivePushEventForProjects(anyString(), anySet());
+ verify(permissionsValidator, times(0)).validateUserCanReceivePushEventForProjectUuids(anyString(), anySet());
verify(sonarLintClient, times(0)).close();
verify(sonarLintClient, times(0)).writeAndFlush(anyString());
}
SonarLintClient sonarLintClient = createSampleSLClient();
underTest.registerClient(sonarLintClient);
- doThrow(new ForbiddenException("Access forbidden")).when(permissionsValidator).validateUserCanReceivePushEventForProjects(anyString(), anySet());
+ doThrow(new ForbiddenException("Access forbidden")).when(permissionsValidator).validateUserCanReceivePushEventForProjectUuids(anyString(), anySet());
underTest.broadcastMessage(event);
private SonarLintClient createSampleSLClient() {
SonarLintClient mock = mock(SonarLintClient.class);
when(mock.getLanguages()).thenReturn(Set.of("java"));
- when(mock.getClientProjectKeys()).thenReturn(exampleKeys);
+ when(mock.getClientProjectUuids()).thenReturn(exampleProjectUuids);
when(mock.getUserUuid()).thenReturn("userUuid");
return mock;
}
*/
package org.sonar.server.component;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.project.ProjectDto;
+import org.sonar.db.pushevent.PushEventDto;
import org.sonar.server.es.ProjectIndexer;
import org.sonar.server.es.ProjectIndexers;
import org.sonar.server.project.Project;
import org.sonar.server.project.RekeyedProject;
import org.sonar.server.user.UserSession;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.sonar.core.component.ComponentKeys.checkProjectKey;
@ServerSide
public class ComponentService {
+ private static final Gson GSON = new GsonBuilder().create();
+
private final DbClient dbClient;
private final UserSession userSession;
private final ProjectIndexers projectIndexers;
projectIndexers.commitAndIndexProjects(dbSession, singletonList(project), ProjectIndexer.Cause.PROJECT_KEY_UPDATE);
Project newProject = new Project(project.getUuid(), newKey, project.getName(), project.getDescription(), project.getTags());
projectLifeCycleListeners.onProjectsRekeyed(singleton(new RekeyedProject(newProject, project.getKey())));
+ persistEvent(project, newKey);
+ }
+
+ private void persistEvent(ProjectDto project, String newProjectKey) {
+ ProjectKeyChangedEvent event = new ProjectKeyChangedEvent(project.getKey(), newProjectKey);
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ PushEventDto eventDto = new PushEventDto()
+ .setName("ProjectKeyChanged")
+ .setProjectUuid(project.getUuid())
+ .setPayload(serializeIssueToPushEvent(event));
+ dbClient.pushEventDao().insert(dbSession, eventDto);
+ dbSession.commit();
+ }
+ }
+
+ private static byte[] serializeIssueToPushEvent(ProjectKeyChangedEvent event) {
+ return GSON.toJson(event).getBytes(UTF_8);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.server.component;
+
+import java.io.Serializable;
+
+public class ProjectKeyChangedEvent implements Serializable {
+ private static final String EVENT = "ProjectKeyChanged";
+
+ private final String oldProjectKey;
+ private final String newProjectKey;
+
+ public ProjectKeyChangedEvent(String oldProjectKey, String newProjectKey) {
+ this.oldProjectKey = oldProjectKey;
+ this.newProjectKey = newProjectKey;
+ }
+
+ public String getEvent() {
+ return EVENT;
+ }
+
+ public String getOldProjectKey() {
+ return oldProjectKey;
+ }
+
+ public String getNewProjectKey() {
+ return newProjectKey;
+ }
+
+}
*/
package org.sonar.server.component;
+import java.nio.charset.StandardCharsets;
+import java.util.Deque;
+import java.util.Optional;
+import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.project.ProjectDto;
+import org.sonar.db.pushevent.PushEventDto;
import org.sonar.server.es.ProjectIndexer;
import org.sonar.server.es.TestProjectIndexers;
import org.sonar.server.exceptions.ForbiddenException;
assertThat(dbClient.componentDao().selectByKey(dbSession, inactiveFile.getDbKey())).isEmpty();
assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue();
+
+ Deque<PushEventDto> pushEvents = db.getDbClient().pushEventDao().selectChunkByProjectUuids(dbSession, Set.of(project.uuid()), 0L, "id", 20);
+
+ assertThat(pushEvents).isNotEmpty();
+
+ Optional<PushEventDto> event = pushEvents.stream().filter(e -> e.getProjectUuid().equals(project.uuid()) && e.getName().equals("ProjectKeyChanged")).findFirst();
+ assertThat(event).isNotEmpty();
+
+ String payload = new String(event.get().getPayload(), StandardCharsets.UTF_8);
+
+ assertThat(payload).isEqualTo("{\"oldProjectKey\":\"sample:root\",\"newProjectKey\":\"sample2:root\"}");
}
@Test
String anotherProjectDbKey = anotherProject.getDbKey();
assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto,
anotherProjectDbKey))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage("Impossible to update key: a component with key \"" + anotherProjectDbKey + "\" already exists.");
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Impossible to update key: a component with key \"" + anotherProjectDbKey + "\" already exists.");
}
@Test
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.server.component;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class ProjectKeyChangedEventTest {
+
+ @Test
+ public void gettersAndSettersWorkCorrectly() {
+ ProjectKeyChangedEvent underTest = new ProjectKeyChangedEvent("oldKey", "newKey");
+ assertThat(underTest.getEvent()).isEqualTo("ProjectKeyChanged");
+ assertThat(underTest.getOldProjectKey()).isEqualTo("oldKey");
+ assertThat(underTest.getNewProjectKey()).isEqualTo("newKey");
+ }
+}