3.6.6 - Application size discrepancy after an application import
Overview
This page describes a workaround for an issue specific to CAST Imaging 3.6.6-funcrel (see IMAGKSL-5754), in which the application size (Lines of code) displayed in CAST Imaging is significantly larger than the real size of the application. The issue is fixed in 3.6.7-funcrel.
Symptoms
After importing an application (for example an application exported from one CAST Imaging instance and imported into another, including across platforms such as Windows to Linux), the application size reported in the Viewer and on the Console onboarding page can be several times larger than the size reported for the same application onboarded from scratch.
The import creates duplicate Language nodes in the Neo4j database. Because the size of an application is derived from its active HAS_LANGUAGE relationships, the duplicated nodes cause the size to be counted multiple times.
The impact is not limited to the imported application: applications that are onboarded or imported after the first import also report an incorrect size.
Workaround
Two options are available:
- Update to 3.6.7-funcrel, in which the issue is fixed. This is the recommended option.
- Run the Cypher queries below to correct the data in place, as described in Correct the data in 3.6.6-funcrel.
The Cypher queries correct the data at a point in time only. If you import another application while you are still running 3.6.6-funcrel, the duplicate nodes are re-created and the queries need to be run again. Update to 3.6.7-funcrel to resolve the issue permanently.
Correct the data in 3.6.6-funcrel
Run the following queries in order, against the Neo4j database of the tenant on which the discrepancy is visible, for example using the Neo4j Browser. Steps 2, 3 and 4 use the APOC procedures that are bundled with CAST Imaging.
Back up your Neo4j database before you run these queries.
Step 1 - Detect the affected applications
This query is read-only and lists the applications and languages that are affected:
MATCH (a:Application|Repository)-[r:HAS_LANGUAGE]->(l:Language)
WHERE r.EndDate IS NULL
WITH a, l.Name AS langName, count(DISTINCT l) AS nodeCount
WHERE nodeCount > 1
RETURN a.Name AS app, langName, nodeCount
ORDER BY app, nodeCount DESC
Step 2 - Retire the redundant active relationships
This query corrects the reported size immediately:
CALL apoc.periodic.iterate(
"MATCH (a:Application|Repository)-[r:HAS_LANGUAGE]->(l:Language)
WHERE r.EndDate IS NULL
WITH a, l.Name AS langName, l, r
ORDER BY elementId(a), langName, l.StartDate ASC, elementId(l) ASC
WITH a, langName, collect(l) AS nodes, collect(r) AS rels
WHERE size(nodes) > 1
RETURN rels[1..] AS relsToRetire",
"UNWIND relsToRetire AS rel
SET rel.EndDate = datetime(), rel.Status = 'deleted'",
{ batchSize: 1000, parallel: false, retries: 3 }
) YIELD batch, operations, timeTaken, errorMessages, retries
RETURN batch, operations, timeTaken, errorMessages, retries
Step 3 - Merge the duplicate nodes
This query closes the gap that allows subsequent onboarding and import operations to duplicate the nodes again:
CALL apoc.periodic.iterate(
"MATCH (l:Language)
WITH l.Name AS langName, l
ORDER BY langName, l.StartDate ASC, elementId(l) ASC
WITH langName, collect(l) AS nodes
WHERE size(nodes) > 1
RETURN nodes",
"CALL apoc.refactor.mergeNodes(nodes, {mergeRels:false, properties:'discard'}) YIELD node RETURN node",
{ batchSize: 1000, parallel: false, retries: 3 }
) YIELD batch, operations, timeTaken, errorMessages, retries
RETURN batch, operations, timeTaken, errorMessages, retries
Step 4 - Recompute the application size
This query updates the stored Lines of code value for every application whose value is now stale:
CALL apoc.periodic.iterate(
"MATCH (a:Application|Repository)-[r:HAS_LANGUAGE]->(l:Language) WHERE r.EndDate IS NULL
WITH a, SUM(r.NbLocs) AS totalLoc
MATCH (a)-[:Property]->(p:Property) WHERE p.Label = 'Lines of code' AND p.Value <> toString(totalLoc)
RETURN a, p, totalLoc",
"SET p.Value = toString(totalLoc)",
{ batchSize: 1000, parallel: false, retries: 3 }
) YIELD batch, operations, timeTaken, errorMessages, retries
RETURN batch, operations, timeTaken, errorMessages, retries
Step 5 - Check the result
Run the detection query in Step 1 again. It should return no rows. The corrected application size is displayed in the Viewer and on the Console onboarding page.