[ 
https://issues.apache.org/jira/browse/KNOX-2900?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18113348#comment-18113348
 ] 

Sandor Molnar commented on KNOX-2900:
-------------------------------------

Claude input:

h2. Verification

I reviewed the current code against all five points. First, some context on the 
current state: KNOX-2899 disabled the per-service filter in 
{{ClouderaManagerServiceDiscovery.discoverService}} (lines 297-300 are now 
commented out), while the {{shouldSkipServiceDiscovery}} helper is retained but 
marked {{@SuppressWarnings("PMD.UnusedPrivateMethod")}}. "The service filter" 
refers to skipping services whose model generators aren't in the topology's 
{{includedServices}} set, which originates from the descriptor in 
{{SimpleDescriptorHandler}} (lines 265-266).

All five points are valid:

1) Invalid config + restart re-triggers autodiscovery — CONFIRMED
In {{PollingConfigurationAnalyzer.hasConfigChanged}} (lines 341-362), the 
previously recorded config is looked up by service type. If a service was in an 
invalid config state, discovery never produced a {{ServiceModel}}, so 
{{addServiceConfiguration}} never stored a {{ServiceConfigurationModel}} for 
that type. Therefore the lookup returns {{null}}, the code hits the {{else}} 
branch, logs {{serviceEnabled}}, and sets {{configHasChanged = true}}. Every 
subsequent restart of the still-invalid service repeats this.

2) PCA uses a different workflow than CM discovery — CONFIRMED
{{getCurrentServiceConfiguration}} (lines 600-635) builds a raw 
{{ServiceConfigurationModel}} (service props + role props) directly from the CM 
API. It never runs {{ServiceModelGenerator.handles()}} / {{generateService()}}. 
So PCA compares raw config maps and cannot observe whether the config is valid 
(would actually yield a model), nor compare against the discovery output stored 
in {{ClusterConfigurationCache}}.

3) Discovery overwrites the global cache/.ver instead of merging — CONFIRMED 
(core blocker)
{{ClusterConfigurationCache.addServiceConfiguration}} does 
{{clusterMap.put(cluster, configs)}} (line 57) — full replace. 
{{ClusterConfigurationFileStore.store}} writes a fresh 
{{ServiceConfigurationRecord}} with only the passed configs (lines 57-72) — 
full overwrite of the {{.ver}} file. With the filter off (today), every 
discovery returns all services, so the cache stays complete and PCA works. With 
the filter on, a descriptor referencing only a subset produces a {{scpMap}} 
with only that subset and clobbers the cache/{{.ver}} for the whole {{(address, 
cluster)}}. This is precisely why the filter was disabled.

4) {{excluded.service.types}} only applied in autodiscovery, not PCA — CONFIRMED
Excluded service types are filtered in {{getClusterServices}} (lines 404-410). 
PCA's {{isStartEvent}} (lines 525-538) only checks 
{{serviceModelGeneratorExists}}, not the excluded set. An excluded type that 
still has a model generator will trigger rediscovery on start/restart.

5) {{excluded.role.types}} not respected by PCA scale events — CONFIRMED
Excluded role types are applied via {{TypeNameFilter}} in 
{{ServiceRoleCollectorBuilder}} (lines 80-81) during discovery. PCA's 
{{isScaleEvent}} (lines 540-549) only checks {{serviceModelGeneratorExists}} 
for the service type and the event code — it never checks the event's 
{{ROLE_TYPE}} against the excluded role types.

h2. Plan

Root cause chain: re-enabling the filter makes each discovery return only a 
topology's subset of services -> the overwrite semantics (#3) corrupt the 
shared cache -> PCA (which reads that cache and uses a divergent workflow, #2) 
then makes
wrong rediscovery decisions (#1, #4, #5). So #3 and #2 are the foundation; 
#1/#4/#5 are correctness fixes oter is the last step.

Step 1 — Merge instead of overwrite the cache and .ver file (issue #3)
- {{ClusterConfigurationCache.addServiceConfiguration}}: merge the incoming 
configs into the existing per-cluster {{Map<serviceType, 
ServiceConfigurationModel>}} (merge by service type) instead of 
{{put}}-replacing the whole map.
- {{ClusterConfigurationFileStore.store}}: read the existing {{.ver}} record, 
merge the new service types imerge}} method invoked from 
{{ClouderaManagerClusterConfigurationMonitor.addServiceConfiguration}}).
- Nuance: merging alone never evicts a genuinely removed service type. Removal 
must stay driven by {{clearCache}}/{{stopMonitoring}} when no descriptor 
references the cluster, and by role-delete scale events. Document this so merge 
doesn't
mask real removals.

Step 2 — Make PCA reuse the discovery workflow and compare against the cache 
(issue #2)
- Change {{getCurrentServiceConfiguration}} (or add a helper) to run the same 
model-building path as {{ClouderaManagerServiceDiscovery}} 
({{ServiceModelGenerator.handles()}} -> {{generateService()}}) rather than 
assembling a raw
{{ServiceConfigurationModel}}. Practically, refactor 
{{discoverService}}/{{generateServiceModels}} into a rl.
- Compare the freshly-built models against what's in 
{{ClusterConfigurationCache}} for that {{(address, cluster)}}. Trigger 
rediscovery only when the model output differs — not when raw config bytes 
differ.

Step 3 — Suppress rediscovery for services stuck in invalid config (issue #1)
- In {{hasConfigChanged}}, the {{serviceConfig == null}} -> {{serviceEnabled}} 
-> {{configHasChanged = trueWith Step 2 in place, gate this on whether the 
service now produces a valid {{ServiceModel}}. If discoverystill yields no 
model (config still invalid), do not trigger rediscovery. Only flip to changed 
when an actual model appears where there was none.

Step 4 — Honor {{excluded.service.types}} in PCA (issue #4)
- Load {{getClouderaManagerServiceDiscoveryExcludedServiceTypes()}} into PCA 
(lowercased, mirroring {{Cloud}}).
- In {{isStartEvent}}, treat start/restart events whose {{SERVICE_TYPE}} is 
excluded as non-relevant so they're never added to {{relevantEvents}}.

Step 5 — Honor {{excluded.role.types}} in PCA scale events (issue #5)
- Load {{getClouderaManagerServiceDiscoveryExcludedRoleTypes()}} into PCA and 
reuse {{TypeNameFilter}}.
- In {{isScaleEvent}}, read the event's {{ROLE_TYPE}} (already captured as 
{{RelevantEvent.role}}) and return false when that role type is excluded.

Step 6 — Re-enable the filter
- Uncomment the skip logic in {{discoverService}} (lines 297-300), restore the 
{{log.skipServiceDiscovery}}pressWarnings("PMD.UnusedPrivateMethod")}} on 
{{shouldSkipServiceDiscovery}}.

Step 7 — Tests
- {{PollingConfigurationAnalyzerTest}}: invalid-config-restart produces no 
rediscovery (#1); excluded service start event ignored (#4); excluded role-type 
scale event ignored (#5); rediscovery fires only on real model-output change 
(#2).
- New cache/store test: two descriptors referencing disjoint service subsets of 
one cluster both survive insequential discovery (#3).
- Existing CM discovery tests still pass with the filter re-enabled (#6).

Sequencing: #3 -> #2 -> #1 -> #4/#5 (independent) -> #6 -> tests throughout. #3 
and #2 are the hard parts; #4 and #5 are small and self-contained.

> KNOX-2899 followup - reenable service based discovery filter
> ------------------------------------------------------------
>
>                 Key: KNOX-2900
>                 URL: https://issues.apache.org/jira/browse/KNOX-2900
>             Project: Apache Knox
>          Issue Type: Task
>            Reporter: Attila Magyar
>            Priority: Major
>
> In KNOX-2899 the service based discovery filter was temporary disabled 
> because it interferes with the polling configurator analyzer. 
> * Either a permanent fix is needed that works well with the polling config 
> analyizer
> * Or the filter should be permanently removed, if the performance gain would 
> be negligible
> cc: [~smolnar]



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to