Browse Source

Data Exchange - Implemented reconciliation options + cosmetics on synchro_exec

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1093 a333f486-631f-4898-b8df-5754b55c2be0
romainq 14 years ago
parent
commit
a318b83e49
3 changed files with 75 additions and 22 deletions
  1. 14 2
      synchro/synchro_exec.php
  2. 2 1
      synchro/synchro_import.php
  3. 59 19
      synchro/synchrodatasource.class.inc.php

+ 14 - 2
synchro/synchro_exec.php

@@ -138,15 +138,27 @@ try
 			{
 				CMDBSource::Query('START TRANSACTION');
 			}
-			$oSynchroDataSource->Synchronize($aResults, null);
+			$oStatLog = $oSynchroDataSource->Synchronize($aResults, null);
 			foreach ($aResults as $sMessage)
 			{
-				$oP->p("results: $sMessage");
+				$oP->p($sMessage);
 			}
 			if ($bSimulate)
 			{
 				CMDBSource::Query('ROLLBACK');
 			}
+			$oP->p("Replicas: ".$oStatLog->Get('stats_nb_replica_total'));
+			$oP->p("Replicas touched since last synchro: ".$oStatLog->Get('stats_nb_replica_seen'));
+			$oP->p("Objects deleted: ".$oStatLog->Get('stats_nb_obj_deleted'));
+			$oP->p("Objects deletion errors: ".$oStatLog->Get('stats_nb_obj_deleted_errors'));
+			$oP->p("Objects obsoleted: ".$oStatLog->Get('stats_nb_obj_obsoleted'));
+			$oP->p("Objects obsolescence errors: ".$oStatLog->Get('stats_nb_obj_obsoleted_errors'));
+			$oP->p("Objects created: ".$oStatLog->Get('stats_nb_obj_created'));
+			$oP->p("Objects creation errors: ".$oStatLog->Get('stats_nb_obj_created_errors'));
+			$oP->p("Objects updated: ".$oStatLog->Get('stats_nb_obj_updated'));
+			$oP->p("Objects update errors: ".$oStatLog->Get('stats_nb_obj_updated_errors'));
+			$oP->p("Objects reconciled: ".$oStatLog->Get('stats_nb_replica_reconciled'));
+			$oP->p("Objects reconciliation errors: ".$oStatLog->Get('stats_nb_replica_reconciled_errors'));
 		}
 	}
 }

+ 2 - 1
synchro/synchro_import.php

@@ -466,10 +466,11 @@ try
 	if ($bSynchronize && !$bSimulate)
 	{
 		$aTraces = array();
-		$oDataSource->Synchronize($aTraces, $oLoadStartDate);
+		$oStatLog = $oDataSource->Synchronize($aTraces, $oLoadStartDate);
 		//echo "#@# Synchronize() returned :<br/>\n";
 		//echo "<pre>\n";
 		//print_r($aTraces);
+		//print_r($oStatLog);
 		//echo "</pre>\n";
 	}
 

+ 59 - 19
synchro/synchrodatasource.class.inc.php

@@ -59,7 +59,7 @@ class SynchroDataSource extends cmdbAbstractObject
 //		MetaModel::Init_AddAttribute(new AttributeString("reconciliation_list", array("allowed_values"=>null, "sql"=>"reconciliation_list", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("reconciliation_policy", array("allowed_values"=>new ValueSetEnum('use_primary_key,use_attributes'), "sql"=>"reconciliation_policy", "default_value"=>"use_attributes", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("action_on_zero", array("allowed_values"=>new ValueSetEnum('create,error'), "sql"=>"action_on_zero", "default_value"=>"create", "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeEnum("action_on_one", array("allowed_values"=>new ValueSetEnum('update,error,delete'), "sql"=>"action_on_one", "default_value"=>"update", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeEnum("action_on_one", array("allowed_values"=>new ValueSetEnum('update,error'), "sql"=>"action_on_one", "default_value"=>"update", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("action_on_multiple", array("allowed_values"=>new ValueSetEnum('take_first,create,error'), "sql"=>"action_on_multiple", "default_value"=>"error", "is_null_allowed"=>false, "depends_on"=>array())));
 		
 		MetaModel::Init_AddAttribute(new AttributeEnum("delete_policy", array("allowed_values"=>new ValueSetEnum('ignore,delete,update,update_then_delete'), "sql"=>"delete_policy", "default_value"=>"ignore", "is_null_allowed"=>false, "depends_on"=>array())));
@@ -964,6 +964,7 @@ class SynchroReplica extends DBObject
 				else
 				{
 					// Reconciliation could not be performed - log and EXIT
+					$aTraces[] = "Could not reconcile on null value: ".$sFilterCode;
 					$this->SetLastError('Could not reconcile on null value: '.$sFilterCode);
 					$oStatLog->Inc('stats_nb_replica_reconciled_errors');
 					return;
@@ -971,34 +972,71 @@ class SynchroReplica extends DBObject
 			}
 			$oDestSet = new DBObjectSet(self::$aSearches[$oDataSource->GetKey()], array(), $aFilterValues);
 			$iCount = $oDestSet->Count();
+			$aConditions = array();
+			foreach($aFilterValues as $sCode => $sValue)
+			{
+				$aConditions[] = $sCode.'='.$sValue;
+			}
+			$sConditionDesc = implode(' AND ', $aConditions);
 			// How many objects match the reconciliation criterias
 			switch($iCount)
 			{
 				case 0:
-				//echo "<p>Nothing found for: ".self::$aSearches[$oDataSource->GetKey()]->ToOQL(true, $aFilterValues)."</p>";
-				$this->CreateObjectFromReplica($oDataSource->GetTargetClass(), $aAttributes, $oChange, $oStatLog, $aTraces);
-				$oStatLog->Inc('stats_nb_obj_created');
+				$aTraces[] = "Nothing found on: $sConditionDesc";
+				if ($oDataSource->Get('action_on_zero') == 'create')
+				{
+					$this->CreateObjectFromReplica($oDataSource->GetTargetClass(), $aAttributes, $oChange, $oStatLog, $aTraces);
+				}
+				else // assumed to be 'error'
+				{
+					$aTraces[] = "Failed to reconcile (no match)";
+					$this->SetLastError('Could not find a match for reconciliation');
+					$oStatLog->Inc('stats_nb_replica_reconciled_errors');
+				}
 				break;
 				
 				case 1:
-				//echo "<p>Found 1 for: ".self::$aSearches[$oDataSource->GetKey()]->ToOQL(true, $aFilterValues)."</p>";
-				$oDestObj = $oDestSet->Fetch();
-				$this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_replica_reconciled');
-				$this->Set('dest_id', $oDestObj->GetKey());
-				$this->Set('status_dest_creator', false);
-				$this->Set('dest_class', get_class($oDestObj));
+				$aTraces[] = "Found 1 object on: $sConditionDesc";
+				if ($oDataSource->Get('action_on_one') == 'update')
+				{
+					$oDestObj = $oDestSet->Fetch();
+					$this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_replica_reconciled');
+					$this->Set('dest_id', $oDestObj->GetKey());
+					$this->Set('status_dest_creator', false);
+					$this->Set('dest_class', get_class($oDestObj));
+	
+					$oStatLog->Inc('stats_nb_replica_reconciled');
+				}
+				else
+				{
+					// assumed to be 'error'
+					$aTraces[] = "Failed to reconcile (1 match)";
+					$this->SetLastError('Found a match while expecting several');
+					$oStatLog->Inc('stats_nb_replica_reconciled_errors');
+				}
 				break;
 				
 				default:
-				$aConditions = array();
-				foreach($aFilterValues as $sCode => $sValue)
+				$aTraces[] = "Found $iCount objects on: $sConditionDesc";
+				if ($oDataSource->Get('action_on_multiple') == 'error')
+				{
+					$aTraces[] = "Failed to reconcile (N>1 matches)";
+					$this->SetLastError($iCount.' destination objects match the reconciliation criterias: '.$sConditionDesc);
+					$oStatLog->Inc('stats_nb_replica_reconciled_errors');
+				}
+				elseif ($oDataSource->Get('action_on_multiple') == 'create')
+				{
+					$this->CreateObjectFromReplica($oDataSource->GetTargetClass(), $aAttributes, $oChange, $oStatLog, $aTraces);
+				}
+				else
 				{
-					$aConditions[] = $sCode.'='.$sValue;
+					// assumed to be 'take_first'
+					$oDestObj = $oDestSet->Fetch();
+					$this->UpdateObjectFromReplica($oDestObj, $aAttributes, $oChange, $oStatLog, $aTraces, 'stats_nb_replica_reconciled');
+					$this->Set('dest_id', $oDestObj->GetKey());
+					$this->Set('status_dest_creator', false);
+					$this->Set('dest_class', get_class($oDestObj));
 				}
-				$sCondition = implode(' AND ', $aConditions);
-				//echo "<p>Found N for: ".self::$aSearches[$oDataSource->GetKey()]->ToOQL(true, $aFilterValues)."</p>";
-				$this->SetLastError($iCount.' destination objects match the reconciliation criterias: '.$sCondition);
-				$oStatLog->Inc('stats_nb_replica_reconciled_errors');
 			}
 			break;
 			
@@ -1033,7 +1071,7 @@ class SynchroReplica extends DBObject
 			if (!is_null($value))
 			{
 				$oDestObj->Set($sAttCode, $value);
-				$aValueTrace[] = "$sAttCode&lt;$value";
+				$aValueTrace[] = "$sAttCode: $value";
 			}
 		}
 		try
@@ -1047,6 +1085,7 @@ class SynchroReplica extends DBObject
 		}
 		catch(Exception $e)
 		{
+			$aTraces[] = "Failed to update destination object: {$e->getMessage()}";
 			$this->SetLastError('Unable to update destination object: ', $e);
 			$oStatLog->Inc($sStatsCode.'_errors');
 		}
@@ -1067,7 +1106,7 @@ class SynchroReplica extends DBObject
 				if (!is_null($value))
 				{
 					$oDestObj->Set($sAttCode, $value);
-					$aValueTrace[] = "$sAttCode&lt;$value";
+					$aValueTrace[] = "$sAttCode: $value";
 				}
 			}
 			$iNew = $oDestObj->DBInsertTracked($oChange);
@@ -1083,6 +1122,7 @@ class SynchroReplica extends DBObject
 		}
 		catch(Exception $e)
 		{
+			$aTraces[] = "Failed to create $sClass ({$e->getMessage()})";
 			$this->SetLastError('Unable to create destination object: ', $e);
 			$oStatLog->Inc('stats_nb_obj_created_errors');
 		}