From aeb8c1afc66a8700ceff62bafa24cb880021333e Mon Sep 17 00:00:00 2001 From: EMaksy Date: Tue, 23 Jul 2024 18:08:49 +0200 Subject: [PATCH 01/11] Add sap system type in view --- .../SapSystemsOverview.jsx | 49 +++++++++++++++++-- lib/trento/sap_systems/sap_system.ex | 17 +++++-- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index d00c0d00f7..8f72599e2b 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-unstable-nested-components */ import React, { useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; -import { filter } from 'lodash'; +import { filter, uniq, flatMap } from 'lodash'; import { getEnsaVersionLabel } from '@lib/model/sapSystems'; @@ -77,6 +77,11 @@ function SapSystemsOverview({ title: 'Tenant', key: 'tenant', }, + { + title: 'Type', + key: 'type', + }, + { title: 'DB Address', key: 'dbAddress', @@ -120,17 +125,53 @@ function SapSystemsOverview({ ), }; + const filterApplicationInstances = (sapSystem) => + filter(applicationInstances, { + sap_system_id: sapSystem.id, + }); + + const getInstanceSystemType = (instanceFeatures) => { + if ( + instanceFeatures.includes('ABAP') && + instanceFeatures.includes('J2EE') + ) { + return 'ABAP/JAVA'; + } + + if (instanceFeatures.includes('ABAP')) { + return 'ABAP'; + } + + if (instanceFeatures.includes('J2EE')) { + return 'JAVA'; + } + + return 'Unknown'; + }; + const filterSapSystemType = (sapSystem) => { + const instances = filterApplicationInstances(sapSystem); + const uniqueInstanceFeatures = uniq( + flatMap( + instances + .map((instance) => instance.features) + .map((feature) => feature.split('|')) + ) + ); + + const systemType = getInstanceSystemType(uniqueInstanceFeatures); + return systemType; + }; + const data = sapSystems.map((sapSystem) => ({ id: sapSystem.id, health: sapSystem.health, sid: sapSystem.sid, attachedRdbms: sapSystem.database_sid, tenant: sapSystem.tenant, + type: filterSapSystemType(sapSystem), dbAddress: sapSystem.db_host, ensaVersion: sapSystem.ensa_version || '-', - applicationInstances: filter(applicationInstances, { - sap_system_id: sapSystem.id, - }), + applicationInstances: filterApplicationInstances(sapSystem), databaseInstances: filter(databaseInstances, { database_id: sapSystem.database_id, }), diff --git a/lib/trento/sap_systems/sap_system.ex b/lib/trento/sap_systems/sap_system.ex index ce8d37489d..dd08170576 100644 --- a/lib/trento/sap_systems/sap_system.ex +++ b/lib/trento/sap_systems/sap_system.ex @@ -638,7 +638,7 @@ defmodule Trento.SapSystems.SapSystem do database_health: database_health } ) do - if instances_have_abap?(instances) and instances_have_messageserver?(instances) do + if instances_have_abap_or_java?(instances) and instances_have_messageserver?(instances) do %SapSystemRestored{ db_host: db_host, health: health, @@ -659,7 +659,7 @@ defmodule Trento.SapSystems.SapSystem do database_health: database_health } ) do - if instances_have_abap?(instances) and instances_have_messageserver?(instances) do + if instances_have_abap_or_java?(instances) and instances_have_messageserver?(instances) do %SapSystemRestored{ health: health, db_host: db_host, @@ -683,7 +683,7 @@ defmodule Trento.SapSystems.SapSystem do database_health: database_health } ) do - if instances_have_abap?(instances) and instances_have_messageserver?(instances) do + if instances_have_abap_or_java?(instances) and instances_have_messageserver?(instances) do %SapSystemRegistered{ sap_system_id: sap_system_id, sid: sid, @@ -794,7 +794,7 @@ defmodule Trento.SapSystems.SapSystem do }, deregistered_at ) do - unless instances_have_abap?(instances) and instances_have_messageserver?(instances) do + unless instances_have_abap_or_java?(instances) and instances_have_messageserver?(instances) do %SapSystemDeregistered{sap_system_id: sap_system_id, deregistered_at: deregistered_at} end end @@ -814,6 +814,15 @@ defmodule Trento.SapSystems.SapSystem do Enum.any?(instances, fn %{features: features} -> features =~ "ABAP" end) end + + defp instances_have_java?(instances) do + Enum.any?(instances, fn %{features: features} -> features =~ "J2EE" end) + end + + defp instances_have_abap_or_java?(instances) do + instances_have_abap?(instances) or instances_have_java?(instances) + end + def instances_have_messageserver?(instances) do Enum.any?(instances, fn %{features: features} -> features =~ "MESSAGESERVER" end) end From af864e346377a2585cce9d33e86af1402d343f4e Mon Sep 17 00:00:00 2001 From: EMaksy Date: Wed, 24 Jul 2024 10:17:44 +0200 Subject: [PATCH 02/11] Update factory and fix test --- assets/js/lib/test-utils/factories/sapSystems.js | 2 ++ .../SapSystemsOverview.test.jsx | 11 +++++++++-- lib/trento/sap_systems/sap_system.ex | 1 - 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/assets/js/lib/test-utils/factories/sapSystems.js b/assets/js/lib/test-utils/factories/sapSystems.js index 55e60c6f51..397fa7127a 100644 --- a/assets/js/lib/test-utils/factories/sapSystems.js +++ b/assets/js/lib/test-utils/factories/sapSystems.js @@ -36,10 +36,12 @@ export const sapSystemFactory = Factory.define(({ params }) => { const sid = params.sid || generateSid(); const databaseId = params.database_id || faker.string.uuid(); const databaseSid = params.database_sid || generateSid(); + const sapSystemType = params.sap_system_type || 'ABAP'; return { application_instances: sapSystemApplicationInstanceFactory.buildList(2, { sap_system_id: id, sid, + features: sapSystemType, }), database_instances: databaseInstanceFactory.buildList(2, { database_id: databaseId, diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx index edd759c2ec..ecc7c40a87 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx @@ -41,7 +41,11 @@ describe('SapSystemsOverviews component', () => { }); it('should display the correct content for a SAP system main row', () => { - const sapSystem = sapSystemFactory.build({ ensa_version: 'ensa1' }); + const sapSystemType = 'ABAP'; + const sapSystem = sapSystemFactory.build({ + ensa_version: 'ensa1', + sap_system_type: 'ABAP', + }); const { id: sapSystemID, sid, @@ -80,9 +84,12 @@ describe('SapSystemsOverviews component', () => { tenant ); expect(mainRow.querySelector('td:nth-child(5)')).toHaveTextContent( - dbAddress + sapSystemType ); expect(mainRow.querySelector('td:nth-child(6)')).toHaveTextContent( + dbAddress + ); + expect(mainRow.querySelector('td:nth-child(7)')).toHaveTextContent( 'ENSA1' ); }); diff --git a/lib/trento/sap_systems/sap_system.ex b/lib/trento/sap_systems/sap_system.ex index dd08170576..70a0edc720 100644 --- a/lib/trento/sap_systems/sap_system.ex +++ b/lib/trento/sap_systems/sap_system.ex @@ -814,7 +814,6 @@ defmodule Trento.SapSystems.SapSystem do Enum.any?(instances, fn %{features: features} -> features =~ "ABAP" end) end - defp instances_have_java?(instances) do Enum.any?(instances, fn %{features: features} -> features =~ "J2EE" end) end From 9293f7d0459c4d8f9add77c92917ecaa0c7ccb0e Mon Sep 17 00:00:00 2001 From: EMaksy Date: Wed, 24 Jul 2024 10:52:37 +0200 Subject: [PATCH 03/11] Refactor type --- .../SapSystemsOverview.jsx | 50 +++++-------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 8f72599e2b..6bfd963c1b 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-unstable-nested-components */ import React, { useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; -import { filter, uniq, flatMap } from 'lodash'; +import { filter, uniq } from 'lodash'; import { getEnsaVersionLabel } from '@lib/model/sapSystems'; @@ -79,7 +79,15 @@ function SapSystemsOverview({ }, { title: 'Type', - key: 'type', + key: 'applicationInstances', + render: (content) => + uniq( + content + .filter(({ features }) => /ABAP|J2EE/.test(features)) + .map(({ features }) => + features.includes('ABAP') ? 'ABAP' : 'JAVA' + ) + ).join('/'), }, { @@ -125,53 +133,21 @@ function SapSystemsOverview({ ), }; - const filterApplicationInstances = (sapSystem) => + const filteredApplicationInstances = (sapSystem) => filter(applicationInstances, { sap_system_id: sapSystem.id, }); - const getInstanceSystemType = (instanceFeatures) => { - if ( - instanceFeatures.includes('ABAP') && - instanceFeatures.includes('J2EE') - ) { - return 'ABAP/JAVA'; - } - - if (instanceFeatures.includes('ABAP')) { - return 'ABAP'; - } - - if (instanceFeatures.includes('J2EE')) { - return 'JAVA'; - } - - return 'Unknown'; - }; - const filterSapSystemType = (sapSystem) => { - const instances = filterApplicationInstances(sapSystem); - const uniqueInstanceFeatures = uniq( - flatMap( - instances - .map((instance) => instance.features) - .map((feature) => feature.split('|')) - ) - ); - - const systemType = getInstanceSystemType(uniqueInstanceFeatures); - return systemType; - }; - const data = sapSystems.map((sapSystem) => ({ id: sapSystem.id, health: sapSystem.health, sid: sapSystem.sid, attachedRdbms: sapSystem.database_sid, tenant: sapSystem.tenant, - type: filterSapSystemType(sapSystem), + type: filteredApplicationInstances(sapSystem), dbAddress: sapSystem.db_host, ensaVersion: sapSystem.ensa_version || '-', - applicationInstances: filterApplicationInstances(sapSystem), + applicationInstances: filteredApplicationInstances(sapSystem), databaseInstances: filter(databaseInstances, { database_id: sapSystem.database_id, }), From 8211191dc907e96f13c0748ab997ce19efc68a20 Mon Sep 17 00:00:00 2001 From: EMaksy Date: Wed, 24 Jul 2024 15:19:58 +0200 Subject: [PATCH 04/11] Refactor type --- .../SapSystemsOverview.jsx | 17 +++++++----- .../SapSystemsOverview.stories.jsx | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 6bfd963c1b..99dd1eb93d 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-unstable-nested-components */ import React, { useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; -import { filter, uniq } from 'lodash'; +import { filter, uniq, flatMap } from 'lodash'; import { getEnsaVersionLabel } from '@lib/model/sapSystems'; @@ -82,12 +82,15 @@ function SapSystemsOverview({ key: 'applicationInstances', render: (content) => uniq( - content - .filter(({ features }) => /ABAP|J2EE/.test(features)) - .map(({ features }) => - features.includes('ABAP') ? 'ABAP' : 'JAVA' - ) - ).join('/'), + flatMap( + content + .map((instance) => instance.features) + .map((feature) => feature.split('|')) + ) + ) + .filter((item) => item === 'J2EE' || item === 'ABAP') + .map((item) => (item === 'J2EE' ? 'JAVA' : item)) + .join('/'), }, { diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx index 4b5431d3a1..1691f765f6 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx @@ -49,6 +49,24 @@ const enrichedAbsentDatabaseInstances = enrichInstances( 'database_instances' ); +const sapSystemsWithDifferentTypes = [ + sapSystemFactory.build({ sap_system_type: 'J2EE' }), + sapSystemFactory.build({ sap_system_type: 'ABAP' }), + sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE' }), + sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE|SAP_APP' }), + sapSystemFactory.build({ + sap_system_type: 'NOT_ABAP|NOT_JAVA|JAVA|NOT_J2EE', + }), +]; +const enrichedApplicationInstancesType = enrichInstances( + sapSystemsWithDifferentTypes, + 'application_instances' +); +const enrichedAbsentDatabaseInstancesType = enrichInstances( + sapSystemsWithDifferentTypes, + 'database_instances' +); + enrichedAbsentApplicationInstances[1].absent_at = faker.date .past() .toISOString(); @@ -140,3 +158,11 @@ export const UnauthorizedCleanUp = { userAbilities: [], }, }; +export const SapSystemsWithDifferentTypes = { + args: { + userAbilities, + sapSystems: sapSystemsWithDifferentTypes, + applicationInstances: enrichedApplicationInstancesType, + databaseInstances: enrichedAbsentDatabaseInstancesType, + }, +}; From c74299206126d12d94812a0396850b9fd30c575e Mon Sep 17 00:00:00 2001 From: EMaksy Date: Wed, 24 Jul 2024 15:31:55 +0200 Subject: [PATCH 05/11] Update existing story and add test --- .../SapSystemsOverview.jsx | 21 ++--- .../SapSystemsOverview.stories.jsx | 11 +-- .../SapSystemsOverview.test.jsx | 79 ++++++++++++++++++- 3 files changed, 96 insertions(+), 15 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 99dd1eb93d..36a523f620 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -80,17 +80,20 @@ function SapSystemsOverview({ { title: 'Type', key: 'applicationInstances', - render: (content) => - uniq( - flatMap( - content - .map((instance) => instance.features) - .map((feature) => feature.split('|')) - ) + render: (content) => { + const instanceTypes = uniq( + flatMap(content, (instance) => instance.features.split('|')) ) .filter((item) => item === 'J2EE' || item === 'ABAP') - .map((item) => (item === 'J2EE' ? 'JAVA' : item)) - .join('/'), + .map((item) => (item === 'J2EE' ? 'JAVA' : item)); + // Join the results in a fixed order + const systemHasABAP = instanceTypes.includes('ABAP'); + const systemHasJAVA = instanceTypes.includes('JAVA'); + const sapSystemType = []; + if (systemHasABAP) sapSystemType.push('ABAP'); + if (systemHasJAVA) sapSystemType.push('JAVA'); + return sapSystemType.join('/'); + }, }, { diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx index 1691f765f6..99ff215722 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx @@ -54,8 +54,9 @@ const sapSystemsWithDifferentTypes = [ sapSystemFactory.build({ sap_system_type: 'ABAP' }), sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE' }), sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE|SAP_APP' }), + sapSystemFactory.build({ sap_system_type: 'J2EE|ABAP|SAP_APP' }), sapSystemFactory.build({ - sap_system_type: 'NOT_ABAP|NOT_JAVA|JAVA|NOT_J2EE', + sap_system_type: 'NOT_ABAP|NOT_JAVA|JAVA|NOT_J2EE|NOT_A_REAL_SAP_SYSTEM', }), ]; const enrichedApplicationInstancesType = enrichInstances( @@ -89,10 +90,6 @@ export default { control: { type: 'array' }, description: 'Application instances', }, - userAbilities: { - control: { type: 'array' }, - description: 'User profile abilities', - }, databaseInstances: { control: { type: 'array' }, description: 'Database instances', @@ -105,6 +102,10 @@ export default { defaultValue: { summary: false }, }, }, + userAbilities: { + control: { type: 'array' }, + description: 'User profile abilities', + }, onTagAdd: { action: 'Add tag', description: 'Called when a new tag is added', diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx index ecc7c40a87..ac78fb99ad 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx @@ -44,7 +44,7 @@ describe('SapSystemsOverviews component', () => { const sapSystemType = 'ABAP'; const sapSystem = sapSystemFactory.build({ ensa_version: 'ensa1', - sap_system_type: 'ABAP', + sap_system_type: sapSystemType, }); const { id: sapSystemID, @@ -94,6 +94,83 @@ describe('SapSystemsOverviews component', () => { ); }); + it('should display the correct SAP system type', () => { + const sapSystemTypes = [ + 'ABAP', + 'J2EE', + 'ABAP|J2EE', + 'J2EE|ABAP', + 'SOME_SAP_SYSTEM_FEATURE|NOT_A_REAL_SYSTEM', + ]; + + const expectedSapSystemTypes = [ + 'ABAP', + 'JAVA', + 'ABAP/JAVA', + 'ABAP/JAVA', + '', + ]; + const sapSystems = [ + sapSystemFactory.build({ + sap_system_type: sapSystemTypes[0], + }), + sapSystemFactory.build({ + sap_system_type: sapSystemTypes[1], + }), + sapSystemFactory.build({ + sap_system_type: sapSystemTypes[2], + }), + sapSystemFactory.build({ + sap_system_type: sapSystemTypes[3], + }), + sapSystemFactory.build({ + sap_system_type: sapSystemTypes[4], + }), + ]; + + const sapSystemApplicationInstances = [ + sapSystems[0].application_instances, + sapSystems[1].application_instances, + sapSystems[2].application_instances, + sapSystems[3].application_instances, + sapSystems[4].application_instances, + ].flat(); + + renderWithRouter( + + ); + const rows = screen.getByRole('table').querySelectorAll('tbody > tr'); + const firstSapSystem = rows[0]; + const secondSapSystem = rows[2]; + const thirdSapSystem = rows[4]; + const fourthSapSystem = rows[6]; + const fifthSapSystem = rows[8]; + + expect(firstSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( + expectedSapSystemTypes[0] + ); + expect( + secondSapSystem.querySelector('td:nth-child(5)') + ).toHaveTextContent(expectedSapSystemTypes[1]); + + expect(thirdSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( + expectedSapSystemTypes[2] + ); + + expect( + fourthSapSystem.querySelector('td:nth-child(5)') + ).toHaveTextContent(expectedSapSystemTypes[3]); + + expect(fifthSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( + expectedSapSystemTypes[4] + ); + }); + it('should display the correct content for a SAP system instances', () => { const sapSystem = sapSystemFactory.build(); const { From 25f6236e590ada71a62175e1bb04b1ff09ebaaf3 Mon Sep 17 00:00:00 2001 From: EMaksy Date: Thu, 25 Jul 2024 16:10:11 +0200 Subject: [PATCH 06/11] Fix existing cypress test --- test/e2e/cypress/e2e/sap_systems_overview.cy.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/cypress/e2e/sap_systems_overview.cy.js b/test/e2e/cypress/e2e/sap_systems_overview.cy.js index d072d60ef3..116707ee36 100644 --- a/test/e2e/cypress/e2e/sap_systems_overview.cy.js +++ b/test/e2e/cypress/e2e/sap_systems_overview.cy.js @@ -73,7 +73,8 @@ context('SAP Systems Overview', () => { .within(() => { cy.get('td').eq(2).contains(attachedDatabase.sid); cy.get('td').eq(3).contains(attachedDatabase.tenant); - cy.get('td').eq(4).contains(attachedDatabase.dbAddress); + + cy.get('td').eq(5).contains(attachedDatabase.dbAddress); }); }); it(`should have a link to the attached HANA database with id: ${attachedDatabase.id}`, () => { From 5b1629fcf3fa94071c3314a3ff901bf4b25239cc Mon Sep 17 00:00:00 2001 From: EMaksy Date: Thu, 25 Jul 2024 16:45:51 +0200 Subject: [PATCH 07/11] Refactor render of sap system type --- .../SapSystemsOverviewPage/SapSystemsOverview.jsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 36a523f620..7c4bbfc722 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -86,13 +86,12 @@ function SapSystemsOverview({ ) .filter((item) => item === 'J2EE' || item === 'ABAP') .map((item) => (item === 'J2EE' ? 'JAVA' : item)); - // Join the results in a fixed order - const systemHasABAP = instanceTypes.includes('ABAP'); - const systemHasJAVA = instanceTypes.includes('JAVA'); - const sapSystemType = []; - if (systemHasABAP) sapSystemType.push('ABAP'); - if (systemHasJAVA) sapSystemType.push('JAVA'); - return sapSystemType.join('/'); + // Join the results in a fixed order ABAP, JAVA, ABAP/JAVA or '' + const sapSystemType = ['ABAP', 'JAVA'] + .filter((type) => instanceTypes.includes(type)) + .join('/'); + + return sapSystemType; }, }, From 23c57b3e6b23b9721e91a3b329d31c4910033e53 Mon Sep 17 00:00:00 2001 From: EMaksy Date: Mon, 29 Jul 2024 14:14:21 +0200 Subject: [PATCH 08/11] Address frontend comments --- .../js/lib/test-utils/factories/sapSystems.js | 3 +- .../SapSystemsOverview.jsx | 32 +++---- .../SapSystemsOverview.stories.jsx | 26 ++++-- .../SapSystemsOverview.test.jsx | 86 ++++++++----------- 4 files changed, 65 insertions(+), 82 deletions(-) diff --git a/assets/js/lib/test-utils/factories/sapSystems.js b/assets/js/lib/test-utils/factories/sapSystems.js index 397fa7127a..6d50f42f82 100644 --- a/assets/js/lib/test-utils/factories/sapSystems.js +++ b/assets/js/lib/test-utils/factories/sapSystems.js @@ -15,6 +15,7 @@ const roles = () => 'GATEWAY', 'ICMAN', 'IGS', + 'J2EE', ]); export const sapSystemApplicationInstanceFactory = Factory.define(() => ({ @@ -36,12 +37,10 @@ export const sapSystemFactory = Factory.define(({ params }) => { const sid = params.sid || generateSid(); const databaseId = params.database_id || faker.string.uuid(); const databaseSid = params.database_sid || generateSid(); - const sapSystemType = params.sap_system_type || 'ABAP'; return { application_instances: sapSystemApplicationInstanceFactory.buildList(2, { sap_system_id: id, sid, - features: sapSystemType, }), database_instances: databaseInstanceFactory.buildList(2, { database_id: databaseId, diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 7c4bbfc722..8fbdb17a0d 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -79,20 +79,18 @@ function SapSystemsOverview({ }, { title: 'Type', - key: 'applicationInstances', - render: (content) => { - const instanceTypes = uniq( - flatMap(content, (instance) => instance.features.split('|')) + key: 'type', + render: (_, items) => + uniq( + flatMap( + filter(items.applicationInstances, { sap_system_id: items.id }), + ({ features }) => features.split('|') + ) ) .filter((item) => item === 'J2EE' || item === 'ABAP') - .map((item) => (item === 'J2EE' ? 'JAVA' : item)); - // Join the results in a fixed order ABAP, JAVA, ABAP/JAVA or '' - const sapSystemType = ['ABAP', 'JAVA'] - .filter((type) => instanceTypes.includes(type)) - .join('/'); - - return sapSystemType; - }, + .map((item) => (item === 'J2EE' ? 'JAVA' : item)) + .toSorted() + .join('/'), }, { @@ -138,21 +136,17 @@ function SapSystemsOverview({ ), }; - const filteredApplicationInstances = (sapSystem) => - filter(applicationInstances, { - sap_system_id: sapSystem.id, - }); - const data = sapSystems.map((sapSystem) => ({ id: sapSystem.id, health: sapSystem.health, sid: sapSystem.sid, attachedRdbms: sapSystem.database_sid, tenant: sapSystem.tenant, - type: filteredApplicationInstances(sapSystem), dbAddress: sapSystem.db_host, ensaVersion: sapSystem.ensa_version || '-', - applicationInstances: filteredApplicationInstances(sapSystem), + applicationInstances: filter(applicationInstances, { + sap_system_id: sapSystem.id, + }), databaseInstances: filter(databaseInstances, { database_id: sapSystem.database_id, }), diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx index 99ff215722..afc2a77a2f 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx @@ -49,16 +49,24 @@ const enrichedAbsentDatabaseInstances = enrichInstances( 'database_instances' ); -const sapSystemsWithDifferentTypes = [ - sapSystemFactory.build({ sap_system_type: 'J2EE' }), - sapSystemFactory.build({ sap_system_type: 'ABAP' }), - sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE' }), - sapSystemFactory.build({ sap_system_type: 'ABAP|J2EE|SAP_APP' }), - sapSystemFactory.build({ sap_system_type: 'J2EE|ABAP|SAP_APP' }), - sapSystemFactory.build({ - sap_system_type: 'NOT_ABAP|NOT_JAVA|JAVA|NOT_J2EE|NOT_A_REAL_SAP_SYSTEM', - }), +const sapSystemTypes = [ + 'ABAP', + 'J2EE', + 'ABAP|J2EE', + 'J2EE|ABAP', + 'SOME_SAP_SYSTEM_FEATURE|NOT_A_REAL_SYSTEM', ]; + +const sapSystemsWithDifferentTypes = sapSystemFactory + .buildList(5) + .map((sapSystem, index) => ({ + ...sapSystem, + application_instances: sapSystem.application_instances.map((instance) => ({ + ...instance, + features: sapSystemTypes[index], + })), + })); + const enrichedApplicationInstancesType = enrichInstances( sapSystemsWithDifferentTypes, 'application_instances' diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx index ac78fb99ad..a803ee4069 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx @@ -41,10 +41,8 @@ describe('SapSystemsOverviews component', () => { }); it('should display the correct content for a SAP system main row', () => { - const sapSystemType = 'ABAP'; const sapSystem = sapSystemFactory.build({ ensa_version: 'ensa1', - sap_system_type: sapSystemType, }); const { id: sapSystemID, @@ -57,11 +55,19 @@ describe('SapSystemsOverviews component', () => { database_sid: attachedRdbms, } = sapSystem; + const sapSystemType = 'ABAP'; + const modifiedApplicationInstances = applicationInstances.map( + (instance) => ({ + ...instance, + features: sapSystemType, + }) + ); + renderWithRouter( ); @@ -110,65 +116,41 @@ describe('SapSystemsOverviews component', () => { 'ABAP/JAVA', '', ]; - const sapSystems = [ - sapSystemFactory.build({ - sap_system_type: sapSystemTypes[0], - }), - sapSystemFactory.build({ - sap_system_type: sapSystemTypes[1], - }), - sapSystemFactory.build({ - sap_system_type: sapSystemTypes[2], - }), - sapSystemFactory.build({ - sap_system_type: sapSystemTypes[3], - }), - sapSystemFactory.build({ - sap_system_type: sapSystemTypes[4], - }), - ]; - const sapSystemApplicationInstances = [ - sapSystems[0].application_instances, - sapSystems[1].application_instances, - sapSystems[2].application_instances, - sapSystems[3].application_instances, - sapSystems[4].application_instances, - ].flat(); + const sapSystems = sapSystemFactory.buildList(5); + + const updatedSapSystemsApplication = sapSystems.map( + (sapSystem, index) => ({ + ...sapSystem, + application_instances: sapSystem.application_instances.map( + (instance) => ({ + ...instance, + features: sapSystemTypes[index], + }) + ), + }) + ); + + const sapSystemApplicationInstances = updatedSapSystemsApplication + .map((sapSystem) => sapSystem.application_instances) + .flat(); renderWithRouter( ); const rows = screen.getByRole('table').querySelectorAll('tbody > tr'); - const firstSapSystem = rows[0]; - const secondSapSystem = rows[2]; - const thirdSapSystem = rows[4]; - const fourthSapSystem = rows[6]; - const fifthSapSystem = rows[8]; - - expect(firstSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( - expectedSapSystemTypes[0] - ); - expect( - secondSapSystem.querySelector('td:nth-child(5)') - ).toHaveTextContent(expectedSapSystemTypes[1]); - - expect(thirdSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( - expectedSapSystemTypes[2] - ); - - expect( - fourthSapSystem.querySelector('td:nth-child(5)') - ).toHaveTextContent(expectedSapSystemTypes[3]); - - expect(fifthSapSystem.querySelector('td:nth-child(5)')).toHaveTextContent( - expectedSapSystemTypes[4] - ); + expectedSapSystemTypes.forEach((expectedType, index) => { + const rowIndex = index * 2; + const sapSystemRow = rows[rowIndex]; + expect(sapSystemRow.querySelector('td:nth-child(5)')).toHaveTextContent( + expectedType + ); + }); }); it('should display the correct content for a SAP system instances', () => { From 1602f552f4b806d237cf67c7e24788ea5ec796ed Mon Sep 17 00:00:00 2001 From: EMaksy Date: Mon, 29 Jul 2024 16:25:15 +0200 Subject: [PATCH 09/11] Refactor frontend code --- .../SapSystemsOverview.jsx | 11 +- .../SapSystemsOverview.stories.jsx | 37 +++---- .../SapSystemsOverview.test.jsx | 103 ++++++++++++------ 3 files changed, 89 insertions(+), 62 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx index 8fbdb17a0d..4243fa2b71 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx @@ -79,14 +79,9 @@ function SapSystemsOverview({ }, { title: 'Type', - key: 'type', - render: (_, items) => - uniq( - flatMap( - filter(items.applicationInstances, { sap_system_id: items.id }), - ({ features }) => features.split('|') - ) - ) + key: 'applicationInstances', + render: (content) => + uniq(flatMap(content, ({ features }) => features.split('|'))) .filter((item) => item === 'J2EE' || item === 'ABAP') .map((item) => (item === 'J2EE' ? 'JAVA' : item)) .toSorted() diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx index afc2a77a2f..f0eba5dd01 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx @@ -5,6 +5,7 @@ import { MemoryRouter } from 'react-router-dom'; import { clusterFactory, hostFactory, + sapSystemApplicationInstanceFactory, sapSystemFactory, } from '@lib/test-utils/factories'; @@ -19,6 +20,7 @@ const enrichInstances = (systems, instanceType) => const cluster = clusterFactory.build(); return { ...instance, + features: 'ABAP', host: { ...hostFactory.build({ id: instance.host_id, @@ -57,24 +59,19 @@ const sapSystemTypes = [ 'SOME_SAP_SYSTEM_FEATURE|NOT_A_REAL_SYSTEM', ]; -const sapSystemsWithDifferentTypes = sapSystemFactory - .buildList(5) - .map((sapSystem, index) => ({ - ...sapSystem, - application_instances: sapSystem.application_instances.map((instance) => ({ - ...instance, - features: sapSystemTypes[index], - })), - })); - -const enrichedApplicationInstancesType = enrichInstances( - sapSystemsWithDifferentTypes, - 'application_instances' -); -const enrichedAbsentDatabaseInstancesType = enrichInstances( - sapSystemsWithDifferentTypes, - 'database_instances' +const sapSystemIDList = sapSystemTypes.map((_) => faker.string.uuid()); +const sapSystemsWithCustomTypes = sapSystemTypes.map((type, index) => + sapSystemFactory.build({ + id: sapSystemIDList[index], + application_instances: sapSystemApplicationInstanceFactory.buildList(2, { + sap_system_id: sapSystemIDList[index], + features: type, + }), + }) ); +const sapSystemApplicationInstances = sapSystemsWithCustomTypes + .map((sapSystem) => sapSystem.application_instances) + .flat(); enrichedAbsentApplicationInstances[1].absent_at = faker.date .past() @@ -170,8 +167,8 @@ export const UnauthorizedCleanUp = { export const SapSystemsWithDifferentTypes = { args: { userAbilities, - sapSystems: sapSystemsWithDifferentTypes, - applicationInstances: enrichedApplicationInstancesType, - databaseInstances: enrichedAbsentDatabaseInstancesType, + sapSystems: sapSystemsWithCustomTypes, + applicationInstances: sapSystemApplicationInstances, + databaseInstances: {}, }, }; diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx index a803ee4069..ce95be1e2d 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx @@ -8,6 +8,7 @@ import userEvent from '@testing-library/user-event'; import { clusterFactory, hostFactory, + sapSystemApplicationInstanceFactory, sapSystemFactory, } from '@lib/test-utils/factories'; import { renderWithRouter } from '@lib/test-utils'; @@ -41,12 +42,19 @@ describe('SapSystemsOverviews component', () => { }); it('should display the correct content for a SAP system main row', () => { + const sapSystemType = 'ABAP'; + const sapSystemID = faker.string.uuid(); + const sapSystemSID = faker.string.uuid(); const sapSystem = sapSystemFactory.build({ + id: sapSystemID, + sid: sapSystemSID, ensa_version: 'ensa1', + application_instances: sapSystemApplicationInstanceFactory.buildList( + 2, + { sap_system_id: sapSystemID, features: sapSystemType } + ), }); const { - id: sapSystemID, - sid, tenant, db_host: dbAddress, application_instances: applicationInstances, @@ -55,26 +63,20 @@ describe('SapSystemsOverviews component', () => { database_sid: attachedRdbms, } = sapSystem; - const sapSystemType = 'ABAP'; - const modifiedApplicationInstances = applicationInstances.map( - (instance) => ({ - ...instance, - features: sapSystemType, - }) - ); - renderWithRouter( ); const rows = screen.getByRole('table').querySelectorAll('tbody > tr'); const mainRow = rows[0]; - expect(mainRow.querySelector('td:nth-child(2)')).toHaveTextContent(sid); + expect(mainRow.querySelector('td:nth-child(2)')).toHaveTextContent( + sapSystemSID + ); expect(mainRow.querySelector('td:nth-child(2) > a')).toHaveAttribute( 'href', `/sap_systems/${sapSystemID}` @@ -100,44 +102,33 @@ describe('SapSystemsOverviews component', () => { ); }); - it('should display the correct SAP system type', () => { + it('should display the correct SAP system type JAVA or ABAP', () => { const sapSystemTypes = [ 'ABAP', 'J2EE', - 'ABAP|J2EE', - 'J2EE|ABAP', 'SOME_SAP_SYSTEM_FEATURE|NOT_A_REAL_SYSTEM', ]; - const expectedSapSystemTypes = [ - 'ABAP', - 'JAVA', - 'ABAP/JAVA', - 'ABAP/JAVA', - '', - ]; - - const sapSystems = sapSystemFactory.buildList(5); + const expectedSapSystemTypes = ['ABAP', 'JAVA', '']; - const updatedSapSystemsApplication = sapSystems.map( - (sapSystem, index) => ({ - ...sapSystem, - application_instances: sapSystem.application_instances.map( - (instance) => ({ - ...instance, - features: sapSystemTypes[index], - }) + const sapSystemIDList = sapSystemTypes.map((_) => faker.string.uuid()); + const sapSystems = sapSystemTypes.map((type, index) => + sapSystemFactory.build({ + id: sapSystemIDList[index], + application_instances: sapSystemApplicationInstanceFactory.buildList( + 2, + { sap_system_id: sapSystemIDList[index], features: type } ), }) ); - const sapSystemApplicationInstances = updatedSapSystemsApplication + const sapSystemApplicationInstances = sapSystems .map((sapSystem) => sapSystem.application_instances) .flat(); renderWithRouter( { }); }); + it('should display the correct SAP system type JAVA and ABAP', () => { + const sapSystemTypes = [ + 'ABAP', + 'J2EE', + 'SOME_SAP_SYSTEM_FEATURE|OTHER_SAP_APP', + ]; + const expectedSapSystemTypes = 'ABAP/JAVA'; + const sapSystemID = faker.string.uuid(); + const sapSystemSID = faker.string.uuid(); + const sapSystem = sapSystemFactory.build({ + id: sapSystemID, + sid: sapSystemSID, + application_instances: [ + sapSystemApplicationInstanceFactory.build({ + sap_system_id: sapSystemID, + features: sapSystemTypes[0], + }), + sapSystemApplicationInstanceFactory.build({ + sap_system_id: sapSystemID, + features: sapSystemTypes[1], + }), + sapSystemApplicationInstanceFactory.build({ + sap_system_id: sapSystemID, + features: sapSystemTypes[2], + }), + ], + }); + + const { application_instances: applicationInstances } = sapSystem; + + renderWithRouter( + + ); + const rows = screen.getByRole('table').querySelectorAll('tbody > tr'); + expect(rows[0].querySelector('td:nth-child(5)')).toHaveTextContent( + expectedSapSystemTypes + ); + }); + it('should display the correct content for a SAP system instances', () => { const sapSystem = sapSystemFactory.build(); const { From d4d41547d8f1237ce1866541eb7e6a8105d02a69 Mon Sep 17 00:00:00 2001 From: EMaksy Date: Tue, 30 Jul 2024 09:20:22 +0200 Subject: [PATCH 10/11] Refactor test and story --- .../SapSystemsOverview.stories.jsx | 14 ++++---- .../SapSystemsOverview.test.jsx | 35 +++++++------------ 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx index f0eba5dd01..6646a864b6 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.stories.jsx @@ -59,16 +59,16 @@ const sapSystemTypes = [ 'SOME_SAP_SYSTEM_FEATURE|NOT_A_REAL_SYSTEM', ]; -const sapSystemIDList = sapSystemTypes.map((_) => faker.string.uuid()); -const sapSystemsWithCustomTypes = sapSystemTypes.map((type, index) => - sapSystemFactory.build({ - id: sapSystemIDList[index], +const sapSystemsWithCustomTypes = sapSystemTypes.map((type) => { + const sapSystemID = faker.string.uuid(); + return sapSystemFactory.build({ + id: sapSystemID, application_instances: sapSystemApplicationInstanceFactory.buildList(2, { - sap_system_id: sapSystemIDList[index], + sap_system_id: sapSystemID, features: type, }), - }) -); + }); +}); const sapSystemApplicationInstances = sapSystemsWithCustomTypes .map((sapSystem) => sapSystem.application_instances) .flat(); diff --git a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx index ce95be1e2d..81d796abc7 100644 --- a/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx +++ b/assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.test.jsx @@ -44,10 +44,9 @@ describe('SapSystemsOverviews component', () => { it('should display the correct content for a SAP system main row', () => { const sapSystemType = 'ABAP'; const sapSystemID = faker.string.uuid(); - const sapSystemSID = faker.string.uuid(); + const sapSystem = sapSystemFactory.build({ id: sapSystemID, - sid: sapSystemSID, ensa_version: 'ensa1', application_instances: sapSystemApplicationInstanceFactory.buildList( 2, @@ -61,6 +60,7 @@ describe('SapSystemsOverviews component', () => { database_instances: databaseInstances, database_id: databaseID, database_sid: attachedRdbms, + sid, } = sapSystem; renderWithRouter( @@ -74,9 +74,7 @@ describe('SapSystemsOverviews component', () => { const rows = screen.getByRole('table').querySelectorAll('tbody > tr'); const mainRow = rows[0]; - expect(mainRow.querySelector('td:nth-child(2)')).toHaveTextContent( - sapSystemSID - ); + expect(mainRow.querySelector('td:nth-child(2)')).toHaveTextContent(sid); expect(mainRow.querySelector('td:nth-child(2) > a')).toHaveAttribute( 'href', `/sap_systems/${sapSystemID}` @@ -111,16 +109,16 @@ describe('SapSystemsOverviews component', () => { const expectedSapSystemTypes = ['ABAP', 'JAVA', '']; - const sapSystemIDList = sapSystemTypes.map((_) => faker.string.uuid()); - const sapSystems = sapSystemTypes.map((type, index) => - sapSystemFactory.build({ - id: sapSystemIDList[index], + const sapSystems = sapSystemTypes.map((type) => { + const sapSystemID = faker.string.uuid(); + return sapSystemFactory.build({ + id: sapSystemID, application_instances: sapSystemApplicationInstanceFactory.buildList( 2, - { sap_system_id: sapSystemIDList[index], features: type } + { sap_system_id: sapSystemID, features: type } ), - }) - ); + }); + }); const sapSystemApplicationInstances = sapSystems .map((sapSystem) => sapSystem.application_instances) @@ -145,29 +143,22 @@ describe('SapSystemsOverviews component', () => { }); it('should display the correct SAP system type JAVA and ABAP', () => { - const sapSystemTypes = [ - 'ABAP', - 'J2EE', - 'SOME_SAP_SYSTEM_FEATURE|OTHER_SAP_APP', - ]; const expectedSapSystemTypes = 'ABAP/JAVA'; const sapSystemID = faker.string.uuid(); - const sapSystemSID = faker.string.uuid(); const sapSystem = sapSystemFactory.build({ id: sapSystemID, - sid: sapSystemSID, application_instances: [ sapSystemApplicationInstanceFactory.build({ sap_system_id: sapSystemID, - features: sapSystemTypes[0], + features: 'ABAP', }), sapSystemApplicationInstanceFactory.build({ sap_system_id: sapSystemID, - features: sapSystemTypes[1], + features: 'J2EE', }), sapSystemApplicationInstanceFactory.build({ sap_system_id: sapSystemID, - features: sapSystemTypes[2], + features: 'SOME_SAP_SYSTEM_FEATURE|OTHER_SAP_APP', }), ], }); From 6a61f6dcfcd6daaa686cacbf3417f1cae9c74e5a Mon Sep 17 00:00:00 2001 From: EMaksy Date: Tue, 30 Jul 2024 09:39:09 +0200 Subject: [PATCH 11/11] Add backend test for j2ee discovery --- test/trento/sap_systems/sap_system_test.exs | 115 +++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/test/trento/sap_systems/sap_system_test.exs b/test/trento/sap_systems/sap_system_test.exs index a19037b715..0b6459f9c6 100644 --- a/test/trento/sap_systems/sap_system_test.exs +++ b/test/trento/sap_systems/sap_system_test.exs @@ -124,6 +124,92 @@ defmodule Trento.SapSystems.SapSystemTest do ) end + test "should register a SAP System and add an application instance when a MESSAGESERVER instance is already present and a new JAVA instance is added" do + sap_system_id = Faker.UUID.v4() + sid = Faker.StarWars.planet() + db_host = Faker.Internet.ip_v4_address() + tenant = Faker.Beer.style() + instance_hostname = Faker.Airports.iata() + http_port = 80 + https_port = 443 + start_priority = "0.9" + host_id = Faker.UUID.v4() + ensa_version = EnsaVersion.ensa1() + java_system_type = "J2EE" + + initial_events = [ + build(:application_instance_registered_event, + sap_system_id: sap_system_id, + sid: sid, + features: "MESSAGESERVER", + instance_number: "00" + ) + ] + + assert_events_and_state( + initial_events, + RegisterApplicationInstance.new!(%{ + sap_system_id: sap_system_id, + sid: sid, + db_host: db_host, + tenant: tenant, + instance_number: "10", + instance_hostname: instance_hostname, + features: java_system_type, + http_port: http_port, + https_port: https_port, + start_priority: start_priority, + host_id: host_id, + health: :passing, + ensa_version: ensa_version, + database_health: :passing + }), + [ + %ApplicationInstanceRegistered{ + sap_system_id: sap_system_id, + sid: sid, + instance_number: "10", + instance_hostname: instance_hostname, + features: java_system_type, + http_port: http_port, + https_port: https_port, + start_priority: start_priority, + host_id: host_id, + health: :passing + }, + %SapSystemRegistered{ + sap_system_id: sap_system_id, + sid: sid, + db_host: db_host, + tenant: tenant, + health: :passing, + database_health: :passing, + ensa_version: ensa_version + } + ], + fn state -> + assert %SapSystem{ + sid: ^sid, + ensa_version: ^ensa_version, + database_health: :passing, + instances: [ + %Instance{ + sid: ^sid, + instance_number: "10", + features: ^java_system_type, + host_id: ^host_id, + health: :passing, + absent_at: nil + }, + %Instance{ + features: "MESSAGESERVER" + } + ] + } = state + end + ) + end + test "should move an application instance if the host_id changed and the instance number already exists and the application is clustered" do sap_system_id = Faker.UUID.v4() sid = fake_sid() @@ -1243,16 +1329,21 @@ defmodule Trento.SapSystems.SapSystemTest do end describe "tombstoning" do - test "should tombstone a deregistered SAP system when no application instances are left" do + test "should tombstone a deregistered SAP system when no ABAP or JAVA application instances are left" do sap_system_id = UUID.uuid4() deregistered_at = DateTime.utc_now() message_server_host_id = UUID.uuid4() message_server_instance_number = "00" abap_host_id = UUID.uuid4() + java_host_id = UUID.uuid4() abap_instance_number = "01" + java_instance_number = "02" application_sid = fake_sid() + # Sap System type + abap_system_type = "ABAP" + java_system_type = "J2EE" initial_events = [ build( @@ -1266,11 +1357,19 @@ defmodule Trento.SapSystems.SapSystemTest do build( :application_instance_registered_event, sap_system_id: sap_system_id, - features: "ABAP|GATEWAY|ICMAN|IGS", + features: abap_system_type, host_id: abap_host_id, sid: application_sid, instance_number: abap_instance_number ), + build( + :application_instance_registered_event, + sap_system_id: sap_system_id, + features: java_system_type, + host_id: java_host_id, + sid: application_sid, + instance_number: java_instance_number + ), build( :sap_system_registered_event, sap_system_id: sap_system_id, @@ -1292,6 +1391,12 @@ defmodule Trento.SapSystems.SapSystemTest do host_id: abap_host_id, instance_number: abap_instance_number, deregistered_at: deregistered_at + }, + %DeregisterApplicationInstance{ + sap_system_id: sap_system_id, + host_id: java_host_id, + instance_number: java_instance_number, + deregistered_at: deregistered_at } ], [ @@ -1311,6 +1416,12 @@ defmodule Trento.SapSystems.SapSystemTest do instance_number: abap_instance_number, deregistered_at: deregistered_at }, + %ApplicationInstanceDeregistered{ + sap_system_id: sap_system_id, + host_id: java_host_id, + instance_number: java_instance_number, + deregistered_at: deregistered_at + }, %SapSystemTombstoned{ sap_system_id: sap_system_id }