/** * Delete the given NGI and cascade delete all of the NGI's child entities. * These include Sites, Services, EndpointLocations, Downtimes that will be * orphaned, CertificationStatusLogs and Roles that previously linked to the * deleted owned entities. * * @param \NGI $ngi * @param \User $user - must be an admin user * @param boolean $logNgiSiteServiceInArchives Record the deletion of the ngi, * its child sites and services in the archive tables. * @throws \org\gocdb\services\Exception */ public function deleteNgi(\NGI $ngi, \User $user = null, $logNgiSiteServiceInArchives = true) { require_once __DIR__ . '/../DAOs/SiteDAO.php'; require_once __DIR__ . '/../DAOs/ServiceDAO.php'; require_once __DIR__ . '/../DAOs/NGIDAO.php'; require_once __DIR__ . '/ServiceService.php'; //Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); //Throws exception if user is not an administrator $this->checkUserIsAdmin($user); $this->em->getConnection()->beginTransaction(); try { $ngiDAO = new \NGIDAO(); $ngiDAO->setEntityManager($this->em); $siteDAO = new \SiteDAO(); $siteDAO->setEntityManager($this->em); $serviceDAO = new \ServiceDAO(); $serviceDAO->setEntityManager($this->em); //Archive ngi if ($logNgiSiteServiceInArchives) { $ngiDAO->addNGIToArchive($ngi, $user); } //delete each child site foreach ($ngi->getSites() as $site) { //Archive site if ($logNgiSiteServiceInArchives) { $siteDAO->addSiteToArchive($site, $user); } //delete each child service foreach ($site->getServices() as $service) { //archive the srvice if ($logNgiSiteServiceInArchives) { $serviceDAO->addServiceToArchive($service, $user); } //remove the service (and any downtimes only associated with it) $serviceDAO->removeService($service); } //remove the site $siteDAO->removeSite($site); } //remove the NGI $ngiDAO->removeNGI($ngi); $this->em->flush(); $this->em->getConnection()->commit(); } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); throw $e; } }
/** * Deletes a service * @param \Service $s To be deleted * @param \User $user Making the request * @param $isTest when unit testing this allows for true to be supplied and this method * will not attempt to archive the service which can easily cause errors for service objects without * a full set of information * @throws \Exception If user can't be authorized */ public function deleteService(\Service $s, \User $user = null, $isTest = false) { require_once __DIR__ . '/../DAOs/ServiceDAO.php'; //Check the portal is not in read only mode, throws exception if it is $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user); //$this->editAuthorization($se, $user); if (count($this->authorizeAction(\Action::EDIT_OBJECT, $s, $user)) == 0) { throw new \Exception("You do not have permission to remove" . $s->getHostName()); } $this->em->getConnection()->beginTransaction(); try { $serviceDAO = new \ServiceDAO(); $serviceDAO->setEntityManager($this->em); //Archive site - if this is a test then don't archive if ($isTest == false) { //Create entry in audit table $serviceDAO->addServiceToArchive($s, $user); } //Break links with downtimes and remove downtimes only associated //with this service, then remove service $serviceDAO->removeService($s); $this->em->flush(); $this->em->getConnection()->commit(); } catch (\Exception $e) { $this->em->getConnection()->rollback(); $this->em->close(); throw $e; } }
/** * Delete both services and enure the DAO cascade deletes both servcies * joined endpoints and downtimes, leaving only the sites and the single orphan downtime. */ public function testServiceDAO_removeService1And2AndJoinedDTs() { print __METHOD__ . "\n"; include __DIR__ . '/resources/sampleFixtureData4.php'; $serviceDao = new ServiceDAO(); $serviceDao->setEntityManager($this->em); $serviceDao->removeService($service2); $serviceDao->removeService($service1); $this->em->flush(); // use DB connection to check data has been deleted $con = $this->getConnection(); $result = $con->createQueryTable('results_table', "SELECT * FROM EndpointLocations"); $this->assertTrue($result->getRowCount() == 0); $result = $con->createQueryTable('results_table', "SELECT * FROM Downtimes"); $this->assertTrue($result->getRowCount() == 1); // orphanDT $result = $con->createQueryTable('results_table', "SELECT * FROM Sites"); $this->assertTrue($result->getRowCount() == 2); // site1 and site2 }
/** * Delete both Services but not the ngi * @see testRolesCascadeDelete_OnOwnedEntityDeletion1 */ public function testRolesCascadeDelete_OnOwnedEntityDeletion2() { print __METHOD__ . "\n"; include __DIR__ . '/resources/sampleFixtureData1.php'; $siteDAO = new SiteDAO(); $serviceDAO = new ServiceDAO(); $ngiDAO = new NGIDAO(); $siteDAO->setEntityManager($this->em); $serviceDAO->setEntityManager($this->em); $ngiDAO->setEntityManager($this->em); // ordering of removal is NOT significant here ! $serviceDAO->removeService($service1); $serviceDAO->removeService($service2); $siteDAO->removeSite($site1); $siteDAO->removeSite($site2); //$ngiDAO->removeNGI($ngi); // don't remove NGI $this->em->flush(); // Need to clear the identity map (all objects become detached) so that // when we re-fetch the user, it will be looked from db not served by entity map $this->em->clear(); // Need to re-fetch the user from the DB again, if don't, then user already // has his eargerly fetched roles present in UserProxy object $userWithRoles = $this->em->find("User", $userId); // user should have 2 remaining roles still from ngi $this->assertEquals(2, count($userWithRoles->getRoles())); $testConn = $this->getConnection(); $result = $testConn->createQueryTable('results_table', "SELECT * FROM Roles"); $this->assertTrue($result->getRowCount() == 2); $result = $testConn->createQueryTable('results_table', "SELECT * FROM NGIs"); $this->assertTrue($result->getRowCount() == 1); }
/** * Test the ServiceDAO->removeService(); * Impt: A cascade=remove is configured between Service and EndpointLocation * so that when a Service is removed, its associated ELs are also removed. * <p> * Note, no cascade remove behaviour is configured between EndpointLocation and * Downtime because we need to have fine-grained programmatic control over * which downtimes are deleted when a service EL is deleted (i.e. we only * want to delete those DTs that exclusively link to one EL only and which * would subsequently be orphaned). We do this managed deletion of DTs in ServiceDAO->removeService(); */ public function testServiceDAO_removeService() { print __METHOD__ . "\n"; include __DIR__ . '/resources/sampleFixtureData1.php'; // Impt: When deleting a service, we can't rely solely on the // 'onDelete=cascade' defined on the 'EndpointLocation->service' // to correctly cascade-delete the EL. This is because downtimes can also be linked // to the EL. Therefore, if we don't invoke an $em->remove() on the EL // (either via cascade="remove" or manually invoking em->remove() on each EL), // Doctrine will not have flagged the EL as removed and so will not automatically delete the // relevant row(s) in 'DOWNTIMES_ENDPOINTLOCATIONS' join table. // This would cause a FK integrity/violation constraint exception // on the 'DOWNTIMES_ENDPOINTLOCATIONS.ENDPOINTLOCATION_ID' FK column. // This is why we need to do a managed delete using the ServiceDAO $serviceDao = new ServiceDAO(); $serviceDao->setEntityManager($this->em); $serviceDao->removeService($service1); $this->em->flush(); // use DB connection to check data has been deleted $con = $this->getConnection(); $result = $con->createQueryTable('results_table', "SELECT * FROM EndpointLocations"); $this->assertTrue($result->getRowCount() == 0); $result = $con->createQueryTable('results_table', "SELECT * FROM Downtimes"); $this->assertTrue($result->getRowCount() == 0); }