Skip to content

Commit

Permalink
feat(#3298): add cypress e2e tests for compact adapter feature (#3308)
Browse files Browse the repository at this point in the history
* feat(#3298): Add test to validate code editor for compact adapters in UI (#3299)

* feat(#3298): Add test to validate code editor for compact adapters in UI

* feat(#3298): Add test to validate success path of add compact adapters (#3301)

* feat(#3298): Add test to validate success path of add compact adapters

* feat(#3298): Add header to yml file

* feat(#3298): Return Conflict Status Code for Duplicate Adapter ID (#3302)

* feat(#3298): Return status code conflict when adapter id is already taken

* feat(#3298): Fix checkstyle

* feat(#3298): Add test to check rename rule for compact adapters

* feat(#3298): Add test to check rename unit transformation rule for compact adapters

* feat(#3298): Fix e2e tests and improve error message in ui
  • Loading branch information
tenthe authored Oct 31, 2024
1 parent 9d070d9 commit 370bc71
Show file tree
Hide file tree
Showing 39 changed files with 778 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,39 +53,52 @@ public class AdapterMasterManagement {

private final DataStreamResourceManager dataStreamResourceManager;

public AdapterMasterManagement(IAdapterStorage adapterInstanceStorage,
AdapterResourceManager adapterResourceManager,
DataStreamResourceManager dataStreamResourceManager,
AdapterMetrics adapterMetrics
public AdapterMasterManagement(
IAdapterStorage adapterInstanceStorage,
AdapterResourceManager adapterResourceManager,
DataStreamResourceManager dataStreamResourceManager,
AdapterMetrics adapterMetrics
) {
this.adapterInstanceStorage = adapterInstanceStorage;
this.adapterMetrics = adapterMetrics;
this.adapterResourceManager = adapterResourceManager;
this.dataStreamResourceManager = dataStreamResourceManager;
}

public void addAdapter(AdapterDescription ad,
String adapterElementId,
String principalSid)
public void addAdapter(
AdapterDescription adapterDescription,
String adapterId,
String principalSid
)
throws AdapterException {

// Create elementId for adapter
// Create elementId for datastream
var dataStreamElementId = ElementIdGenerator.makeElementId(SpDataStream.class);
ad.setElementId(adapterElementId);
ad.setCreatedAt(System.currentTimeMillis());
ad.setCorrespondingDataStreamElementId(dataStreamElementId);
adapterDescription.setElementId(adapterId);
adapterDescription.setCreatedAt(System.currentTimeMillis());
adapterDescription.setCorrespondingDataStreamElementId(dataStreamElementId);

// Add EventGrounding to AdapterDescription
var eventGrounding = GroundingUtils.createEventGrounding();
ad.setEventGrounding(eventGrounding);
adapterDescription.setEventGrounding(eventGrounding);

this.adapterResourceManager.encryptAndCreate(ad);
this.adapterResourceManager.encryptAndCreate(adapterDescription);

// Create stream
var storedDescription = new SourcesManagement().createAdapterDataStream(ad, dataStreamElementId);
storedDescription.setCorrespondingAdapterId(adapterElementId);
// Stream is only created if the adpater is successfully stored
createDataStreamForAdapter(adapterDescription, adapterId, dataStreamElementId, principalSid);
}

private void createDataStreamForAdapter(
AdapterDescription adapterDescription,
String adapterId,
String streamId,
String principalSid
) throws AdapterException {
var storedDescription = new SourcesManagement()
.createAdapterDataStream(adapterDescription, streamId);
storedDescription.setCorrespondingAdapterId(adapterId);
installDataSource(storedDescription, principalSid, true);
LOG.info("Install source (source URL: {} in backend", ad.getElementId());
LOG.info("Install source (source URL: {} in backend", adapterDescription.getElementId());
}

public AdapterDescription getAdapter(String elementId) throws AdapterException {
Expand Down Expand Up @@ -163,7 +176,8 @@ public void startStreamAdapter(String elementId) throws AdapterException {
var baseUrl = new ExtensionsServiceEndpointGenerator().getEndpointBaseUrl(
ad.getAppId(),
SpServiceUrlProvider.ADAPTER,
ad.getDeploymentConfiguration().getDesiredServiceTags()
ad.getDeploymentConfiguration()
.getDesiredServiceTags()
);

// Update selected endpoint URL of adapter
Expand All @@ -182,9 +196,11 @@ public void startStreamAdapter(String elementId) throws AdapterException {
}
}

private void installDataSource(SpDataStream stream,
String principalSid,
boolean publicElement) throws AdapterException {
private void installDataSource(
SpDataStream stream,
String principalSid,
boolean publicElement
) throws AdapterException {
try {
new DataStreamVerifier(stream).verifyAndAdd(principalSid, publicElement);
} catch (SepaParseException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
public class AdapterMasterManagementTest {

@Test
public void getAdapterFailNull() {
AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
public void getAdapter_FailNull() {
var adapterStorage = mock(AdapterInstanceStorageImpl.class);
var resourceManager = mock(AdapterResourceManager.class);
when(adapterStorage.findAll()).thenReturn(null);

AdapterMasterManagement adapterMasterManagement =
var adapterMasterManagement =
new AdapterMasterManagement(
adapterStorage,
resourceManager,
Expand All @@ -53,13 +53,13 @@ public void getAdapterFailNull() {
}

@Test
public void getAdapterFail() {
List<AdapterDescription> adapterDescriptions = List.of(new AdapterDescription());
AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
public void getAdapter_Fail() {
var adapterDescriptions = List.of(new AdapterDescription());
var adapterStorage = mock(AdapterInstanceStorageImpl.class);
var resourceManager = mock(AdapterResourceManager.class);
when(adapterStorage.findAll()).thenReturn(adapterDescriptions);

AdapterMasterManagement adapterMasterManagement =
var adapterMasterManagement =
new AdapterMasterManagement(
adapterStorage,
resourceManager,
Expand All @@ -71,10 +71,10 @@ public void getAdapterFail() {
}

@Test
public void getAllAdaptersSuccess() throws AdapterException {
List<AdapterDescription> adapterDescriptions = List.of(new AdapterDescription());
AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
public void getAllAdapters_Success() throws AdapterException {
var adapterDescriptions = List.of(new AdapterDescription());
var adapterStorage = mock(AdapterInstanceStorageImpl.class);
var resourceManager = mock(AdapterResourceManager.class);
when(adapterStorage.findAll()).thenReturn(adapterDescriptions);

AdapterMasterManagement adapterMasterManagement =
Expand All @@ -91,12 +91,12 @@ public void getAllAdaptersSuccess() throws AdapterException {
}

@Test
public void getAllAdaptersFail() {
AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
public void getAllAdapters_Fail() {
var adapterStorage = mock(AdapterInstanceStorageImpl.class);
var resourceManager = mock(AdapterResourceManager.class);
when(adapterStorage.findAll()).thenReturn(null);

AdapterMasterManagement adapterMasterManagement =
var adapterMasterManagement =
new AdapterMasterManagement(
adapterStorage,
resourceManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ public static ErrorMessage error(NotificationType type) {
return new ErrorMessage(new Notification(type.name(), type.description()));
}

public static ErrorMessage error(String message, String description) {
return new ErrorMessage(new Notification(message, description));
}

public static ErrorMessage error(String message) {
return new ErrorMessage(new Notification(message, ""));
return error(message, "");
}

public static ErrorMessage error(NotificationType type, String info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.apache.streampipes.resource.management;

import org.apache.streampipes.commons.exceptions.connect.AdapterException;
import org.apache.streampipes.model.connect.adapter.AdapterDescription;
import org.apache.streampipes.model.util.Cloner;
import org.apache.streampipes.resource.management.secret.SecretProvider;
Expand All @@ -30,7 +31,8 @@ public AdapterResourceManager(IAdapterStorage adapterStorage) {
}

public AdapterResourceManager() {
super(StorageDispatcher.INSTANCE.getNoSqlStore().getAdapterInstanceStorage());
super(StorageDispatcher.INSTANCE.getNoSqlStore()
.getAdapterInstanceStorage());
}

/**
Expand All @@ -39,19 +41,31 @@ public AdapterResourceManager() {
* @param adapterDescription input adapter description
* @return the id of the created adapter
*/
public String encryptAndCreate(AdapterDescription adapterDescription) {
AdapterDescription encryptedAdapterDescription = cloneAndEncrypt(adapterDescription);
public String encryptAndCreate(AdapterDescription adapterDescription) throws AdapterException {
var encryptedAdapterDescription = cloneAndEncrypt(adapterDescription);
encryptedAdapterDescription.setRev(null);
return db.persist(encryptedAdapterDescription).v;

try {
return db.persist(encryptedAdapterDescription).v;
} catch (org.lightcouch.DocumentConflictException e) {
throw new AdapterException("Conflict occurred while creating the adapter", e);
}
}

/**
* Takes an {@link AdapterDescription}, encrypts the password properties and updates the corresponding database entry
*
* @param adapterDescription input adapter description
*/
public void encryptAndUpdate(AdapterDescription adapterDescription) {
db.updateElement(cloneAndEncrypt(adapterDescription));
public void encryptAndUpdate(AdapterDescription adapterDescription) throws AdapterException {
try {
db.updateElement(cloneAndEncrypt(adapterDescription));
} catch (org.lightcouch.DocumentConflictException e) {
throw new AdapterException(
"Conflict occurred while editing the adapter with id: %s".formatted(adapterDescription.getElementId()),
e
);
}
}

public void delete(String elementId) {
Expand All @@ -63,7 +77,8 @@ public void delete(String elementId) {
*/
private AdapterDescription cloneAndEncrypt(AdapterDescription adapterDescription) {
AdapterDescription encryptedAdapterDescription = new Cloner().adapterDescription(adapterDescription);
SecretProvider.getEncryptionService().apply(encryptedAdapterDescription);
SecretProvider.getEncryptionService()
.apply(encryptedAdapterDescription);
return encryptedAdapterDescription;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,59 @@

package org.apache.streampipes.resource.management;

import org.apache.streampipes.commons.exceptions.connect.AdapterException;
import org.apache.streampipes.model.Tuple2;
import org.apache.streampipes.model.connect.adapter.AdapterDescription;
import org.apache.streampipes.storage.api.IAdapterStorage;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class AdapterResourceManagerTest {

private IAdapterStorage storage;
private AdapterResourceManager adapterResourceManager;

@BeforeEach
void setUp() {
storage = mock(IAdapterStorage.class);
adapterResourceManager = new AdapterResourceManager(storage);
}

@Test
public void encryptAndUpdateValidateDescriptionStored() {
public void encryptAndUpdate_ValidateDescriptionStored() throws AdapterException {

IAdapterStorage storage = mock(IAdapterStorage.class);
AdapterResourceManager adapterResourceManager = new AdapterResourceManager(storage);
adapterResourceManager.encryptAndUpdate(new AdapterDescription());

verify(storage, times(1)).updateElement(any());
}

@Test
void encryptAndCreate_ReturnsIdOnSuccess() throws AdapterException {
var id = "adapterId";

when(storage.persist(any())).thenReturn(new Tuple2<>(true, id));
var result = adapterResourceManager.encryptAndCreate(new AdapterDescription());

verify(storage, times(1)).persist(any());
assertEquals(id, result);
}

@Test
void encryptAndCreate_ThrowsAdapterExceptionOnConflict() {

doThrow(new org.lightcouch.DocumentConflictException("Conflict")).when(storage).persist(any());

assertThrows(AdapterException.class, () -> adapterResourceManager.encryptAndCreate(new AdapterDescription()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.apache.streampipes.storage.api.IPipelineStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -115,7 +116,7 @@ public ResponseEntity<? extends Message> updateAdapter(@RequestBody AdapterDescr
updateManager.updateAdapter(adapterDescription);
} catch (AdapterException e) {
LOG.error("Error while updating adapter with id {}", adapterDescription.getElementId(), e);
return ok(Notifications.error(e.getMessage()));
return ok(Notifications.error(e.getMessage(), ExceptionUtils.getStackTrace(e)));
}

return ok(Notifications.success(adapterDescription.getElementId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
Expand All @@ -58,7 +59,7 @@ public class CompactAdapterResource extends AbstractAdapterResource<AdapterMaste
public CompactAdapterResource() {
super(() -> new AdapterMasterManagement(
StorageDispatcher.INSTANCE.getNoSqlStore()
.getAdapterInstanceStorage(),
.getAdapterInstanceStorage(),
new SpResourceManager().manageAdapters(),
new SpResourceManager().manageDataStreams(),
AdapterMetricsManager.INSTANCE.getAdapterMetrics()
Expand All @@ -82,11 +83,23 @@ public ResponseEntity<?> addAdapterCompact(
var adapterDescription = getGeneratedAdapterDescription(compactAdapter);
var principalSid = getAuthenticatedUserSid();

var adapterId = adapterDescription.getElementId();

try {
var adapterId = adapterDescription.getElementId();
managementService.addAdapter(adapterDescription, adapterId, principalSid);
} catch (AdapterException e) {
LOG.error(
"Error while storing the adapterDescription with appId {}. An adapter with the given id already exists.",
adapterDescription.getAppId(), e
);
return ResponseEntity.status(HttpStatus.CONFLICT)
.body(Notifications.error(e.getMessage()));
}

try {
if (compactAdapter.createOptions() != null) {
if (compactAdapter.createOptions().persist()) {
if (compactAdapter.createOptions()
.persist()) {
var storedAdapter = managementService.getAdapter(adapterId);
var status = new PersistPipelineHandler(
getNoSqlStorage().getPipelineTemplateStorage(),
Expand All @@ -96,7 +109,8 @@ public ResponseEntity<?> addAdapterCompact(
getAuthenticatedUserSid()
).createAndStartPersistPipeline(storedAdapter);
}
if (compactAdapter.createOptions().start()) {
if (compactAdapter.createOptions()
.start()) {
managementService.startStreamAdapter(adapterId);
}
}
Expand Down Expand Up @@ -143,8 +157,10 @@ private AdapterDescription getGeneratedAdapterDescription(CompactAdapter compact
return new CompactAdapterManagement(generators).convertToAdapterDescription(compactAdapter);
}

private AdapterDescription getGeneratedAdapterDescription(CompactAdapter compactAdapter,
AdapterDescription existingAdapter) throws Exception {
private AdapterDescription getGeneratedAdapterDescription(
CompactAdapter compactAdapter,
AdapterDescription existingAdapter
) throws Exception {
var generators = adapterGenerationSteps.getGenerators();
return new CompactAdapterManagement(generators).convertToAdapterDescription(compactAdapter, existingAdapter);
}
Expand Down
Loading

0 comments on commit 370bc71

Please sign in to comment.