chore: Add metrics to newRelic for update JSobject Collection (#35947)
## Description - Add newRelic spans to track performance of process involved in update JSObject collection Fixes #36049 ## Automation /test js ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10704346206> > Commit: 5bf63bb0c04957493d40373b40f6ab46ed447103 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10704346206&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.JS` > Spec: > <hr>Wed, 04 Sep 2024 15:29:57 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Introduced enhanced observability for action collections and layout updates, allowing better tracking and monitoring of actions within the application. - Added new constants related to action collections and layout updates for improved functionality and clarity. - **Bug Fixes** - Improved the reliability of action collection retrieval and layout updates through enhanced observability features. - **Tests** - Updated tests to incorporate observability metrics, ensuring better monitoring of actions during testing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
440ff139e9
commit
b447b0f29e
|
|
@ -0,0 +1,5 @@
|
|||
package com.appsmith.external.constants.spans;
|
||||
|
||||
import com.appsmith.external.constants.spans.ce.ActionCollectionSpanCE;
|
||||
|
||||
public class ActionCollectionSpan extends ActionCollectionSpanCE {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.appsmith.external.constants.spans;
|
||||
|
||||
import com.appsmith.external.constants.spans.ce.LayoutSpanCE;
|
||||
|
||||
public class LayoutSpan extends LayoutSpanCE {}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.appsmith.external.constants.spans.ce;
|
||||
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX;
|
||||
|
||||
/**
|
||||
* Please make sure that all span names start with `appsmith.` because span with any other naming format would get
|
||||
* dropped / ignored as defined in TracingConfig.java
|
||||
*/
|
||||
public class ActionCollectionSpanCE {
|
||||
// Action Collection spans
|
||||
public static final String ACTION_COLLECTION_UPDATE = APPSMITH_SPAN_PREFIX + "update.actionCollection";
|
||||
public static final String GENERATE_ACTION_COLLECTION_BY_VIEW_MODE =
|
||||
APPSMITH_SPAN_PREFIX + "generate.actionCollectionByViewMode";
|
||||
public static final String POPULATE_ACTION_COLLECTION_BY_VIEW_MODE =
|
||||
APPSMITH_SPAN_PREFIX + "populate.actionCollectionByViewMode";
|
||||
public static final String SAVE_ACTION_COLLECTION_LAST_EDIT_INFO =
|
||||
APPSMITH_SPAN_PREFIX + "save.actionCollectionLastEditInfo";
|
||||
|
||||
// Getter spans
|
||||
public static final String GET_ACTION_COLLECTION_BY_ID = APPSMITH_SPAN_PREFIX + "get.actionCollectionById";
|
||||
}
|
||||
|
|
@ -29,4 +29,12 @@ public class ActionSpanCE {
|
|||
public static final String VIEW_MODE_SET_PLUGIN_ID_AND_TYPE_ACTION = ACTIONS_VIEW_MODE_PREFIX + "set_action";
|
||||
public static final String VIEW_MODE_FETCH_PLUGIN_FROM_DB = ACTIONS_VIEW_MODE_PREFIX + "plugindb";
|
||||
public static final String VIEW_MODE_FETCH_ACTIONS_FROM_DB = ACTIONS_VIEW_MODE_PREFIX + "fetchactions";
|
||||
public static final String GET_ACTION_BY_ID = APPSMITH_SPAN_PREFIX + "get.actionById";
|
||||
|
||||
// Action creation, update and delete spans
|
||||
public static final String UPDATE_SINGLE_ACTION = APPSMITH_SPAN_PREFIX + "update.single.action";
|
||||
public static final String UPDATE_ACTION_BASED_ON_CONTEXT = APPSMITH_SPAN_PREFIX + "update.action.context";
|
||||
public static final String CREATE_ACTION = APPSMITH_SPAN_PREFIX + "create.action";
|
||||
public static final String UPDATE_ACTION = APPSMITH_SPAN_PREFIX + "update.action";
|
||||
public static final String DELETE_ACTION = APPSMITH_SPAN_PREFIX + "delete.action";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package com.appsmith.external.constants.spans.ce;
|
||||
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX;
|
||||
|
||||
public class LayoutSpanCE {
|
||||
public static final String UPDATE_LAYOUT = "updateLayout.";
|
||||
public static final String UPDATE_PAGE_LAYOUT_BY_PAGE_ID = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "pageId";
|
||||
public static final String UPDATE_LAYOUT_METHOD = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "method";
|
||||
public static final String UPDATE_LAYOUT_DSL_METHOD = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "dsl.method";
|
||||
public static final String UPDATE_LAYOUT_BASED_ON_CONTEXT = APPSMITH_SPAN_PREFIX + UPDATE_LAYOUT + "context";
|
||||
|
||||
public static final String FIND_ALL_ON_LOAD_EXECUTABLES =
|
||||
APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.findAllOnLoadExecutables";
|
||||
public static final String UPDATE_EXECUTABLES_EXECUTE_ONLOAD =
|
||||
APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.updateExecutablesExecuteOnLoad";
|
||||
public static final String FIND_AND_UPDATE_LAYOUT =
|
||||
APPSMITH_SPAN_PREFIX + "onLoadExecutablesUtil.findAndUpdateLayout";
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package com.appsmith.external.constants.spans.ce;
|
||||
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX;
|
||||
|
||||
public class PageSpanCE {
|
||||
public static final String PAGES = "pages.";
|
||||
public static final String GET_PAGE = PAGES + "getpage";
|
||||
|
|
@ -11,4 +13,6 @@ public class PageSpanCE {
|
|||
public static final String MARK_RECENTLY_ACCESSED_RESOURCES_PAGES = PAGES + "update_recently_accessed_pages";
|
||||
public static final String PREPARE_APPLICATION_PAGES_DTO_FROM_PAGES = PAGES + "generate_app_pages_dto";
|
||||
public static final String MIGRATE_DSL = PAGES + "migrate_dsl";
|
||||
|
||||
public static final String GET_PAGE_BY_ID = APPSMITH_SPAN_PREFIX + "get.page.unpublished";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.appsmith.server.services.AnalyticsService;
|
|||
import com.appsmith.server.services.BaseService;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.ApplicationPermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import jakarta.validation.Validator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
|
@ -28,6 +29,7 @@ import org.springframework.data.domain.Sort;
|
|||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.appsmith.external.constants.spans.ActionCollectionSpan.GET_ACTION_COLLECTION_BY_ID;
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
|
|
@ -53,6 +56,7 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
private final ApplicationService applicationService;
|
||||
private final ApplicationPermission applicationPermission;
|
||||
private final ActionPermission actionPermission;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
@Autowired
|
||||
public ActionCollectionServiceCEImpl(
|
||||
|
|
@ -63,7 +67,8 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
PolicyGenerator policyGenerator,
|
||||
ApplicationService applicationService,
|
||||
ApplicationPermission applicationPermission,
|
||||
ActionPermission actionPermission) {
|
||||
ActionPermission actionPermission,
|
||||
ObservationRegistry observationRegistry) {
|
||||
|
||||
super(validator, repository, analyticsService);
|
||||
this.newActionService = newActionService;
|
||||
|
|
@ -71,6 +76,7 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
this.applicationService = applicationService;
|
||||
this.applicationPermission = applicationPermission;
|
||||
this.actionPermission = actionPermission;
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -372,7 +378,10 @@ public class ActionCollectionServiceCEImpl extends BaseService<ActionCollectionR
|
|||
|
||||
@Override
|
||||
public Mono<ActionCollection> findById(String id, AclPermission aclPermission) {
|
||||
return repository.findById(id, aclPermission);
|
||||
return repository
|
||||
.findById(id, aclPermission)
|
||||
.name(GET_ACTION_COLLECTION_BY_ID)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.appsmith.server.repositories.ActionCollectionRepository;
|
|||
import com.appsmith.server.services.AnalyticsService;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.ApplicationPermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import jakarta.validation.Validator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -22,7 +23,8 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i
|
|||
PolicyGenerator policyGenerator,
|
||||
ApplicationService applicationService,
|
||||
ApplicationPermission applicationPermission,
|
||||
ActionPermission actionPermission) {
|
||||
ActionPermission actionPermission,
|
||||
ObservationRegistry observationRegistry) {
|
||||
super(
|
||||
validator,
|
||||
repository,
|
||||
|
|
@ -31,6 +33,7 @@ public class ActionCollectionServiceImpl extends ActionCollectionServiceCEImpl i
|
|||
policyGenerator,
|
||||
applicationService,
|
||||
applicationPermission,
|
||||
actionPermission);
|
||||
actionPermission,
|
||||
observationRegistry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
68
app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java
Normal file → Executable file
68
app/server/appsmith-server/src/main/java/com/appsmith/server/layouts/UpdateLayoutServiceCEImpl.java
Normal file → Executable file
|
|
@ -25,12 +25,14 @@ import com.appsmith.server.services.SessionUserService;
|
|||
import com.appsmith.server.solutions.PagePermission;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -46,6 +48,12 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.FIND_ALL_ON_LOAD_EXECUTABLES;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.FIND_AND_UPDATE_LAYOUT;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_EXECUTABLES_EXECUTE_ONLOAD;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_DSL_METHOD;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_METHOD;
|
||||
import static com.appsmith.external.constants.spans.PageSpan.GET_PAGE_BY_ID;
|
||||
import static com.appsmith.server.constants.CommonConstants.EVALUATION_VERSION;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
|
||||
|
|
@ -60,8 +68,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
private final AnalyticsService analyticsService;
|
||||
private final PagePermission pagePermission;
|
||||
private final ApplicationService applicationService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
private final String layoutOnLoadActionErrorToastMessage =
|
||||
"A cyclic dependency error has been encountered on current page, \nqueries on page load will not run. \n Please check debugger and Appsmith documentation for more information";
|
||||
|
|
@ -122,6 +130,7 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
try {
|
||||
dsl = extractAllWidgetNamesAndDynamicBindingsFromDSL(
|
||||
dsl, widgetNames, widgetDynamicBindingsMap, creatorId, layoutId, escapedWidgetNames, creatorType);
|
||||
|
||||
} catch (Throwable t) {
|
||||
return sendUpdateLayoutAnalyticsEvent(creatorId, layoutId, dsl, false, t, creatorType)
|
||||
.then(Mono.error(t));
|
||||
|
|
@ -155,6 +164,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
flatmapOnLoadExecutables,
|
||||
executablesUsedInDSL,
|
||||
creatorType)
|
||||
.name(FIND_ALL_ON_LOAD_EXECUTABLES)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.onErrorResume(AppsmithException.class, error -> {
|
||||
log.info(error.getMessage());
|
||||
validOnLoadExecutables.set(FALSE);
|
||||
|
|
@ -181,6 +192,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
return onLoadExecutablesUtil
|
||||
.updateExecutablesExecuteOnLoad(
|
||||
flatmapOnLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType)
|
||||
.name(UPDATE_EXECUTABLES_EXECUTE_ONLOAD)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.thenReturn(allOnLoadExecutables);
|
||||
})
|
||||
// Now update the page layout with the page load executables and the graph.
|
||||
|
|
@ -192,7 +205,10 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
// valid when last stored in the database.
|
||||
layout.setValidOnPageLoadActions(validOnLoadExecutables.get());
|
||||
|
||||
return onLoadExecutablesUtil.findAndUpdateLayout(creatorId, creatorType, layoutId, layout);
|
||||
return onLoadExecutablesUtil
|
||||
.findAndUpdateLayout(creatorId, creatorType, layoutId, layout)
|
||||
.name(FIND_AND_UPDATE_LAYOUT)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
})
|
||||
.map(savedLayout -> {
|
||||
savedLayout.setDsl(this.unescapeMongoSpecialCharacters(savedLayout));
|
||||
|
|
@ -219,7 +235,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
if (evaluationVersion == null) {
|
||||
evaluationVersion = EVALUATION_VERSION;
|
||||
}
|
||||
return updateLayoutDsl(pageId, layoutId, layout, evaluationVersion, CreatorContextType.PAGE);
|
||||
return updateLayoutDsl(pageId, layoutId, layout, evaluationVersion, CreatorContextType.PAGE)
|
||||
.name(UPDATE_LAYOUT_DSL_METHOD);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -276,13 +293,17 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
return Mono.justOrEmpty(pageId)
|
||||
// fetch the unpublished page
|
||||
.flatMap(id -> newPageService.findPageById(id, pagePermission.getEditPermission(), false))
|
||||
.name(GET_PAGE_BY_ID)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMapMany(page -> {
|
||||
if (page.getLayouts() == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return Flux.fromIterable(page.getLayouts()).flatMap(layout -> {
|
||||
layout.setDsl(this.unescapeMongoSpecialCharacters(layout));
|
||||
return this.updateLayout(page.getId(), page.getApplicationId(), layout.getId(), layout);
|
||||
return this.updateLayout(page.getId(), page.getApplicationId(), layout.getId(), layout)
|
||||
.name(UPDATE_LAYOUT_METHOD)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
});
|
||||
})
|
||||
.collectList()
|
||||
|
|
@ -324,7 +345,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
|
||||
AtomicReference<Boolean> validOnLoadExecutables = new AtomicReference<>(Boolean.TRUE);
|
||||
|
||||
// setting the layoutOnLoadActionActionErrors to empty to remove the existing errors before new DAG calculation.
|
||||
// setting the layoutOnLoadActionActionErrors to empty to remove the existing
|
||||
// errors before new DAG calculation.
|
||||
layout.setLayoutOnLoadActionErrors(new ArrayList<>());
|
||||
|
||||
return onLoadExecutablesUtil
|
||||
|
|
@ -364,13 +386,15 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
String widgetType = dsl.getAsString(FieldName.WIDGET_TYPE);
|
||||
if (widgetType.equals(FieldName.TABLE_WIDGET)) {
|
||||
// UnEscape Table widget keys
|
||||
// Since this is a table widget, it wouldnt have children. We can safely return from here with updated
|
||||
// Since this is a table widget, it wouldnt have children. We can safely return
|
||||
// from here with updated
|
||||
// dsl
|
||||
return WidgetSpecificUtils.unEscapeTableWidgetPrimaryColumns(dsl);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the children of the current node in the DSL and recursively iterate over them to extract bindings
|
||||
// Fetch the children of the current node in the DSL and recursively iterate
|
||||
// over them to extract bindings
|
||||
ArrayList<Object> children = (ArrayList<Object>) dsl.get(FieldName.CHILDREN);
|
||||
ArrayList<Object> newChildren = new ArrayList<>();
|
||||
if (children != null) {
|
||||
|
|
@ -392,9 +416,11 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
|
||||
/**
|
||||
* Walks the DSL and extracts all the widget names from it.
|
||||
* A widget is expected to have a few properties defining its own behaviour, with any mustache bindings present
|
||||
* A widget is expected to have a few properties defining its own behaviour,
|
||||
* with any mustache bindings present
|
||||
* in them aggregated in the field dynamicBindingsPathList.
|
||||
* A widget may also have other widgets as children, each of which will follow the same structure
|
||||
* A widget may also have other widgets as children, each of which will follow
|
||||
* the same structure
|
||||
* Refer to FieldName.DEFAULT_PAGE_LAYOUT for a template
|
||||
*
|
||||
* @param dsl
|
||||
|
|
@ -423,27 +449,33 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
String widgetId = dsl.getAsString(FieldName.WIDGET_ID);
|
||||
String widgetType = dsl.getAsString(FieldName.WIDGET_TYPE);
|
||||
|
||||
// Since we are parsing this widget in this, add it to the global set of widgets found so far in the DSL.
|
||||
// Since we are parsing this widget in this, add it to the global set of widgets
|
||||
// found so far in the DSL.
|
||||
widgetNames.add(widgetName);
|
||||
|
||||
// Start by picking all fields where we expect to find dynamic bindings for this particular widget
|
||||
// Start by picking all fields where we expect to find dynamic bindings for this
|
||||
// particular widget
|
||||
ArrayList<Object> dynamicallyBoundedPathList = (ArrayList<Object>) dsl.get(FieldName.DYNAMIC_BINDING_PATH_LIST);
|
||||
|
||||
// Widgets will not have FieldName.DYNAMIC_BINDING_PATH_LIST if there are no bindings in that widget.
|
||||
// Widgets will not have FieldName.DYNAMIC_BINDING_PATH_LIST if there are no
|
||||
// bindings in that widget.
|
||||
// Hence we skip over the extraction of the bindings from that widget.
|
||||
if (dynamicallyBoundedPathList != null) {
|
||||
// Each of these might have nested structures, so we iterate through them to find the leaf node for each
|
||||
// Each of these might have nested structures, so we iterate through them to
|
||||
// find the leaf node for each
|
||||
for (Object x : dynamicallyBoundedPathList) {
|
||||
final String fieldPath = String.valueOf(((Map) x).get(FieldName.KEY));
|
||||
String[] fields = fieldPath.split("[].\\[]");
|
||||
// For nested fields, the parent dsl to search in would shift by one level every iteration
|
||||
// For nested fields, the parent dsl to search in would shift by one level every
|
||||
// iteration
|
||||
Object parent = dsl;
|
||||
Iterator<String> fieldsIterator = Arrays.stream(fields)
|
||||
.filter(fieldToken -> !fieldToken.isBlank())
|
||||
.iterator();
|
||||
boolean isLeafNode = false;
|
||||
Object oldParent;
|
||||
// This loop will end at either a leaf node, or the last identified JSON field (by throwing an
|
||||
// This loop will end at either a leaf node, or the last identified JSON field
|
||||
// (by throwing an
|
||||
// exception)
|
||||
// Valid forms of the fieldPath for this search could be:
|
||||
// root.field.list[index].childField.anotherList.indexWithDotOperator.multidimensionalList[index1][index2]
|
||||
|
|
@ -510,7 +542,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
// Only extract mustache keys from leaf nodes
|
||||
if (isLeafNode) {
|
||||
|
||||
// We found the path. But if the path does not have any mustache bindings, throw the error
|
||||
// We found the path. But if the path does not have any mustache bindings, throw
|
||||
// the error
|
||||
if (!MustacheHelper.laxIsBindingPresentInString((String) parent)) {
|
||||
try {
|
||||
String bindingAsString = objectMapper.writeValueAsString(parent);
|
||||
|
|
@ -551,7 +584,8 @@ public class UpdateLayoutServiceCEImpl implements UpdateLayoutServiceCE {
|
|||
// Escape the widget keys if required and update dsl and escapedWidgetNames
|
||||
removeSpecialCharactersFromKeys(dsl, escapedWidgetNames);
|
||||
|
||||
// Fetch the children of the current node in the DSL and recursively iterate over them to extract bindings
|
||||
// Fetch the children of the current node in the DSL and recursively iterate
|
||||
// over them to extract bindings
|
||||
ArrayList<Object> children = (ArrayList<Object>) dsl.get(FieldName.CHILDREN);
|
||||
ArrayList<Object> newChildren = new ArrayList<>();
|
||||
if (children != null) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.appsmith.server.services.AnalyticsService;
|
|||
import com.appsmith.server.services.SessionUserService;
|
||||
import com.appsmith.server.solutions.PagePermission;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
|
|
@ -19,7 +20,8 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement
|
|||
AnalyticsService analyticsService,
|
||||
PagePermission pagePermission,
|
||||
ApplicationService applicationService,
|
||||
ObjectMapper objectMapper) {
|
||||
ObjectMapper objectMapper,
|
||||
ObservationRegistry observationRegistry) {
|
||||
super(
|
||||
onLoadExecutablesUtil,
|
||||
sessionUserService,
|
||||
|
|
@ -27,6 +29,7 @@ public class UpdateLayoutServiceImpl extends UpdateLayoutServiceCEImpl implement
|
|||
analyticsService,
|
||||
pagePermission,
|
||||
applicationService,
|
||||
objectMapper);
|
||||
objectMapper,
|
||||
observationRegistry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.appsmith.server.refactors.applications.RefactoringService;
|
|||
import com.appsmith.server.services.ce.LayoutActionServiceCEImpl;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.PagePermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
|
@ -24,7 +25,9 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement
|
|||
UpdateLayoutService updateLayoutService,
|
||||
DatasourceService datasourceService,
|
||||
PagePermission pagePermission,
|
||||
ActionPermission actionPermission) {
|
||||
ActionPermission actionPermission,
|
||||
ObservationRegistry observationRegistry) {
|
||||
|
||||
super(
|
||||
analyticsService,
|
||||
newPageService,
|
||||
|
|
@ -34,6 +37,7 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement
|
|||
updateLayoutService,
|
||||
datasourceService,
|
||||
pagePermission,
|
||||
actionPermission);
|
||||
actionPermission,
|
||||
observationRegistry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.appsmith.server.repositories.ActionCollectionRepository;
|
|||
import com.appsmith.server.services.ce.LayoutCollectionServiceCEImpl;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.PagePermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
|
@ -26,7 +27,8 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i
|
|||
AnalyticsService analyticsService,
|
||||
ActionCollectionRepository actionCollectionRepository,
|
||||
PagePermission pagePermission,
|
||||
ActionPermission actionPermission) {
|
||||
ActionPermission actionPermission,
|
||||
ObservationRegistry observationRegistry) {
|
||||
super(
|
||||
newPageService,
|
||||
layoutActionService,
|
||||
|
|
@ -37,6 +39,7 @@ public class LayoutCollectionServiceImpl extends LayoutCollectionServiceCEImpl i
|
|||
analyticsService,
|
||||
actionCollectionRepository,
|
||||
pagePermission,
|
||||
actionPermission);
|
||||
actionPermission,
|
||||
observationRegistry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java
Normal file → Executable file
22
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java
Normal file → Executable file
|
|
@ -23,14 +23,20 @@ import com.appsmith.server.services.AnalyticsService;
|
|||
import com.appsmith.server.services.CollectionService;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.PagePermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.GET_ACTION_BY_ID;
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_ACTION_BASED_ON_CONTEXT;
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_SINGLE_ACTION;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_PAGE_LAYOUT_BY_PAGE_ID;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
@Slf4j
|
||||
|
|
@ -47,6 +53,7 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
|||
private final DatasourceService datasourceService;
|
||||
private final PagePermission pagePermission;
|
||||
private final ActionPermission actionPermission;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
/**
|
||||
* Called by Action controller to create Action
|
||||
|
|
@ -214,7 +221,11 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
|||
public Mono<ActionDTO> updateNewActionByBranchedId(String branchedId, ActionDTO actionDTO) {
|
||||
return newActionService
|
||||
.findById(branchedId, actionPermission.getEditPermission())
|
||||
.flatMap(newAction -> updateActionBasedOnContextType(newAction, actionDTO));
|
||||
.name(GET_ACTION_BY_ID)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMap(newAction -> updateActionBasedOnContextType(newAction, actionDTO)
|
||||
.name(UPDATE_ACTION_BASED_ON_CONTEXT)
|
||||
.tap(Micrometer.observation(observationRegistry)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -227,8 +238,13 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
|||
action.setApplicationId(null);
|
||||
action.setPageId(null);
|
||||
return updateSingleAction(newAction.getId(), action)
|
||||
.flatMap(updatedAction ->
|
||||
updateLayoutService.updatePageLayoutsByPageId(pageId).thenReturn(updatedAction))
|
||||
.name(UPDATE_SINGLE_ACTION)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMap(updatedAction -> updateLayoutService
|
||||
.updatePageLayoutsByPageId(pageId)
|
||||
.name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.thenReturn(updatedAction))
|
||||
.zipWhen(actionDTO -> newPageService.findPageById(pageId, pagePermission.getEditPermission(), false))
|
||||
.map(tuple2 -> {
|
||||
ActionDTO actionDTO = tuple2.getT1();
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@ import com.appsmith.server.services.AnalyticsService;
|
|||
import com.appsmith.server.services.LayoutActionService;
|
||||
import com.appsmith.server.solutions.ActionPermission;
|
||||
import com.appsmith.server.solutions.PagePermission;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -36,6 +38,14 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.external.constants.spans.ActionCollectionSpan.ACTION_COLLECTION_UPDATE;
|
||||
import static com.appsmith.external.constants.spans.ActionCollectionSpan.GENERATE_ACTION_COLLECTION_BY_VIEW_MODE;
|
||||
import static com.appsmith.external.constants.spans.ActionCollectionSpan.POPULATE_ACTION_COLLECTION_BY_VIEW_MODE;
|
||||
import static com.appsmith.external.constants.spans.ActionCollectionSpan.SAVE_ACTION_COLLECTION_LAST_EDIT_INFO;
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.CREATE_ACTION;
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.DELETE_ACTION;
|
||||
import static com.appsmith.external.constants.spans.ActionSpan.UPDATE_ACTION;
|
||||
import static com.appsmith.external.constants.spans.LayoutSpan.UPDATE_LAYOUT_BASED_ON_CONTEXT;
|
||||
import static com.appsmith.external.helpers.AppsmithBeanUtils.copyNewFieldValuesIntoOldObject;
|
||||
import static com.appsmith.server.helpers.ContextTypeUtils.isPageContext;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
|
@ -55,6 +65,7 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
private final ActionCollectionRepository actionCollectionRepository;
|
||||
private final PagePermission pagePermission;
|
||||
private final ActionPermission actionPermission;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
@Override
|
||||
public Mono<ActionCollectionDTO> createCollection(ActionCollection actionCollection) {
|
||||
|
|
@ -325,7 +336,10 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
actionDTO.setPluginId(actionCollectionDTO.getPluginId());
|
||||
actionDTO.setBranchName(branchedActionCollection.getBranchName());
|
||||
// actionCollectionService is a new action, we need to create one
|
||||
return layoutActionService.createSingleAction(actionDTO, Boolean.TRUE);
|
||||
return layoutActionService
|
||||
.createSingleAction(actionDTO, Boolean.TRUE)
|
||||
.name(CREATE_ACTION)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
} else {
|
||||
actionDTO.setCollectionId(null);
|
||||
// Client only knows about the default action ID, fetch branched action id to update the
|
||||
|
|
@ -333,7 +347,10 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
String branchedActionId = actionDTO.getId();
|
||||
actionDTO.setId(null);
|
||||
actionDTO.setBaseId(null);
|
||||
return layoutActionService.updateNewActionByBranchedId(branchedActionId, actionDTO);
|
||||
return layoutActionService
|
||||
.updateNewActionByBranchedId(branchedActionId, actionDTO)
|
||||
.name(UPDATE_ACTION)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
}
|
||||
})
|
||||
.collect(toMap(actionDTO -> actionDTO.getBaseId(), ActionDTO::getId)));
|
||||
|
|
@ -354,7 +371,9 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
log.error(throwable.getMessage());
|
||||
return Mono.empty();
|
||||
}))
|
||||
.collectList();
|
||||
.collectList()
|
||||
.name(DELETE_ACTION)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
|
||||
return deleteNonExistingActionMono
|
||||
.then(newValidActionIdsMono)
|
||||
|
|
@ -373,17 +392,27 @@ public class LayoutCollectionServiceCEImpl implements LayoutCollectionServiceCE
|
|||
});
|
||||
})
|
||||
.flatMap(actionCollection -> actionCollectionService.update(actionCollection.getId(), actionCollection))
|
||||
.name(ACTION_COLLECTION_UPDATE)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMap(actionCollectionRepository::setUserPermissionsInObject)
|
||||
.flatMap(savedActionCollection ->
|
||||
updateLayoutBasedOnContext(savedActionCollection).thenReturn(savedActionCollection))
|
||||
.flatMap(savedActionCollection -> updateLayoutBasedOnContext(savedActionCollection)
|
||||
.name(UPDATE_LAYOUT_BASED_ON_CONTEXT)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.thenReturn(savedActionCollection))
|
||||
.flatMap(savedActionCollection -> analyticsService.sendUpdateEvent(
|
||||
savedActionCollection, actionCollectionService.getAnalyticsProperties(savedActionCollection)))
|
||||
.flatMap(actionCollection -> actionCollectionService
|
||||
.generateActionCollectionByViewMode(actionCollection, false)
|
||||
.name(GENERATE_ACTION_COLLECTION_BY_VIEW_MODE)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMap(actionCollectionDTO1 -> actionCollectionService
|
||||
.populateActionCollectionByViewMode(actionCollection.getUnpublishedCollection(), false)
|
||||
.name(POPULATE_ACTION_COLLECTION_BY_VIEW_MODE)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.flatMap(actionCollectionDTO2 -> actionCollectionService
|
||||
.saveLastEditInformationInParent(actionCollectionDTO2)
|
||||
.name(SAVE_ACTION_COLLECTION_LAST_EDIT_INFO)
|
||||
.tap(Micrometer.observation(observationRegistry))
|
||||
.thenReturn(actionCollectionDTO2))))
|
||||
.flatMap(branchedActionCollection -> sendErrorReportsFromPageToCollection(branchedActionCollection));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.appsmith.server.solutions.PagePermission;
|
|||
import com.appsmith.server.solutions.PagePermissionImpl;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import jakarta.validation.Validator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
|
@ -86,6 +87,9 @@ public class ActionCollectionServiceImplTest {
|
|||
PagePermission pagePermission;
|
||||
ActionPermission actionPermission;
|
||||
|
||||
@MockBean
|
||||
ObservationRegistry observationRegistry;
|
||||
|
||||
@MockBean
|
||||
private Validator validator;
|
||||
|
||||
|
|
@ -108,7 +112,8 @@ public class ActionCollectionServiceImplTest {
|
|||
policyGenerator,
|
||||
applicationService,
|
||||
applicationPermission,
|
||||
actionPermission);
|
||||
actionPermission,
|
||||
observationRegistry);
|
||||
|
||||
layoutCollectionService = new LayoutCollectionServiceImpl(
|
||||
newPageService,
|
||||
|
|
@ -120,7 +125,8 @@ public class ActionCollectionServiceImplTest {
|
|||
analyticsService,
|
||||
actionCollectionRepository,
|
||||
pagePermission,
|
||||
actionPermission);
|
||||
actionPermission,
|
||||
observationRegistry);
|
||||
|
||||
Mockito.when(analyticsService.sendCreateEvent(Mockito.any()))
|
||||
.thenAnswer(
|
||||
|
|
@ -149,6 +155,10 @@ public class ActionCollectionServiceImplTest {
|
|||
Mockito.when(analyticsService.sendArchiveEvent(Mockito.any(), Mockito.any()))
|
||||
.thenAnswer(
|
||||
invocationOnMock -> Mono.justOrEmpty(invocationOnMock.getArguments()[0]));
|
||||
|
||||
ObservationRegistry.ObservationConfig mockObservationConfig =
|
||||
Mockito.mock(ObservationRegistry.ObservationConfig.class);
|
||||
Mockito.when(observationRegistry.observationConfig()).thenReturn(mockObservationConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user