/**
  * Test the <code>$serviceDAO->removeEndpoint($endpoint)</code> method.   
  */
 public function testServiceDAORemoveEndpoint()
 {
     print __METHOD__ . "\n";
     // create a linked entity graph as beow:
     //
     //      se -----|    (1 service)
     //     / | \    |
     //  el1 el2 el3 |    (3 endpoints)
     //  |  \ | /    |
     // dt0  dt1 ----|    (1 downtime)
     $dt1 = new Downtime();
     $dt1->setDescription('downtime description');
     $dt1->setSeverity("WARNING");
     $dt1->setClassification("UNSCHEDULED");
     $dt0 = new Downtime();
     $dt0->setDescription('downtime description');
     $dt0->setSeverity("WARNING");
     $dt0->setClassification("UNSCHEDULED");
     $se = TestUtil::createSampleService('service1');
     $el1 = TestUtil::createSampleEndpointLocation();
     $el2 = TestUtil::createSampleEndpointLocation();
     $el3 = TestUtil::createSampleEndpointLocation();
     $se->addEndpointLocationDoJoin($el1);
     $se->addEndpointLocationDoJoin($el2);
     $se->addEndpointLocationDoJoin($el3);
     //$se->_addDowntime($dt1); // we don't call this in client code !
     $dt1->addEndpointLocation($el1);
     $dt1->addEndpointLocation($el2);
     $dt1->addEndpointLocation($el3);
     $dt1->addService($se);
     $dt0->addEndpointLocation($el1);
     //$dt0->addService($se); // note we don't add this relationship for purposes of the test
     // persist and flush
     $this->em->persist($se);
     $this->em->persist($el1);
     $this->em->persist($el2);
     $this->em->persist($el3);
     $this->em->persist($dt1);
     $this->em->persist($dt0);
     $this->em->flush();
     // create DAO to test
     $serviceDao = new ServiceDAO();
     $serviceDao->setEntityManager($this->em);
     // remove first endpoint causing dt0 to be orphaned
     $serviceDao->removeEndpoint($el1);
     $this->em->flush();
     // Assert expected object graph
     //     se -----|   (1 service)
     //      | \    |
     //     el2 el3 |   (2 endpoints)
     //      | /    |
     // dt0 dt1-----|   (2 downtime)
     //
     $testConn = $this->getConnection();
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM EndpointLocations");
     $this->assertTrue($result->getRowCount() == 2);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes");
     $this->assertTrue($result->getRowCount() == 2);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes_EndpointLocations");
     $this->assertTrue($result->getRowCount() == 2);
     // Assert expected object graph in ORM Mem
     $this->assertEquals(1, count($el2->getDowntimes()));
     $this->assertEquals(1, count($el3->getDowntimes()));
     $this->assertEquals(2, count($se->getEndpointLocations()));
     $this->assertEquals(1, count($se->getDowntimes()));
     $this->assertEquals(2, count($dt1->getEndpointLocations()));
     $this->assertEquals(1, count($dt1->getServices()));
     // remove another el
     $serviceDao->removeEndpoint($el2);
     $this->em->flush();
     // Assert expected object graph in DB
     //     se -----| (1 service)
     //       \     |
     //        el3  | (1 endpoints)
     //        /    |
     // dt0 dt1-----| (2 downtime)
     //
     $testConn = $this->getConnection();
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM EndpointLocations");
     $this->assertTrue($result->getRowCount() == 1);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes");
     $this->assertTrue($result->getRowCount() == 2);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes_EndpointLocations");
     $this->assertTrue($result->getRowCount() == 1);
     // Assert expected object graph in ORM Mem
     $this->assertEquals(1, count($el3->getDowntimes()));
     $this->assertEquals(1, count($se->getEndpointLocations()));
     $this->assertEquals(1, count($se->getDowntimes()));
     $this->assertEquals(1, count($dt1->getEndpointLocations()));
     $this->assertEquals(1, count($dt1->getServices()));
     // remove another el
     $serviceDao->removeEndpoint($el3);
     $this->em->flush();
     // Assert expected object graph in DB
     //     se -----| (1 service)
     //             |
     //             | (1 endpoints)
     //             |
     // dt0 dt1-----| (2 downtime)
     //
     $testConn = $this->getConnection();
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM EndpointLocations");
     $this->assertTrue($result->getRowCount() == 0);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes");
     $this->assertTrue($result->getRowCount() == 2);
     $result = $testConn->createQueryTable('results_table', "SELECT * FROM Downtimes_EndpointLocations");
     $this->assertTrue($result->getRowCount() == 0);
     // Assert expected object graph in ORM Mem
     $this->assertEquals(0, count($se->getEndpointLocations()));
     $this->assertEquals(1, count($se->getDowntimes()));
     $this->assertEquals(0, count($dt1->getEndpointLocations()));
     $this->assertEquals(1, count($dt1->getServices()));
 }
Пример #2
0
 /**
  * Array
  * (
  *     [DOWNTIME] => Array
  *     (
  *         [SEVERITY] => OUTAGE
  *         [DESCRIPTION] => Test
  *         [START_TIMESTAMP] => 20/03/2013 00:00
  *         [END_TIMESTAMP] => 23/03/2013 00:00
  *     )
  *     [Impacted_Services] => Array
  *     (
  *         [0] => 824
  *         [1] => 825
  *         [2] => 2146
  *     )
  *     [Impacted_Endpoints] => Array
  *     (
  *         [0] => 54
  *         [1] => 15
  *         [2] => 26     
  *      )
  * Adds a downtime
  * @param Array $values Downtime values, shown above
  * @param \User $user User making the request
  * @return \Downtime $dt The new downtime
  */
 public function addDowntime($values, \User $user = null)
 {
     //Check the portal is not in read only mode, throws exception if it is
     $this->checkPortalIsNotReadOnlyOrUserIsAdmin($user);
     require_once __DIR__ . '/ServiceService.php';
     $serviceService = new \org\gocdb\services\ServiceService();
     $serviceService->setEntityManager($this->em);
     // Get the affected services
     $services = array();
     foreach ($values['Impacted_Services'] as $service) {
         $services[] = $serviceService->getService($service);
     }
     // Get the affected endpoints
     $endpoints = array();
     foreach ($values['Impacted_Endpoints'] as $endpoint) {
         $endpoints[] = $serviceService->getEndpoint($endpoint);
     }
     if (count($services) == 0) {
         throw new \Exception("A downtime must affect at least one service");
     }
     // Check that each endpoint belongs to one of the services.
     // It is an error if an endpoint does not belong to one of the services.
     foreach ($endpoints as $checkEndpoint) {
         $endpointBelongsToService = false;
         foreach ($services as $checkService) {
             if (in_array($checkEndpoint, $checkService->getEndpointLocations()->toArray())) {
                 $endpointBelongsToService = true;
             }
         }
         if (!$endpointBelongsToService) {
             throw new \Exception('Error, affected endpoint is not owned by an affected service');
         }
     }
     // get the affected sites
     $sites = array();
     foreach ($services as $se) {
         $site = $se->getParentSite();
         if (!in_array($site, $sites)) {
             $sites[] = $site;
         }
     }
     if (count($sites) != 1) {
         // if there are multiple affected services from multiple sites,
         // the gui must either enforce single site selection
         // or prevent selecting 'define DT in site timezone' if selecting
         // multiple sites (i.e. utc only when selecting services from multiple sites).
         throw new \Exception("Downtime creation for multiple sites not supported yet");
     }
     // Check the user has a role covering the passed SEs
     $this->authorization($services, $user);
     $this->validate($values['DOWNTIME']);
     $startStr = $values['DOWNTIME']['START_TIMESTAMP'];
     $endStr = $values['DOWNTIME']['END_TIMESTAMP'];
     //echo($startStr. ' '.$endStr); // 14/05/2015 16:16      14/05/2015 16:17   d/m/Y H:i
     // did the user specify the downtime info in utc (default) or in site's local timezone?
     /*$requestUtcOrSiteTimezone = $values['DOWNTIME']['DEFINE_TZ_BY_UTC_OR_SITE'];
             $tzStr = 'UTC'; // the timezone label specified by the user (e.g. 'UTC' or 'Europe/London') 
             if($requestUtcOrSiteTimezone == 'site'){
                 // if there are multiple affected services from multiple sites, 
                 // we assume utc - the gui must therefore either enforce single site selection 
                 // or prevent selecting 'define DT in site timezone' if selecting 
                 // multiple sites (i.e. utc only when selecting services from multiple sites). 
                  
                 // get the site timezone label 
                 if(count($sites) > 1){
                     $tzStr = 'UTC'; // if many sites are affected (not implemented yet), assume UTC 
                 } else {
                     $siteTzOrNull = $sites[0]->getTimezoneId();  
                     if( !empty($siteTzOrNull)){
                         $tzStr = $siteTzOrNull;  
                     } else {
                         $tzStr = 'UTC'; 
                     }
                 }
             }
     
             // convert start and end into UTC 
             $UTC = new \DateTimeZone("UTC");
             if($tzStr != 'UTC'){
                 // specify dateTime in source TZ
                 $sourceTZ = new \DateTimeZone($tzStr);
                 $start = \DateTime::createFromFormat($this::FORMAT, $startStr, $sourceTZ);
                 $end = \DateTime::createFromFormat($this::FORMAT, $endStr, $sourceTZ);
                 // reset the TZ to UTC
                 $start->setTimezone($UTC); 
                 $end->setTimezone($UTC); 
             } else {
                 $start = \DateTime::createFromFormat($this::FORMAT, $startStr, $UTC);
                 $end = \DateTime::createFromFormat($this::FORMAT, $endStr, $UTC); 
             }*/
     $start = \DateTime::createFromFormat($this::FORMAT, $startStr, new \DateTimeZone("UTC"));
     $end = \DateTime::createFromFormat($this::FORMAT, $endStr, new \DateTimeZone("UTC"));
     $this->validateDates($start, $end);
     // calculate classification
     $nowPlus1Day = new \DateTime(null, new \DateTimeZone('UTC'));
     $oneDay = \DateInterval::createFromDateString('1 days');
     if ($start > $nowPlus1Day->add($oneDay)) {
         $class = "SCHEDULED";
     } else {
         $class = "UNSCHEDULED";
     }
     $this->em->getConnection()->beginTransaction();
     try {
         $dt = new \Downtime();
         $dt->setClassification($class);
         $dt->setDescription($values['DOWNTIME']['DESCRIPTION']);
         $dt->setSeverity($values['DOWNTIME']['SEVERITY']);
         $dt->setStartDate($start);
         $dt->setEndDate($end);
         $dt->setInsertDate(new \DateTime(null, new \DateTimeZone('UTC')));
         // Create a new pk and persist/flush to sync in-mem object state
         // with DB - is needed so that the call to v4DowntimePK->getId() actually
         // returns a value (we can still rollback no probs if an issue occurs
         // to remove the Downtime)
         $v4DowntimePk = new \PrimaryKey();
         $this->em->persist($v4DowntimePk);
         $this->em->flush();
         $dt->setPrimaryKey($v4DowntimePk->getId() . 'G0');
         //Create a link to the services
         foreach ($services as $service) {
             $dt->addService($service);
         }
         //Create a link to the affected endpoints (if any endpoints were selected)
         foreach ($endpoints as $endpoint) {
             $dt->addEndpointLocation($endpoint);
         }
         $this->em->persist($dt);
         $this->em->flush();
         $this->em->getConnection()->commit();
     } catch (\Exception $e) {
         $this->em->getConnection()->rollback();
         $this->em->close();
         throw $e;
     }
     return $dt;
 }