public static function addViolation($rule, $srcAtom, $tgtAtom)
 {
     $session = Session::singleton();
     $ruleHash = hash('md5', $rule['name']);
     $ruleMessage = $rule['message'] ? $rule['message'] : "Violation of rule '" . $rule['name'] . "'";
     $pairView = RuleEngine::getPairView($srcAtom, $rule['srcConcept'], $tgtAtom, $rule['tgtConcept'], $rule['pairView']);
     self::$violations[$ruleHash]['ruleMessage'] = $ruleMessage;
     self::$violations[$ruleHash]['interfaceIds'] = $pairView['interfaceIds'];
     $violationMessage = empty($pairView['violationMessage']) ? $srcAtom . " - " . $tgtAtom : $pairView['violationMessage'];
     // Make links to interfaces
     $links = array();
     foreach ($session->getInterfacesToReadConcept($rule['srcConcept']) as $interface) {
         $links[] = '#/' . $interface->id . '/' . $srcAtom;
     }
     foreach ($session->getInterfacesToReadConcept($rule['tgtConcept']) as $interface) {
         $links[] = '#/' . $interface->id . '/' . $tgtAtom;
     }
     $links = array_unique($links);
     self::$violations[$ruleHash]['tuples'][] = array('violationMessage' => $violationMessage, 'links' => $links);
     self::addLog($violationMessage . ' - ' . $violationMessage, 'VIOLATION');
 }
Example #2
0
 public function closeTransaction($succesMessage = 'Updated', $checkAllConjucts = true, $databaseCommit = false, $setNewContent = true)
 {
     $session = Session::singleton();
     Hooks::callHooks('preDatabaseCloseTransaction', get_defined_vars());
     Notifications::addLog('========================= CLOSING TRANSACTION =========================', 'DATABASE');
     if ($checkAllConjucts) {
         Notifications::addLog("Check all conjuncts", 'DATABASE');
         // Evaluate all invariant conjuncts. Conjuncts are cached.
         $invariantRulesHold = RuleEngine::checkInvariantRules();
         // Evaluate all signal conjuncts. Conjuncts are cached
         RuleEngine::checkProcessRules();
     } else {
         Notifications::addLog("Check all affected conjuncts", 'DATABASE');
         // Evaluate all affected invariant conjuncts. Conjuncts are cached.
         $invariantRulesHold = RuleEngine::checkInvariantRules(RuleEngine::getAffectedInvConjuncts($this->affectedConcepts, $this->affectedRelations), true);
         // Evaluate all affected signal conjuncts. Conjuncts are cached
         RuleEngine::checkConjuncts(RuleEngine::getAffectedSigConjuncts($this->affectedConcepts, $this->affectedRelations), true);
         // Check only those process rules that are relevant for the activate roles
         RuleEngine::checkProcessRules($session);
     }
     unset($this->affectedConcepts, $this->affectedRelations);
     $this->affectedConcepts = array();
     $this->affectedRelations = array();
     if ($setNewContent && isset($session->atom)) {
         $session->atom->setNewContent($session->interface);
     }
     // e.g. not needed in Atom::delete() function
     if ($invariantRulesHold && $databaseCommit) {
         $this->commitTransaction();
         // commit database transaction
         Notifications::addSuccess($succesMessage);
     } elseif (Config::get('ignoreInvariantViolations', 'transactions') && COMMIT_INV_VIOLATIONS) {
         $this->commitTransaction();
         Notifications::addError("Transaction committed with invariant violations");
     } elseif ($invariantRulesHold) {
         $this->rollbackTransaction();
         // rollback database transaction
         Notifications::addInfo($succesMessage);
     } else {
         $this->rollbackTransaction();
         // rollback database transaction
     }
     Hooks::callHooks('postDatabaseCloseTransaction', get_defined_vars());
     return $invariantRulesHold;
 }
Example #3
0
 public static function getRule($ruleName)
 {
     $allRules = RuleEngine::getAllRules();
     if (!array_key_exists($ruleName, $allRules)) {
         throw new Exception("Rule \\'{$ruleName}\\' does not exists in allRules", 500);
     }
     return $rule = $allRules[$ruleName];
 }
Example #4
0
 /**
  * @url GET stats/performance/conjuncts
  * @param string $groupBy
  * @param int $from
  * @param int $to
  */
 public function conjPerfStats($groupBy = 'conjuncts', $from = 0, $to = 10)
 {
     try {
         if (Config::get('productionEnv')) {
             throw new Exception("Performance tests are not allowed in production environment", 403);
         }
         $performanceArr = array();
         // run all conjuncts (from - to)
         for ($i = $from; $i <= $to; $i++) {
             $conj = RuleEngine::getConjunct('conj_' . $i);
             $startTimeStamp = microtime(true);
             // true means get as float instead of string
             RuleEngine::checkConjunct('conj_' . $i, false);
             $endTimeStamp = microtime(true);
             $performanceArr['conj_' . $i] = array('id' => 'conj_' . $i, 'start' => $startTimeStamp, 'end' => $endTimeStamp, 'duration' => $endTimeStamp - $startTimeStamp, 'invariantRules' => implode(';', $conj['invariantRuleNames']), 'signalRules' => implode(';', $conj['signalRuleNames']));
         }
         switch ($groupBy) {
             case 'conjuncts':
                 return array_values($performanceArr);
                 break;
             case 'rules':
                 $ruleArr = array();
                 foreach (RuleEngine::getAllRules() as $rule) {
                     $duration = 0;
                     foreach ($rule['conjunctIds'] as $conj) {
                         $duration += $performanceArr[$conj]['duration'];
                     }
                     $ruleArr[] = array('ruleName' => $rule['name'], 'duration' => $duration, 'conjuncts' => implode(';', $rule['conjunctIds']));
                 }
                 return $ruleArr;
                 break;
             case 'relations':
                 $relArr = array();
                 foreach (Relation::getAllRelations() as $sig => $rel) {
                     $duration = 0;
                     $conjuncts = array_merge($rel['affectedInvConjunctIds'], $rel['affectedSigConjunctIds']);
                     foreach ($conjuncts as $conj) {
                         $duration += $performanceArr[$conj]['duration'];
                     }
                     $relArr[] = array('relationSignature' => $sig, 'duration' => $duration, 'conjuncts' => implode(';', $conjuncts));
                 }
                 return $relArr;
                 break;
             default:
                 throw new Exception("Unknown groupBy argument", 500);
                 break;
         }
     } catch (Exception $e) {
         throw new RestException($e->getCode(), $e->getMessage());
     }
 }
Example #5
0
 public function getViolations()
 {
     $conjunctIds = array();
     $conjunctRuleMap = array();
     foreach ($this->maintains as $ruleName) {
         $rule = RuleEngine::getRule($ruleName);
         foreach ($rule['conjunctIds'] as $conjunctId) {
             $conjunctRuleMap[$conjunctId][] = $ruleName;
         }
         $conjunctIds = array_merge($conjunctIds, $rule['conjunctIds']);
     }
     $signals = RuleEngine::getSignalsFromDB($conjunctIds);
     /*
      * $signal[] = array('conjId' => , 'src' => , 'tgt' => )
      * 
      */
     foreach ($signals as $signal) {
         foreach ($conjunctRuleMap[$signal['conjId']] as $ruleName) {
             Notifications::addViolation(RuleEngine::getRule($ruleName), $signal['src'], $signal['tgt']);
         }
     }
 }
 public static function getProcessViolationsFromDB($session)
 {
     $conjunctIds = array();
     $conjunctRuleMap = array();
     foreach ($session->rulesToMaintain as $ruleName) {
         $rule = RuleEngine::getRule($ruleName);
         foreach ($rule['conjunctIds'] as $conjunctId) {
             $conjunctRuleMap[$conjunctId][] = $ruleName;
         }
         $conjunctIds = array_merge($conjunctIds, $rule['conjunctIds']);
     }
     $signals = RuleEngine::getSignalsFromDB($conjunctIds);
     foreach ($signals as $signal) {
         // $signal[] = array('conjId' => , 'src' => , 'tgt' => )
         foreach ($conjunctRuleMap[$signal['conjId']] as $ruleName) {
             Notifications::addViolation(RuleEngine::getRule($ruleName), $signal['src'], $signal['tgt']);
         }
     }
 }
 public static function run($allRules = false)
 {
     $database = Database::singleton();
     Notifications::addLog('------------------------- EXEC ENGINE STARTED -------------------------', 'ExecEngine');
     // Load the execEngine functions (security hazard :P)
     $files = getDirectoryList(__DIR__ . '/functions');
     foreach ($files as $file) {
         if (substr($file, -3) !== 'php') {
             continue;
         }
         require_once __DIR__ . '/functions/' . $file;
         Notifications::addLog('Included file: ' . __DIR__ . '/functions/' . $file, 'ExecEngine');
     }
     self::$roleName = Config::get('execEngineRoleName', 'execEngine');
     $role = Role::getRoleByName(self::$roleName);
     $maxRunCount = Config::get('maxRunCount', 'execEngine');
     self::$runCount = 0;
     self::$autoRerun = Config::get('autoRerun', 'execEngine');
     if ($role) {
         // Get all rules that are maintained by the ExecEngine
         while (self::$doRun) {
             self::$doRun = false;
             self::$runCount++;
             if (self::$runCount > $maxRunCount) {
                 throw new Exception('Maximum reruns exceeded for ExecEngine (rules with violations:' . implode(', ', $rulesThatHaveViolations) . ')', 500);
             }
             Notifications::addLog("ExecEngine run #" . self::$runCount . " (auto rerun: " . var_export(self::$autoRerun, true) . ") for role '" . $role->label . "'", 'ExecEngine');
             // Determine affected rules that must be checked by the exec engine
             $affectedConjuncts = (array) RuleEngine::getAffectedInvConjuncts($database->getAffectedConcepts(), $database->getAffectedRelations());
             $affectedConjuncts = array_merge($affectedConjuncts, (array) RuleEngine::getAffectedSigConjuncts($database->getAffectedConcepts(), $database->getAffectedRelations()));
             $affectedRules = array();
             foreach ($affectedConjuncts as $conjunctId) {
                 $conjunct = RuleEngine::getConjunct($conjunctId);
                 foreach ($conjunct['invariantRuleNames'] as $ruleName) {
                     $affectedRules[] = $ruleName;
                 }
                 foreach ($conjunct['signalRuleNames'] as $ruleName) {
                     $affectedRules[] = $ruleName;
                 }
             }
             // Check rules
             $rulesThatHaveViolations = array();
             foreach ($role->maintains() as $ruleName) {
                 if (!in_array($ruleName, $affectedRules) && !$allRules) {
                     continue;
                 }
                 // skip this rule
                 $rule = RuleEngine::getRule($ruleName);
                 $violations = RuleEngine::checkRule($rule, false);
                 if (count($violations)) {
                     $rulesThatHaveViolations[] = $rule['name'];
                     // Fix violations for every rule
                     ExecEngine::fixViolations($rule, $violations);
                     // Conjunct violations are not cached, because they are fixed by the ExecEngine
                     // If $autoRerun, set $doRun to true because violations have been fixed (this may fire other execEngine rules)
                     if (self::$autoRerun) {
                         self::$doRun = true;
                     }
                 }
             }
         }
     } else {
         Notifications::addInfo("ExecEngine extension included but role '" . self::$roleName . "' not found.");
     }
     Notifications::addLog('------------------------- END OF EXEC ENGINE -------------------------', 'ExecEngine');
 }