SET NOCOUNT ON SET QUOTED_IDENTIFIER ON DECLARE @ErrorTag NVARCHAR(20) = '###ERROR### ' DECLARE @WarningTag NVARCHAR(20) = '###WARNING### ' DECLARE @AdviceTag NVARCHAR(20) = '###ADVICE### ' DECLARE @DescTag NVARCHAR(20) = '###DESCRIPTION###' DECLARE @errorMsg NVARCHAR(MAX) = 'The CommServe does not have sufficient ' DECLARE @warningMsg NVARCHAR(MAX) = '' DECLARE @adviceWarnMsg NVARCHAR(MAX) = 'Make sure that the CommServe has the necessary permanent ' DECLARE @adviceMsg NVARCHAR(MAX) = 'Contact your Software Provider to obtain ' DECLARE @errorCode INT = 0 DECLARE @retCode INT = 0 DECLARE @isLicAvail INT = 1 DECLARE @FreePermLicensesAvailable INT = 0 DECLARE @FreeEvalLicensesAvailable INT = 0 DECLARE @TotalLicensesCount INT = 0 DECLARE @ExDAGAppType INT = 53 DECLARE @OracleRacAppType INT = 80 -- windows DECLARE @SharePointAppType INT = 78 DECLARE @MsSqlAG INT = 81 DECLARE @SapHanaAppType INT = 135 DECLARE @DB2AppType INT = 103 DECLARE @VsaAppType INT = 106 DECLARE @DistributedAppsAppType INT = 64 DECLARE @apptypeTable TABLE (t_PseudoApptype INT, t_PhysicalApptype INT, t_status INT, t_lic INT, t_attrName VARCHAR(256), t_AgentName VARCHAR(256)) DECLARE @appClass1Lic INT = 3 DECLARE @appClass3Lic INT = 16 DECLARE @appClass2Lic INT = 17 DECLARE @FSLic INT = 1 DECLARE @vsaLic INT = 143 DECLARE @licToConsume INT = 0 DECLARE @PermLicToRelease INT = 0 DECLARE @EvalLicToRelease INT = 0 DECLARE @currentTime BIGINT = 0 DECLARE @OracleDBAppType INT = 22 -- physical client apptype for oracle DECLARE @SapHanaPhysAppType INT = 136 -- physical client apptype for sap DECLARE @DB2PhysAppType INT = 62 -- physical client apptype for db2 SET @currentTime = dbo.GetUnixTime(GETUTCDATE()) PRINT @DescTag + ' Check for enough Licenses for Pseudo Clients' DECLARE @prevReleaseID INT = 0 select top 1 @prevReleaseID = id from simAllGalaxyRel order by id desc IF @prevReleaseID < 16 OR (@prevReleaseID = 16 AND (select TOP 1 HighestSP from simInstalledPackages where ClientId = 2 order by id desc) < 7) BEGIN INSERT INTO @apptypeTable VALUES(@ExDAGAppType, @ExDAGAppType, 0x200000, @appClass1Lic, '', 'Exchange Database'), (@OracleRacAppType, @OracleDBAppType, 0x0040, 0, '', 'Oracle Database'), (@MsSqlAG, @MsSqlAG, 0x20000000, @appClass1Lic, '', 'SQL Server'), (@SapHanaAppType, @SapHanaPhysAppType,0x2000000, @appClass3Lic, '', 'SAP HANA'), (@DB2AppType, @DB2PhysAppType, 0x0200, @appClass2Lic, '', 'DB2 on Unix'), (@SharePointAppType, @SharePointAppType, 0, @appClass1Lic, 'SharePoint Farm Client', 'SharePoint Server'), (@VsaAppType, @VsaAppType, 0, @vsaLic, 'Vs Member Servers', 'Virtual Server'), (@DistributedAppsAppType, 0, 0, @FSLic, 'Distributed iDA Client', 'Distributed Apps') DECLARE @PseudoClientsList TABLE(t_cid int, t_name VARCHAR(512), t_apptype int, t_lictype INT ) INSERT INTO @PseudoClientsList SELECT distinct AC.id, AC.name, t_PseudoApptype, t_lic FROM @apptypeTable, APP_Client AC WITH (NOLOCK) INNER JOIN APP_IDAName IDN WITH (NOLOCK) ON IDN.clientId = AC.id AND IDN.status&(2+4) = 0 WHERE (AC.status&t_status > 0) --SharePoint, Distributed Apps INSERT INTO @PseudoClientsList SELECT distinct AC.id, AC.name, t_PseudoApptype, t_lic FROM @apptypeTable, APP_ClientProp AP WITH (NOLOCK) INNER JOIN APP_Client AC WITH (NOLOCK) ON AP.componentNameId = AC.id INNER JOIN APP_IDAName IDN WITH (NOLOCK) ON IDN.clientId = AC.id AND IDN.status&(2+4) = 0 WHERE AP.attrName = t_attrName AND AP.attrval = '1' AND AP.modified = 0 AND LEN(AP.attrName) > 0 --VSA INSERT INTO @PseudoClientsList SELECT distinct AC.id, AC.name, t_PseudoApptype, t_lic FROM @apptypeTable, APP_INSTANCEPROP INS WITH (NOLOCK) INNER JOIN APP_Application APP WITH (NOLOCK) ON INS.componentNameId = APP.instance INNER JOIN APP_Client AC WITH (NOLOCK) on APP.clientId = AC.id INNER JOIN APP_IDAName IDN WITH (NOLOCK) on IDN.clientId = AC.id AND IDN.status&(2+4) = 0 WHERE INS.attrName = t_attrName AND INS.modified = 0 AND LEN(INS.attrName) > 0 -- delete the clients where license is already consumed DELETE @PseudoClientsList FROM LicUsage WHERE t_cid = cid AND AppType = t_apptype DECLARE @OracleRacphysicalClient TABLE(t_pseudoCid INT, t_physicalCid INT, t_simosId INT) INSERT INTO @OracleRacphysicalClient SELECT tmp.t_cid, rac.clientId, AC.simOperatingSystemId FROM @PseudoClientsList tmp JOIN APP_Application app WITH (NOLOCK) ON tmp.t_cid = app.clientId AND tmp.t_apptype = @OracleRacAppType JOIN APP_OracleRacInstance rac WITH (NOLOCK) ON rac.instaceId = app.instance JOIN APP_Client AC WITH (NOLOCK) ON AC.id = rac.clientId UPDATE T SET t_lictype = @appClass1Lic FROM @PseudoClientsList T JOIN @OracleRacphysicalClient tmp ON t_pseudoCid = t_cid JOIN simOperatingSystem OS WITH(NOLOCK) ON tmp.t_simosId = id AND Type = 'Windows' WHERE t_apptype = @OracleRacAppType UPDATE @PseudoClientsList SET t_lictype = @appClass2Lic WHERE t_lictype = 0 -- Determine where SharePoint 'SharePoint Member Servers' client properties are being stored for PreUpgrade Check DECLARE @SharePointMSLocation INT = 0 -- 0:Unknown, 1:APP_ClientProp, 2:APP_ComponentProp -- Original Location SELECT TOP 1 @SharePointMSLocation = 1 FROM APP_ClientProp CP WITH(NOLOCK) WHERE CP.attrName = N'SharePoint Member Servers' IF (@SharePointMSLocation <> 1) BEGIN -- New Location SELECT TOP 1 @SharePointMSLocation = 2 FROM -- Relocated 'SharePoint Member Servers' XML Document from APP_ClientProp to APP_ComponentProp Table since attrVal limited to max data size of NVARCHAR(1024) APP_ComponentProp CP WITH (NOLOCK) WHERE CP.componentType = 3 -- CV_COMPONENT_TYPE_CLIENT AND CP.propertyTypeId = 1046 -- CV_COMPONENT_SHAREPOINT_SECONDARY_MEMBER_SERVERS -- Old APP_ClientProp 'SharePoint Member Servers' END --Count license for physical client. DECLARE @PhysicalClientsList TABLE(t_cid int, t_apptype int ) INSERT INTO @PhysicalClientsList --RAC SELECT distinct I.clientId, t_PhysicalApptype FROM @apptypeTable tmp,APP_OracleRacInstance I WITH (NOLOCK) WHERE t_AgentName = 'Oracle Database' UNION ALL --Exchange DAG SELECT distinct AC.id, t_PhysicalApptype FROM @apptypeTable tmp,APP_ClientProp AP WITH (NOLOCK) JOIN APP_Client AC WITH (NOLOCK) ON AP.attrName = AC.net_hostname WHERE AP.attrType = 125 AND AP.modified = 0 AND t_AgentName = 'Exchange Database' UNION ALL -- DB2_DPF SELECT distinct t_pClientId, t_PhysicalApptype FROM @apptypeTable tmp, (SELECT t_pClientId = substring(T1.Data, CHARINDEX(',', T1.Data)+1, LEN(T1.Data)) FROM APP_InstanceProp IP WITH (NOLOCK) CROSS APPLY dbo.SplitString(IP.attrVal, ' ') T1 WHERE IP.attrName = 'DB2 Partition Clients' and IP.modified = 0 AND LEN(IP.attrVal) > 0 ) T2 WHERE t_AgentName = 'DB2 on Unix' UNION ALL --SharePoint SELECT distinct Cid, t_PhysicalApptype FROM @apptypeTable tmp, (SELECT CAST(AP.attrVal AS INT) AS cid FROM APP_ClientProp AP WITH (NOLOCK) WHERE AP.attrName = 'SharePoint Primary Member Server' AND LEN(AP.attrVal) > 0 AND AP.modified = 0) T WHERE t_AgentName = 'SharePoint Server' UNION SELECT distinct Cid, t_PhysicalApptype FROM @apptypeTable tmp, (SELECT p.value('@clientId', 'int') AS cid FROM APP_ClientProp AP WITH (NOLOCK) CROSS APPLY (select cast(attrVal as xml)) as X(X) CROSS APPLY X.nodes('App_MemberServers/memberServers/client') as P(P) WHERE AP.attrName = 'SharePoint Member Servers' AND LEN(AP.attrVal) > 0 AND AP.modified = 0 AND @SharePointMSLocation = 1) T WHERE t_AgentName = 'SharePoint Server' AND @SharePointMSLocation = 1 UNION SELECT distinct T.Cid, t_PhysicalApptype FROM @apptypeTable tmp, ( -- Relocated 'SharePoint Member Servers' XML Document from APP_ClientProp to APP_ComponentProp Table since attrVal limited to max data size of NVARCHAR(1024) SELECT DISTINCT P.value('@clientId', 'int') AS cid FROM APP_ComponentProp CP WITH (NOLOCK) CROSS APPLY (SELECT CAST(CP.stringVal as xml)) AS X(X) CROSS APPLY X.nodes('App_MemberServers/memberServers/client') AS P(P) WHERE CP.componentType = 3 -- CV_COMPONENT_TYPE_CLIENT AND CP.propertyTypeId = 1046 -- CV_COMPONENT_SHAREPOINT_SECONDARY_MEMBER_SERVERS -- Old APP_ClientProp 'SharePoint Member Servers' AND LEN(CP.stringVal) > 0 AND CP.modified = 0 AND @SharePointMSLocation = 2 ) T WHERE t_AgentName = 'SharePoint Server' AND @SharePointMSLocation = 2 UNION ALL --MSSqlAG SELECT distinct Cid, t_PhysicalApptype FROM @apptypeTable tmp, (SELECT p.value('@clientId', 'int') AS cid FROM APP_InstanceProp AP WITH (NOLOCK) CROSS APPLY (select cast(attrVal as xml)) as X(X) CROSS APPLY X.nodes('App_SQLAvailabilityReplicas/SQLAvailabilityReplicasList/replicaClient') as P(P) WHERE AP.attrName = 'Availability Replicas' AND LEN(AP.attrVal) > 0 AND AP.modified = 0) T WHERE t_AgentName = 'SQL Server' UNION ALL --VSA SELECT distinct Cid, t_PhysicalApptype FROM @apptypeTable tmp,LicUsage WITH (NOLOCK) WHERE AppType = t_PhysicalApptype AND t_AgentName = 'Virtual Server' UNION ALL -- SAP_HANA SELECT distinct t_pClientId, t_PhysicalApptype FROM @apptypeTable tmp,(SELECT t_pClientId = T1.Data FROM APP_InstanceProp IP WITH (NOLOCK) CROSS APPLY dbo.SplitString(IP.attrVal, '+') T1 WHERE IP.attrName = 'Database Clients' and IP.modified = 0 AND LEN(IP.attrVal) > 0 ) T2 WHERE t_AgentName = 'SAP HANA' --Remove pseudo clients from the list fetched which leave us with only proxy clients. DELETE @PhysicalClientsList FROM APP_Application app WITH (NOLOCK) JOIN app_instanceprop Iprop WITH (NOLOCK) ON app.instance = Iprop.componentNameId AND Iprop.attrName = 'Virtual Server Instance Type' AND LEN(Iprop.attrVal) > 0 AND Iprop.modified = 0 WHERE t_cid = clientId AND app.appTypeId = t_apptype AND t_apptype = 106 --Remove clients where data is backedup in DB DELETE @PhysicalClientsList FROM APP_Application app WITH (NOLOCK) JOIN archFile afile WITH (NOLOCK) ON app.id = afile.appId WHERE t_cid = app.clientId AND app.appTypeId = t_apptype DECLARE @totalLicCount TABLE(t_lictype INT, t_perm INT, t_eval INT) INSERT INTO @totalLicCount SELECT lictype, [0] AS Perm, [1] AS Eval FROM (SELECT cid,lictype,eval FROM LicUsage LU WITH (NOLOCK) JOIN @PhysicalClientsList tmp ON LU.cid = tmp.t_cid AND LU.appType = tmp.t_apptype WHERE opType = 'Install' AND (dbo.GetUnixTime(ExpiryDateUTC) = 0 OR dbo.GetUnixTime(ExpiryDateUTC) > @currentTime)) T pivot ( COUNT(cid) FOR eval in([0],[1]) ) AS P DECLARE LicenseCursor CURSOR LOCAL FORWARD_ONLY FOR SELECT DISTINCT t_lictype FROM @PseudoClientsList GROUP BY t_lictype OPEN LicenseCursor FETCH FROM LicenseCursor INTO @licToConsume WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @LicName NVARCHAR(256) = '' SET @TotalLicensesCount = 0 SET @TotalLicensesCount = (SELECT COUNT(distinct t_cid) FROM @PseudoClientsList WHERE t_lictype = @licToConsume) IF (@TotalLicensesCount = 0) BEGIN GOTO CONT END SELECT @LicName = short_name FROM simLicAppTypeV2 WHERE id = @licToConsume IF NOT EXISTS (SELECT * FROM licAAL WHERE simLicAppTypeId = @licToConsume) BEGIN SET @errorCode = 2 SET @errorMsg = @errorMsg + @LicName + ',' SET @adviceMsg = @adviceMsg + cast(@TotalLicensesCount as varchar(10) )+' more '+@LicName+',' GOTO CX_EXIT END DECLARE @retLicData TABLE ( licName varchar(1024), TotalPermLicensesIssued INTEGER, FreePermLicensesAvailable INTEGER, TotalEvalLicensesIssued INTEGER, FreeEvalLicensesAvailable INTEGER ) BEGIN TRY INSERT INTO @retLicData EXEC QS_GetLicenseInfo @LicName END TRY BEGIN CATCH --If extended SP are not found, skip the check GOTO CONT END CATCH SELECT @FreePermLicensesAvailable = FreePermLicensesAvailable , @FreeEvalLicensesAvailable = FreeEvalLicensesAvailable FROM @retLicData IF @FSLic <> @licToConsume BEGIN IF (@FreePermLicensesAvailable >= 0) SELECT @FreePermLicensesAvailable = @FreePermLicensesAvailable + t_perm FROM @totalLicCount WHERE t_lictype = @licToConsume IF (@FreeEvalLicensesAvailable >= 0) SELECT @FreeEvalLicensesAvailable = @FreeEvalLicensesAvailable + t_eval FROM @totalLicCount WHERE t_lictype = @licToConsume END /*CS has sufficient quantity*/ IF (@FreePermLicensesAvailable < 0) OR (@FreePermLicensesAvailable >= @TotalLicensesCount) BEGIN GOTO CONT END IF (@FreeEvalLicensesAvailable < 0) OR ( @FreePermLicensesAvailable + @FreeEvalLicensesAvailable >= @TotalLicensesCount) BEGIN SET @warningMsg = @warningMsg + cast( (@TotalLicensesCount - @FreePermLicensesAvailable) as varchar(10) ) + ' Pseudo clients will consume '+@LicName+' Evaluation licenses' SET @warningMsg = @warningMsg + CHAR(13) + CHAR(10) SET @adviceWarnMsg = @adviceWarnMsg + @LicName + ',' IF @errorCode = 0 SET @errorCode = 1 GOTO CONT END ELSE BEGIN SET @errorMsg = @errorMsg + @LicName + ',' SET @adviceMsg = @adviceMsg + cast((@TotalLicensesCount - @FreePermLicensesAvailable) as varchar(10) )+' more '+@LicName+',' SET @errorCode = 2 GOTO CONT END CONT: FETCH FROM LicenseCursor INTO @licToConsume END CX_EXIT: BEGIN IF @errorCode = 2 BEGIN PRINT @ErrorTag + LEFT(@errorMsg, LEN(@errorMsg) - 1) + ' licenses for pseudo clients.' PRINT @AdviceTag + LEFT(@adviceMsg, LEN(@adviceMsg) - 1) + ' licenses' PRINT CHAR(13) + CHAR(10) IF @warningMsg <> '' BEGIN PRINT @WarningTag + @warningMsg PRINT @AdviceTag + LEFT(@adviceWarnMsg, LEN(@adviceWarnMsg) - 1) + ' licenses' END END ELSE IF @errorCode = 1 BEGIN PRINT @WarningTag +@warningMsg PRINT @AdviceTag + LEFT(@adviceWarnMsg, LEN(@adviceWarnMsg) - 1) + ' licenses' END END END SELECT @errorCode