-
Notifications
You must be signed in to change notification settings - Fork 1
XEN-3141: Support Elastic #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
… logic - other packages also include plugins, so 'plugins' was too ambiguous a name
…co version configurability - integration test AMP failed to install due to description in module.properties
|
@pvriel Would it be possible to add build secrets to the project so that the integration tests using Enterprise ACS 25.1 may run successfully? Unfortunately, since ACS Community does not support ElasticSearch, it was neccessary to add a sub-project for Enterprise to test this particular PR's feature. |
| @AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
| public class NodeHealthReport implements Serializable { | ||
|
|
||
| private static final long serialVersionUID = -939101152283421058L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I don't see a problem with doing this at the moment, I don't understand why we are adding this now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not blocking for this PR, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just fixing a compiler warning. Any serialisable class should have a serial version UID to ensure Java can detect when attempting to de-serialise an object from binary with an incompatible state. I believe when not explicitly set, JVM may dynamically generate a UID. It could be left out, much like other compiler warnings I tried to address so I wasn't cluttered with warnings to a degree I was missing any I might introduce.
| }; | ||
| try | ||
| { | ||
| ElasticResult searchResult = elasticRequestExecutor.checkNodeIndexed(searchEndpoint, expectedNodeRefStatuses); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is checkNodeIndexed an expensive operation? I'm wondering whether it makes sense to use a parallel stream (or thread executor) here instead of just using a for-loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checkNodeIndexed is quite inexpensive. It is a multi-retrieval-by-ID kind of operation, and the post-processing (matching nodes into state buckets) is done based on node state already loaded into txn cache before checkNodeIndexed is even called (during the endpoint selection).
| entry.getKey().getNodeRef(), messages); | ||
| healthReport.data(NodeIndexHealthReport.class).addAll(entry.getValue()); | ||
| return healthReport; | ||
| }).filter(Objects::nonNull).forEach(healthReports::add); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm missing something here: how can this stream produce null values?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It no longer can. At some point in the development it might have, and I just forgot to remove the now redundant nonNull.
| @Override | ||
| protected Set<NodeHealthReport> doProcess(Set<NodeRef> nodeRefs) | ||
| { | ||
| Set<NodeHealthReport> healthReports = new HashSet<>(nodeRefs.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The process of finding a search endpoint seems to be similar to the one from ElasticIndexValidationHealthProcessorPlugin. Do you think it's worth exploring some abstraction possibilities here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An abstraction for the for-loop would be possible and trivial. It felt wrong to move it into the abstract class I had already introduced for the subsystem-specific enablement logic, and I did not feel like it was worth to introduce yet another intermediate class at the time.
| */ | ||
| @Slf4j | ||
| @AllArgsConstructor | ||
| public class ElasticEndpointSelectorBeanPostProcessor implements BeanDefinitionRegistryPostProcessor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is not that difficult to understand, I'm wondering if we can have a more clean solution here instead of dynamically adjusting constructor arguments.
Would it be possible to:
- use the endpoint properties as a @ConfigurationProperties bean;
- use it as a @ConstructorBinding for the aggregate selector.
Unless I'm misunderstanding this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I would not use constructor arguments at all. I was mostly trying to follow the existing Lombok-heavy patterns in the health processor module. @ConfigurationProperties or @ConstructorBinding are Spring Boot annotations that should not be available in ACS. My trust in Spring annotations beyond trivial @Value is very low, especially in non-trivial systems like ACS. My personal idea of a cleaner solution would be to turn most (or everything) into regular Spring XML property instead of constructor arguments.
| return; | ||
| } | ||
|
|
||
| BeanDefinition aggregateSelector = registry.getBeanDefinition("eu.xenit.alfresco.healthprocessor.endpoint.solr." + AggregateSearchEndpointSelector.class.getSimpleName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cf. ElasticEndpointSelectorBeanPostProcessor
| { | ||
| if (!first) | ||
| { | ||
| sb.append(','); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to double-check: why only the first one? Or are you only expecting two Statuses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other way around: For all BUT the first one we are adding a comma, so that the JSON is structurally valid. This needs to support an arbitrary number of entries depending on the configured batch size in the processor / indexing strategy.
2bbd8b8 to
7f88cef
Compare
98b9131 to
162fcdc
Compare
|




This PR provides changes to support ElasticSearch with regards to index health check and fix functionalities. This includes handling to determine whether SOLR or ElasticSearch plugins are actually relevant based on checks on the
Searchsubsystem activation state (checking thesourceBeanNameproperty dynamically).The ElasticSearch support includes the following capabilities:
ALIVEstate which seems to only be partially used by ACS (i.e. Admin Console only countsALIVEindex entries when reporting indexed nodes)PATHfield if path indexing is expected (issues during indexing based on timing / missed events may cause index entries not to have aPATHfield)The following issues have been encountered and identified with the ElasticSearch-based search subsystem in general:
PATHindexing is extremely brittle, can cause a lot of error messages in the indexer app log, introduce significant delays, and cause nodes not to be found when the ACS Admin Console actually shows all nodes to be indexedprimaryHierarchyandsecondaryParents)PATHvalues from there, and use these as prefixes to build thePATHvalues for the node to be indexedPATHfield, an error is thrown and event processing is retries with a bit of a processing delayPATHfor node B because the rename of node A may not be reflected in itsPATHindex values yet when they are used as prefixes to build the newPATHvalues of node BPATHof otherssys:*type filter - this prevents indexing of anysys:containerorsys:store_rootnodes, which would prevent the Elastic node index fixer plugin of this PR from fixingPATHissues for any nodes immediately below such nodes and transitively for potentially more (thesys:store_rootmight actually block ANYPATHindexing unless the official re-indexer app was used to ensure thesys:store_roothas been indexed)PATHindex values and errors in the indexer appsys:deleted,sys:descriptor,sys:reference,sys:lost_found,sys:archiveUser, rule:*, act:*, fm:*, cm:thumbnail, cm:failedThumbnail, cm:rating, rma:rmsite include_subtypes, usr:usersys:*, fm:*, cm:thumbnail, cm:failedThumbnail, cm:rating, rma:rmsite include_subtypes, usr:userPATHindexing because the node grouping all rules for a folder is of typecm:systemFolder, which is hard-coded to be filtered from event sending (as are all sub-types of the system folder type) - it seems questionable any out-of-process extension would ever be interested to react to any events on rules/actionssys:*wildcard to filter out any types of the system model except for thesys:containerandsys:store_root- the former is relevant forPATHindexing of person or group authority nodes, the latter is relevant if the Elastic index fixer plugin of this PR is used to trigger an index build from a completely empty ElasticSearch index