Skip to content

Commit

Permalink
fix: migrate dictionaries event with latest start or stop publish or …
Browse files Browse the repository at this point in the history
…unpublish state

(cherry picked from commit cae1d15)

# Conflicts:
#	gravitee-apim-rest-api/gravitee-apim-rest-api-service/src/main/java/io/gravitee/rest/api/service/impl/EventServiceImpl.java
  • Loading branch information
Okhelifi authored and mergify[bot] committed Sep 20, 2024
1 parent a17c92c commit 43cc6a2
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
* @author Titouan COMPIEGNE
*/
public interface EventService {
public static final String EVENT_LATEST_DYNAMIC_SUFFIX = "-dynamic";

EventEntity findById(ExecutionContext executionContext, String id);

EventEntity createApiEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
<<<<<<< HEAD
import java.util.function.Consumer;
=======
import java.util.stream.Collectors;
>>>>>>> cae1d1561e (fix: migrate dictionaries event with latest start or stop publish or unpublish state)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -197,8 +201,13 @@ public EventEntity createDynamicDictionaryEvent(
if (dictionaryId != null) {
eventProperties.put(Event.EventProperties.DICTIONARY_ID.getValue(), dictionaryId);
}
<<<<<<< HEAD
EventEntity event = createEvent(executionContext, environmentsIds, organizationId, type, null, eventProperties);
createOrPatchLatestEvent(dictionaryId + "-dynamic", organizationId, event);
=======
EventEntity event = createEvent(executionContext, environmentsIds, type, null, eventProperties);
createOrPatchLatestEvent(dictionaryId + EVENT_LATEST_DYNAMIC_SUFFIX, event);
>>>>>>> cae1d1561e (fix: migrate dictionaries event with latest start or stop publish or unpublish state)
return event;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@
import io.gravitee.repository.management.api.search.EventCriteria;
import io.gravitee.repository.management.api.search.builder.PageableBuilder;
import io.gravitee.repository.management.model.Dictionary;
import io.gravitee.repository.management.model.DictionaryType;
import io.gravitee.repository.management.model.Event;
import io.gravitee.repository.management.model.EventType;
import io.gravitee.repository.management.model.Organization;
import io.gravitee.rest.api.service.EventService;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -127,8 +130,9 @@ private void migrateDictionaryEvents() throws TechnicalException {
eventsForModelCounter = 0;
Set<Dictionary> dictionaries = this.dictionaryRepository.findAll();
if (dictionaries != null) {
List<String> ids = dictionaries.stream().map(Dictionary::getId).collect(Collectors.toList());
migrateEvents(Event.EventProperties.DICTIONARY_ID.getValue(), ids);
for (Dictionary dictionary : dictionaries) {
migrateDictionaryEvents(dictionary);
}
}
log.info("{} events regarding {} dictionaries have been migrated", eventsForModelCounter, modelCounter);
}
Expand All @@ -148,29 +152,72 @@ private void migrateOrganizationEvents() throws TechnicalException {
private void migrateEvents(final String propertyId, final List<String> ids) throws TechnicalException {
for (String id : ids) {
modelCounter++;
Page<Event> search =
this.eventRepository.search(
EventCriteria.builder().property(propertyId, id).build(),
new PageableBuilder().pageNumber(0).pageSize(1).build()
);
if (search.getPageElements() > 0) {
Event event = search.getContent().get(0);
if (event.getProperties() == null) {
event.setProperties(new HashMap<>());
}
event.getProperties().put(Event.EventProperties.ID.getValue(), event.getId());
event.setId(id);
// allow to reformat json payload without pretty
if (event.getPayload() != null) {
try {
event.setPayload(objectMapper.writeValueAsString(objectMapper.readTree(event.getPayload())));
} catch (JsonProcessingException e) {
// Ignore this and keep existing payload
}
}
this.eventLatestRepository.createOrUpdate(event);
eventsForModelCounter++;
Page<Event> eventPage = searchEvents(propertyId, id);
if (eventPage.getPageElements() > 0) {
processEvent(eventPage.getContent().get(0), id);
}
}
}

private void migrateDictionaryEvents(Dictionary dictionary) throws TechnicalException {
Page<Event> eventPage = searchEvents(
Event.EventProperties.DICTIONARY_ID.getValue(),
dictionary.getId(),
Set.of(EventType.PUBLISH_DICTIONARY, EventType.UNPUBLISH_DICTIONARY)
);
if (eventPage.getPageElements() > 0) {
Event event = eventPage.getContent().get(0);
processEvent(
event,
DictionaryType.DYNAMIC.equals(dictionary.getType())
? dictionary.getId() + EventService.EVENT_LATEST_DYNAMIC_SUFFIX
: dictionary.getId()
);
}

if (DictionaryType.DYNAMIC.equals(dictionary.getType())) {
eventPage =
searchEvents(
Event.EventProperties.DICTIONARY_ID.getValue(),
dictionary.getId(),
Set.of(EventType.START_DICTIONARY, EventType.STOP_DICTIONARY)
);
if (eventPage.getPageElements() > 0) {
Event event = eventPage.getContent().get(0);
processEvent(event, dictionary.getId());
}
}
}

private Page<Event> searchEvents(String propertyId, String id) {
return searchEvents(propertyId, id, null);
}

private Page<Event> searchEvents(String propertyId, String id, Set<EventType> types) {
EventCriteria.EventCriteriaBuilder criteria = EventCriteria.builder().property(propertyId, id);

if (types != null && !types.isEmpty()) {
criteria.types(types);
}

return this.eventRepository.search(criteria.build(), new PageableBuilder().pageNumber(0).pageSize(1).build());
}

private void processEvent(Event event, String id) throws TechnicalException {
if (event.getProperties() == null) {
event.setProperties(new HashMap<>());
}
event.getProperties().put(Event.EventProperties.ID.getValue(), event.getId());
event.setId(id);
// allow to reformat json payload without pretty
if (event.getPayload() != null) {
try {
event.setPayload(objectMapper.writeValueAsString(objectMapper.readTree(event.getPayload())));
} catch (JsonProcessingException e) {
// Ignore this and keep existing payload
}
}
this.eventLatestRepository.createOrUpdate(event);
eventsForModelCounter++;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.gravitee.rest.api.service.impl.upgrade.upgrader;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
Expand All @@ -37,8 +38,11 @@
import io.gravitee.repository.management.api.search.EventCriteria;
import io.gravitee.repository.management.api.search.builder.PageableBuilder;
import io.gravitee.repository.management.model.Dictionary;
import io.gravitee.repository.management.model.DictionaryType;
import io.gravitee.repository.management.model.Event;
import io.gravitee.repository.management.model.EventType;
import io.gravitee.repository.management.model.Organization;
import io.gravitee.rest.api.service.EventService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -48,6 +52,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

Expand Down Expand Up @@ -76,6 +82,9 @@ public class EventsLatestUpgraderTest {
@Mock
private EventsLatestUpgrader cut;

@Captor
private ArgumentCaptor<Event> eventCaptor;

@Before
public void before() {
cut =
Expand Down Expand Up @@ -187,32 +196,66 @@ public void should_create_latest_events_from_existing_apis_with_valid_and_invali
public void should_create_latest_events_from_existing_dictionaries() throws TechnicalException {
Dictionary dictionary1 = new Dictionary();
dictionary1.setId("dictionary1");
dictionary1.setType(DictionaryType.DYNAMIC);
Dictionary dictionary2 = new Dictionary();
dictionary2.setId("dictionary2");
dictionary2.setType(DictionaryType.MANUAL);
when(dictionaryRepository.findAll()).thenReturn(Set.of(dictionary1, dictionary2));
Event event1 = new Event();
event1.setType(EventType.PUBLISH_DICTIONARY);
when(
eventRepository.search(
EventCriteria.builder().property(Event.EventProperties.DICTIONARY_ID.getValue(), dictionary1.getId()).build(),
EventCriteria
.builder()
.property(Event.EventProperties.DICTIONARY_ID.getValue(), dictionary1.getId())
.types(Set.of(EventType.PUBLISH_DICTIONARY, EventType.UNPUBLISH_DICTIONARY))
.build(),
new PageableBuilder().pageNumber(0).pageSize(1).build()
)
)
.thenReturn(new Page<>(List.of(event1), 0, 1, 1));
when(eventLatestRepository.createOrUpdate(event1)).thenReturn(event1);
Event event2 = new Event();
event2.setType(EventType.STOP_DICTIONARY);
when(
eventRepository.search(
EventCriteria.builder().property(Event.EventProperties.DICTIONARY_ID.getValue(), dictionary2.getId()).build(),
EventCriteria
.builder()
.property(Event.EventProperties.DICTIONARY_ID.getValue(), dictionary1.getId())
.types(Set.of(EventType.START_DICTIONARY, EventType.STOP_DICTIONARY))
.build(),
new PageableBuilder().pageNumber(0).pageSize(1).build()
)
)
.thenReturn(new Page<>(List.of(event2), 0, 1, 1));
when(eventLatestRepository.createOrUpdate(event2)).thenReturn(event2);
Event event3 = new Event();
event3.setType(EventType.UNPUBLISH_DICTIONARY);
when(
eventRepository.search(
EventCriteria
.builder()
.property(Event.EventProperties.DICTIONARY_ID.getValue(), dictionary2.getId())
.types(Set.of(EventType.PUBLISH_DICTIONARY, EventType.UNPUBLISH_DICTIONARY))
.build(),
new PageableBuilder().pageNumber(0).pageSize(1).build()
)
)
.thenReturn(new Page<>(List.of(event3), 0, 1, 1));
when(eventLatestRepository.createOrUpdate(event3)).thenReturn(event3);

cut.upgrade();

verify(eventLatestRepository).createOrUpdate(event1);
verify(eventLatestRepository).createOrUpdate(event2);
verify(eventLatestRepository, times(3)).createOrUpdate(eventCaptor.capture());
var eventsSaved = eventCaptor.getAllValues();
assertThat(eventsSaved)
.extracting(Event::getId, Event::getType)
.containsExactlyInAnyOrder(
tuple("dictionary1" + EventService.EVENT_LATEST_DYNAMIC_SUFFIX, EventType.PUBLISH_DICTIONARY),
tuple("dictionary1", EventType.STOP_DICTIONARY),
tuple("dictionary2", EventType.UNPUBLISH_DICTIONARY)
);

verifyNoMoreInteractions(eventLatestRepository);
}

Expand Down

0 comments on commit 43cc6a2

Please sign in to comment.