chore: consolidated API: add NewRelic OTLP trace (#30241)

This commit is contained in:
Sumit Kumar 2024-01-11 18:23:27 +05:30 committed by GitHub
parent 66c3a17c94
commit 2c00b1b104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 249 additions and 33 deletions

View File

@ -0,0 +1,28 @@
package com.appsmith.server.constants;
public class OtlpSpanNames {
public static final String CONSOLIDATED_API_PREFIX = "consolidated-api/";
public static final String VIEW = "view/";
public static final String EDIT = "edit/";
public static final String ROOT = "root";
public static final String CONSOLIDATED_API_ROOT_EDIT = CONSOLIDATED_API_PREFIX + EDIT + ROOT;
public static final String CONSOLIDATED_API_ROOT_VIEW = CONSOLIDATED_API_PREFIX + VIEW + ROOT;
public static final String USER_PROFILE_SPAN = "user_profile";
public static final String FEATURE_FLAG_SPAN = "feature_flag";
public static final String TENANT_SPAN = "tenant";
public static final String PRODUCT_ALERT_SPAN = "product_alert";
public static final String APPLICATION_ID_SPAN = "application_id";
public static final String PAGES_SPAN = "pages";
public static final String PAGES_DSL_SPAN = "pages_dsl_list";
public static final String CURRENT_THEME_SPAN = "current_theme";
public static final String THEMES_SPAN = "themes";
public static final String CUSTOM_JS_LIB_SPAN = "js_libs";
public static final String CURRENT_PAGE_SPAN = "current_page";
public static final String ACTIONS_SPAN = "actions";
public static final String ACTION_COLLECTIONS_SPAN = "action_collections";
public static final String PLUGINS_SPAN = "plugins";
public static final String WORKSPACE_SPAN = "workspace";
public static final String DATASOURCES_SPAN = "datasources";
public static final String FORM_CONFIG_SPAN = "form_config";
public static final String MOCK_DATASOURCES_SPAN = "mock_datasources";
}

View File

@ -6,8 +6,10 @@ import com.appsmith.server.constants.Url;
import com.appsmith.server.domains.ApplicationMode;
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.helpers.OtlpTelemetry;
import com.appsmith.server.services.ConsolidatedAPIService;
import com.fasterxml.jackson.annotation.JsonView;
import io.opentelemetry.api.trace.Span;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
@ -17,14 +19,19 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import static com.appsmith.server.constants.OtlpSpanNames.CONSOLIDATED_API_ROOT_EDIT;
import static com.appsmith.server.constants.OtlpSpanNames.CONSOLIDATED_API_ROOT_VIEW;
@Slf4j
@RestController
@RequestMapping(Url.CONSOLIDATED_API_URL)
public class ConsolidatedAPIController {
private final ConsolidatedAPIService consolidatedAPIService;
private final OtlpTelemetry otlpTelemetry;
public ConsolidatedAPIController(ConsolidatedAPIService consolidatedAPIService) {
public ConsolidatedAPIController(ConsolidatedAPIService consolidatedAPIService, OtlpTelemetry otlpTelemetry) {
this.consolidatedAPIService = consolidatedAPIService;
this.otlpTelemetry = otlpTelemetry;
}
/**
@ -45,10 +52,14 @@ public class ConsolidatedAPIController {
defaultPageId,
branchName,
ApplicationMode.EDIT);
Span consolidatedApiOtlpSpan = this.otlpTelemetry.startOTLPSpan(CONSOLIDATED_API_ROOT_EDIT, null, null);
return consolidatedAPIService
.getConsolidatedInfoForPageLoad(defaultPageId, applicationId, branchName, ApplicationMode.EDIT)
.getConsolidatedInfoForPageLoad(
defaultPageId, applicationId, branchName, ApplicationMode.EDIT, consolidatedApiOtlpSpan)
.map(consolidatedAPIResponseDTO ->
new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null));
new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null))
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(consolidatedApiOtlpSpan));
}
@JsonView(Views.Public.class)
@ -64,9 +75,13 @@ public class ConsolidatedAPIController {
defaultPageId,
branchName,
ApplicationMode.PUBLISHED);
Span consolidatedApiOtlpSpan = this.otlpTelemetry.startOTLPSpan(CONSOLIDATED_API_ROOT_VIEW, null, null);
return consolidatedAPIService
.getConsolidatedInfoForPageLoad(defaultPageId, applicationId, branchName, ApplicationMode.PUBLISHED)
.getConsolidatedInfoForPageLoad(
defaultPageId, applicationId, branchName, ApplicationMode.PUBLISHED, consolidatedApiOtlpSpan)
.map(consolidatedAPIResponseDTO ->
new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null));
new ResponseDTO<>(HttpStatus.OK.value(), consolidatedAPIResponseDTO, null))
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(consolidatedApiOtlpSpan));
}
}

View File

@ -1,7 +1,10 @@
package com.appsmith.server.helpers;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
@ -72,11 +75,26 @@ public class OtlpTelemetry {
return W3CTraceContextPropagator.getInstance().extract(Context.current(), model, getter);
}
private Span startOTLPSpan(String spanName, Context context) {
return tracer.spanBuilder(spanName)
.setSpanKind(SpanKind.SERVER)
.setParent(context)
.startSpan();
public Span startOTLPSpan(String spanName, Context context, Span parentSpan) {
if (tracer == null) {
return null;
}
if (isBlank(spanName)) {
throw new AppsmithException(AppsmithError.INVALID_PARAMETER, "spanName");
}
SpanBuilder spanBuilder = tracer.spanBuilder(spanName).setSpanKind(SpanKind.SERVER);
if (context != null) {
return spanBuilder.setParent(context).startSpan();
}
if (parentSpan != null) {
return spanBuilder.setParent(Context.current().with(parentSpan)).startSpan();
}
return spanBuilder.startSpan();
}
// we build traces using the client's trace context as the parent context, So that any other spans generated
// from the server appear as a subspan of the client
@ -88,7 +106,7 @@ public class OtlpTelemetry {
return null;
}
Context context = generateContextFromTraceHeader(traceparent);
return startOTLPSpan(spanName, context);
return startOTLPSpan(spanName, context, null);
}
public void endOtlpSpanSafely(Span span) {

View File

@ -2,9 +2,10 @@ package com.appsmith.server.services;
import com.appsmith.server.domains.ApplicationMode;
import com.appsmith.server.dtos.ConsolidatedAPIResponseDTO;
import io.opentelemetry.api.trace.Span;
import reactor.core.publisher.Mono;
public interface ConsolidatedAPIService {
Mono<ConsolidatedAPIResponseDTO> getConsolidatedInfoForPageLoad(
String defaultPageId, String applicationId, String branchName, ApplicationMode mode);
String defaultPageId, String applicationId, String branchName, ApplicationMode mode, Span parentSpan);
}

View File

@ -25,11 +25,13 @@ import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.dtos.UserProfileDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.helpers.OtlpTelemetry;
import com.appsmith.server.jslibs.base.CustomJSLibService;
import com.appsmith.server.newactions.base.NewActionService;
import com.appsmith.server.newpages.base.NewPageService;
import com.appsmith.server.plugins.base.PluginService;
import com.appsmith.server.themes.base.ThemeService;
import io.opentelemetry.api.trace.Span;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.util.Pair;
import org.springframework.http.HttpStatus;
@ -49,6 +51,27 @@ import java.util.stream.Collectors;
import static com.appsmith.external.constants.PluginConstants.PackageName.GRAPHQL_PLUGIN;
import static com.appsmith.external.constants.PluginConstants.PackageName.REST_API_PLUGIN;
import static com.appsmith.server.constants.OtlpSpanNames.ACTIONS_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.ACTION_COLLECTIONS_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.APPLICATION_ID_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.CONSOLIDATED_API_PREFIX;
import static com.appsmith.server.constants.OtlpSpanNames.CURRENT_PAGE_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.CURRENT_THEME_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.CUSTOM_JS_LIB_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.DATASOURCES_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.EDIT;
import static com.appsmith.server.constants.OtlpSpanNames.FEATURE_FLAG_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.FORM_CONFIG_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.MOCK_DATASOURCES_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.PAGES_DSL_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.PAGES_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.PLUGINS_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.PRODUCT_ALERT_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.TENANT_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.THEMES_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.USER_PROFILE_SPAN;
import static com.appsmith.server.constants.OtlpSpanNames.VIEW;
import static com.appsmith.server.constants.OtlpSpanNames.WORKSPACE_SPAN;
import static com.appsmith.server.constants.ce.FieldNameCE.APPLICATION_ID;
import static com.appsmith.server.constants.ce.FieldNameCE.APP_MODE;
import static com.appsmith.server.constants.ce.FieldNameCE.WORKSPACE_ID;
@ -78,6 +101,7 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
private final ApplicationService applicationService;
private final DatasourceService datasourceService;
private final MockDataService mockDataService;
private final OtlpTelemetry otlpTelemetry;
public ConsolidatedAPIServiceImpl(
SessionUserService sessionUserService,
@ -94,7 +118,8 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
PluginService pluginService,
ApplicationService applicationService,
DatasourceService datasourceService,
MockDataService mockDataService) {
MockDataService mockDataService,
OtlpTelemetry otlpTelemetry) {
this.sessionUserService = sessionUserService;
this.userService = userService;
this.userDataService = userDataService;
@ -110,6 +135,7 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
this.applicationService = applicationService;
this.datasourceService = datasourceService;
this.mockDataService = mockDataService;
this.otlpTelemetry = otlpTelemetry;
}
<T> ResponseDTO<T> getSuccessResponse(T data) {
@ -131,16 +157,24 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
INTERNAL_SERVER_ERROR_STATUS, new ErrorDTO(INTERNAL_SERVER_ERROR_CODE, error.getMessage())));
}
public static String getQualifiedSpanName(String spanName, ApplicationMode mode) {
return ApplicationMode.PUBLISHED.equals(mode)
? CONSOLIDATED_API_PREFIX + VIEW + spanName
: CONSOLIDATED_API_PREFIX + EDIT + spanName;
}
/**
* This method is meant to be used by the client application at the time of 1st page load. Client currently makes
* several API calls to fetch all the required data. This method consolidates all that data and returns them as
* response hence enabling the client to fetch the required data via a single API call only.
* Please check out this Slack conversation to understand why span objects need be put in a list:
* https://theappsmith.slack.com/archives/C024GUDM0LT/p1704891881312049
*
* PLEASE TAKE CARE TO USE .cache() FOR Mono THAT GETS REUSED SO THAT FIRST PAGE LOAD PERFORMANCE DOES NOT DEGRADE.
*/
@Override
public Mono<ConsolidatedAPIResponseDTO> getConsolidatedInfoForPageLoad(
String defaultPageId, String applicationId, String branchName, ApplicationMode mode) {
String defaultPageId, String applicationId, String branchName, ApplicationMode mode, Span parentSpan) {
/* if either of pageId or applicationId are provided then application mode must also be provided */
if (mode == null && (!isBlank(defaultPageId) || !isBlank(applicationId))) {
@ -151,27 +185,46 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
ConsolidatedAPIResponseDTO consolidatedAPIResponseDTO = new ConsolidatedAPIResponseDTO();
/* Get user profile data */
ArrayList<Span> userProfileSpanList = new ArrayList<>();
Mono<ResponseDTO<UserProfileDTO>> userProfileDTOResponseDTOMono = sessionUserService
.getCurrentUser()
.flatMap(userService::buildUserProfileDTO)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, UserProfileDTO.class));
.onErrorResume(error -> getErrorResponseMono(error, UserProfileDTO.class))
.doOnSubscribe(subscription -> {
userProfileSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(USER_PROFILE_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(userProfileSpanList.get(0)));
/* Get all feature flags data */
ArrayList<Span> featureFlagsSpanList = new ArrayList<>();
Mono<ResponseDTO<Map>> featureFlagsForCurrentUserResponseDTOMonoCache = userDataService
.getFeatureFlagsForCurrentUser()
.map(res -> (Map) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, Map.class))
.doOnSubscribe(subscription -> {
featureFlagsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(FEATURE_FLAG_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(featureFlagsSpanList.get(0)))
.cache();
/* Get tenant config data */
ArrayList<Span> tenantSpanList = new ArrayList<>();
Mono<ResponseDTO<Tenant>> tenantResponseDTOMono = tenantService
.getTenantConfiguration()
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, Tenant.class));
.onErrorResume(error -> getErrorResponseMono(error, Tenant.class))
.doOnSubscribe(subscription -> {
tenantSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(TENANT_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(tenantSpanList.get(0)));
/* Get any product alert info */
ArrayList<Span> productAlertSpanList = new ArrayList<>();
Mono<ResponseDTO<ProductAlertResponseDTO>> productAlertResponseDTOMono = productAlertService
.getSingleApplicableMessage()
.map(messages -> {
@ -182,7 +235,12 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
return new ProductAlertResponseDTO();
})
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, ProductAlertResponseDTO.class));
.onErrorResume(error -> getErrorResponseMono(error, ProductAlertResponseDTO.class))
.doOnSubscribe(subscription -> {
productAlertSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(PRODUCT_ALERT_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(productAlertSpanList.get(0)));
if (isBlank(defaultPageId) && isBlank(applicationId)) {
@ -208,41 +266,71 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
/* Fetch application id if not provided */
Mono<String> applicationIdMonoCache;
if (isBlank(applicationId)) {
ArrayList<Span> applicationIdSpanList = new ArrayList<>();
applicationIdMonoCache = newPageService
.findRootApplicationIdFromNewPage(branchName, defaultPageId)
.doOnSubscribe(subscription -> {
applicationIdSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(APPLICATION_ID_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(applicationIdSpanList.get(0)))
.cache();
} else {
applicationIdMonoCache = Mono.just(applicationId).cache();
}
/* Get all pages in application */
ArrayList<Span> pagesSpanList = new ArrayList<>();
Mono<ResponseDTO<ApplicationPagesDTO>> applicationPagesDTOResponseDTOMonoCache = applicationIdMonoCache
.flatMap(appId -> newPageService.findApplicationPages(appId, null, branchName, mode))
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, ApplicationPagesDTO.class))
.doOnSubscribe(subscription -> {
pagesSpanList.add(
this.otlpTelemetry.startOTLPSpan(getQualifiedSpanName(PAGES_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(pagesSpanList.get(0)))
.cache();
/* Get current theme */
ArrayList<Span> currentThemeSpanList = new ArrayList<>();
Mono<ResponseDTO<Theme>> applicationThemeResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> themeService.getApplicationTheme(appId, mode, branchName))
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, Theme.class));
.onErrorResume(error -> getErrorResponseMono(error, Theme.class))
.doOnSubscribe(subscription -> {
currentThemeSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(CURRENT_THEME_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(currentThemeSpanList.get(0)));
/* Get all themes */
ArrayList<Span> themesSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> ThemesListResponseDTOMono = applicationIdMonoCache
.flatMap(appId ->
themeService.getApplicationThemes(appId, branchName).collectList())
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
themesSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(THEMES_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(themesSpanList.get(0)));
/* Get all custom JS libraries installed in the application */
ArrayList<Span> customJSLibSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> allJSLibsInContextDTOResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> customJSLibService.getAllJSLibsInContext(
appId, CreatorContextType.APPLICATION, branchName, isViewMode))
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
customJSLibSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(CUSTOM_JS_LIB_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(customJSLibSpanList.get(0)));
/* Check if release_server_dsl_migrations_enabled flag is true for the user */
Mono<Boolean> migrateDslMonoCache = featureFlagsForCurrentUserResponseDTOMonoCache
@ -266,32 +354,50 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
Mono<ResponseDTO<PageDTO>> currentPageDTOResponseDTOMono = Mono.empty();
if (!isBlank(defaultPageId)) {
/* Get current page */
ArrayList<Span> currentPageSpanList = new ArrayList<>();
currentPageDTOResponseDTOMono = migrateDslMonoCache
.flatMap(migrateDsl -> applicationPageService.getPageAndMigrateDslByBranchAndDefaultPageId(
defaultPageId, branchName, isViewMode, migrateDsl))
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, PageDTO.class));
.onErrorResume(error -> getErrorResponseMono(error, PageDTO.class))
.doOnSubscribe(subscription -> {
currentPageSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(CURRENT_PAGE_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(currentPageSpanList.get(0)));
}
/* Fetch view specific data */
if (isViewMode) {
/* Get list of all actions in view mode */
ArrayList<Span> actionsSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfActionViewResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> newActionService
.getActionsForViewMode(appId, branchName)
.collectList())
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
actionsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(ACTIONS_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(actionsSpanList.get(0)));
/* Get list of all action collections in view mode */
ArrayList<Span> actionCollectionsSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfActionCollectionViewResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> actionCollectionService
.getActionCollectionsForViewMode(appId, branchName)
.collectList())
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
actionCollectionsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(ACTION_COLLECTIONS_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(actionCollectionsSpanList.get(0)));
/* This list contains the Mono objects corresponding to all the data points required for view mode. All
* the Mono objects in this list will be evaluated via Mono.zip operator.
@ -333,6 +439,7 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
});
} else {
/* Get all actions in edit mode */
ArrayList<Span> actionsSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfActionResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
@ -343,9 +450,15 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
})
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
actionsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(ACTIONS_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(actionsSpanList.get(0)));
/* Get all action collections in edit mode */
ArrayList<Span> actionCollectionsSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfActionCollectionResponseDTOMono = applicationIdMonoCache
.flatMap(appId -> {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
@ -356,9 +469,15 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
.map(res -> (List) res)
.map(this::getSuccessResponse);
})
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
actionCollectionsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(ACTION_COLLECTIONS_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(actionCollectionsSpanList.get(0)));
/* Get all pages in edit mode post apply migrate DSL changes */
ArrayList<Span> pagesPostMigrateDslSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfAllPageResponseDTOMono = migrateDslMonoCache
.flatMap(migrateDsl -> applicationPagesDTOResponseDTOMonoCache
.map(ResponseDTO::getData)
@ -369,9 +488,15 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
.collect(Collectors.toList()))
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
pagesPostMigrateDslSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(PAGES_DSL_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(pagesPostMigrateDslSpanList.get(0)));
/* Get all workspace id */
ArrayList<Span> workspaceIdSpanList = new ArrayList<>();
Mono<String> workspaceIdMonoCache = applicationPagesDTOResponseDTOMonoCache
.map(responseDTO -> {
if (INTERNAL_SERVER_ERROR_STATUS
@ -382,9 +507,15 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
return responseDTO.getData().getWorkspaceId();
})
.onErrorResume(error -> Mono.just(EMPTY_WORKSPACE_ID_ON_ERROR))
.doOnSubscribe(subscription -> {
workspaceIdSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(WORKSPACE_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(workspaceIdSpanList.get(0)))
.cache();
/* Get all plugins in workspace */
ArrayList<Span> pluginsSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfPluginsResponseDTOMonoCache = workspaceIdMonoCache
.flatMap(workspaceId -> {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
@ -396,9 +527,15 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
pluginsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(PLUGINS_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(pluginsSpanList.get(0)))
.cache();
/* Get all datasources in workspace */
ArrayList<Span> datasourcesSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> listOfDatasourcesResponseDTOMonoCache = workspaceIdMonoCache
.flatMap(workspaceId -> {
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
@ -410,6 +547,11 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
datasourcesSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(DATASOURCES_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(datasourcesSpanList.get(0)))
.cache();
/* Get form config for all relevant plugins by following this rule:
@ -417,6 +559,7 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
* (b) include REST API and GraphQL API plugin always
* (c) ignore any other plugin
* */
ArrayList<Span> formConfigsSpanList = new ArrayList<>();
Mono<ResponseDTO<Map>> listOfFormConfigsResponseDTOMono = Mono.zip(
listOfPluginsResponseDTOMonoCache, listOfDatasourcesResponseDTOMonoCache)
.map(tuple2 -> {
@ -451,15 +594,26 @@ public class ConsolidatedAPIServiceImpl implements ConsolidatedAPIService {
})
.map(res -> (Map) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, Map.class));
.onErrorResume(error -> getErrorResponseMono(error, Map.class))
.doOnSubscribe(subscription -> {
formConfigsSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(FORM_CONFIG_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(formConfigsSpanList.get(0)));
/* List of mock datasources available to the user */
ArrayList<Span> mockDatasourcesSpanList = new ArrayList<>();
Mono<ResponseDTO<List>> mockDataListResponseDTOMono = mockDataService
.getMockDataSet()
.map(MockDataDTO::getMockdbs)
.map(res -> (List) res)
.map(this::getSuccessResponse)
.onErrorResume(error -> getErrorResponseMono(error, List.class));
.onErrorResume(error -> getErrorResponseMono(error, List.class))
.doOnSubscribe(subscription -> {
mockDatasourcesSpanList.add(this.otlpTelemetry.startOTLPSpan(
getQualifiedSpanName(MOCK_DATASOURCES_SPAN, mode), null, parentSpan));
})
.doFinally(signalType -> this.otlpTelemetry.endOtlpSpanSafely(mockDatasourcesSpanList.get(0)));
/* This list contains the Mono objects corresponding to all the data points required for edit mode. All
* the Mono objects in this list will be evaluated via Mono.zip operator

View File

@ -118,7 +118,7 @@ public class ConsolidatedAPIServiceImplTest {
@Test
public void testErrorWhenModeIsNullAndPageIdAvailable() {
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
consolidatedAPIService.getConsolidatedInfoForPageLoad("pageId", null, null, null);
consolidatedAPIService.getConsolidatedInfoForPageLoad("pageId", null, null, null, null);
StepVerifier.create(consolidatedInfoForPageLoad).verifyErrorSatisfies(error -> {
assertTrue(error instanceof AppsmithException);
assertEquals("Please enter a valid parameter appMode.", error.getMessage());
@ -149,7 +149,7 @@ public class ConsolidatedAPIServiceImplTest {
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
consolidatedAPIService.getConsolidatedInfoForPageLoad(
"pageId", "appId", "branch", ApplicationMode.PUBLISHED);
"pageId", "appId", "branch", ApplicationMode.PUBLISHED, null);
StepVerifier.create(consolidatedInfoForPageLoad)
.assertNext(consolidatedAPIResponseDTO -> {
assertNotNull(consolidatedAPIResponseDTO.getUserProfile());
@ -243,7 +243,7 @@ public class ConsolidatedAPIServiceImplTest {
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
consolidatedAPIService.getConsolidatedInfoForPageLoad(
"pageId", "appId", "branch", ApplicationMode.PUBLISHED);
"pageId", "appId", "branch", ApplicationMode.PUBLISHED, null);
StepVerifier.create(consolidatedInfoForPageLoad)
.assertNext(consolidatedAPIResponseDTO -> {
assertNotNull(consolidatedAPIResponseDTO.getPublishedActions());
@ -439,7 +439,7 @@ public class ConsolidatedAPIServiceImplTest {
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
consolidatedAPIService.getConsolidatedInfoForPageLoad(
"pageId", "appId", "branch", ApplicationMode.EDIT);
"pageId", "appId", "branch", ApplicationMode.EDIT, null);
StepVerifier.create(consolidatedInfoForPageLoad)
.assertNext(consolidatedAPIResponseDTO -> {
assertNotNull(consolidatedAPIResponseDTO.getUserProfile());
@ -637,7 +637,7 @@ public class ConsolidatedAPIServiceImplTest {
Mono<ConsolidatedAPIResponseDTO> consolidatedInfoForPageLoad =
consolidatedAPIService.getConsolidatedInfoForPageLoad(
"pageId", "appId", "branch", ApplicationMode.PUBLISHED);
"pageId", "appId", "branch", ApplicationMode.PUBLISHED, null);
StepVerifier.create(consolidatedInfoForPageLoad)
.assertNext(consolidatedAPIResponseDTO -> {
assertNotNull(consolidatedAPIResponseDTO.getUserProfile());