m_aRequested = [ 'plannedcontacts' => $iPlannedContacts, 'plannedcontracts' => $iPlannedContracts, ]; $this->m_aPlanned = [ 'Contacts' => $iPlannedContacts, 'Contracts' => $iPlannedContracts, 'Documents' => $iPlannedContracts * 2, ]; } public function PlanCis($iPlannedCIs) { $this->m_aRequested = [ 'plannedcis' => $iPlannedCIs, ]; $this->m_iIfByServer = 2; $this->m_iIfByNWDevice = 10; $iServers = ceil($iPlannedCIs * 9 / 10); $iNWDevices = ceil($iPlannedCIs / 10); $iInterfaces = $iServers * $this->m_iIfByServer + $iNWDevices * $this->m_iIfByNWDevice; $iApplications = $iServers * 5; $iSolutions = ceil($iApplications / 2); $iProcesses = ceil($iSolutions / 2); $this->m_aPlanned = [ 'Network devices' => $iNWDevices, 'Servers' => $iServers, 'Interfaces' => $iInterfaces, 'Application SW' => 2, 'Applications' => $iApplications, 'Solutions' => $iSolutions, 'Processes' => $iProcesses, ]; } public function PlanTickets($iPlannedTickets, $iBigTicketCis) { $this->m_aRequested = [ 'plannedtickets' => $iPlannedTickets, 'plannedbigticketcis' => $iBigTicketCis, ]; $this->m_aPlanned = [ 'Incidents' => ceil($iPlannedTickets / 2), 'Changes' => ceil($iPlannedTickets / 2), 'Big ticket: CIs' => $iBigTicketCis, ]; } public function ShowPlans($oP) { $oP->add("

Planned creations

\n"); $aPlanned = $this->m_aPlanned; $aForm = []; foreach ($aPlanned as $sKey => $iCount) { $aForm[] = [ 'label' => $sKey, 'input' => $iCount, ]; } $oP->form($aForm); } public function ShowForm($oP, $sNextOperation) { $aRequested = $this->m_aRequested; $oP->add("
\n"); $oP->add("\n"); foreach ($this->m_aRequested as $sName => $sValue) { $oP->add("\n"); } $oP->add("\n"); $oP->add("
\n"); } protected function CreateObject($sClass, $aData, $sClassDesc = '') { $mu_t1 = MyHelpers::getmicrotime(); $oMyObject = MetaModel::NewObject($sClass); foreach ($aData as $sProp => $value) { if (is_array($value)) { // transform into a link set $sCSVSpec = implode('|', $value); $oAttDef = MetaModel::GetAttributeDef($sClass, $sProp); $value = $oAttDef->MakeValueFromString($sCSVSpec, $bLocalizedValue = false, $sSepItem = '|', $sSepAttribute = ';', $sSepValue = ':', $sAttributeQualifier = '"'); } $oMyObject->Set($sProp, $value); } $iId = $oMyObject->DBInsertNoReload(); $sClassId = "$sClass ($sClassDesc)"; $this->m_aCreatedByDesc[$sClassId][] = $iId; $this->m_aCreatedByClass[$sClass][] = $iId; $mu_t2 = MyHelpers::getmicrotime(); $this->m_aStatsByClass[$sClass][] = $mu_t2 - $mu_t1; return $iId; } public static $m_aClassIdCache = []; protected function GetClassIds($sClass) { if (!isset(self::$m_aClassIdCache[$sClass])) { // Load the cache now self::$m_aClassIdCache[$sClass] = []; $oSet = new DBObjectSet(new DBObjectSearch($sClass)); while ($oObj = $oSet->Fetch()) { self::$m_aClassIdCache[$sClass][] = $oObj->GetKey(); } } return self::$m_aClassIdCache[$sClass]; } protected function RandomId($sClass, $sClassDesc = '') { $sClassId = "$sClass ($sClassDesc)"; if (isset($this->m_aCreatedByDesc[$sClassId])) { return $this->m_aCreatedByDesc[$sClassId][array_rand($this->m_aCreatedByDesc[$sClassId])]; } $aIds = self::GetClassIds($sClass); return $aIds[array_rand($aIds)]; } protected static function FindId($sClass) { $oSet = new DBObjectSet(new DBObjectSearch($sClass)); if ($oSet->Count() < 1) { return null; } $oObj = $oSet->Fetch(); return $oObj->GetKey(); } protected static function FindIdFromOQL($sOQL) { $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL)); if ($oSet->Count() < 1) { return null; } $oObj = $oSet->Fetch(); return $oObj->GetKey(); } protected function my_array_rand($aData, $iCount) { if ($iCount == 0) { return []; } elseif ($iCount == 1) { // array_rand() for one item returns only the key $key = array_rand($aData); $aSample = [$key]; } elseif ($iCount <= count($aData)) { $aSample = array_rand($aData, $iCount); } else { $aSample = array_merge(array_keys($aData), self::my_array_rand($aData, $iCount - count($aData))); } return $aSample; } protected function CreateLinks($iFrom, $iCount, $sLinkClass, $sAttCodeFrom, $sAttCodeTo) { $oAttTo = MetaModel::GetAttributeDef($sLinkClass, $sAttCodeTo); $sToClass = $oAttTo->GetTargetClass(); $aTargets = self::GetClassIds($sToClass); $aSample = self::my_array_rand($aTargets, $iCount); foreach ($aSample as $key) { $aData = [ $sAttCodeFrom => $iFrom, $sAttCodeTo => $aTargets[$key], ]; $this->CreateObject($sLinkClass, $aData); } } public function CreateStructure($oP) { $aClasses = MetaModel::GetClasses(); $aActions = ['Read', 'Bulk Read', 'Delete', 'Bulk Delete', 'Modify', 'Bulk Modify']; $aStdProfiles = [2, 3, 4, 5, 6, 7, 8, 9]; //////////////////////////////////////// // New specific profile, giving access to everything // $aData = [ 'name' => 'Data guru', 'description' => 'Could do anything, because everything is granted', ]; $iGuruProfile = $this->CreateObject('URP_Profiles', $aData); foreach ($aClasses as $sClass) { foreach ($aActions as $sAction) { $aData = [ 'profileid' => $iGuruProfile, 'class' => $sClass, 'permission' => 'yes', 'action' => $sAction, ]; $this->CreateObject('URP_ActionGrant', $aData); } } // User login with super access rights // $aData = [ 'org_id' => self::FindId('Organization'), 'location_id' => self::FindId('Location'), 'first_name' => 'Jesus', 'name' => 'Deus', 'email' => 'guru@combodo.com', ]; $iPerson = $this->CreateObject('Person', $aData); $aData = [ 'contactid' => $iPerson, 'login' => 'guru', 'password' => 'guru', 'language' => 'EN US', 'profile_list' => ["profileid:$iGuruProfile;reason:he is the one"], ]; $iLogin = $this->CreateObject('UserLocal', $aData); //////////////////////////////////////// // User login having all std profiles // $aData = [ 'org_id' => self::FindId('Organization'), 'location_id' => self::FindId('Location'), 'first_name' => 'Little ze', 'name' => 'Foo', 'email' => 'foo@combodo.com', ]; $iPerson = $this->CreateObject('Person', $aData); $aProfileSet = []; foreach ($aStdProfiles as $iProfileId) { $aProfileSet[] = "profileid:$iProfileId;reason:xxx"; } $aData = [ 'contactid' => $iPerson, 'login' => 'foo', 'password' => 'foo', 'language' => 'EN US', 'profile_list' => $aProfileSet, ]; $iLogin = $this->CreateObject('UserLocal', $aData); ///////////////////////// // // Organizations // $aData = [ 'name' => 'Benchmark', ]; $iOrg = $this->CreateObject('Organization', $aData); ///////////////////////// // // Locations // $aData = [ 'org_id' => $iOrg, 'name' => 'Rio de Janeiro', ]; $iLoc = $this->CreateObject('Location', $aData); ///////////////////////// // // Teams // $aData = [ 'org_id' => $iOrg, 'location_id' => $iLoc, 'name' => 'Fluminense', 'email' => 'fluminense@combodo.com', ]; $iTeam = $this->CreateObject('Team', $aData); ///////////////////////// // // Persons // for ($i = 0 ; $i < $this->m_aPlanned['Contacts'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'location_id' => $iLoc, 'first_name' => 'JoaƵ', 'name' => 'Ningem #'.$i, 'email' => 'foo'.$i.'@nowhere.fr', ]; $iPerson = $this->CreateObject('Person', $aData); // Contract/Infra // $aData = [ 'contact_id' => $iPerson, 'team_id' => $this->RandomId('Team'), ]; $this->CreateObject('lnkTeamToContact', $aData); } ///////////////////////// // // Services // $aData = [ 'org_id' => $iOrg, 'name' => 'My Service', ]; $iService = $this->CreateObject('Service', $aData); ///////////////////////// // // Service subcategories // $aData = [ 'name' => 'My subcategory', 'service_id' => $iService, ]; $iOrg = $this->CreateObject('ServiceSubcategory', $aData); ///////////////////////// // // Contracts // for ($i = 0 ; $i < $this->m_aPlanned['Contracts'] ; $i++) { $aData = [ 'name' => "Contract #$i", 'description' => 'Created for benchmarking purposes', 'org_id' => $this->RandomId('Organization'), 'provider_id' => $this->RandomId('Organization'), 'start_date' => '2009-12-25', 'end_date' => '2019-08-01', 'support_team_id' => $this->RandomId('Team'), ]; $iContract = $this->CreateObject('CustomerContract', $aData); // Contract/Contact (10% of contacts) // $iContactCount = ceil($this->m_aPlanned['Contracts'] / 10); for ($iLinked = 0 ; $iLinked < $iContactCount ; $iLinked++) { $aData = [ 'contact_id' => $this->RandomId('Person'), 'contract_id' => $iContract, 'role' => 'role '.$iLinked, ]; $this->CreateObject('lnkContractToContact', $aData); } } ///////////////////////// // // Documents // $sMyDoc = ''; for ($i = 0 ; $i < 1000 ; $i++) { // 100 chars $sMyDoc .= "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n"; } $oRefDoc = new ormDocument($sMyDoc, 'text/plain'); for ($i = 0 ; $i < $this->m_aPlanned['Documents'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'name' => "document$i", 'contents' => $oRefDoc, ]; $this->CreateObject('FileDoc', $aData); } } public function CreateCis($oP) { $iOrg = $this->FindIdFromOQL("SELECT Organization WHERE name = 'Benchmark'"); $iLoc = $this->FindIdFromOQL("SELECT Location WHERE org_id = $iOrg"); ///////////////////////// // // Servers // for ($i = 0 ; $i < $this->m_aPlanned['Servers'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'location_id' => $iLoc, 'name' => 'server'.$i, 'status' => 'production', ]; $iServer = $this->CreateObject('Server', $aData); // Contract/Infra $this->CreateLinks($iServer, 1, 'lnkContractToCI', 'ci_id', 'contract_id'); // Interfaces for ($iLinked = 0 ; $iLinked < $this->m_iIfByServer ; $iLinked++) { $aData = [ 'name' => "eth$iLinked", 'status' => 'implementation', 'org_id' => $iOrg, 'device_id' => $iServer, 'status' => 'production', ]; $this->CreateObject('NetworkInterface', $aData, 'server if'); } } ///////////////////////// // // Network devices // for ($i = 0 ; $i < $this->m_aPlanned['Network devices'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'location_id' => $iLoc, 'name' => 'equipment #'.$i, 'status' => 'production', ]; $iNWDevice = $this->CreateObject('NetworkDevice', $aData); // Contract/Infra $this->CreateLinks($iNWDevice, 1, 'lnkContractToCI', 'ci_id', 'contract_id'); // Interfaces // for ($iLinked = 0 ; $iLinked < $this->m_iIfByNWDevice ; $iLinked++) { $aData = [ 'name' => "eth$iLinked", 'status' => 'implementation', 'org_id' => $iOrg, 'device_id' => $iNWDevice, 'connected_if' => $this->RandomId('NetworkInterface', 'server if'), 'status' => 'production', ]; $this->CreateObject('NetworkInterface', $aData, 'equipment if'); } } ///////////////////////// // // Application Software // for ($i = 0 ; $i < $this->m_aPlanned['Application SW'] ; $i++) { $aData = [ 'name' => 'Software #'.$i, ]; $iNWDevice = $this->CreateObject('Application', $aData); } ///////////////////////// // // Applications // for ($i = 0 ; $i < $this->m_aPlanned['Applications'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'device_id' => $this->RandomId('Server'), 'software_id' => $this->RandomId('Application'), 'name' => 'Application #'.$i, 'status' => 'production', ]; $iAppInstance = $this->CreateObject('ApplicationInstance', $aData); // Contract/Infra $this->CreateLinks($iAppInstance, 1, 'lnkContractToCI', 'ci_id', 'contract_id'); } ///////////////////////// // // Application Solution // for ($i = 0 ; $i < $this->m_aPlanned['Solutions'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'name' => 'Solution #'.$i, 'status' => 'production', ]; $iAppSolution = $this->CreateObject('ApplicationSolution', $aData); // Contract/Infra $this->CreateLinks($iAppSolution, 1, 'lnkContractToCI', 'ci_id', 'contract_id'); } ///////////////////////// // // Business Process // for ($i = 0 ; $i < $this->m_aPlanned['Processes'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'name' => 'Process #'.$i, 'status' => 'production', ]; $iProcess = $this->CreateObject('BusinessProcess', $aData); // Contract/Infra $this->CreateLinks($iProcess, 1, 'lnkContractToCI', 'ci_id', 'contract_id'); } } public function CreateTickets($oP) { $iOrg = $this->FindIdFromOQL("SELECT Organization WHERE name = 'Benchmark'"); $iLoc = $this->FindIdFromOQL("SELECT Location WHERE org_id = $iOrg"); ///////////////////////// // // Incident Tickets // for ($i = 0 ; $i < $this->m_aPlanned['Incidents'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'caller_id' => $this->RandomId('Person'), 'workgroup_id' => $this->RandomId('Team'), 'agent_id' => $this->RandomId('Person'), 'service_id' => $this->RandomId('Service'), 'servicesubcategory_id' => $this->RandomId('ServiceSubcategory'), 'title' => 'Incident #'.$i, 'description' => 'O que aconteceu?', 'ticket_log' => 'Testing...', ]; $iTicket = $this->CreateObject('Incident', $aData); // Incident/Infra $iInfraCount = rand(1, 6); $this->CreateLinks($iTicket, $iInfraCount, 'lnkTicketToCI', 'ticket_id', 'ci_id'); // Incident/Infra $iContactCount = rand(1, 6); $this->CreateLinks($iTicket, $iContactCount, 'lnkTicketToContact', 'ticket_id', 'contact_id'); } ///////////////////////// // // Big Ticket // $aData = [ 'org_id' => $iOrg, 'caller_id' => $this->RandomId('Person'), 'workgroup_id' => $this->RandomId('Team'), 'agent_id' => $this->RandomId('Person'), 'service_id' => $this->RandomId('Service'), 'servicesubcategory_id' => $this->RandomId('ServiceSubcategory'), 'title' => 'Big ticket', 'description' => 'O que aconteceu?', 'ticket_log' => 'Testing...', ]; $iTicket = $this->CreateObject('Incident', $aData); // Incident/Infra $iInfraCount = $this->m_aPlanned['Big ticket: CIs']; $this->CreateLinks($iTicket, $iInfraCount, 'lnkTicketToCI', 'ticket_id', 'ci_id'); // Incident/Infra $iContactCount = rand(1, 6); $this->CreateLinks($iTicket, $iContactCount, 'lnkTicketToContact', 'ticket_id', 'contact_id'); ///////////////////////// // // Change Tickets // for ($i = 0 ; $i < $this->m_aPlanned['Changes'] ; $i++) { $aData = [ 'org_id' => $iOrg, 'requestor_id' => $this->RandomId('Person'), 'workgroup_id' => $this->RandomId('Team'), 'agent_id' => $this->RandomId('Person'), 'supervisor_group_id' => $this->RandomId('Team'), 'supervisor_id' => $this->RandomId('Person'), 'manager_group_id' => $this->RandomId('Team'), 'manager_id' => $this->RandomId('Person'), 'title' => 'change #'.$i, 'description' => "Let's do something there", ]; $iTicket = $this->CreateObject('NormalChange', $aData); // Incident/Infra $iInfraCount = rand(1, 6); $this->CreateLinks($iTicket, $iInfraCount, 'lnkTicketToCI', 'ticket_id', 'ci_id'); // Incident/Infra $iContactCount = rand(1, 6); $this->CreateLinks($iTicket, $iContactCount, 'lnkTicketToContact', 'ticket_id', 'contact_id'); } } public function MakeFeedback($oP) { foreach ($this->m_aCreatedByClass as $sClass => $aClassIds) { $iSample = reset($aClassIds); $sSample = "sample"; $iDuration = number_format(array_sum($this->m_aStatsByClass[$sClass]), 3); $fDurationMin = number_format(min($this->m_aStatsByClass[$sClass]), 3); $fDurationMax = number_format(max($this->m_aStatsByClass[$sClass]), 3); $fDurationAverage = number_format(array_sum($this->m_aStatsByClass[$sClass]) / count($this->m_aStatsByClass[$sClass]), 3); $oP->add(""); } } } /** * Ask the user what are the settings for the data load */ function DisplayStep1(SetupPage $oP) { $sNextOperation = 'step2'; $oP->add("

iTop benchmarking

\n"); $oP->add("
\n"); $oP->add("
Data load configuration\n"); $aForm = []; $aForm[] = [ 'label' => "Contacts:", 'input' => "", 'help' => '', ]; $aForm[] = [ 'label' => "Contracts:", 'input' => "", 'help' => '', ]; $oP->form($aForm); $oP->add("
\n"); $oP->add("\n"); $oP->add("\n"); $oP->add("
\n"); $oP->add("
\n"); $oP->add("
Data load configuration\n"); $aForm = []; $aForm[] = [ 'label' => "Main CIs:", 'input' => "", 'help' => ' exclude interfaces, subnets or any other type of secondary CI', ]; $oP->form($aForm); $oP->add("
\n"); $oP->add("\n"); $oP->add("\n"); $oP->add("
\n"); $oP->add("
\n"); $oP->add("
Data load configuration\n"); $aForm = []; $aForm[] = [ 'label' => "Tickets:", 'input' => "", 'help' => ' 50% incidents, 50% changes', ]; $aForm[] = [ 'label' => "CIs for the big ticket:", 'input' => "", 'help' => 'Number of CI for the single big ticket', ]; $oP->form($aForm); $oP->add("
\n"); $oP->add("\n"); $oP->add("\n"); $oP->add("
\n"); } /** * Main program */ LoginWebPage::DoLogin(); // Check user rights and prompt if needed $sOperation = Utils::ReadParam('operation', 'step1'); $oP = new SetupPage('iTop benchmark utility'); ExecutionKPI::EnableDuration(); $oKPI = new ExecutionKPI(); try { switch ($sOperation) { case 'step1': DisplayStep1($oP); break; case 'create_structure': $oP->no_cache(); $oP->add_http_headers('DENY'); $iPlannedContacts = Utils::ReadParam('plannedcontacts'); $iPlannedContracts = Utils::ReadParam('plannedcontracts'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanStructure($iPlannedContacts, $iPlannedContracts); $oDataCreation->ShowPlans($oP); $oDataCreation->ShowForm($oP, 'create_structure_go'); break; case 'create_structure_go': $oP->no_cache(); $iPlannedContacts = Utils::ReadParam('plannedcontacts'); $iPlannedContracts = Utils::ReadParam('plannedcontracts'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanStructure($iPlannedContacts, $iPlannedContracts); $oDataCreation->CreateStructure($oP); $oDataCreation->MakeFeedback($oP); break; case 'create_cis': $oP->no_cache(); $iPlannedCIs = Utils::ReadParam('plannedcis'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanCis($iPlannedCIs); $oDataCreation->ShowPlans($oP); $oDataCreation->ShowForm($oP, 'create_cis_go'); break; case 'create_cis_go': $oP->no_cache(); $iPlannedCIs = Utils::ReadParam('plannedcis'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanCis($iPlannedCIs); $oDataCreation->CreateCis($oP); $oDataCreation->MakeFeedback($oP); break; case 'create_tickets': $oP->no_cache(); $iPlannedTickets = Utils::ReadParam('plannedtickets'); $iBigTicketCis = Utils::ReadParam('plannedbigticketcis'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis); $oDataCreation->ShowPlans($oP); $oDataCreation->ShowForm($oP, 'create_tickets_go'); break; case 'create_tickets_go': $oP->no_cache(); $iPlannedTickets = Utils::ReadParam('plannedtickets'); $iBigTicketCis = Utils::ReadParam('plannedbigticketcis'); $oDataCreation = new BenchmarkDataCreation(); $oDataCreation->PlanTickets($iPlannedTickets, $iBigTicketCis); $oDataCreation->CreateTickets($oP); $oDataCreation->MakeFeedback($oP); break; default: $oP->error("Error: unsupported operation '$sOperation'"); } } catch (ZZException $e) { $oP->error("Error: '".$e->getMessage()."'"); } catch (ZZCoreException $e) { $oP->error("Error: '".$e->getHtmlDesc()."'"); } $oKPI->ComputeAndReport('Total execution'); //DBSearch::RecordQueryTrace(); $oP->output();