diff --git a/config/sql/_all/h2-3.4.1-all.sql b/config/sql/_all/h2-3.4.1-all.sql index dfb781b5f8c..fd62cd2c91c 100644 --- a/config/sql/_all/h2-3.4.1-all.sql +++ b/config/sql/_all/h2-3.4.1-all.sql @@ -390,6 +390,7 @@ CREATE TABLE m_object ( creatorRef_type INTEGER, datesCount SMALLINT, fullObject BLOB, + lifecycleState VARCHAR(255), longsCount SMALLINT, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -805,6 +806,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/_all/mysql-3.4.1-all.sql b/config/sql/_all/mysql-3.4.1-all.sql index 7669a7efc21..da485464e40 100644 --- a/config/sql/_all/mysql-3.4.1-all.sql +++ b/config/sql/_all/mysql-3.4.1-all.sql @@ -480,6 +480,7 @@ CREATE TABLE m_object ( creatorRef_type INTEGER, datesCount SMALLINT, fullObject LONGBLOB, + lifecycleState VARCHAR(255), longsCount SMALLINT, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -985,6 +986,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/_all/oracle-3.4.1-all.sql b/config/sql/_all/oracle-3.4.1-all.sql index ca813b11b6d..b1441eaf946 100644 --- a/config/sql/_all/oracle-3.4.1-all.sql +++ b/config/sql/_all/oracle-3.4.1-all.sql @@ -389,6 +389,7 @@ CREATE TABLE m_object ( creatorRef_type NUMBER(10, 0), datesCount NUMBER(5, 0), fullObject BLOB, + lifecycleState VARCHAR2(255 CHAR), longsCount NUMBER(5, 0), modifierRef_relation VARCHAR2(157 CHAR), modifierRef_targetOid VARCHAR2(36 CHAR), @@ -811,6 +812,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass) INITRANS 30; CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp) INITRANS 30; +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState) INITRANS 30; + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue) INITRANS 30; CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType) INITRANS 30; diff --git a/config/sql/_all/postgresql-3.4.1-all.sql b/config/sql/_all/postgresql-3.4.1-all.sql index 259d29e6dec..20e28ce3f4f 100644 --- a/config/sql/_all/postgresql-3.4.1-all.sql +++ b/config/sql/_all/postgresql-3.4.1-all.sql @@ -386,6 +386,7 @@ CREATE TABLE m_object ( creatorRef_type INT4, datesCount INT2, fullObject BYTEA, + lifecycleState VARCHAR(255), longsCount INT2, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -801,6 +802,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/_all/sqlserver-3.4.1-all.sql b/config/sql/_all/sqlserver-3.4.1-all.sql index 7a4d5314e9b..f85787997cf 100644 --- a/config/sql/_all/sqlserver-3.4.1-all.sql +++ b/config/sql/_all/sqlserver-3.4.1-all.sql @@ -386,6 +386,7 @@ CREATE TABLE m_object ( creatorRef_type INT, datesCount SMALLINT, fullObject VARBINARY(MAX), + lifecycleState NVARCHAR(255) COLLATE database_default, longsCount SMALLINT, modifierRef_relation NVARCHAR(157) COLLATE database_default, modifierRef_targetOid NVARCHAR(36) COLLATE database_default, @@ -801,6 +802,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/midpoint/3.4.1/h2/h2-upgrade-3.3-3.4.sql b/config/sql/midpoint/3.4.1/h2/h2-upgrade-3.3-3.4.sql deleted file mode 100644 index 4f82ba77515..00000000000 --- a/config/sql/midpoint/3.4.1/h2/h2-upgrade-3.3-3.4.sql +++ /dev/null @@ -1,173 +0,0 @@ -CREATE TABLE m_service ( - displayOrder INTEGER, - locality_norm VARCHAR(255), - locality_orig VARCHAR(255), - name_norm VARCHAR(255), - name_orig VARCHAR(255), - oid VARCHAR(36) NOT NULL, - PRIMARY KEY (oid) -); - -CREATE TABLE m_service_type ( - service_oid VARCHAR(36) NOT NULL, - serviceType VARCHAR(255) -); - -ALTER TABLE m_service - ADD CONSTRAINT fk_service -FOREIGN KEY (oid) -REFERENCES m_abstract_role; - -ALTER TABLE m_service_type - ADD CONSTRAINT fk_service_type -FOREIGN KEY (service_oid) -REFERENCES m_service; - -ALTER TABLE m_task ADD wfEndTimestamp TIMESTAMP; -ALTER TABLE m_task ADD wfObjectRef_relation VARCHAR(157); -ALTER TABLE m_task ADD wfObjectRef_targetOid VARCHAR(36); -ALTER TABLE m_task ADD wfObjectRef_type INTEGER; -ALTER TABLE m_task ADD wfProcessInstanceId VARCHAR(255); -ALTER TABLE m_task ADD wfRequesterRef_relation VARCHAR(157); -ALTER TABLE m_task ADD wfRequesterRef_targetOid VARCHAR(36); -ALTER TABLE m_task ADD wfRequesterRef_type INTEGER; -ALTER TABLE m_task ADD wfStartTimestamp TIMESTAMP; -ALTER TABLE m_task ADD wfTargetRef_relation VARCHAR(157); -ALTER TABLE m_task ADD wfTargetRef_targetOid VARCHAR(36); -ALTER TABLE m_task ADD wfTargetRef_type INTEGER; - -CREATE INDEX iTaskWfProcessInstanceId ON m_task (wfProcessInstanceId); - -CREATE INDEX iTaskWfStartTimestamp ON m_task (wfStartTimestamp); - -CREATE INDEX iTaskWfEndTimestamp ON m_task (wfEndTimestamp); - -CREATE INDEX iTaskWfRequesterOid ON m_task (wfRequesterRef_targetOid); - -CREATE INDEX iTaskWfObjectOid ON m_task (wfObjectRef_targetOid); - -CREATE INDEX iTaskWfTargetOid ON m_task (wfTargetRef_targetOid); - -ALTER TABLE m_abstract_role ADD ownerRef_relation VARCHAR(157); -ALTER TABLE m_abstract_role ADD ownerRef_targetOid VARCHAR(36); -ALTER TABLE m_abstract_role ADD ownerRef_type INTEGER; - -ALTER TABLE m_acc_cert_campaign ADD endTimestamp TIMESTAMP; -ALTER TABLE m_acc_cert_campaign ADD handlerUri VARCHAR(255); -ALTER TABLE m_acc_cert_campaign ADD ownerRef_relation VARCHAR(157); -ALTER TABLE m_acc_cert_campaign ADD ownerRef_targetOid VARCHAR(36); -ALTER TABLE m_acc_cert_campaign ADD ownerRef_type INTEGER; -ALTER TABLE m_acc_cert_campaign ADD stageNumber INTEGER; -ALTER TABLE m_acc_cert_campaign ADD startTimestamp TIMESTAMP; -ALTER TABLE m_acc_cert_campaign ADD state INTEGER; - -ALTER TABLE m_acc_cert_definition ADD handlerUri VARCHAR(255); -ALTER TABLE m_acc_cert_definition ADD lastCampaignClosedTimestamp TIMESTAMP; -ALTER TABLE m_acc_cert_definition ADD lastCampaignStartedTimestamp TIMESTAMP; -ALTER TABLE m_acc_cert_definition ADD ownerRef_relation VARCHAR(157); -ALTER TABLE m_acc_cert_definition ADD ownerRef_targetOid VARCHAR(36); -ALTER TABLE m_acc_cert_definition ADD ownerRef_type INTEGER; - -CREATE TABLE m_acc_cert_case ( - id INTEGER NOT NULL, - owner_oid VARCHAR(36) NOT NULL, - administrativeStatus INTEGER, - archiveTimestamp TIMESTAMP, - disableReason VARCHAR(255), - disableTimestamp TIMESTAMP, - effectiveStatus INTEGER, - enableTimestamp TIMESTAMP, - validFrom TIMESTAMP, - validTo TIMESTAMP, - validityChangeTimestamp TIMESTAMP, - validityStatus INTEGER, - currentStageNumber INTEGER, - currentStageOutcome INTEGER, - fullObject BLOB, - objectRef_relation VARCHAR(157), - objectRef_targetOid VARCHAR(36), - objectRef_type INTEGER, - orgRef_relation VARCHAR(157), - orgRef_targetOid VARCHAR(36), - orgRef_type INTEGER, - overallOutcome INTEGER, - remediedTimestamp TIMESTAMP, - reviewDeadline TIMESTAMP, - reviewRequestedTimestamp TIMESTAMP, - targetRef_relation VARCHAR(157), - targetRef_targetOid VARCHAR(36), - targetRef_type INTEGER, - tenantRef_relation VARCHAR(157), - tenantRef_targetOid VARCHAR(36), - tenantRef_type INTEGER, - PRIMARY KEY (id, owner_oid) -); - -CREATE TABLE m_acc_cert_case_reference ( - owner_id INTEGER NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reference_type INTEGER NOT NULL, - relation VARCHAR(157) NOT NULL, - targetOid VARCHAR(36) NOT NULL, - containerType INTEGER, - PRIMARY KEY (owner_id, owner_owner_oid, reference_type, relation, targetOid) -); - -CREATE TABLE m_acc_cert_decision ( - id INTEGER NOT NULL, - owner_id INTEGER NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reviewerComment VARCHAR(255), - response INTEGER, - reviewerRef_relation VARCHAR(157), - reviewerRef_targetOid VARCHAR(36), - reviewerRef_type INTEGER, - stageNumber INTEGER NOT NULL, - timestamp TIMESTAMP, - PRIMARY KEY (id, owner_id, owner_owner_oid) -); - -CREATE INDEX iCaseObjectRefTargetOid ON m_acc_cert_case (objectRef_targetOid); - -CREATE INDEX iCaseTargetRefTargetOid ON m_acc_cert_case (targetRef_targetOid); - -CREATE INDEX iCaseTenantRefTargetOid ON m_acc_cert_case (tenantRef_targetOid); - -CREATE INDEX iCaseOrgRefTargetOid ON m_acc_cert_case (orgRef_targetOid); - -CREATE INDEX iCaseReferenceTargetOid ON m_acc_cert_case_reference (targetOid); - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT uc_case_stage_reviewer UNIQUE (owner_owner_oid, owner_id, stageNumber, reviewerRef_targetOid); - -ALTER TABLE m_acc_cert_case -ADD CONSTRAINT fk_acc_cert_case_owner -FOREIGN KEY (owner_oid) -REFERENCES m_object; - -ALTER TABLE m_acc_cert_case_reference -ADD CONSTRAINT fk_acc_cert_case_ref_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT fk_acc_cert_decision_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_lookup_table_row -DROP CONSTRAINT uc_row_key; - -ALTER TABLE m_lookup_table_row -ADD CONSTRAINT uc_row_key UNIQUE (owner_oid, row_key); - -ALTER TABLE m_abstract_role ADD displayName_norm VARCHAR(255); -ALTER TABLE m_abstract_role ADD displayName_orig VARCHAR(255); -ALTER TABLE m_abstract_role ADD identifier VARCHAR(255); -ALTER TABLE m_abstract_role ADD riskLevel VARCHAR(255); - -ALTER TABLE m_org DROP COLUMN displayName_norm; -ALTER TABLE m_org DROP COLUMN displayName_orig; -ALTER TABLE m_org DROP COLUMN identifier; - -CREATE INDEX iAbstractRoleIdentifier ON m_abstract_role (identifier); diff --git a/config/sql/midpoint/3.4.1/mysql/mysql-upgrade-3.3-3.4.sql b/config/sql/midpoint/3.4.1/mysql/mysql-upgrade-3.3-3.4.sql deleted file mode 100644 index c62fef838b3..00000000000 --- a/config/sql/midpoint/3.4.1/mysql/mysql-upgrade-3.3-3.4.sql +++ /dev/null @@ -1,192 +0,0 @@ -CREATE TABLE m_service ( - displayOrder INTEGER, - locality_norm VARCHAR(255), - locality_orig VARCHAR(255), - name_norm VARCHAR(255), - name_orig VARCHAR(255), - oid VARCHAR(36) NOT NULL, - PRIMARY KEY (oid) -) - DEFAULT CHARACTER SET utf8 - COLLATE utf8_bin - ENGINE = InnoDB; - -CREATE TABLE m_service_type ( - service_oid VARCHAR(36) NOT NULL, - serviceType VARCHAR(255) -) - DEFAULT CHARACTER SET utf8 - COLLATE utf8_bin - ENGINE = InnoDB; - -ALTER TABLE m_service - ADD CONSTRAINT fk_service -FOREIGN KEY (oid) -REFERENCES m_abstract_role (oid); - -ALTER TABLE m_service_type - ADD CONSTRAINT fk_service_type -FOREIGN KEY (service_oid) -REFERENCES m_service (oid); - -ALTER TABLE m_task - ADD wfEndTimestamp DATETIME(6), - ADD wfObjectRef_relation VARCHAR(157), - ADD wfObjectRef_targetOid VARCHAR(36), - ADD wfObjectRef_type INTEGER, - ADD wfProcessInstanceId VARCHAR(255), - ADD wfRequesterRef_relation VARCHAR(157), - ADD wfRequesterRef_targetOid VARCHAR(36), - ADD wfRequesterRef_type INTEGER, - ADD wfStartTimestamp DATETIME(6), - ADD wfTargetRef_relation VARCHAR(157), - ADD wfTargetRef_targetOid VARCHAR(36), - ADD wfTargetRef_type INTEGER; - -CREATE INDEX iTaskWfProcessInstanceId ON m_task (wfProcessInstanceId); - -CREATE INDEX iTaskWfStartTimestamp ON m_task (wfStartTimestamp); - -CREATE INDEX iTaskWfEndTimestamp ON m_task (wfEndTimestamp); - -CREATE INDEX iTaskWfRequesterOid ON m_task (wfRequesterRef_targetOid); - -CREATE INDEX iTaskWfObjectOid ON m_task (wfObjectRef_targetOid); - -CREATE INDEX iTaskWfTargetOid ON m_task (wfTargetRef_targetOid); - -ALTER TABLE m_abstract_role - ADD ownerRef_relation VARCHAR(157), - ADD ownerRef_targetOid VARCHAR(36), - ADD ownerRef_type INTEGER; - -ALTER TABLE m_acc_cert_campaign -ADD endTimestamp DATETIME(6), -ADD handlerUri VARCHAR(255), -ADD ownerRef_relation VARCHAR(157), -ADD ownerRef_targetOid VARCHAR(36), -ADD ownerRef_type INTEGER, -ADD stageNumber INTEGER, -ADD startTimestamp DATETIME(6), -ADD state INTEGER; - -ALTER TABLE m_acc_cert_definition -ADD handlerUri VARCHAR(255), -ADD lastCampaignClosedTimestamp DATETIME(6), -ADD lastCampaignStartedTimestamp DATETIME(6), -ADD ownerRef_relation VARCHAR(157), -ADD ownerRef_targetOid VARCHAR(36), -ADD ownerRef_type INTEGER; - -CREATE TABLE m_acc_cert_case ( - id INTEGER NOT NULL, - owner_oid VARCHAR(36) NOT NULL, - administrativeStatus INTEGER, - archiveTimestamp DATETIME(6), - disableReason VARCHAR(255), - disableTimestamp DATETIME(6), - effectiveStatus INTEGER, - enableTimestamp DATETIME(6), - validFrom DATETIME(6), - validTo DATETIME(6), - validityChangeTimestamp DATETIME(6), - validityStatus INTEGER, - currentStageNumber INTEGER, - currentStageOutcome INTEGER, - fullObject LONGBLOB, - objectRef_relation VARCHAR(157), - objectRef_targetOid VARCHAR(36), - objectRef_type INTEGER, - orgRef_relation VARCHAR(157), - orgRef_targetOid VARCHAR(36), - orgRef_type INTEGER, - overallOutcome INTEGER, - remediedTimestamp DATETIME(6), - reviewDeadline DATETIME(6), - reviewRequestedTimestamp DATETIME(6), - targetRef_relation VARCHAR(157), - targetRef_targetOid VARCHAR(36), - targetRef_type INTEGER, - tenantRef_relation VARCHAR(157), - tenantRef_targetOid VARCHAR(36), - tenantRef_type INTEGER, - PRIMARY KEY (id, owner_oid) -) - DEFAULT CHARACTER SET utf8 - COLLATE utf8_bin - ENGINE = InnoDB; - -CREATE TABLE m_acc_cert_case_reference ( - owner_id INTEGER NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reference_type INTEGER NOT NULL, - relation VARCHAR(157) NOT NULL, - targetOid VARCHAR(36) NOT NULL, - containerType INTEGER, - PRIMARY KEY (owner_id, owner_owner_oid, reference_type, relation, targetOid) -) - DEFAULT CHARACTER SET utf8 - COLLATE utf8_bin - ENGINE = InnoDB; - -CREATE TABLE m_acc_cert_decision ( - id INTEGER NOT NULL, - owner_id INTEGER NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reviewerComment VARCHAR(255), - response INTEGER, - reviewerRef_relation VARCHAR(157), - reviewerRef_targetOid VARCHAR(36), - reviewerRef_type INTEGER, - stageNumber INTEGER NOT NULL, - timestamp DATETIME(6), - PRIMARY KEY (id, owner_id, owner_owner_oid) -) - DEFAULT CHARACTER SET utf8 - COLLATE utf8_bin - ENGINE = InnoDB; - -CREATE INDEX iCaseObjectRefTargetOid ON m_acc_cert_case (objectRef_targetOid); - -CREATE INDEX iCaseTargetRefTargetOid ON m_acc_cert_case (targetRef_targetOid); - -CREATE INDEX iCaseTenantRefTargetOid ON m_acc_cert_case (tenantRef_targetOid); - -CREATE INDEX iCaseOrgRefTargetOid ON m_acc_cert_case (orgRef_targetOid); - -CREATE INDEX iCaseReferenceTargetOid ON m_acc_cert_case_reference (targetOid); - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT uc_case_stage_reviewer UNIQUE (owner_owner_oid, owner_id, stageNumber, reviewerRef_targetOid); - -ALTER TABLE m_acc_cert_case -ADD CONSTRAINT fk_acc_cert_case_owner -FOREIGN KEY (owner_oid) -REFERENCES m_object (oid); - -ALTER TABLE m_acc_cert_case_reference -ADD CONSTRAINT fk_acc_cert_case_ref_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case (id, owner_oid); - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT fk_acc_cert_decision_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case (id, owner_oid); - -ALTER TABLE m_lookup_table_row -DROP KEY uc_row_key; - -ALTER TABLE m_lookup_table_row -ADD CONSTRAINT uc_row_key UNIQUE (owner_oid, row_key); - -ALTER TABLE m_abstract_role ADD displayName_norm VARCHAR(255); -ALTER TABLE m_abstract_role ADD displayName_orig VARCHAR(255); -ALTER TABLE m_abstract_role ADD identifier VARCHAR(255); -ALTER TABLE m_abstract_role ADD riskLevel VARCHAR(255); - -ALTER TABLE m_org DROP COLUMN displayName_norm; -ALTER TABLE m_org DROP COLUMN displayName_orig; -ALTER TABLE m_org DROP COLUMN identifier; - -CREATE INDEX iAbstractRoleIdentifier ON m_abstract_role (identifier); diff --git a/config/sql/midpoint/3.4.1/oracle/oracle-upgrade-3.3-3.4.sql b/config/sql/midpoint/3.4.1/oracle/oracle-upgrade-3.3-3.4.sql deleted file mode 100644 index 34c73270ecd..00000000000 --- a/config/sql/midpoint/3.4.1/oracle/oracle-upgrade-3.3-3.4.sql +++ /dev/null @@ -1,178 +0,0 @@ -CREATE TABLE m_service ( - displayOrder NUMBER(10, 0), - locality_norm VARCHAR2(255 CHAR), - locality_orig VARCHAR2(255 CHAR), - name_norm VARCHAR2(255 CHAR), - name_orig VARCHAR2(255 CHAR), - oid VARCHAR2(36 CHAR) NOT NULL, - PRIMARY KEY (oid) -) INITRANS 30; - -CREATE TABLE m_service_type ( - service_oid VARCHAR2(36 CHAR) NOT NULL, - serviceType VARCHAR2(255 CHAR) -) INITRANS 30; - -ALTER TABLE m_service - ADD CONSTRAINT fk_service -FOREIGN KEY (oid) -REFERENCES m_abstract_role; - -ALTER TABLE m_service_type - ADD CONSTRAINT fk_service_type -FOREIGN KEY (service_oid) -REFERENCES m_service; - -ALTER TABLE m_task ADD ( - wfEndTimestamp TIMESTAMP, - wfObjectRef_relation VARCHAR2(157 CHAR), - wfObjectRef_targetOid VARCHAR2(36 CHAR), - wfObjectRef_type NUMBER(10, 0), - wfProcessInstanceId VARCHAR2(255 CHAR), - wfRequesterRef_relation VARCHAR2(157 CHAR), - wfRequesterRef_targetOid VARCHAR2(36 CHAR), - wfRequesterRef_type NUMBER(10, 0), - wfStartTimestamp TIMESTAMP, - wfTargetRef_relation VARCHAR2(157 CHAR), - wfTargetRef_targetOid VARCHAR2(36 CHAR), - wfTargetRef_type NUMBER(10, 0) -); - -CREATE INDEX iTaskWfProcessInstanceId ON m_task (wfProcessInstanceId) INITRANS 30; - -CREATE INDEX iTaskWfStartTimestamp ON m_task (wfStartTimestamp) INITRANS 30; - -CREATE INDEX iTaskWfEndTimestamp ON m_task (wfEndTimestamp) INITRANS 30; - -CREATE INDEX iTaskWfRequesterOid ON m_task (wfRequesterRef_targetOid) INITRANS 30; - -CREATE INDEX iTaskWfObjectOid ON m_task (wfObjectRef_targetOid) INITRANS 30; - -CREATE INDEX iTaskWfTargetOid ON m_task (wfTargetRef_targetOid) INITRANS 30; - -ALTER TABLE m_abstract_role ADD ( - ownerRef_relation VARCHAR2(157 CHAR), - ownerRef_targetOid VARCHAR2(36 CHAR), - ownerRef_type NUMBER(10, 0) -); - -ALTER TABLE m_acc_cert_campaign ADD ( -endTimestamp TIMESTAMP, -handlerUri VARCHAR2(255 CHAR), -ownerRef_relation VARCHAR2(157 CHAR), -ownerRef_targetOid VARCHAR2(36 CHAR), -ownerRef_type NUMBER(10, 0), -stageNumber NUMBER(10, 0), -startTimestamp TIMESTAMP, -state NUMBER(10, 0)); - -ALTER TABLE m_acc_cert_definition ADD ( -handlerUri VARCHAR2(255 CHAR), -lastCampaignClosedTimestamp TIMESTAMP, -lastCampaignStartedTimestamp TIMESTAMP, -ownerRef_relation VARCHAR2(157 CHAR), -ownerRef_targetOid VARCHAR2(36 CHAR), -ownerRef_type NUMBER(10, 0)); - -CREATE TABLE m_acc_cert_case ( - id NUMBER(10, 0) NOT NULL, - owner_oid VARCHAR2(36 CHAR) NOT NULL, - administrativeStatus NUMBER(10, 0), - archiveTimestamp TIMESTAMP, - disableReason VARCHAR2(255 CHAR), - disableTimestamp TIMESTAMP, - effectiveStatus NUMBER(10, 0), - enableTimestamp TIMESTAMP, - validFrom TIMESTAMP, - validTo TIMESTAMP, - validityChangeTimestamp TIMESTAMP, - validityStatus NUMBER(10, 0), - currentStageNumber NUMBER(10, 0), - currentStageOutcome NUMBER(10, 0), - fullObject BLOB, - objectRef_relation VARCHAR2(157 CHAR), - objectRef_targetOid VARCHAR2(36 CHAR), - objectRef_type NUMBER(10, 0), - orgRef_relation VARCHAR2(157 CHAR), - orgRef_targetOid VARCHAR2(36 CHAR), - orgRef_type NUMBER(10, 0), - overallOutcome NUMBER(10, 0), - remediedTimestamp TIMESTAMP, - reviewDeadline TIMESTAMP, - reviewRequestedTimestamp TIMESTAMP, - targetRef_relation VARCHAR2(157 CHAR), - targetRef_targetOid VARCHAR2(36 CHAR), - targetRef_type NUMBER(10, 0), - tenantRef_relation VARCHAR2(157 CHAR), - tenantRef_targetOid VARCHAR2(36 CHAR), - tenantRef_type NUMBER(10, 0), - PRIMARY KEY (id, owner_oid) -) INITRANS 30; - -CREATE TABLE m_acc_cert_case_reference ( - owner_id NUMBER(10, 0) NOT NULL, - owner_owner_oid VARCHAR2(36 CHAR) NOT NULL, - reference_type NUMBER(10, 0) NOT NULL, - relation VARCHAR2(157 CHAR) NOT NULL, - targetOid VARCHAR2(36 CHAR) NOT NULL, - containerType NUMBER(10, 0), - PRIMARY KEY (owner_id, owner_owner_oid, reference_type, relation, targetOid) -) INITRANS 30; - -CREATE TABLE m_acc_cert_decision ( - id NUMBER(10, 0) NOT NULL, - owner_id NUMBER(10, 0) NOT NULL, - owner_owner_oid VARCHAR2(36 CHAR) NOT NULL, - reviewerComment VARCHAR2(255 CHAR), - response NUMBER(10, 0), - reviewerRef_relation VARCHAR2(157 CHAR), - reviewerRef_targetOid VARCHAR2(36 CHAR), - reviewerRef_type NUMBER(10, 0), - stageNumber NUMBER(10, 0) NOT NULL, - timestamp TIMESTAMP, - PRIMARY KEY (id, owner_id, owner_owner_oid) -) INITRANS 30; - -CREATE INDEX iCaseObjectRefTargetOid ON m_acc_cert_case (objectRef_targetOid) INITRANS 30; - -CREATE INDEX iCaseTargetRefTargetOid ON m_acc_cert_case (targetRef_targetOid) INITRANS 30; - -CREATE INDEX iCaseTenantRefTargetOid ON m_acc_cert_case (tenantRef_targetOid) INITRANS 30; - -CREATE INDEX iCaseOrgRefTargetOid ON m_acc_cert_case (orgRef_targetOid) INITRANS 30; - -CREATE INDEX iCaseReferenceTargetOid ON m_acc_cert_case_reference (targetOid) INITRANS 30; - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT uc_case_stage_reviewer UNIQUE (owner_owner_oid, owner_id, stageNumber, reviewerRef_targetOid) INITRANS 30; - -ALTER TABLE m_acc_cert_case -ADD CONSTRAINT fk_acc_cert_case_owner -FOREIGN KEY (owner_oid) -REFERENCES m_object; - -ALTER TABLE m_acc_cert_case_reference -ADD CONSTRAINT fk_acc_cert_case_ref_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT fk_acc_cert_decision_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_lookup_table_row -DROP CONSTRAINT uc_row_key; - -ALTER TABLE m_lookup_table_row -ADD CONSTRAINT uc_row_key UNIQUE (owner_oid, row_key) INITRANS 30; - -ALTER TABLE m_abstract_role ADD ( - displayName_norm VARCHAR2(255 CHAR), - displayName_orig VARCHAR2(255 CHAR), - identifier VARCHAR2(255 CHAR), - riskLevel VARCHAR2(255 CHAR)); - -ALTER TABLE m_org DROP (displayName_norm, displayName_orig, identifier); - -CREATE INDEX iAbstractRoleIdentifier ON m_abstract_role (identifier) INITRANS 30; diff --git a/config/sql/midpoint/3.4.1/postgresql/postgresql-upgrade-3.3-3.4.sql b/config/sql/midpoint/3.4.1/postgresql/postgresql-upgrade-3.3-3.4.sql deleted file mode 100644 index 8fce73055d4..00000000000 --- a/config/sql/midpoint/3.4.1/postgresql/postgresql-upgrade-3.3-3.4.sql +++ /dev/null @@ -1,179 +0,0 @@ -CREATE TABLE m_service ( - displayOrder INT4, - locality_norm VARCHAR(255), - locality_orig VARCHAR(255), - name_norm VARCHAR(255), - name_orig VARCHAR(255), - oid VARCHAR(36) NOT NULL, - PRIMARY KEY (oid) -); - -CREATE TABLE m_service_type ( - service_oid VARCHAR(36) NOT NULL, - serviceType VARCHAR(255) -); - -ALTER TABLE m_service - ADD CONSTRAINT fk_service -FOREIGN KEY (oid) -REFERENCES m_abstract_role; - -ALTER TABLE m_service_type - ADD CONSTRAINT fk_service_type -FOREIGN KEY (service_oid) -REFERENCES m_service; - -ALTER TABLE m_task - ADD wfEndTimestamp TIMESTAMP, - ADD wfObjectRef_relation VARCHAR(157), - ADD wfObjectRef_targetOid VARCHAR(36), - ADD wfObjectRef_type INT4, - ADD wfProcessInstanceId VARCHAR(255), - ADD wfRequesterRef_relation VARCHAR(157), - ADD wfRequesterRef_targetOid VARCHAR(36), - ADD wfRequesterRef_type INT4, - ADD wfStartTimestamp TIMESTAMP, - ADD wfTargetRef_relation VARCHAR(157), - ADD wfTargetRef_targetOid VARCHAR(36), - ADD wfTargetRef_type INT4; - -CREATE INDEX iTaskWfProcessInstanceId ON m_task (wfProcessInstanceId); - -CREATE INDEX iTaskWfStartTimestamp ON m_task (wfStartTimestamp); - -CREATE INDEX iTaskWfEndTimestamp ON m_task (wfEndTimestamp); - -CREATE INDEX iTaskWfRequesterOid ON m_task (wfRequesterRef_targetOid); - -CREATE INDEX iTaskWfObjectOid ON m_task (wfObjectRef_targetOid); - -CREATE INDEX iTaskWfTargetOid ON m_task (wfTargetRef_targetOid); - -ALTER TABLE m_abstract_role - ADD ownerRef_relation VARCHAR(157), - ADD ownerRef_targetOid VARCHAR(36), - ADD ownerRef_type INT4; - -ALTER TABLE m_acc_cert_campaign -ADD endTimestamp TIMESTAMP, -ADD handlerUri VARCHAR(255), -ADD ownerRef_relation VARCHAR(157), -ADD ownerRef_targetOid VARCHAR(36), -ADD ownerRef_type INT4, -ADD stageNumber INT4, -ADD startTimestamp TIMESTAMP, -ADD state INT4; - -ALTER TABLE m_acc_cert_definition -ADD handlerUri VARCHAR(255), -ADD lastCampaignClosedTimestamp TIMESTAMP, -ADD lastCampaignStartedTimestamp TIMESTAMP, -ADD ownerRef_relation VARCHAR(157), -ADD ownerRef_targetOid VARCHAR(36), -ADD ownerRef_type INT4; - -CREATE TABLE m_acc_cert_case ( - id INT4 NOT NULL, - owner_oid VARCHAR(36) NOT NULL, - administrativeStatus INT4, - archiveTimestamp TIMESTAMP, - disableReason VARCHAR(255), - disableTimestamp TIMESTAMP, - effectiveStatus INT4, - enableTimestamp TIMESTAMP, - validFrom TIMESTAMP, - validTo TIMESTAMP, - validityChangeTimestamp TIMESTAMP, - validityStatus INT4, - currentStageNumber INT4, - currentStageOutcome INT4, - fullObject BYTEA, - objectRef_relation VARCHAR(157), - objectRef_targetOid VARCHAR(36), - objectRef_type INT4, - orgRef_relation VARCHAR(157), - orgRef_targetOid VARCHAR(36), - orgRef_type INT4, - overallOutcome INT4, - remediedTimestamp TIMESTAMP, - reviewDeadline TIMESTAMP, - reviewRequestedTimestamp TIMESTAMP, - targetRef_relation VARCHAR(157), - targetRef_targetOid VARCHAR(36), - targetRef_type INT4, - tenantRef_relation VARCHAR(157), - tenantRef_targetOid VARCHAR(36), - tenantRef_type INT4, - PRIMARY KEY (id, owner_oid) -); - -CREATE TABLE m_acc_cert_case_reference ( - owner_id INT4 NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reference_type INT4 NOT NULL, - relation VARCHAR(157) NOT NULL, - targetOid VARCHAR(36) NOT NULL, - containerType INT4, - PRIMARY KEY (owner_id, owner_owner_oid, reference_type, relation, targetOid) -); - -CREATE TABLE m_acc_cert_decision ( - id INT4 NOT NULL, - owner_id INT4 NOT NULL, - owner_owner_oid VARCHAR(36) NOT NULL, - reviewerComment VARCHAR(255), - response INT4, - reviewerRef_relation VARCHAR(157), - reviewerRef_targetOid VARCHAR(36), - reviewerRef_type INT4, - stageNumber INT4 NOT NULL, - timestamp TIMESTAMP, - PRIMARY KEY (id, owner_id, owner_owner_oid) -); - -CREATE INDEX iCaseObjectRefTargetOid ON m_acc_cert_case (objectRef_targetOid); - -CREATE INDEX iCaseTargetRefTargetOid ON m_acc_cert_case (targetRef_targetOid); - -CREATE INDEX iCaseTenantRefTargetOid ON m_acc_cert_case (tenantRef_targetOid); - -CREATE INDEX iCaseOrgRefTargetOid ON m_acc_cert_case (orgRef_targetOid); - -CREATE INDEX iCaseReferenceTargetOid ON m_acc_cert_case_reference (targetOid); - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT uc_case_stage_reviewer UNIQUE (owner_owner_oid, owner_id, stageNumber, reviewerRef_targetOid); - -ALTER TABLE m_acc_cert_case -ADD CONSTRAINT fk_acc_cert_case_owner -FOREIGN KEY (owner_oid) -REFERENCES m_object; - -ALTER TABLE m_acc_cert_case_reference -ADD CONSTRAINT fk_acc_cert_case_ref_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT fk_acc_cert_decision_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_lookup_table_row -DROP CONSTRAINT uc_row_key; - -ALTER TABLE m_lookup_table_row -ADD CONSTRAINT uc_row_key UNIQUE (owner_oid, row_key); - -ALTER TABLE m_abstract_role - ADD displayName_norm VARCHAR(255), - ADD displayName_orig VARCHAR(255), - ADD identifier VARCHAR(255), - ADD riskLevel VARCHAR(255); - -ALTER TABLE m_org - DROP COLUMN displayName_norm, - DROP COLUMN displayName_orig, - DROP COLUMN identifier; - -CREATE INDEX iAbstractRoleIdentifier ON m_abstract_role (identifier); diff --git a/config/sql/midpoint/3.4.1/sqlserver/sqlserver-upgrade-3.3-3.4.sql b/config/sql/midpoint/3.4.1/sqlserver/sqlserver-upgrade-3.3-3.4.sql deleted file mode 100644 index 11ef88a5440..00000000000 --- a/config/sql/midpoint/3.4.1/sqlserver/sqlserver-upgrade-3.3-3.4.sql +++ /dev/null @@ -1,176 +0,0 @@ -CREATE TABLE m_service ( - displayOrder INT, - locality_norm NVARCHAR(255) COLLATE database_default, - locality_orig NVARCHAR(255) COLLATE database_default, - name_norm NVARCHAR(255) COLLATE database_default, - name_orig NVARCHAR(255) COLLATE database_default, - oid NVARCHAR(36) COLLATE database_default NOT NULL, - PRIMARY KEY (oid) -); - -CREATE TABLE m_service_type ( - service_oid NVARCHAR(36) COLLATE database_default NOT NULL, - serviceType NVARCHAR(255) COLLATE database_default -); - -ALTER TABLE m_service - ADD CONSTRAINT fk_service -FOREIGN KEY (oid) -REFERENCES m_abstract_role; - -ALTER TABLE m_service_type - ADD CONSTRAINT fk_service_type -FOREIGN KEY (service_oid) -REFERENCES m_service; - -ALTER TABLE m_task ADD - wfEndTimestamp DATETIME2, - wfObjectRef_relation NVARCHAR(157) COLLATE database_default, - wfObjectRef_targetOid NVARCHAR(36) COLLATE database_default, - wfObjectRef_type INT, - wfProcessInstanceId NVARCHAR(255) COLLATE database_default, - wfRequesterRef_relation NVARCHAR(157) COLLATE database_default, - wfRequesterRef_targetOid NVARCHAR(36) COLLATE database_default, - wfRequesterRef_type INT, - wfStartTimestamp DATETIME2, - wfTargetRef_relation NVARCHAR(157) COLLATE database_default, - wfTargetRef_targetOid NVARCHAR(36) COLLATE database_default, - wfTargetRef_type INT; - -CREATE INDEX iTaskWfProcessInstanceId ON m_task (wfProcessInstanceId); - -CREATE INDEX iTaskWfStartTimestamp ON m_task (wfStartTimestamp); - -CREATE INDEX iTaskWfEndTimestamp ON m_task (wfEndTimestamp); - -CREATE INDEX iTaskWfRequesterOid ON m_task (wfRequesterRef_targetOid); - -CREATE INDEX iTaskWfObjectOid ON m_task (wfObjectRef_targetOid); - -CREATE INDEX iTaskWfTargetOid ON m_task (wfTargetRef_targetOid); - -ALTER TABLE m_abstract_role ADD - ownerRef_relation NVARCHAR(157) COLLATE database_default, - ownerRef_targetOid NVARCHAR(36) COLLATE database_default, - ownerRef_type INT; - -ALTER TABLE m_acc_cert_campaign ADD -endTimestamp DATETIME2, -handlerUri NVARCHAR(255) COLLATE database_default, -ownerRef_relation NVARCHAR(157) COLLATE database_default, -ownerRef_targetOid NVARCHAR(36) COLLATE database_default, -ownerRef_type INT, -stageNumber INT, -startTimestamp DATETIME2, -state INT; - -ALTER TABLE m_acc_cert_definition ADD -handlerUri NVARCHAR(255) COLLATE database_default, -lastCampaignClosedTimestamp DATETIME2, -lastCampaignStartedTimestamp DATETIME2, -ownerRef_relation NVARCHAR(157) COLLATE database_default, -ownerRef_targetOid NVARCHAR(36) COLLATE database_default, -ownerRef_type INT; - -CREATE TABLE m_acc_cert_case ( - id INT NOT NULL, - owner_oid NVARCHAR(36) COLLATE database_default NOT NULL, - administrativeStatus INT, - archiveTimestamp DATETIME2, - disableReason NVARCHAR(255) COLLATE database_default, - disableTimestamp DATETIME2, - effectiveStatus INT, - enableTimestamp DATETIME2, - validFrom DATETIME2, - validTo DATETIME2, - validityChangeTimestamp DATETIME2, - validityStatus INT, - currentStageNumber INT, - currentStageOutcome INT, - fullObject VARBINARY(MAX), - objectRef_relation NVARCHAR(157) COLLATE database_default, - objectRef_targetOid NVARCHAR(36) COLLATE database_default, - objectRef_type INT, - orgRef_relation NVARCHAR(157) COLLATE database_default, - orgRef_targetOid NVARCHAR(36) COLLATE database_default, - orgRef_type INT, - overallOutcome INT, - remediedTimestamp DATETIME2, - reviewDeadline DATETIME2, - reviewRequestedTimestamp DATETIME2, - targetRef_relation NVARCHAR(157) COLLATE database_default, - targetRef_targetOid NVARCHAR(36) COLLATE database_default, - targetRef_type INT, - tenantRef_relation NVARCHAR(157) COLLATE database_default, - tenantRef_targetOid NVARCHAR(36) COLLATE database_default, - tenantRef_type INT, - PRIMARY KEY (id, owner_oid) -); - -CREATE TABLE m_acc_cert_case_reference ( - owner_id INT NOT NULL, - owner_owner_oid NVARCHAR(36) COLLATE database_default NOT NULL, - reference_type INT NOT NULL, - relation NVARCHAR(157) COLLATE database_default NOT NULL, - targetOid NVARCHAR(36) COLLATE database_default NOT NULL, - containerType INT, - PRIMARY KEY (owner_id, owner_owner_oid, reference_type, relation, targetOid) -); - -CREATE TABLE m_acc_cert_decision ( - id INT NOT NULL, - owner_id INT NOT NULL, - owner_owner_oid NVARCHAR(36) COLLATE database_default NOT NULL, - reviewerComment NVARCHAR(255) COLLATE database_default, - response INT, - reviewerRef_relation NVARCHAR(157) COLLATE database_default, - reviewerRef_targetOid NVARCHAR(36) COLLATE database_default, - reviewerRef_type INT, - stageNumber INT NOT NULL, - timestamp DATETIME2, - PRIMARY KEY (id, owner_id, owner_owner_oid) -); - -CREATE INDEX iCaseObjectRefTargetOid ON m_acc_cert_case (objectRef_targetOid); - -CREATE INDEX iCaseTargetRefTargetOid ON m_acc_cert_case (targetRef_targetOid); - -CREATE INDEX iCaseTenantRefTargetOid ON m_acc_cert_case (tenantRef_targetOid); - -CREATE INDEX iCaseOrgRefTargetOid ON m_acc_cert_case (orgRef_targetOid); - -CREATE INDEX iCaseReferenceTargetOid ON m_acc_cert_case_reference (targetOid); - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT uc_case_stage_reviewer UNIQUE (owner_owner_oid, owner_id, stageNumber, reviewerRef_targetOid); - -ALTER TABLE m_acc_cert_case -ADD CONSTRAINT fk_acc_cert_case_owner -FOREIGN KEY (owner_oid) -REFERENCES m_object; - -ALTER TABLE m_acc_cert_case_reference -ADD CONSTRAINT fk_acc_cert_case_ref_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_acc_cert_decision -ADD CONSTRAINT fk_acc_cert_decision_owner -FOREIGN KEY (owner_id, owner_owner_oid) -REFERENCES m_acc_cert_case; - -ALTER TABLE m_lookup_table_row -DROP CONSTRAINT uc_row_key; - -ALTER TABLE m_lookup_table_row -ADD CONSTRAINT uc_row_key UNIQUE (owner_oid, row_key); - -ALTER TABLE m_abstract_role ADD - displayName_norm NVARCHAR(255) COLLATE database_default, - displayName_orig NVARCHAR(255) COLLATE database_default, - identifier NVARCHAR(255) COLLATE database_default, - riskLevel NVARCHAR(255) COLLATE database_default; - -ALTER TABLE m_org DROP COLUMN displayName_norm, displayName_orig, identifier; - -CREATE INDEX iAbstractRoleIdentifier ON m_abstract_role (identifier); diff --git a/config/sql/midpoint/3.4.1/h2/h2-3.4.sql b/config/sql/midpoint/3.5/h2/h2-3.5.sql similarity index 99% rename from config/sql/midpoint/3.4.1/h2/h2-3.4.sql rename to config/sql/midpoint/3.5/h2/h2-3.5.sql index 8f04979597d..a439be81d66 100644 --- a/config/sql/midpoint/3.4.1/h2/h2-3.4.sql +++ b/config/sql/midpoint/3.5/h2/h2-3.5.sql @@ -386,6 +386,7 @@ CREATE TABLE m_object ( creatorRef_type INTEGER, datesCount SMALLINT, fullObject BLOB, + lifecycleState VARCHAR(255), longsCount SMALLINT, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -801,6 +802,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/midpoint/3.5/h2/h2-upgrade-3.4-3.5.sql b/config/sql/midpoint/3.5/h2/h2-upgrade-3.4-3.5.sql new file mode 100644 index 00000000000..b2ef62f976e --- /dev/null +++ b/config/sql/midpoint/3.5/h2/h2-upgrade-3.4-3.5.sql @@ -0,0 +1,3 @@ +ALTER TABLE m_object ADD lifecycleState VARCHAR(157); + +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); \ No newline at end of file diff --git a/config/sql/midpoint/3.4.1/mysql/mysql-3.4.sql b/config/sql/midpoint/3.5/mysql/mysql-3.5.sql similarity index 99% rename from config/sql/midpoint/3.4.1/mysql/mysql-3.4.sql rename to config/sql/midpoint/3.5/mysql/mysql-3.5.sql index bbf6f91ef10..60ebce13077 100644 --- a/config/sql/midpoint/3.4.1/mysql/mysql-3.4.sql +++ b/config/sql/midpoint/3.5/mysql/mysql-3.5.sql @@ -480,6 +480,7 @@ CREATE TABLE m_object ( creatorRef_type INTEGER, datesCount SMALLINT, fullObject LONGBLOB, + lifecycleState VARCHAR(255), longsCount SMALLINT, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -985,6 +986,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/midpoint/3.5/mysql/mysql-upgrade-3.4-3.5.sql b/config/sql/midpoint/3.5/mysql/mysql-upgrade-3.4-3.5.sql new file mode 100644 index 00000000000..f5ac940b896 --- /dev/null +++ b/config/sql/midpoint/3.5/mysql/mysql-upgrade-3.4-3.5.sql @@ -0,0 +1,5 @@ +ALTER TABLE m_object + ADD lifecycleState VARCHAR(255); + +CREATE INDEX iObjectLifecycleState + ON m_object (lifecycleState); \ No newline at end of file diff --git a/config/sql/midpoint/3.4.1/oracle/oracle-3.4.sql b/config/sql/midpoint/3.5/oracle/oracle-3.5.sql similarity index 99% rename from config/sql/midpoint/3.4.1/oracle/oracle-3.4.sql rename to config/sql/midpoint/3.5/oracle/oracle-3.5.sql index e5b941ac759..f1791409829 100644 --- a/config/sql/midpoint/3.4.1/oracle/oracle-3.4.sql +++ b/config/sql/midpoint/3.5/oracle/oracle-3.5.sql @@ -389,6 +389,7 @@ CREATE TABLE m_object ( creatorRef_type NUMBER(10, 0), datesCount NUMBER(5, 0), fullObject BLOB, + lifecycleState VARCHAR2(255 CHAR), longsCount NUMBER(5, 0), modifierRef_relation VARCHAR2(157 CHAR), modifierRef_targetOid VARCHAR2(36 CHAR), @@ -811,6 +812,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass) INITRANS 30; CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp) INITRANS 30; +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState) INITRANS 30; + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue) INITRANS 30; CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType) INITRANS 30; diff --git a/config/sql/midpoint/3.5/oracle/oracle-upgrade-3.4-3.5.sql b/config/sql/midpoint/3.5/oracle/oracle-upgrade-3.4-3.5.sql new file mode 100644 index 00000000000..2f4b47fd2f8 --- /dev/null +++ b/config/sql/midpoint/3.5/oracle/oracle-upgrade-3.4-3.5.sql @@ -0,0 +1,3 @@ +ALTER TABLE m_object ADD (lifecycleState VARCHAR2(255 CHAR)); + +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState) INITRANS 30; \ No newline at end of file diff --git a/config/sql/midpoint/3.4.1/postgresql/postgresql-3.4.sql b/config/sql/midpoint/3.5/postgresql/postgresql-3.5.sql similarity index 99% rename from config/sql/midpoint/3.4.1/postgresql/postgresql-3.4.sql rename to config/sql/midpoint/3.5/postgresql/postgresql-3.5.sql index 399758bf742..ceade91b6e3 100644 --- a/config/sql/midpoint/3.4.1/postgresql/postgresql-3.4.sql +++ b/config/sql/midpoint/3.5/postgresql/postgresql-3.5.sql @@ -386,6 +386,7 @@ CREATE TABLE m_object ( creatorRef_type INT4, datesCount INT2, fullObject BYTEA, + lifecycleState VARCHAR(255), longsCount INT2, modifierRef_relation VARCHAR(157), modifierRef_targetOid VARCHAR(36), @@ -801,6 +802,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/midpoint/3.5/postgresql/postgresql-upgrade-3.4-3.5.sql b/config/sql/midpoint/3.5/postgresql/postgresql-upgrade-3.4-3.5.sql new file mode 100644 index 00000000000..39bc951d540 --- /dev/null +++ b/config/sql/midpoint/3.5/postgresql/postgresql-upgrade-3.4-3.5.sql @@ -0,0 +1,3 @@ +ALTER TABLE m_object ADD lifecycleState VARCHAR(255); + +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); \ No newline at end of file diff --git a/config/sql/midpoint/3.4.1/sqlserver/sqlserver-3.4.sql b/config/sql/midpoint/3.5/sqlserver/sqlserver-3.5.sql similarity index 99% rename from config/sql/midpoint/3.4.1/sqlserver/sqlserver-3.4.sql rename to config/sql/midpoint/3.5/sqlserver/sqlserver-3.5.sql index a717e8c45f2..847b647c6b8 100644 --- a/config/sql/midpoint/3.4.1/sqlserver/sqlserver-3.4.sql +++ b/config/sql/midpoint/3.5/sqlserver/sqlserver-3.5.sql @@ -386,6 +386,7 @@ CREATE TABLE m_object ( creatorRef_type INT, datesCount SMALLINT, fullObject VARBINARY(MAX), + lifecycleState NVARCHAR(255) COLLATE database_default, longsCount SMALLINT, modifierRef_relation NVARCHAR(157) COLLATE database_default, modifierRef_targetOid NVARCHAR(36) COLLATE database_default, @@ -801,6 +802,8 @@ CREATE INDEX iObjectTypeClass ON m_object (objectTypeClass); CREATE INDEX iObjectCreateTimestamp ON m_object (createTimestamp); +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); + CREATE INDEX iExtensionBoolean ON m_object_ext_boolean (ownerType, eName, booleanValue); CREATE INDEX iExtensionBooleanDef ON m_object_ext_boolean (owner_oid, ownerType); diff --git a/config/sql/midpoint/3.5/sqlserver/sqlserver-upgrade-3.4-3.5.sql b/config/sql/midpoint/3.5/sqlserver/sqlserver-upgrade-3.4-3.5.sql new file mode 100644 index 00000000000..b6be7bf11cf --- /dev/null +++ b/config/sql/midpoint/3.5/sqlserver/sqlserver-upgrade-3.4-3.5.sql @@ -0,0 +1,3 @@ +ALTER TABLE m_object ADD lifecycleState NVARCHAR(255) COLLATE database_default; + +CREATE INDEX iObjectLifecycleState ON m_object (lifecycleState); \ No newline at end of file diff --git a/gui/admin-gui/src/main/resources/initial-objects/230-lookup-lifecycle-state.xml b/gui/admin-gui/src/main/resources/initial-objects/230-lookup-lifecycle-state.xml new file mode 100644 index 00000000000..cabb0f49b59 --- /dev/null +++ b/gui/admin-gui/src/main/resources/initial-objects/230-lookup-lifecycle-state.xml @@ -0,0 +1,48 @@ + + + + + + Lifecycle States + + + draft + + + + proposed + + + + active + + + + deprecated + + + + archived + + + + failed + + + + diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 984e7d41f8b..837d7be603e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3399,4 +3399,7 @@ MergeType.EXPRESSION=expression MergeType.ALL_RIGHT=allRight MergeType.ALL_LEFT=allLeft MergeType.EMPTY=empty -PageMergeObjects.warningMessage=Two objects' oids should be specified \ No newline at end of file +PageMergeObjects.warningMessage=Two objects' oids should be specified +ObjectType.name=Name +ObjectType.lifecycleState=Lifecycle state +ObjectType.description=description diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties index ab51e0873e1..44bf215cf3e 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en.properties @@ -3355,3 +3355,6 @@ MergeType.ALL_RIGHT=allRight MergeType.ALL_LEFT=allLeft MergeType.EMPTY=empty PageMergeObjects.warningMessage=Two objects' oids should be specified +ObjectType.name=Name +ObjectType.lifecycleState=Lifecycle state +ObjectType.description=description \ No newline at end of file diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/ActivationComputer.java b/infra/common/src/main/java/com/evolveum/midpoint/common/ActivationComputer.java index bfdba50fd1e..c51ed1a6ae5 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/ActivationComputer.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/ActivationComputer.java @@ -18,6 +18,7 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TimeIntervalStatusType; @@ -50,13 +51,23 @@ public void setClock(Clock clock) { this.clock = clock; } - public ActivationStatusType getEffectiveStatus(ActivationType activationType, ActivationStatusType defaultStatus) { - return getEffectiveStatus(activationType, getValidityStatus(activationType), defaultStatus); + public ActivationStatusType getEffectiveStatus(String lifecycleStatus, ActivationType activationType) { + return getEffectiveStatus(lifecycleStatus, activationType, getValidityStatus(activationType)); } - public ActivationStatusType getEffectiveStatus(ActivationType activationType, TimeIntervalStatusType validityStatus, ActivationStatusType defaultStatus) { + public ActivationStatusType getEffectiveStatus(String lifecycleStatus, ActivationType activationType, TimeIntervalStatusType validityStatus) { + + if (SchemaConstants.LIFECYCLE_ARCHIVED.equals(lifecycleStatus)) { + return ActivationStatusType.ARCHIVED; + } + + if (lifecycleStatus != null && + !lifecycleStatus.equals(SchemaConstants.LIFECYCLE_ACTIVE) && !lifecycleStatus.equals(SchemaConstants.LIFECYCLE_DEPRECATED)) { + return ActivationStatusType.DISABLED; + } + if (activationType == null) { - return defaultStatus; + return ActivationStatusType.ENABLED; } ActivationStatusType administrativeStatus = activationType.getAdministrativeStatus(); if (administrativeStatus != null) { @@ -65,7 +76,7 @@ public ActivationStatusType getEffectiveStatus(ActivationType activationType, Ti } if (validityStatus == null) { // No administrative status, no validity. Return default. - return defaultStatus; + return ActivationStatusType.ENABLED; } switch (validityStatus) { case AFTER: @@ -101,17 +112,28 @@ public TimeIntervalStatusType getValidityStatus(ActivationType activationType, X return status; } - public void computeEffective(ActivationType activationType) { - computeEffective(activationType, clock.currentTimeXMLGregorianCalendar()); + public void computeEffective(String lifecycleStatus, ActivationType activationType) { + computeEffective(lifecycleStatus, activationType, clock.currentTimeXMLGregorianCalendar()); } - public void computeEffective(ActivationType activationType, XMLGregorianCalendar referenceTime) { + public void computeEffective(String lifecycleStatus, ActivationType activationType, XMLGregorianCalendar referenceTime) { ActivationStatusType effectiveStatus = null; + + if (lifecycleStatus != null && + !lifecycleStatus.equals(SchemaConstants.LIFECYCLE_ACTIVE) && !lifecycleStatus.equals(SchemaConstants.LIFECYCLE_DEPRECATED)) { + effectiveStatus = ActivationStatusType.DISABLED; + } + + if (SchemaConstants.LIFECYCLE_ARCHIVED.equals(lifecycleStatus)) { + effectiveStatus = ActivationStatusType.ARCHIVED; + } + ActivationStatusType administrativeStatus = activationType.getAdministrativeStatus(); - if (administrativeStatus != null) { + if (effectiveStatus == null && administrativeStatus != null) { // Explicit administrative status overrides everything effectiveStatus = administrativeStatus; } + TimeIntervalStatusType validityStatus = getValidityStatus(activationType); if (effectiveStatus == null) { if (validityStatus == null) { @@ -133,13 +155,13 @@ public void computeEffective(ActivationType activationType, XMLGregorianCalendar activationType.setValidityStatus(validityStatus); } - public boolean isActive(ActivationType activationType) { + public boolean isActive(String lifecycleStatus, ActivationType activationType) { if (activationType == null) { return true; } ActivationStatusType effectiveStatus = activationType.getEffectiveStatus(); if (effectiveStatus == null) { - computeEffective(activationType); + computeEffective(lifecycleStatus, activationType); effectiveStatus = activationType.getEffectiveStatus(); } if (effectiveStatus == null) { diff --git a/infra/common/src/test/java/com/evolveum/midpoint/common/TestActivationComputer.java b/infra/common/src/test/java/com/evolveum/midpoint/common/TestActivationComputer.java index 62dde124cda..6e7a3c0dc43 100644 --- a/infra/common/src/test/java/com/evolveum/midpoint/common/TestActivationComputer.java +++ b/infra/common/src/test/java/com/evolveum/midpoint/common/TestActivationComputer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; @@ -64,7 +65,7 @@ public void testGetAdministrativeEnabled() throws Exception { ActivationType activationType = createActivationType(ActivationStatusType.ENABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.DISABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.ENABLED, effectiveStatus); @@ -80,7 +81,7 @@ public void testGetAdministrativeDisabled() throws Exception { ActivationType activationType = createActivationType(ActivationStatusType.DISABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); @@ -96,11 +97,140 @@ public void testGetAdministrativeArchived() throws Exception { ActivationType activationType = createActivationType(ActivationStatusType.ARCHIVED, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.ARCHIVED, effectiveStatus); } + + @Test + public void testGetDraftAdministrativeEnabled() throws Exception { + System.out.println("\n===[ testGetDraftAdministrativeEnabled ]===\n"); + + // GIVEN + Clock clock = createClock(YEAR_START); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.DISABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_DRAFT, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); + } + + @Test + public void testGetProposedAdministrativeEnabled() throws Exception { + System.out.println("\n===[ testGetProposedAdministrativeEnabled ]===\n"); + + // GIVEN + Clock clock = createClock(YEAR_START); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.DISABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_PROPOSED, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); + } + + @Test + public void testGetActiveAdministrativeEnabled() throws Exception { + System.out.println("\n===[ testGetActiveAdministrativeEnabled ]===\n"); + + // GIVEN + Clock clock = createClock(YEAR_START); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.ENABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_ACTIVE, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.ENABLED, effectiveStatus); + } + + @Test + public void testGetActiveAdministrativeDisabled() throws Exception { + System.out.println("\n===[ testGetActiveAdministrativeDisabled ]===\n"); + + // GIVEN + Clock clock = createClock(YEAR_START); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.DISABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_ACTIVE, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); + } + + @Test + public void testGetDeprecatedAdministrativeDisabled() throws Exception { + System.out.println("\n===[ testGetDeprecatedAdministrativeDisabled ]===\n"); + + // GIVEN + Clock clock = createClock(SUMMER_SOLSTICE); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.DISABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_DEPRECATED, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); + } + + @Test + public void testGetDeprecatedAdministrativeEnabled() throws Exception { + System.out.println("\n===[ testGetDeprecatedAdministrativeEnabled ]===\n"); + + // GIVEN + Clock clock = createClock(SUMMER_SOLSTICE); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.ENABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_DEPRECATED, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.ENABLED, effectiveStatus); + } + + @Test + public void testGetActiveAdministrativeArchived() throws Exception { + System.out.println("\n===[ testGetAdministrativeArchived ]===\n"); + + // GIVEN + Clock clock = createClock(SUMMER_SOLSTICE); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.ARCHIVED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_ACTIVE, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.ARCHIVED, effectiveStatus); + } + + @Test + public void testGetArchivedAdministrativeEnabled() throws Exception { + System.out.println("\n===[ testGetArchivedAdministrativeEnabled ]===\n"); + + // GIVEN + Clock clock = createClock(SUMMER_SOLSTICE); + ActivationComputer activationComputer = createActivationComputer(clock); + ActivationType activationType = createActivationType(ActivationStatusType.ENABLED, SPRING_EQUINOX, AUTUMN_EQUINOX); + + // WHEN + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(SchemaConstants.LIFECYCLE_ARCHIVED, activationType); + + // THEN + assertEquals("Unexpected effective status", ActivationStatusType.ARCHIVED, effectiveStatus); + } + @Test public void testGetBeforeValidity() throws Exception { @@ -112,7 +242,7 @@ public void testGetBeforeValidity() throws Exception { ActivationType activationType = createActivationType(null, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); @@ -128,7 +258,7 @@ public void testGetInValidity() throws Exception { ActivationType activationType = createActivationType(null, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.ENABLED, effectiveStatus); @@ -144,7 +274,7 @@ public void testGetAfterValidity() throws Exception { ActivationType activationType = createActivationType(null, SPRING_EQUINOX, AUTUMN_EQUINOX); // WHEN - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(null, activationType); // THEN assertEquals("Unexpected effective status", ActivationStatusType.DISABLED, effectiveStatus); @@ -217,13 +347,25 @@ void testCompute(final String TEST_NAME, XMLGregorianCalendar now, ActivationSta XMLGregorianCalendar validTo, ActivationStatusType expectedEffective, TimeIntervalStatusType expectedValidity) { System.out.println("\n===[ "+TEST_NAME+" ]===\n"); + testCompute(TEST_NAME, null, now, administrativeStatus, validFrom, validTo, expectedEffective, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_DRAFT, now, administrativeStatus, validFrom, validTo, ActivationStatusType.DISABLED, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_PROPOSED, now, administrativeStatus, validFrom, validTo, ActivationStatusType.DISABLED, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_ACTIVE, now, administrativeStatus, validFrom, validTo, expectedEffective, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_DEPRECATED, now, administrativeStatus, validFrom, validTo, expectedEffective, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_FAILED, now, administrativeStatus, validFrom, validTo, ActivationStatusType.DISABLED, expectedValidity); + testCompute(TEST_NAME, SchemaConstants.LIFECYCLE_ARCHIVED, now, administrativeStatus, validFrom, validTo, ActivationStatusType.ARCHIVED, expectedValidity); + } + + void testCompute(final String TEST_NAME, String lifecycleState, XMLGregorianCalendar now, ActivationStatusType administrativeStatus, XMLGregorianCalendar validFrom, + XMLGregorianCalendar validTo, ActivationStatusType expectedEffective, TimeIntervalStatusType expectedValidity) { + // GIVEN Clock clock = createClock(now); ActivationComputer activationComputer = createActivationComputer(clock); ActivationType activationType = createActivationType(administrativeStatus, validFrom, validTo); // WHEN - activationComputer.computeEffective(activationType); + activationComputer.computeEffective(lifecycleState, activationType); // THEN assertEquals("Unexpected effective status", expectedEffective, activationType.getEffectiveStatus()); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java index 8105fbb3c8d..40fddc160fc 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java @@ -394,6 +394,9 @@ public PropertyDelta diff(PrismProperty other, boolean ignoreMetadata, boo public static PropertyDelta diff(PrismProperty a, PrismProperty b) { if (a == null) { + if (b == null) { + return null; + } PropertyDelta delta = b.createDelta(); delta.addValuesToAdd(PrismValue.cloneCollection(b.getValues())); return delta; diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java index 2c6ec6a451f..ef96c5ef531 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java @@ -106,7 +106,7 @@ public class GetOperationOptions implements Serializable, Cloneable { * don't log it. In other cases, error in logs may lead to misleading * information.. */ - Boolean allowNotFound; + private Boolean allowNotFound; /** * Return read-only object. The returned object will be only read by the client. The client will not modify it. @@ -115,6 +115,14 @@ public class GetOperationOptions implements Serializable, Cloneable { * at all times when the client do not plan to modify the returned object. */ private Boolean readOnly; + + /** + * Requirement how stale or fresh the retrieved data should be. It specifies maximum age of the value in millisecods. + * The default value is zero, which means that a fresh value must always be returned. This means that caches that do + * not guarantee fresh value cannot be used. If non-zero value is specified then such caches may be used. In case that + * Long.MAX_VALUE is specified then the caches are always used and fresh value is never retrieved. + */ + private Long staleness; public RetrieveOption getRetrieve() { return retrieve; @@ -394,6 +402,41 @@ public static boolean isReadOnly(GetOperationOptions options) { return options.readOnly; } + public Long getStaleness() { + return staleness; + } + + public void setStaleness(Long staleness) { + this.staleness = staleness; + } + + public static GetOperationOptions createStaleness(Long staleness) { + GetOperationOptions opts = new GetOperationOptions(); + opts.setStaleness(staleness); + return opts; + } + + public static GetOperationOptions createMaxStaleness() { + GetOperationOptions opts = new GetOperationOptions(); + opts.setStaleness(Long.MAX_VALUE); + return opts; + } + + public static long getStaleness(GetOperationOptions options) { + if (options == null) { + return 0L; + } + if (options.getStaleness() == null) { + return 0L; + } + return options.getStaleness(); + } + + public static boolean isMaxStaleness(GetOperationOptions options) { + return GetOperationOptions.getStaleness(options) == Long.MAX_VALUE; + } + + public RelationalValueSearchQuery getRelationalValueSearchQuery() { return relationalValueSearchQuery; } @@ -402,7 +445,7 @@ public void setRelationalValueSearchQuery(RelationalValueSearchQuery relationalV this.relationalValueSearchQuery = relationalValueSearchQuery; } - @Override + @Override public int hashCode() { final int prime = 31; int result = 1; @@ -410,60 +453,102 @@ public int hashCode() { result = prime * result + ((doNotDiscovery == null) ? 0 : doNotDiscovery.hashCode()); result = prime * result + ((noFetch == null) ? 0 : noFetch.hashCode()); result = prime * result + ((raw == null) ? 0 : raw.hashCode()); + result = prime * result + ((readOnly == null) ? 0 : readOnly.hashCode()); result = prime * result + ((relationalValueSearchQuery == null) ? 0 : relationalValueSearchQuery.hashCode()); result = prime * result + ((resolve == null) ? 0 : resolve.hashCode()); result = prime * result + ((resolveNames == null) ? 0 : resolveNames.hashCode()); result = prime * result + ((retrieve == null) ? 0 : retrieve.hashCode()); + result = prime * result + ((staleness == null) ? 0 : staleness.hashCode()); + result = prime * result + ((tolerateRawData == null) ? 0 : tolerateRawData.hashCode()); return result; } @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } GetOperationOptions other = (GetOperationOptions) obj; if (allowNotFound == null) { - if (other.allowNotFound != null) + if (other.allowNotFound != null) { return false; - } else if (!allowNotFound.equals(other.allowNotFound)) + } + } else if (!allowNotFound.equals(other.allowNotFound)) { return false; + } if (doNotDiscovery == null) { - if (other.doNotDiscovery != null) + if (other.doNotDiscovery != null) { return false; - } else if (!doNotDiscovery.equals(other.doNotDiscovery)) + } + } else if (!doNotDiscovery.equals(other.doNotDiscovery)) { return false; + } if (noFetch == null) { - if (other.noFetch != null) + if (other.noFetch != null) { return false; - } else if (!noFetch.equals(other.noFetch)) + } + } else if (!noFetch.equals(other.noFetch)) { return false; + } if (raw == null) { - if (other.raw != null) + if (other.raw != null) { + return false; + } + } else if (!raw.equals(other.raw)) { + return false; + } + if (readOnly == null) { + if (other.readOnly != null) { return false; - } else if (!raw.equals(other.raw)) + } + } else if (!readOnly.equals(other.readOnly)) { return false; + } if (relationalValueSearchQuery == null) { - if (other.relationalValueSearchQuery != null) + if (other.relationalValueSearchQuery != null) { return false; - } else if (!relationalValueSearchQuery.equals(other.relationalValueSearchQuery)) + } + } else if (!relationalValueSearchQuery.equals(other.relationalValueSearchQuery)) { return false; + } if (resolve == null) { - if (other.resolve != null) + if (other.resolve != null) { return false; - } else if (!resolve.equals(other.resolve)) + } + } else if (!resolve.equals(other.resolve)) { return false; + } if (resolveNames == null) { - if (other.resolveNames != null) + if (other.resolveNames != null) { return false; - } else if (!resolveNames.equals(other.resolveNames)) + } + } else if (!resolveNames.equals(other.resolveNames)) { return false; - if (retrieve != other.retrieve) + } + if (retrieve != other.retrieve) { return false; + } + if (staleness == null) { + if (other.staleness != null) { + return false; + } + } else if (!staleness.equals(other.staleness)) { + return false; + } + if (tolerateRawData == null) { + if (other.tolerateRawData != null) { + return false; + } + } else if (!tolerateRawData.equals(other.tolerateRawData)) { + return false; + } return true; } @@ -477,6 +562,7 @@ public GetOperationOptions clone() { clone.retrieve = this.retrieve; clone.allowNotFound = this.allowNotFound; clone.readOnly = this.readOnly; + clone.staleness = this.staleness; if (this.relationalValueSearchQuery != null) { clone.relationalValueSearchQuery = this.relationalValueSearchQuery.clone(); } @@ -494,6 +580,7 @@ public String toString() { appendVal(sb, "retrieve", retrieve); appendFlag(sb, "allowNotFound", allowNotFound); appendFlag(sb, "readOnly", readOnly); + appendVal(sb, "staleness", staleness); appendVal(sb, "relationalValueSearchQuery", relationalValueSearchQuery); if (sb.charAt(sb.length() - 1) == ',') { sb.deleteCharAt(sb.length() - 1); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 0f1b7abadd3..55bb010cb00 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -298,6 +298,15 @@ public abstract class SchemaConstants { public static final QName C_MODEL_CONTEXT = new QName(NS_C, "modelContext"); public static final QName C_ITEM_TO_APPROVE = new QName(NS_C, "itemToApprove"); public static final QName C_SHADOW_DISCRIMINATOR = new QName(NS_C, "shadowDiscriminator"); + + // Lifecycle + + public static final String LIFECYCLE_DRAFT = "draft"; + public static final String LIFECYCLE_PROPOSED = "proposed"; + public static final String LIFECYCLE_ACTIVE = "active"; + public static final String LIFECYCLE_DEPRECATED = "deprecated"; + public static final String LIFECYCLE_ARCHIVED = "archived"; + public static final String LIFECYCLE_FAILED = "failed"; // Samples diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java index 11e97b844fb..738947c2840 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/SchemaDebugUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,7 @@ import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.PropertyReferenceListType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; @@ -298,29 +299,26 @@ public static String prettyPrint(ResourceAttributeDefinitionType vc) { sb.append("..."); } -// if (vc.getValueConstructor() != null) { -// prettyPringValueConstructor(sb, vc.getValueConstructor()); -// sb.append(","); -// } -// -// if (vc.getSequence() != null) { -// sb.append("["); -// for (JAXBElement vconstr: vc.getSequence().getValueConstructor()) { -// prettyPringValueConstructor(sb,vconstr); -// sb.append(","); -// } -// sb.append("]"); -// } - // TODO: Other properties sb.append(")"); return sb.toString(); } - private static void prettyPringValueConstructor(StringBuilder sb, JAXBElement vconstr) { - sb.append("ValueConstructor("); - sb.append(prettyPrint(vconstr)); + public static String prettyPrint(CachingMetadataType cachingMetadata) { + if (cachingMetadata == null) { + return "null"; + } + StringBuilder sb = new StringBuilder("CachingMetadataType("); + if (cachingMetadata.getSerialNumber() != null) { + sb.append("serialNumber:"); + sb.append(prettyPrint(cachingMetadata.getSerialNumber())); + } + if (cachingMetadata.getRetrievalTimestamp() != null) { + sb.append("retrievalTimestamp:"); + sb.append(prettyPrint(cachingMetadata.getRetrievalTimestamp())); + } sb.append(")"); + return sb.toString(); } public static String prettyPrint(ObjectReferenceType ref) { diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index c6582c622d3..fb172b6e471 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -294,9 +294,54 @@ 250 - + + + + + +

+ Lifecycle state of the object. This property defines whether the + object represents a draft, proposed definition, whether it is active, + deprecated, and so on. +

+

+ There are few pre-defined lifecycle states. But custom lifecycle states + may also be defined. Pre-defined lifecycle states are: +

+
    +
  • draft: Definition of the new object in progress. The object is + NOT active. The definition may change at any moment. It is + not ready yet.
  • +
  • proposed: Definition of a new object is ready for use, but there + is still a review process to be applied (e.g. approval). + The object is NOT active. However the definition should + not change in this state.
  • +
  • active: Active and working definition. Ready to be used without + any unusual limitations.
  • +
  • deprecated: Active definition which is being phased out. The + definition is still fully operational. But it should not + be used for new assignments. E.g. it should not be requested, + it should not be approved, etc.
  • +
  • archived: Inactive historical definition. It is no longer used. + It is maintained only for historical, auditing and + sentimental reasons.
  • +
  • failed: Unexpected error has occured during object lifecycle. Result + of that event is that the object is rendered inactive. + The situation cannot be automatically remedied. Manual action + is needed.
  • +
+
+ + ObjectType.lifecycleState + 20 + 3.5 + + +
+
+ - + @@ -3350,6 +3395,7 @@ + @@ -10710,6 +10756,13 @@ + + + + + + + @@ -12628,5 +12681,54 @@ + + + + + TODO + + + + + + + + + + + + + + Definition of overall caching strategy. + + + + + + + Do not cache information at all. Caches are not used and not maintained. + + + + + + + + + + Caches are maintained with minimal impact on normal operations. + Generally the data are cached only if they are retrieved for other + reasons. There is no read-ahead. The writes are always going to the + resource (synchronously): read-through, write-through. + There is no cache eviction (but old information is overwritten if + newer information is available). + + + + + + + + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/UserComputer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/UserComputer.java index 5f127242f29..d96fd9036be 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/UserComputer.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/UserComputer.java @@ -37,7 +37,7 @@ public void recompute(PrismObject user) { UserType userType = user.asObjectable(); ActivationType activationType = userType.getActivation(); if (activationType != null) { - activationComputer.computeEffective(activationType); + activationComputer.computeEffective(userType.getLifecycleState(), activationType); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java index 571cbb96bac..3fa957a833d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java @@ -845,20 +845,23 @@ public static boolean evaluateIterationCondition(LensCont } + /** + * Used for assignments and similar objects that do not have separate lifecycle. + */ public static boolean isValid(AssignmentType assignmentType, XMLGregorianCalendar now, ActivationComputer activationComputer) { - return isValid(assignmentType.getActivation(), now, activationComputer); + return isValid(null, assignmentType.getActivation(), now, activationComputer); } public static boolean isValid(FocusType focus, XMLGregorianCalendar now, ActivationComputer activationComputer) { - return isValid(focus.getActivation(), now, activationComputer); + return isValid(focus.getLifecycleState(), focus.getActivation(), now, activationComputer); } - private static boolean isValid(ActivationType activationType, XMLGregorianCalendar now, ActivationComputer activationComputer) { + private static boolean isValid(String lifecycleState, ActivationType activationType, XMLGregorianCalendar now, ActivationComputer activationComputer) { if (activationType == null) { return true; } TimeIntervalStatusType validityStatus = activationComputer.getValidityStatus(activationType, now); - ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(activationType, validityStatus, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatus = activationComputer.getEffectiveStatus(lifecycleState, activationType, validityStatus); return effectiveStatus == ActivationStatusType.ENABLED; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java index a2554ac345a..1bd1a9d08de 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/FocusProcessor.java @@ -460,24 +460,30 @@ private void processActivationAdministrativeAndValidity(Le TimeIntervalStatusType validityStatusCurrent = null; XMLGregorianCalendar validityChangeTimestamp = null; + String lifecycleStateNew = null; + String lifecycleStateCurrent = null; ActivationType activationNew = null; ActivationType activationCurrent = null; PrismObject focusNew = focusContext.getObjectNew(); if (focusNew != null) { - activationNew = focusNew.asObjectable().getActivation(); + F focusTypeNew = focusNew.asObjectable(); + activationNew = focusTypeNew.getActivation(); if (activationNew != null) { validityStatusNew = activationComputer.getValidityStatus(activationNew, now); validityChangeTimestamp = activationNew.getValidityChangeTimestamp(); } + lifecycleStateNew = focusTypeNew.getLifecycleState(); } PrismObject focusCurrent = focusContext.getObjectCurrent(); if (focusCurrent != null) { - activationCurrent = focusCurrent.asObjectable().getActivation(); + F focusCurrentType = focusCurrent.asObjectable(); + activationCurrent = focusCurrentType.getActivation(); if (activationCurrent != null) { validityStatusCurrent = activationComputer.getValidityStatus(activationCurrent, validityChangeTimestamp); } + lifecycleStateCurrent = focusCurrentType.getLifecycleState(); } if (validityStatusCurrent == validityStatusNew) { @@ -493,8 +499,8 @@ private void processActivationAdministrativeAndValidity(Le recordValidityDelta(focusContext, validityStatusNew, now); } - ActivationStatusType effectiveStatusNew = activationComputer.getEffectiveStatus(activationNew, validityStatusNew, ActivationStatusType.ENABLED); - ActivationStatusType effectiveStatusCurrent = activationComputer.getEffectiveStatus(activationCurrent, validityStatusCurrent, ActivationStatusType.ENABLED); + ActivationStatusType effectiveStatusNew = activationComputer.getEffectiveStatus(lifecycleStateNew, activationNew, validityStatusNew); + ActivationStatusType effectiveStatusCurrent = activationComputer.getEffectiveStatus(lifecycleStateCurrent, activationCurrent, validityStatusCurrent); if (effectiveStatusCurrent == effectiveStatusNew) { // No change, (almost) no work diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java index 9413afb4fec..3911ed61583 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java @@ -630,8 +630,7 @@ private SynchronizationSituation determineSituationWithCor ObjectDelta syncDelta = change.getObjectDelta(); if (resourceShadow == null && syncDelta != null && ChangeType.ADD.equals(syncDelta.getChangeType())) { LOGGER.trace("Trying to compute current shadow from change delta add."); - PrismObject shadow = syncDelta - .computeChangedObject(syncDelta.getObjectToAdd()); + PrismObject shadow = syncDelta.computeChangedObject(syncDelta.getObjectToAdd()); resourceShadow = shadow; change.setCurrentShadow(shadow); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 68373bc7157..7b1090b6444 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -103,6 +103,7 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final File RESOURCE_DUMMY_FILE = new File(COMMON_DIR, "resource-dummy.xml"); protected static final File RESOURCE_DUMMY_DEPRECATED_FILE = new File(COMMON_DIR, "resource-dummy-deprecated.xml"); + protected static final File RESOURCE_DUMMY_CACHING_FILE = new File(COMMON_DIR, "resource-dummy-caching.xml"); protected static final String RESOURCE_DUMMY_OID = "10000000-0000-0000-0000-000000000004"; protected static final String RESOURCE_DUMMY_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004"; protected static final String RESOURCE_DUMMY_DRINK = "rum"; @@ -116,6 +117,7 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra // BLUE resource has WEAK mappings protected static final File RESOURCE_DUMMY_BLUE_FILE = new File(COMMON_DIR, "resource-dummy-blue.xml"); protected static final File RESOURCE_DUMMY_BLUE_DEPRECATED_FILE = new File(COMMON_DIR, "resource-dummy-blue-deprecated.xml"); + protected static final File RESOURCE_DUMMY_BLUE_CACHING_FILE = new File(COMMON_DIR, "resource-dummy-blue-caching.xml"); protected static final String RESOURCE_DUMMY_BLUE_OID = "10000000-0000-0000-0000-000000000204"; protected static final String RESOURCE_DUMMY_BLUE_NAME = "blue"; protected static final String RESOURCE_DUMMY_BLUE_NAMESPACE = MidPointConstants.NS_RI; @@ -135,6 +137,7 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra // Green dummy resource is authoritative protected static final File RESOURCE_DUMMY_GREEN_FILE = new File(COMMON_DIR, "resource-dummy-green.xml"); protected static final File RESOURCE_DUMMY_GREEN_DEPRECATED_FILE = new File(COMMON_DIR, "resource-dummy-green-deprecated.xml"); + protected static final File RESOURCE_DUMMY_GREEN_CACHING_FILE = new File(COMMON_DIR, "resource-dummy-green-caching.xml"); protected static final String RESOURCE_DUMMY_GREEN_OID = "10000000-0000-0000-0000-000000000404"; protected static final String RESOURCE_DUMMY_GREEN_NAME = "green"; protected static final String RESOURCE_DUMMY_GREEN_NAMESPACE = MidPointConstants.NS_RI; diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java index 9d3c6966bf8..cc4be884ff5 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java @@ -261,6 +261,164 @@ public void test055ModifyUserJackEnable() throws Exception { TestUtil.assertModifyTimestamp(userJack, start, end); } + @Test + public void test060ModifyUserJackLifecycleActive() throws Exception { + final String TEST_NAME = "test060ModifyUserJackLifecycleActive"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + modifyUserReplace(USER_JACK_OID, UserType.F_LIFECYCLE_STATE, task, result, SchemaConstants.LIFECYCLE_ACTIVE); + + // THEN + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack, "Jack Sparrow"); + + assertAdministrativeStatusEnabled(userJack); + assertValidity(userJack, null); + assertEffectiveStatus(userJack, ActivationStatusType.ENABLED); + assertEnableTimestampFocus(userJack, null, start); + + TestUtil.assertModifyTimestamp(userJack, start, end); + } + + @Test + public void test061ModifyUserJackLifecycleDraft() throws Exception { + final String TEST_NAME = "test061ModifyUserJackLifecycleDraft"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + modifyUserReplace(USER_JACK_OID, UserType.F_LIFECYCLE_STATE, task, result, SchemaConstants.LIFECYCLE_DRAFT); + + // THEN + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack, "Jack Sparrow"); + + assertAdministrativeStatusEnabled(userJack); + assertValidity(userJack, null); + assertEffectiveStatus(userJack, ActivationStatusType.DISABLED); + assertDisableTimestampFocus(userJack, start, end); + + TestUtil.assertModifyTimestamp(userJack, start, end); + } + + @Test + public void test065ModifyUserJackLifecycleDeprecated() throws Exception { + final String TEST_NAME = "test065ModifyUserJackLifecycleDeprecated"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + modifyUserReplace(USER_JACK_OID, UserType.F_LIFECYCLE_STATE, task, result, SchemaConstants.LIFECYCLE_DEPRECATED); + + // THEN + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack, "Jack Sparrow"); + + assertAdministrativeStatusEnabled(userJack); + assertValidity(userJack, null); + assertEffectiveStatus(userJack, ActivationStatusType.ENABLED); + assertEnableTimestampFocus(userJack, start, end); + + TestUtil.assertModifyTimestamp(userJack, start, end); + } + + @Test + public void test068ModifyUserJackLifecycleArchived() throws Exception { + final String TEST_NAME = "test068ModifyUserJackLifecycleArchived"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + modifyUserReplace(USER_JACK_OID, UserType.F_LIFECYCLE_STATE, task, result, SchemaConstants.LIFECYCLE_ARCHIVED); + + // THEN + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack, "Jack Sparrow"); + + assertAdministrativeStatusEnabled(userJack); + assertValidity(userJack, null); + assertEffectiveStatus(userJack, ActivationStatusType.ARCHIVED); + + TestUtil.assertModifyTimestamp(userJack, start, end); + } + + @Test + public void test069ModifyUserJackLifecycleNull() throws Exception { + final String TEST_NAME = "test069ModifyUserJackLifecycleNull"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + modifyUserReplace(USER_JACK_OID, UserType.F_LIFECYCLE_STATE, task, result); + + // THEN + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); + TestUtil.assertSuccess(result); + + PrismObject userJack = getUser(USER_JACK_OID); + display("User after change execution", userJack); + assertUserJack(userJack, "Jack Sparrow"); + + assertAdministrativeStatusEnabled(userJack); + assertValidity(userJack, null); + assertEffectiveStatus(userJack, ActivationStatusType.ENABLED); + + TestUtil.assertModifyTimestamp(userJack, start, end); + } + @Test public void test100ModifyUserJackAssignAccount() throws Exception { final String TEST_NAME = "test100ModifyUserJackAssignAccount"; @@ -1604,7 +1762,7 @@ public void test350AssignMancombBlueAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1631,7 +1789,7 @@ public void test352AssignMancombBlackAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1664,7 +1822,7 @@ public void test355MancombModifyAdministrativeStatusNull() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1716,7 +1874,7 @@ public void test410AssignHermanKhakiAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestActivation.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java index 17db4b94aa3..abbb0f7585c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestCaseIgnore.java @@ -229,7 +229,7 @@ public void test139ModifyUserJackUnassignAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestCaseIgnore.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); rememberShadowFetchOperationCount(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java index 5b5bb707917..a28a3e056dd 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestIntent.java @@ -91,7 +91,7 @@ public void test131ModifyUserJackAssignAccountDefault() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -152,7 +152,7 @@ public void test132ModifyUserJackAssignAccountTest() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -226,7 +226,7 @@ public void test135ModifyUserJackFullName() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -289,7 +289,7 @@ public void test147ModifyUserJackUnAssignAccountDefault() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); @@ -350,7 +350,7 @@ public void test149ModifyUserJackUnassignAccountTest() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestIntent.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); preTestCleanup(AssignmentPolicyEnforcementType.RELATIVE); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java index 553dd8fe5d2..56348ac7a85 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java @@ -71,7 +71,7 @@ public void test100GetRepositoryDiag() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestMisc.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -93,7 +93,7 @@ public void test110RepositorySelfTest() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestMisc.class.getName() + "." + TEST_NAME); // WHEN OperationResult testResult = modelDiagnosticService.repositorySelfTest(task); @@ -111,7 +111,7 @@ public void test200ExportUsers() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestMisc.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContractCaching.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContractCaching.java new file mode 100644 index 00000000000..9c23e125ae1 --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestModelServiceContractCaching.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.model.intest; + +import static org.testng.AssertJUnit.assertTrue; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.File; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; + +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.match.MatchingRule; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; + +/** + * @author semancik + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestModelServiceContractCaching extends TestModelServiceContract { + + @Override + protected File getResourceDummyFile() { + return RESOURCE_DUMMY_CACHING_FILE; + } + + @Override + protected File getResourceDummyBlueFile() { + return RESOURCE_DUMMY_BLUE_CACHING_FILE; + } + + @Override + protected File getResourceDummyGreenFile() { + return RESOURCE_DUMMY_GREEN_CACHING_FILE; + } + + @Override + protected void assertShadowRepo(PrismObject shadow, String oid, String username, ResourceType resourceType, + QName objectClass, MatchingRule nameMatchingRule) throws SchemaException { + super.assertShadowRepo(shadow, oid, username, resourceType, objectClass, nameMatchingRule); + CachingMetadataType cachingMetadata = shadow.asObjectable().getCachingMetadata(); + assertNotNull("Missing caching metadata in repo shadow"+shadow, cachingMetadata); + } + + @Override + protected void assertRepoShadowAttributes(List> attributes, int expectedNumberOfIdentifiers) { + // We can only assert that there are at least the identifiers. But we do not know how many attributes should be there + assertTrue("Unexpected number of attributes in repo shadow, expected at least "+ + expectedNumberOfIdentifiers+", but was "+attributes.size(), attributes.size() >= expectedNumberOfIdentifiers); + } +} diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java index d59d44bf085..390ae725b00 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMultiResource.java @@ -672,7 +672,7 @@ public void test227ModifyUserJackDefaultDummyBrokenSchemaViolation() throws Exce TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestMultiResource.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -716,7 +716,7 @@ public void test228ModifyUserJackDefaultDummyNoError() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestMultiResource.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); dummyResource.resetBreakMode(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java index c5118826d7f..083bac736da 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRbac.java @@ -319,7 +319,7 @@ public void test120JackAssignRolePirateWhileAlreadyHasAccount() throws Exception TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject account = PrismTestUtil.parseObject(ACCOUNT_JACK_DUMMY_FILE); @@ -384,7 +384,7 @@ public void test121JackAssignAccountImplicitIntent() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // Precondition (simplified) @@ -417,7 +417,7 @@ public void test122JackAssignAccountExplicitIntent() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // Precondition (simplified) diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java index 712afde1139..cb42a7027c9 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java @@ -171,7 +171,7 @@ public void test100ModifyUserGuybrushAddAccountDummyRedNoAttributesConflict() th TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE); @@ -349,7 +349,7 @@ public void test200ModifyUserJackBrokenAccountRefAndPolyString() throws Exceptio TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -395,7 +395,7 @@ public void test210ModifyUserAddAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -427,7 +427,7 @@ public void test212ModifyUserAddAccountRed() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); @@ -462,7 +462,7 @@ public void test212ModifyUserJackBrokenSchemaViolationPolyString() throws Except TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -506,7 +506,7 @@ public void test214ModifyUserJackBrokenPassword() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -550,7 +550,7 @@ public void test220ModifyUserJackBrokenConflict() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -617,7 +617,7 @@ public void test301AddUserDeGhoulash() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -701,7 +701,7 @@ private void searchDeGhoulash(String testName, QName propName, T propValue) TestUtil.displayTestTile(this, testName); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + testName); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + testName); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); @@ -757,7 +757,7 @@ public void test330AssignDeGhoulashIdiot() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -791,7 +791,7 @@ public void test332AssignDeGhoulashRecursion() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -822,7 +822,7 @@ public void test340AssignDeGhoulashConstructionNonExistentResource() throws Exce TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -849,7 +849,7 @@ public void test349UnAssignDeGhoulashConstructionNonExistentResource() throws Ex TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -874,7 +874,7 @@ public void test350AssignDeGhoulashRoleBadConstructionResourceRef() throws Excep TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -903,7 +903,7 @@ public void test351UnAssignDeGhoulashRoleBadConstructionResourceRef() throws Exc TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -932,7 +932,7 @@ public void test360AddRoleTargetBadConstructionResourceRef() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -956,7 +956,7 @@ public void test400ImportJackMockTask() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -979,7 +979,7 @@ public void test401ListTasks() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -1028,7 +1028,7 @@ public void test410DeleteJack() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -1102,7 +1102,7 @@ public void test502EnumerationStoreGood() throws Exception { PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); PrismPropertyDefinition markDef = userDef.findPropertyDefinition(new ItemPath(UserType.F_EXTENSION, PIRACY_MARK)); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -1142,7 +1142,7 @@ public void test510EnumerationGetBad() throws Exception { } // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -1171,7 +1171,7 @@ public void test520ShipReadBad() throws Exception { // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyAuditService.clear(); @@ -1206,7 +1206,7 @@ public void test600AddUserGuybrushAssignAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject userBefore = getUser(USER_GUYBRUSH_OID); @@ -1251,7 +1251,7 @@ public void test610GetAccountGuybrushRogueAttribute() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestStrangeCases.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); dummyResource.setEnforceSchema(false); @@ -1287,7 +1287,7 @@ private void assertExtension(PrismObject object, QN * Break the user in the repo by inserting accountRef that points nowhere. */ private void addBrokenAccountRef(String userOid) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { - OperationResult result = new OperationResult(TestModelServiceContract.class.getName() + ".addBrokenAccountRef"); + OperationResult result = new OperationResult(TestStrangeCases.class.getName() + ".addBrokenAccountRef"); Collection modifications = ReferenceDelta.createModificationAddCollection(UserType.class, UserType.F_LINK_REF, prismContext, NON_EXISTENT_ACCOUNT_OID); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java index c0ded1aa06f..6c292a745d4 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java @@ -15,8 +15,23 @@ */ package com.evolveum.midpoint.model.intest.gensync; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.util.Collection; + +import javax.xml.namespace.QName; + +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.model.intest.TestModelServiceContract; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; @@ -39,7 +54,6 @@ import com.evolveum.midpoint.schema.RelationalValueSearchQuery; import com.evolveum.midpoint.schema.RelationalValueSearchType; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; @@ -55,7 +69,6 @@ import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.util.exception.TunnelException; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ImportOptionsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; @@ -70,22 +83,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; -import org.testng.annotations.Test; - -import java.io.File; -import java.util.Collection; - -import javax.xml.namespace.QName; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertTrue; - /** * @author semancik * @@ -113,7 +110,7 @@ public void test100LookupLanguagesGet() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -141,7 +138,7 @@ public void test102LookupLanguagesGetExclude() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); Collection> options = SelectorOptions.createCollection(LookupTableType.F_ROW, @@ -172,7 +169,7 @@ public void test110LookupLanguagesGetAll() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -195,7 +192,7 @@ public void test120LookupLanguagesGetByKeyExact() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -219,7 +216,7 @@ public void test121LookupLanguagesGetByKeyStartingWith() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -244,7 +241,7 @@ public void test122LookupLanguagesGetByKeyContaining() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -268,7 +265,7 @@ public void test123LookupLanguagesGetByKeyContainingWithPaging() throws Exceptio TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -293,7 +290,7 @@ public void test124LookupLanguagesGetByKeyContainingReturningNothing() throws Ex TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -324,7 +321,7 @@ public void test130LookupLanguagesGetByValueExact() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -352,7 +349,7 @@ public void test131LookupLanguagesGetByLabelStartingWith() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -379,7 +376,7 @@ public void test133LookupLanguagesGetByValueContainingWithPaging() throws Except TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -407,7 +404,7 @@ public void test140LookupLanguagesGetByIdExisting() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -450,7 +447,7 @@ public void test150LookupLanguagesAddRowFull() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -498,7 +495,7 @@ public void test152LookupLanguagesAddRowKeyLabel() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -546,7 +543,7 @@ public void test154LookupLanguagesAddRowKeyValue() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -595,7 +592,7 @@ public void test156LookupLanguagesAddRowExistingKey() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -620,7 +617,7 @@ public void test156LookupLanguagesAddRowExistingKey() throws Exception { result.computeStatus(); TestUtil.assertSuccess(result); - task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); result = task.getResult(); PrismObject lookup = getLookupTableAll(LOOKUP_LANGUAGES_OID, task, result); @@ -656,7 +653,7 @@ public void test162LookupLanguagesDeleteRowFullNoId() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -704,7 +701,7 @@ public void test164LookupLanguagesDeleteRowFullId() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -752,7 +749,7 @@ public void test166LookupLanguagesDeleteRowIdOnly() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -796,7 +793,7 @@ public void test168LookupLanguagesDeleteRowByKey() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row = new LookupTableRowType(); @@ -839,7 +836,7 @@ public void test170LookupLanguagesReplaceRows() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LookupTableRowType row1 = new LookupTableRowType(); @@ -895,7 +892,7 @@ public void test180LookupLanguagesReplaceObject() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject replacement = PrismTestUtil.parseObject(LOOKUP_LANGUAGES_REPLACEMENT_FILE); @@ -935,7 +932,7 @@ public void test182LookupLanguagesReimport() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ImportOptionsType options = new ImportOptionsType(); @@ -998,7 +995,7 @@ public void test200EditSchemaUser() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); @@ -1066,7 +1063,7 @@ public void test210UserDefinition() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1152,7 +1149,7 @@ public void test213ModifiedUserJack() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); modifyObjectReplaceProperty(UserType.class, USER_JACK_OID, UserType.F_PREFERRED_LANGUAGE, task, result, "en_PR"); @@ -1226,7 +1223,7 @@ public void test250EditSchemaRole() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObjectDefinition roleDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(RoleType.class); @@ -1253,7 +1250,7 @@ public void test260EditShadowSchemaKindIntent() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ResourceShadowDiscriminator discr = new ResourceShadowDiscriminator(RESOURCE_DUMMY_OID, ShadowKindType.ACCOUNT, null); @@ -1286,7 +1283,7 @@ public void test261EditShadowSchemaObjectclass() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ResourceShadowDiscriminator discr = new ResourceShadowDiscriminator(RESOURCE_DUMMY_OID, dummyResourceCtl.getAccountObjectClassQName()); @@ -1320,7 +1317,7 @@ public void test263EditShadowSchemaEmpty() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ResourceShadowDiscriminator discr = new ResourceShadowDiscriminator(null, null); @@ -1352,7 +1349,7 @@ public void test265EditShadowSchemaNull() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1396,7 +1393,7 @@ public void test800OtisEditSchemaUser() throws Exception { // GIVEN login(USER_OTIS_USERNAME); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObjectDefinition userDef = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(UserType.class); @@ -1466,7 +1463,7 @@ public void test810OtisGetJack() throws Exception { // GIVEN login(USER_OTIS_USERNAME); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -1550,7 +1547,7 @@ public void test820OtisSearchUsers() throws Exception { // GIVEN login(USER_OTIS_USERNAME); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestEditSchema.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java index d9bd78bb4a3..07a3a20dd9c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestAssignmentErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,6 @@ import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.impl.lens.LensContext; import com.evolveum.midpoint.model.intest.AbstractInitializedModelIntegrationTest; -import com.evolveum.midpoint.model.intest.TestModelServiceContract; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -172,7 +171,7 @@ public void test100UserJackAssignBlankAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); @@ -215,7 +214,7 @@ public void test101AddUserCharlesAssignBlankAccount() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyAuditService.clear(); @@ -257,7 +256,7 @@ public void test200UserLemonheadAssignAccountBrokenNetwork() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); @@ -301,7 +300,7 @@ public void test200UserLemonheadAssignAccountBrokenNetwork() throws Exception { // TestUtil.displayTestTile(this, TEST_NAME); // // // GIVEN -// Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); +// Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); // OperationResult result = task.getResult(); // assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); // @@ -335,7 +334,7 @@ public void test210UserSharptoothAssignAccountBrokenGeneric() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); @@ -400,7 +399,7 @@ public void test220UserAssignAccountDeletedShadowRecomputeSync() throws Exceptio PrismObject user = setupUserAssignAccountDeletedShadowRecompute(TEST_NAME, RESOURCE_DUMMY_OID, null, USER_AFET_NAME, USER_AFET_FULLNAME); String shadowOidBefore = getSingleLinkOid(user); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -422,7 +421,7 @@ public void test220UserAssignAccountDeletedShadowRecomputeSync() throws Exceptio // ... and again ... - task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); result = task.getResult(); // WHEN @@ -455,7 +454,7 @@ public void test222UserAssignAccountDeletedShadowRecomputeNoSync() throws Except //GIVEN PrismObject user = setupUserAssignAccountDeletedShadowRecompute(TEST_NAME, RESOURCE_DUMMY_RED_OID, RESOURCE_DUMMY_RED_NAME, USER_BFET_NAME, USER_BFET_FULLNAME); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); try { @@ -475,7 +474,7 @@ public void test222UserAssignAccountDeletedShadowRecomputeNoSync() throws Except // and again ... - task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); result = task.getResult(); try { @@ -511,7 +510,7 @@ public void test224UserAssignAccountDeletedShadowRecomputeReducedSync() throws E RESOURCE_DUMMY_YELLOW_OID, RESOURCE_DUMMY_YELLOW_NAME, USER_CFET_NAME, USER_CFET_FULLNAME); String shadowOidBefore = getSingleLinkOid(user); - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -533,7 +532,7 @@ public void test224UserAssignAccountDeletedShadowRecomputeReducedSync() throws E // ... and again ... - task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); result = task.getResult(); // WHEN @@ -557,7 +556,7 @@ private PrismObject setupUserAssignAccountDeletedShadowRecompute(final String dummyResourceName, String userName, String userFullName) throws Exception { // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestAssignmentErrors.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); dummyResource.resetBreakMode(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestBrokenResources.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestBrokenResources.java index 59957d84f5e..248cc6949c1 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestBrokenResources.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/negative/TestBrokenResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,13 @@ */ package com.evolveum.midpoint.model.intest.negative; +import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; -import static com.evolveum.midpoint.test.IntegrationTestTools.display; import java.io.File; import java.util.Collection; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -32,15 +31,11 @@ import com.evolveum.icf.dummy.resource.BreakMode; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyResource; -import com.evolveum.midpoint.model.api.ModelExecuteOptions; -import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.intest.AbstractConfiguredModelIntegrationTest; -import com.evolveum.midpoint.model.intest.TestModelServiceContract; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ObjectOperationOption; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; @@ -48,7 +43,6 @@ import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.test.AbstractIntegrationTest; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.MiscUtil; @@ -169,7 +163,7 @@ public void test010TestResourceBroken() throws Exception { TestUtil.displayTestTile(this, "test010TestResourceBroken"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test010TestResourceBroken"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test010TestResourceBroken"); OperationResult result = task.getResult(); // WHEN @@ -185,7 +179,7 @@ public void test020GetResourceBroken() throws Exception { TestUtil.displayTestTile(this, "test020GetResourceBroken"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test020GetResourceBroken"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test020GetResourceBroken"); OperationResult result = task.getResult(); // WHEN @@ -215,7 +209,7 @@ public void test100GetAccountMurray() throws Exception { TestUtil.displayTestTile(this, "test100GetAccountMurray"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test100GetAccountMurray"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test100GetAccountMurray"); OperationResult result = task.getResult(); try { @@ -240,7 +234,7 @@ public void test101GetAccountMurrayNoFetch() throws Exception { TestUtil.displayTestTile(this, "test101GetAccountMurrayNoFetch"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test101GetAccountMurrayNoFetch"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test101GetAccountMurrayNoFetch"); OperationResult result = task.getResult(); Collection> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch()); @@ -262,7 +256,7 @@ public void test102GetAccountMurrayRaw() throws Exception { TestUtil.displayTestTile(this, "test102GetAccountMurrayRaw"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test102GetAccountMurrayRaw"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test102GetAccountMurrayRaw"); OperationResult result = task.getResult(); Collection> options = SelectorOptions.createCollection(GetOperationOptions.createRaw()); @@ -285,7 +279,7 @@ public void test120SearchAccountByUsernameJack() throws Exception { TestUtil.displayTestTile(this, "test120SearchAccountByUsernameJack"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test120SearchAccountByUsernameJack"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test120SearchAccountByUsernameJack"); OperationResult result = task.getResult(); PrismObject resource = modelService.getObject(ResourceType.class, RESOURCE_CSVFILE_BROKEN_OID, null, task, result); @@ -310,7 +304,7 @@ public void test210TestResourceNotFound() throws Exception { TestUtil.displayTestTile(this, "test210TestResourceNotFound"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test210TestResourceNotFound"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test210TestResourceNotFound"); OperationResult result = task.getResult(); @@ -328,7 +322,7 @@ public void test220GetResourceNotFound() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "."+TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "."+TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -354,7 +348,7 @@ public void test221GetResourceNotFoundResolveConnector() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "."+TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "."+TEST_NAME); OperationResult result = task.getResult(); Collection> options = SelectorOptions.createCollection( @@ -385,7 +379,7 @@ public void test310TestResourceNoJars() throws Exception { TestUtil.displayTestTile(this, "test310TestResourceNoJars"); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + ".test310TestResourceNoJars"); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + ".test310TestResourceNoJars"); // WHEN OperationResult testResult = modelService.testResource(RESOURCE_DUMMY_NOJARS_OID, task); @@ -401,7 +395,7 @@ public void test320GetResourceNoJars() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -427,7 +421,7 @@ public void test350AddResourceWrongConnectorOid() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject resource = PrismTestUtil.parseObject(RESOURCE_DUMMY_WRONG_CONNECTOR_OID_FILE); @@ -459,7 +453,7 @@ public void test352AddResourceWrongConnectorOidRaw() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject resource = PrismTestUtil.parseObject(RESOURCE_DUMMY_WRONG_CONNECTOR_OID_FILE); @@ -492,7 +486,7 @@ public void test355AddResourceWrongConnectorOidRepo() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject resource = PrismTestUtil.parseObject(RESOURCE_DUMMY_WRONG_CONNECTOR_OID_FILE); @@ -511,7 +505,7 @@ public void test358GetResourceWrongConnectorOid() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -537,7 +531,7 @@ public void test359DeleteResourceWrongConnectorOid() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ObjectDelta delta = ObjectDelta.createDeleteDelta(ResourceType.class, RESOURCE_DUMMY_WRONG_CONNECTOR_OID_OID, prismContext); @@ -560,7 +554,7 @@ public void test360AddResourceNoConfiguration() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject resource = PrismTestUtil.parseObject(RESOURCE_DUMMY_NO_CONFIGURATION_FILE); @@ -584,7 +578,7 @@ public void test362GetResourceNoConfiguration() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -616,7 +610,7 @@ public void test369DeleteResourceNoConfiguration() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); ObjectDelta delta = ObjectDelta.createDeleteDelta(ResourceType.class, RESOURCE_DUMMY_NO_CONFIGURATION_OID, prismContext); @@ -645,7 +639,7 @@ public void test371ImportUnaccessibleResource() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -668,7 +662,7 @@ public void test373GetResourceNoConfiguration() throws Exception { TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN @@ -718,7 +712,7 @@ private void testAssignTwoResoures(final String TEST_NAME, String badResourceOid TestUtil.displayTestTile(this, TEST_NAME); // GIVEN - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); assumeAssignmentPolicy(AssignmentPolicyEnforcementType.POSITIVE); @@ -747,7 +741,7 @@ public void testListResources(final String TEST_NAME, int expectedNumber) throws TestUtil.displayTestTile(this, TEST_NAME); // GIVEN (1) - Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + Task task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN (1) @@ -762,7 +756,7 @@ public void testListResources(final String TEST_NAME, int expectedNumber) throws // GIVEN (2) resources.clear(); - task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + task = taskManager.createTaskInstance(TestBrokenResources.class.getName() + "." + TEST_NAME); result = task.getResult(); ResultHandler handler = new ResultHandler() { diff --git a/model/model-intest/src/test/resources/common/resource-dummy-blue-caching.xml b/model/model-intest/src/test/resources/common/resource-dummy-blue-caching.xml new file mode 100644 index 00000000000..c38b32e6ed1 --- /dev/null +++ b/model/model-intest/src/test/resources/common/resource-dummy-blue-caching.xml @@ -0,0 +1,328 @@ + + + + + + + + + + Dummy Resource Blue + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + + blue + true + + + + + + + + + + + + + + + icfs:uid + icfs:name + icfs:name + icfs:name + __ACCOUNT__ + + + + + + + + + ICF UID + read + + + + + + + + + + ICF NAME + + + + + + + + + + + + + + + + + + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + Username + + weak + + name + + + + + + + + $user/name + + + + + icfs:uid + UID + + + ri:fullname + Full Name + + weak + + $user/fullName + + + + + + + weak + + $user/fullName + + + + + ri:ship + Ship + + weak + + $user/organizationalUnit + + + + + ri:location + Location + + weak + + + $user/locality + + + + + + ri:drink + + weak + + + uuid + + + + + + ri:quote + Quote + false + + weak + + $user/description + + + $user/fullName + + + + + + + + ri:gossip + true + + weak + + $configuration/name + + + + + 5 + + + + + weak + + + + + + + + weak + + + + + + + + weak + + + + + + + + + + + passive + + + + + true + + + c:name + + + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + + + unmatched + http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#NoNsEnSe + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#inactivateShadow + + + + + + diff --git a/model/model-intest/src/test/resources/common/resource-dummy-caching.xml b/model/model-intest/src/test/resources/common/resource-dummy-caching.xml new file mode 100644 index 00000000000..d7d732ef34f --- /dev/null +++ b/model/model-intest/src/test/resources/common/resource-dummy-caching.xml @@ -0,0 +1,729 @@ + + + + + + + + Dummy Resource + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + + + true + + whatever + + USEless + true + + + + false + false + false + + + + + http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004 + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + Username + + strong + + $user/name + + + + + + + + weak + + $user/name + + + + + icfs:uid + UID + + + ri:fullname + Full Name + + + $user/fullName + + + + weak + + + + + $user/fullName + + + + + ri:title + true + + + ri:location + Location + + strong + + + $user/locality + + + + + http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#import + + false + + + + description + + + + + ri:ship + Ship + + + + + + organizationalUnit + + + + + + + + ri:loot + Loot + explicit + + http://pirates.net/avast + + + + + + + ri:weapon + Weapon + + weak + + + declare namespace piracy = "http://midpoint.evolveum.com/xml/ns/samples/piracy"; + $user/extension/piracy:weapon + + + + + + ri:drink + Drink + false + + strong + + rum + + + + + ri:quote + Quote + true + + strong + + Arr! + + + + + ri:gossip + Gossip + true + + + ri:water + + true + + + + + fishy + + + + + + very FISHY + + + $user/fullName + + + + + + ri:group + false + entitlement + group + objectToSubject + ri:members + icfs:name + + + + ri:priv + entitlement + privilege + subjectToObject + ri:privileges + icfs:name + + + + 5 + + + + daviejones + + + calypso + + + + + + + + + + + + + + + weak + + + + + + + + + + + + + + weak + + + + + + weak + + + + + + + + + + + account + test + Testing Account + false + ri:AccountObjectClass + + icfs:name + + strong + + $user/name + + + + + + + + weak + + + + + $user/name + + + + + ri:fullname + + + $user/fullName + + + + + + + weak + + $user/fullName + + + + + ri:location + + strong + + + $user/locality + + + + + + ri:ship + Ship + + + + + + organizationalUnit + + + + + + + + + ri:group + + + + + ri:group + + + + + entitlement + group + objectToSubject + ri:members + icfs:name + + + + ri:priv + entitlement + privilege + subjectToObject + ri:privileges + icfs:name + + + + 5 + + + + + + + weak + + + + + + + + + + + + + + + + entitlement + group + true + ri:GroupObjectClass + + icfs:name + Groupname + true + + + $focus/name + + + declare namespace t="http://prism.evolveum.com/xml/ns/public/types-3"; + t:norm + + + + + ri:description + + + $focus/description + + + + + ri:cc + + weak + + + declare namespace piracy = "http://midpoint.evolveum.com/xml/ns/samples/piracy"; + $focus/extension/piracy:costCenter + + + + + + declare namespace piracy = "http://midpoint.evolveum.com/xml/ns/samples/piracy"; + $focus/extension/piracy:costCenter + + + + + ri:members + minimal + + + + + entitlement + privilege + false + ri:CustomprivilegeObjectClass + + + + + + + usr + + + + acc + + + + res + + + 3 + size + + +to spiral :size + if :size > 30 [stop] + fd :size rt 15 + spiral :size *1.02 +end + + add + account + after + + + + + + + + + true + true + + + + passive + + + + + ri:AccountObjectClass + account + default + true + + + + + + name + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + $account/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + + ri:AccountObjectClass + account + test + true + + + + + + name + + + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + + diff --git a/model/model-intest/src/test/resources/common/resource-dummy-green-caching.xml b/model/model-intest/src/test/resources/common/resource-dummy-green-caching.xml new file mode 100644 index 00000000000..f78ce7c043c --- /dev/null +++ b/model/model-intest/src/test/resources/common/resource-dummy-green-caching.xml @@ -0,0 +1,533 @@ + + + + + + + + + + Dummy Resource Green + + + + + connectorType + com.evolveum.icf.dummy.connector.DummyConnector + + + connectorVersion + 2.0 + + + + + + + + green + true + true + + + + + + + + + + + + + + + icfs:uid + icfs:name + icfs:name + icfs:name + __ACCOUNT__ + + + + + + + + + ICF UID + read + + + + + + + + + + ICF NAME + + + + + + + + + + + + + + + + + + + + Default Account + true + ri:AccountObjectClass + + icfs:name + Username + + weak + + $user/name + + + + + + + + weak + + $c:user/c:name + + + + + icfs:uid + UID + + + ri:fullname + Full Name + + + $user/fullName + + + + strong + + $user/fullName + + + + + ri:location + Location + + strong + + + $c:user/c:locality + + + + + strong + http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#import + + + + + description + + + + + ri:ship + Ship + + strong + + + + + organizationalUnit + + + + + ri:internalId + + strong + + employeeNumber + + + + + ri:loot + Loot + + http://pirates.net/avast + + 10000 + + + + + ri:weapon + Weapon + + weak + + + $user/extension/piracy:weapon + + + + + + ri:drink + Drink + false + + strong + + rum + + + + + ri:quote + Quote + true + + strong + + Arr! + + + + + + 5 + + + + daviejones + + + calypso + + + + + + weak + + + + + + + + + weak + + + + + + + + + weak + + + + + + + + + + + + weak + + + + + + weak + + + + + + + + + + + account + admin + Admin Account + false + ri:AccountObjectClass + + icfs:name + Username + + weak + + $user/name + + + + + + + + weak + + + + + $c:user/c:name + + + + + icfs:uid + UID + + + ri:fullname + Full Name + + + $user/fullName + + + + weak + + $user/fullName + + + + + ri:weapon + Weapon + + weak + + Administrative Powers + + + + + + + + weak + + + + + + weak + + + + + + + + weak + + + + + + weak + + + + + + + + + + + + + none + + + + true + + + + passive + + + + + default account type + true + + + + + + c:name + + $account/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#deleteFocus + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + + admin account type + account + admin + true + + + + + + c:name + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + $account/attributes/icfs:name + + + + + linked + true + + + deleted + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#deleteFocus + + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + + diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index b76a092d39a..500f9a86969 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -23,6 +23,7 @@ + diff --git a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceObjectShadowChangeDescription.java b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceObjectShadowChangeDescription.java index 138a5938bee..98a68cf1152 100644 --- a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceObjectShadowChangeDescription.java +++ b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceObjectShadowChangeDescription.java @@ -39,10 +39,11 @@ * @author Radovan Semancik */ public class ResourceObjectShadowChangeDescription implements DebugDumpable, Serializable { + private static final long serialVersionUID = 1L; - private ObjectDelta objectDelta; - private PrismObject currentShadow; - private PrismObject oldShadow; + private ObjectDelta objectDelta; + private PrismObject currentShadow; + private PrismObject oldShadow; private String sourceChannel; private PrismObject resource; @@ -60,27 +61,27 @@ public class ResourceObjectShadowChangeDescription implements DebugDumpable, Ser */ private boolean unrelatedChange = false; - public ObjectDelta getObjectDelta() { + public ObjectDelta getObjectDelta() { return objectDelta; } - public void setObjectDelta(ObjectDelta objectDelta) { + public void setObjectDelta(ObjectDelta objectDelta) { this.objectDelta = objectDelta; } - public PrismObject getCurrentShadow() { + public PrismObject getCurrentShadow() { return currentShadow; } - public void setCurrentShadow(PrismObject currentShadow) { + public void setCurrentShadow(PrismObject currentShadow) { this.currentShadow = currentShadow; } - public PrismObject getOldShadow() { + public PrismObject getOldShadow() { return oldShadow; } - public void setOldShadow(PrismObject oldShadow) { + public void setOldShadow(PrismObject oldShadow) { this.oldShadow = oldShadow; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java index 9d3829ce04c..d26efd8ece0 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java @@ -80,11 +80,13 @@ import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningScriptType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; @@ -1042,7 +1044,8 @@ public void finishOperation(PrismObject object, Provis private boolean handleRepoObject(final Class type, PrismObject object, final Collection> options, - final ResultHandler handler, final OperationResult objResult){ + final ResultHandler handler, final OperationResult objResult) { + PrismObject completeObject; try { completeObject = completeObject(type, object, options, objResult); @@ -1073,9 +1076,21 @@ private boolean handleRepoObject(final Class type, Pri } validateObject(completeObject); + if (ShadowType.class.isAssignableFrom(type) && GetOperationOptions.isMaxStaleness(SelectorOptions.findRootOptions(options))) { + CachingMetadataType cachingMetadata = ((ShadowType)completeObject.asObjectable()).getCachingMetadata(); + if (cachingMetadata == null) { + objResult.recordFatalError("Requested cached data but no cached data are available in the shadow"); + } + } + objResult.computeStatus(); objResult.recordSuccessIfUnknown(); + if (!objResult.isSuccess()) { + OperationResultType resultType = objResult.createOperationResultType(); + completeObject.asObjectable().setFetchResult(resultType); + } + return handler.handle(completeObject, objResult); } @@ -1160,6 +1175,7 @@ public boolean handle(PrismObject object, OperationResult objResult) { return metadata; } + final boolean shouldDoRepoSearch = ProvisioningUtil.shouldDoRepoSearch(rootOptions); final ShadowHandler shadowHandler = new ShadowHandler() { @@ -1168,8 +1184,8 @@ public boolean handle(ShadowType shadowType) { OperationResult handleResult = result.createSubresult(ProvisioningService.class.getName() + ".searchObjectsIterative.handle"); - - if (GetOperationOptions.isNoFetch(rootOptions)){ + + if (shouldDoRepoSearch) { return handleRepoObject(type, shadowType.asPrismObject(), options, handler, handleResult); } @@ -1263,8 +1279,7 @@ public boolean handle(ShadowType shadowType) { return metadata; } - - /* + /* * (non-Javadoc) * * @see diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java index e9e16521f56..7c7e4940dbc 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ public void notifyEvent(ResourceEventDescription eventDescription, Task task, Op Collection> identifiers = ShadowUtil.getPrimaryIdentifiers(shadow); - Change change = new Change(identifiers, eventDescription.getCurrentShadow(), eventDescription.getOldShadow(), eventDescription.getDelta()); + Change change = new Change(identifiers, eventDescription.getCurrentShadow(), eventDescription.getOldShadow(), eventDescription.getDelta()); ObjectClassComplexTypeDefinition objectClassDefinition = ShadowUtil.getObjectClassDefinition(shadow); change.setObjectClassDefinition(objectClassDefinition); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java index cef3fcd58ff..9664cda7c53 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java @@ -1565,7 +1565,7 @@ private boolean isAttributeDelta(ItemDelta itemDelta) { return new ItemPath(ShadowType.F_ATTRIBUTES).equivalent(itemDelta.getParentPath()); } - public List> fetchChanges(ProvisioningContext ctx, PrismProperty lastToken, + public List fetchChanges(ProvisioningContext ctx, PrismProperty lastToken, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, GenericFrameworkException, ObjectNotFoundException { Validate.notNull(parentResult, "Operation result must not be null."); @@ -1579,11 +1579,11 @@ public List> fetchChanges(ProvisioningContext ctx, PrismPrope ConnectorInstance connector = ctx.getConnector(parentResult); // get changes from the connector - List> changes = connector.fetchChanges(ctx.getObjectClassDefinition(), lastToken, attrsToReturn, ctx, parentResult); + List changes = connector.fetchChanges(ctx.getObjectClassDefinition(), lastToken, attrsToReturn, ctx, parentResult); - Iterator> iterator = changes.iterator(); + Iterator iterator = changes.iterator(); while (iterator.hasNext()) { - Change change = iterator.next(); + Change change = iterator.next(); LOGGER.trace("Original change:\n{}", change.debugDump()); if (change.isTokenOnly()) { continue; @@ -1665,7 +1665,6 @@ private PrismObject postProcessResourceObjectRead(ProvisioningContex ConnectorInstance connector = ctx.getConnector(parentResult); ShadowType resourceObjectType = resourceObject.asObjectable(); - setCachingMetadata(ctx, resourceObject); ProvisioningUtil.setProtectedFlag(ctx, resourceObject, matchingRuleRegistry); // Simulated Activation @@ -1692,12 +1691,6 @@ private PrismObject postProcessResourceObjectRead(ProvisioningContex return resourceObject; } - public void setCachingMetadata(ProvisioningContext ctx, PrismObject resourceObject) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { - CachingMetadataType cachingMetadata = new CachingMetadataType(); - cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); - resourceObject.asObjectable().setCachingMetadata(cachingMetadata); - } - /** * Completes activation state by determinig simulated activation if * necessary. diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index a2f28a4be40..69ce0216094 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -20,6 +20,7 @@ import java.util.Iterator; import java.util.List; +import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.Item; @@ -30,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -68,6 +70,7 @@ import com.evolveum.midpoint.prism.query.SubstringFilter; import com.evolveum.midpoint.prism.query.ValueFilter; import com.evolveum.midpoint.prism.util.PrismUtil; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ChangeNotificationDispatcher; import com.evolveum.midpoint.provisioning.api.GenericConnectorException; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; @@ -119,7 +122,9 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AvailabilityStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; @@ -158,6 +163,9 @@ public abstract class ShadowCache { @Autowired(required = true) private ResourceManager resourceManager; + + @Autowired(required = true) + private Clock clock; @Autowired(required = true) private PrismContext prismContext; @@ -235,6 +243,11 @@ public PrismObject getShadow(String oid, PrismObject rep parentResult.recordFatalError("Provided OID is not equal to OID of repository shadow"); throw new IllegalArgumentException("Provided OID is not equal to OID of repository shadow"); } + + if (canReturnCached(options, repositoryShadow)) { + applyDefinition(repositoryShadow, parentResult); + return repositoryShadow; + } ProvisioningContext ctx = ctxFactory.create(repositoryShadow, task, parentResult); try { @@ -347,6 +360,31 @@ public PrismObject getShadow(String oid, PrismObject rep } + private boolean canReturnCached(Collection> options, PrismObject repositoryShadow) throws ConfigurationException { + long stalenessOption = GetOperationOptions.getStaleness(SelectorOptions.findRootOptions(options)); + if (stalenessOption == 0L) { + return false; + } + CachingMetadataType cachingMetadata = repositoryShadow.asObjectable().getCachingMetadata(); + if (cachingMetadata == null) { + if (stalenessOption == Long.MAX_VALUE) { + // We must return cached version but there is no cached version. + throw new ConfigurationException("Cached version of "+repositoryShadow+" requested, but there is no cached value"); + } + return false; + } + if (stalenessOption == Long.MAX_VALUE) { + return true; + } + + XMLGregorianCalendar retrievalTimestamp = cachingMetadata.getRetrievalTimestamp(); + if (retrievalTimestamp == null) { + return false; + } + long retrievalTimestampMillis = XmlTypeConverter.toMillis(retrievalTimestamp); + return (clock.currentTimeMillis() - retrievalTimestampMillis < stalenessOption); + } + private boolean isCompensate(GetOperationOptions rootOptions) { return !GetOperationOptions.isDoNotDiscovery(rootOptions); } @@ -424,6 +462,8 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr applyAttributesDefinition(ctx, shadow); shadowManager.setKindIfNecessary(shadow.asObjectable(), ctx.getObjectClassDefinition()); accessChecker.checkAdd(ctx, shadow, parentResult); + + // RESOURCE OPERATION: add shadow = resouceObjectConverter.addResourceObject(ctx, shadow, scripts, parentResult); } catch (Exception ex) { @@ -432,6 +472,7 @@ public String addShadow(PrismObject shadow, OperationProvisioningScr return shadow.getOid(); } + // REPO OPERATION: add // This is where the repo shadow is created (if needed) String oid = afterAddOnResource(ctx, shadow, parentResult); shadow.setOid(oid); @@ -830,7 +871,7 @@ public SearchResultMetadata searchObjectsIterative(final ProvisioningContext ctx applyDefinition(ctx, query); GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); - if (GetOperationOptions.isNoFetch(rootOptions)) { + if (ProvisioningUtil.shouldDoRepoSearch(rootOptions)) { return searchObjectsIterativeRepository(ctx, query, options, handler, parentResult); } @@ -1260,7 +1301,7 @@ public int synchronize(ResourceShadowDiscriminator shadowCoordinates, PrismPrope final ProvisioningContext ctx = ctxFactory.create(shadowCoordinates, task, parentResult); - List> changes = null; + List changes = null; try { changes = resouceObjectConverter.fetchChanges(ctx, lastToken, parentResult); @@ -1269,7 +1310,7 @@ public int synchronize(ResourceShadowDiscriminator shadowCoordinates, PrismPrope int processedChanges = 0; - for (Change change : changes) { + for (Change change : changes) { if (change.isTokenOnly()) { LOGGER.trace("Found token-only change: {}", change); @@ -1373,7 +1414,7 @@ public int synchronize(ResourceShadowDiscriminator shadowCoordinates, PrismPrope } @SuppressWarnings("rawtypes") - boolean processSynchronization(ProvisioningContext ctx, Change change, OperationResult result) + boolean processSynchronization(ProvisioningContext ctx, Change change, OperationResult result) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException { @@ -1435,7 +1476,7 @@ private void notifyResourceObjectChangeListeners(ResourceObjectShadowChangeDescr @SuppressWarnings("unchecked") private ResourceObjectShadowChangeDescription createResourceShadowChangeDescription( - Change change, ResourceType resourceType, String channel) { + Change change, ResourceType resourceType, String channel) { ResourceObjectShadowChangeDescription shadowChangeDescription = new ResourceObjectShadowChangeDescription(); shadowChangeDescription.setObjectDelta(change.getObjectDelta()); shadowChangeDescription.setResource(resourceType.asPrismObject()); @@ -1539,7 +1580,7 @@ private void deleteShadowFromRepo(Change change, OperationResult parentResult) } } - void processChange(ProvisioningContext ctx, Change change, PrismObject oldShadow, + void processChange(ProvisioningContext ctx, Change change, PrismObject oldShadow, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, GenericConnectorException, ObjectAlreadyExistsException { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCacheProvisioner.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCacheProvisioner.java index fde7fd39210..6fb1fcdfbf9 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCacheProvisioner.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCacheProvisioner.java @@ -24,6 +24,8 @@ import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType; + import org.springframework.stereotype.Component; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -120,6 +122,7 @@ private Collection extractRepoShadowChanges(ProvisioningCon throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); + CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); Collection shadowChanges = new ArrayList(); for (ItemDelta itemDelta : objectChange) { if (new ItemPath(ShadowType.F_ATTRIBUTES).equivalent(itemDelta.getParentPath())) { @@ -136,7 +139,7 @@ private Collection extractRepoShadowChanges(ProvisioningCon PropertyDelta nameDelta = PropertyDelta.createReplaceDelta(shadow.getDefinition(), ShadowType.F_NAME, new PolyString(newName)); shadowChanges.add(nameDelta); } - if (!ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrName)) { + if (!ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrName, cachingStrategy)) { continue; } } else if (new ItemPath(ShadowType.F_ACTIVATION).equivalent(itemDelta.getParentPath())) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 131c655f146..778407b6b1a 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -28,10 +28,16 @@ import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingPolicyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType; + +import org.jfree.util.Log; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; +import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -112,10 +118,16 @@ public class ShadowManager { @Autowired(required = true) @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; + + @Autowired(required = true) + private Clock clock; + @Autowired(required = true) private PrismContext prismContext; + @Autowired(required = true) private TaskManager taskManager; + @Autowired(required = true) private MatchingRuleRegistry matchingRuleRegistry; @@ -403,7 +415,7 @@ public PrismObject addRepositoryShadow(ProvisioningContext ctx, } // beware, may return null if an shadow that was to be marked as DEAD, was deleted in the meantime - public PrismObject findOrAddShadowFromChange(ProvisioningContext ctx, Change change, + public PrismObject findOrAddShadowFromChange(ProvisioningContext ctx, Change change, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException { @@ -475,7 +487,7 @@ public PrismObject findOrAddShadowFromChange(ProvisioningContext ctx return newShadow; } - public PrismObject findOrAddShadowFromChangeGlobalContext(ProvisioningContext globalCtx, Change change, + public PrismObject findOrAddShadowFromChangeGlobalContext(ProvisioningContext globalCtx, Change change, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException { @@ -547,7 +559,7 @@ public PrismObject findOrAddShadowFromChangeGlobalContext(Provisioni return newShadow; } - private PrismObject createNewAccountFromChange(ProvisioningContext ctx, Change change, + private PrismObject createNewAccountFromChange(ProvisioningContext ctx, Change change, OperationResult parentResult) throws SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException { @@ -578,7 +590,7 @@ private PrismObject createNewAccountFromChange(ProvisioningContext c return shadow; } - private List> searchShadowByIdenifiers(ProvisioningContext ctx, Change change, OperationResult parentResult) + private List> searchShadowByIdenifiers(ProvisioningContext ctx, Change change, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { Collection> identifiers = change.getIdentifiers(); @@ -766,38 +778,53 @@ public PrismObject createRepositoryShadow(ProvisioningContext ctx, P ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(shadow); PrismObject repoShadow = shadow.clone(); + ShadowType repoShadowType = repoShadow.asObjectable(); ResourceAttributeContainer repoAttributesContainer = ShadowUtil .getAttributesContainer(repoShadow); - // Clean all repoShadow attributes and add only those that should be - // there - repoAttributesContainer.clear(); - Collection> primaryIdentifiers = attributesContainer.getPrimaryIdentifiers(); - for (PrismProperty p : primaryIdentifiers) { - repoAttributesContainer.add(p.clone()); - } - - Collection> secondaryIdentifiers = attributesContainer.getSecondaryIdentifiers(); - for (PrismProperty p : secondaryIdentifiers) { - repoAttributesContainer.add(p.clone()); - } - - // Also add all the attributes that act as association identifiers. - // We will need them when the shadow is deleted (to remove the shadow from entitlements). - RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); - for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { - if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { - QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); - if (repoAttributesContainer.findAttribute(valueAttributeName) == null) { - ResourceAttribute valueAttribute = attributesContainer.findAttribute(valueAttributeName); - if (valueAttribute != null) { - repoAttributesContainer.add(valueAttribute.clone()); + CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); + if (cachingStrategy == CachingStategyType.NONE) { + // Clean all repoShadow attributes and add only those that should be + // there + repoAttributesContainer.clear(); + Collection> primaryIdentifiers = attributesContainer.getPrimaryIdentifiers(); + for (PrismProperty p : primaryIdentifiers) { + repoAttributesContainer.add(p.clone()); + } + + Collection> secondaryIdentifiers = attributesContainer.getSecondaryIdentifiers(); + for (PrismProperty p : secondaryIdentifiers) { + repoAttributesContainer.add(p.clone()); + } + + // Also add all the attributes that act as association identifiers. + // We will need them when the shadow is deleted (to remove the shadow from entitlements). + RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); + for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { + if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { + QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); + if (repoAttributesContainer.findAttribute(valueAttributeName) == null) { + ResourceAttribute valueAttribute = attributesContainer.findAttribute(valueAttributeName); + if (valueAttribute != null) { + repoAttributesContainer.add(valueAttribute.clone()); + } } } } + + repoShadowType.setCachingMetadata(null); + + ProvisioningUtil.cleanupShadowActivation(repoShadowType); + + } else if (cachingStrategy == CachingStategyType.PASSIVE) { + // Do not need to clear anything. Just store all attributes and add metadata. + CachingMetadataType cachingMetadata = new CachingMetadataType(); + cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); + repoShadowType.setCachingMetadata(cachingMetadata); + + } else { + throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); } - - ShadowType repoShadowType = repoShadow.asObjectable(); setKindIfNecessary(repoShadowType, ctx.getObjectClassDefinition()); // setIntentIfNecessary(repoShadowType, objectClassDefinition); @@ -831,21 +858,20 @@ public PrismObject createRepositoryShadow(ProvisioningContext ctx, P } normalizeAttributes(repoShadow, ctx.getObjectClassDefinition()); - - repoShadowType.setCachingMetadata(null); - - ProvisioningUtil.cleanupShadowActivation(repoShadowType); return repoShadow; } + @SuppressWarnings("unchecked") public Collection updateShadow(ProvisioningContext ctx, PrismObject resourceShadow, Collection aprioriDeltas, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { PrismObject repoShadow = repositoryService.getObject(ShadowType.class, resourceShadow.getOid(), null, result); RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition(); Collection repoShadowChanges = new ArrayList(); + CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); + for (RefinedAttributeDefinition attrDef: objectClassDefinition.getAttributeDefinitions()) { - if (ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrDef.getName())) { + if (ProvisioningUtil.shouldStoreAtributeInShadow(objectClassDefinition, attrDef.getName(), cachingStrategy)) { ResourceAttribute resourceAttr = ShadowUtil.getAttribute(resourceShadow, attrDef.getName()); PrismProperty repoAttr = repoShadow.findProperty(new ItemPath(ShadowType.F_ATTRIBUTES, attrDef.getName())); PropertyDelta attrDelta; @@ -857,6 +883,7 @@ public Collection updateShadow(ProvisioningContext ctx, PrismObject updateShadow(ProvisioningContext ctx, PrismObject updateShadow(ProvisioningContext ctx, PrismObject updateShadow(ProvisioningContext ctx, PrismObject currentResourceShadow, PrismObject oldRepoShadow, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, CommunicationException { @@ -888,11 +919,14 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject ObjectDelta shadowDelta = oldRepoShadow.createModifyDelta(); PrismContainer currentResourceAttributesContainer = currentResourceShadow.findContainer(ShadowType.F_ATTRIBUTES); PrismContainer oldRepoAttributesContainer = oldRepoShadow.findContainer(ShadowType.F_ATTRIBUTES); + + CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx); + for (Item currentResourceItem: currentResourceAttributesContainer.getValue().getItems()) { if (currentResourceItem instanceof PrismProperty) { PrismProperty currentResourceAttrProperty = (PrismProperty)currentResourceItem; RefinedAttributeDefinition attrDef = ocDef.findAttributeDefinition(currentResourceAttrProperty.getElementName()); - if (ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName())) { + if (ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName(), cachingStrategy)) { MatchingRule matchingRule = matchingRuleRegistry.getMatchingRule(attrDef.getMatchingRuleQName(), attrDef.getTypeName()); PrismProperty oldRepoAttributeProperty = oldRepoAttributesContainer.findProperty(currentResourceAttrProperty.getElementName()); if (oldRepoAttributeProperty == null ) { @@ -905,6 +939,7 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject normalizedRealValue = matchingRule.normalize(pval.getValue()); } attrAddDelta.addValueToAdd(new PrismPropertyValue(normalizedRealValue)); + LOGGER.trace("CURRENT ATTR:\n{}\nATTR DELTA:\n{}", currentResourceAttrProperty.debugDump(1), attrAddDelta.debugDump(1)); } shadowDelta.addModification(attrAddDelta); } else { @@ -917,6 +952,7 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject currentResourceNormalizedRealValue = matchingRule.normalize(currentResourceRealValue); } if (!currentResourceNormalizedRealValue.equals(oldRepoAttributeProperty.getRealValue())) { + LOGGER.trace("CURRENT ATTR:\n{}\ncurrentResourceNormalizedRealValue: {}", currentResourceAttrProperty.debugDump(1), currentResourceNormalizedRealValue); shadowDelta.addModificationReplaceProperty(currentResourceAttrProperty.getPath(), currentResourceNormalizedRealValue); } } else { @@ -927,8 +963,13 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject pval.setValue(normalizedRealValue); } } - PropertyDelta attrDiff = normalizedCurrentResourceAttrProperty.diff(oldRepoAttributeProperty); + PropertyDelta attrDiff = oldRepoAttributeProperty.diff(normalizedCurrentResourceAttrProperty); + LOGGER.trace("DIFF:\n{}\n-\n{}\n=:\n{}", + oldRepoAttributeProperty==null?null:oldRepoAttributeProperty.debugDump(1), + normalizedCurrentResourceAttrProperty==null?null:normalizedCurrentResourceAttrProperty.debugDump(1), + attrDiff==null?null:attrDiff.debugDump(1)); if (attrDiff != null && !attrDiff.isEmpty()) { + attrDiff.setParentPath(new ItemPath(ShadowType.F_ATTRIBUTES)); shadowDelta.addModification(attrDiff); } @@ -941,8 +982,10 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject if (oldRepoItem instanceof PrismProperty) { PrismProperty oldRepoAttrProperty = (PrismProperty)oldRepoItem; RefinedAttributeDefinition attrDef = ocDef.findAttributeDefinition(oldRepoAttrProperty.getElementName()); - if (attrDef == null || !ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName())) { - // No definition for this property, it should not be in the shadow + PrismProperty currentAttribute = currentResourceAttributesContainer.findProperty(oldRepoAttrProperty.getElementName()); + if (attrDef == null || !ProvisioningUtil.shouldStoreAtributeInShadow(ocDef, attrDef.getName(), cachingStrategy) || + currentAttribute == null) { + // No definition for this property it should not be there or no current value: remove it from the shadow PropertyDelta oldRepoAttrPropDelta = oldRepoAttrProperty.createDelta(); oldRepoAttrPropDelta.addValuesToDelete((Collection)PrismPropertyValue.cloneCollection(oldRepoAttrProperty.getValues())); shadowDelta.addModification(oldRepoAttrPropDelta); @@ -965,9 +1008,29 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject shadowDelta.addModification(auxOcDelta); } + if (cachingStrategy == CachingStategyType.NONE) { + if (oldRepoShadow.asObjectable().getCachingMetadata() != null) { + shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA); + } + + } else if (cachingStrategy == CachingStategyType.PASSIVE) { + + compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, currentResourceShadow, oldRepoShadow); + compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_FROM, currentResourceShadow, oldRepoShadow); + compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_TO, currentResourceShadow, oldRepoShadow); + compareUpdateProperty(shadowDelta, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS, currentResourceShadow, oldRepoShadow); + + CachingMetadataType cachingMetadata = new CachingMetadataType(); + cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); + shadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA, cachingMetadata); + + } else { + throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); + } + if (!shadowDelta.isEmpty()) { if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Updating shadow {} with delta:\n{}", oldRepoShadow, shadowDelta.debugDump()); + LOGGER.trace("Updating repo shadow {} with delta:\n{}", oldRepoShadow, shadowDelta.debugDump(1)); } ConstraintsChecker.onShadowModifyOperation(shadowDelta.getModifications()); try { @@ -976,16 +1039,27 @@ public PrismObject updateShadow(ProvisioningContext ctx, PrismObject // This should not happen for shadows throw new SystemException(e.getMessage(), e); } + PrismObject newRepoShadow = oldRepoShadow.clone(); shadowDelta.applyTo(newRepoShadow); return newRepoShadow; } else { - LOGGER.trace("No need to update shadow {} (empty delta)", oldRepoShadow); + LOGGER.trace("No need to update repo shadow {} (empty delta)", oldRepoShadow); return oldRepoShadow; } } + private void compareUpdateProperty(ObjectDelta shadowDelta, + ItemPath itemPath, PrismObject currentResourceShadow, PrismObject oldRepoShadow) { + PrismProperty currentProperty = currentResourceShadow.findProperty(itemPath); + PrismProperty oldProperty = oldRepoShadow.findProperty(itemPath); + PropertyDelta itemDelta = PrismProperty.diff(oldProperty, currentProperty); + if (itemDelta != null && !itemDelta.isEmpty()) { + shadowDelta.addModification(itemDelta); + } + } + /** * Re-reads the shadow, re-evaluates the identifiers and stored values, updates them if necessary. Returns * fixed shadow. @@ -1172,5 +1246,4 @@ public boolean compareAttribute(RefinedObjectClassDefinition refinedObjectCl Collection valuesB = getNormalizedAttributeValues(attributeB, refinedAttributeDefinition); return MiscUtil.unorderedCollectionEquals(valuesA, valuesB); } - } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Change.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Change.java index d0bfeec6e51..602771dff0d 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Change.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Change.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,47 +31,47 @@ * @author Radovan Semancik * */ -public final class Change implements DebugDumpable { +public final class Change implements DebugDumpable { private Collection> identifiers; private ObjectClassComplexTypeDefinition objectClassDefinition; - private ObjectDelta objectDelta; + private ObjectDelta objectDelta; private PrismProperty token; // TODO: maybe call this repoShadow? - private PrismObject oldShadow; - private PrismObject currentShadow; + private PrismObject oldShadow; + private PrismObject currentShadow; - public Change(Collection> identifiers, ObjectDelta change, PrismProperty token) { + public Change(Collection> identifiers, ObjectDelta change, PrismProperty token) { this.identifiers = identifiers; this.objectDelta = change; this.currentShadow = null; this.token = token; } - public Change(Collection> identifiers, PrismObject currentShadow, PrismProperty token) { + public Change(Collection> identifiers, PrismObject currentShadow, PrismProperty token) { this.identifiers = identifiers; this.objectDelta = null; this.currentShadow = currentShadow; this.token = token; } - public Change(Collection> identifiers, PrismObject currentShadow, PrismObject oldStadow, ObjectDelta objectDetla){ + public Change(Collection> identifiers, PrismObject currentShadow, PrismObject oldStadow, ObjectDelta objectDetla){ this.identifiers = identifiers; this.currentShadow = currentShadow; this.oldShadow = oldStadow; this.objectDelta = objectDetla; } - public Change(ObjectDelta change, PrismProperty token) { + public Change(ObjectDelta change, PrismProperty token) { this.objectDelta = change; this.token = token; } - public ObjectDelta getObjectDelta() { + public ObjectDelta getObjectDelta() { return objectDelta; } - public void setObjectDelta(ObjectDelta change) { + public void setObjectDelta(ObjectDelta change) { this.objectDelta = change; } @@ -99,19 +99,19 @@ public void setToken(PrismProperty token) { this.token = token; } - public PrismObject getOldShadow() { + public PrismObject getOldShadow() { return oldShadow; } - public void setOldShadow(PrismObject oldShadow) { + public void setOldShadow(PrismObject oldShadow) { this.oldShadow = oldShadow; } - public PrismObject getCurrentShadow() { + public PrismObject getCurrentShadow() { return currentShadow; } - public void setCurrentShadow(PrismObject currentShadow) { + public void setCurrentShadow(PrismObject currentShadow) { this.currentShadow = currentShadow; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java index 70b1c8809b1..a4fa67e4f50 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java @@ -300,7 +300,7 @@ void deleteObject(ObjectClassComplexTypeDefinition objectClass, Collection List> fetchChanges(ObjectClassComplexTypeDefinition objectClass, PrismProperty lastToken, AttributesToReturn attrsToReturn, StateReporter reporter, + List fetchChanges(ObjectClassComplexTypeDefinition objectClass, PrismProperty lastToken, AttributesToReturn attrsToReturn, StateReporter reporter, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException; //public ValidationResult validateConfiguration(ResourceConfiguration newConfiguration); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java index d429491e9ba..240c7170c13 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java @@ -2138,7 +2138,7 @@ public PrismProperty fetchCurrentToken(ObjectClassComplexTypeDefinition o } @Override - public List> fetchChanges(ObjectClassComplexTypeDefinition objectClass, PrismProperty lastToken, AttributesToReturn attrsToReturn, StateReporter reporter, + public List fetchChanges(ObjectClassComplexTypeDefinition objectClass, PrismProperty lastToken, AttributesToReturn attrsToReturn, StateReporter reporter, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException { @@ -2216,7 +2216,7 @@ public boolean handle(SyncDelta delta) { } } // convert changes from icf to midpoint Change - List> changeList; + List changeList; try { changeList = getChangesFromSyncDeltas(icfObjectClass, syncDeltas, resourceSchema, result); } catch (SchemaException ex) { @@ -2225,7 +2225,7 @@ public boolean handle(SyncDelta delta) { } if (lastReceivedToken != null) { - Change lastChange = new Change((ObjectDelta)null, getToken(lastReceivedToken)); + Change lastChange = new Change((ObjectDelta)null, getToken(lastReceivedToken)); LOGGER.trace("Adding last change: {}", lastChange); changeList.add(lastChange); } @@ -2805,10 +2805,10 @@ private void addConvertedValues(Collection> pvals, attributes.add(ab.build()); } - private List> getChangesFromSyncDeltas(ObjectClass connIdObjClass, Collection connIdDeltas, + private List getChangesFromSyncDeltas(ObjectClass connIdObjClass, Collection connIdDeltas, PrismSchema schema, OperationResult parentResult) throws SchemaException, GenericFrameworkException { - List> changeList = new ArrayList>(); + List changeList = new ArrayList(); QName objectClass = icfNameMapper.objectClassToQname(connIdObjClass, getSchemaNamespace(), legacySchema); ObjectClassComplexTypeDefinition objClassDefinition = null; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index 056eee27d93..37d3be723b9 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.ExecuteScriptArgument; import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; import com.evolveum.midpoint.schema.CapabilityUtil; +import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; @@ -56,6 +57,8 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingPolicyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionReturnMultiplicityType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningScriptArgumentType; @@ -310,19 +313,29 @@ public static void logWarning(Trace logger, OperationResult opResult, String mes opResult.recordWarning(message, ex); } - public static boolean shouldStoreAtributeInShadow(RefinedObjectClassDefinition objectClassDefinition, QName attributeName) { - if (objectClassDefinition.isPrimaryIdentifier(attributeName) || objectClassDefinition.isSecondaryIdentifier(attributeName)) { - return true; - } - for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { - if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { - QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); - if (QNameUtil.match(attributeName, valueAttributeName)) { - return true; + public static boolean shouldStoreAtributeInShadow(RefinedObjectClassDefinition objectClassDefinition, QName attributeName, + CachingStategyType cachingStrategy) throws ConfigurationException { + if (cachingStrategy == CachingStategyType.NONE) { + if (objectClassDefinition.isPrimaryIdentifier(attributeName) || objectClassDefinition.isSecondaryIdentifier(attributeName)) { + return true; + } + for (RefinedAssociationDefinition associationDef: objectClassDefinition.getAssociations()) { + if (associationDef.getResourceObjectAssociationType().getDirection() == ResourceObjectAssociationDirectionType.OBJECT_TO_SUBJECT) { + QName valueAttributeName = associationDef.getResourceObjectAssociationType().getValueAttribute(); + if (QNameUtil.match(attributeName, valueAttributeName)) { + return true; + } } } + return false; + + } else if (cachingStrategy == CachingStategyType.PASSIVE) { + RefinedAttributeDefinition attrDef = objectClassDefinition.findAttributeDefinition(attributeName); + return attrDef != null; + + } else { + throw new ConfigurationException("Unknown caching strategy "+cachingStrategy); } - return false; } public static boolean shouldStoreActivationItemInShadow(QName elementName) { // MID-2585 @@ -376,4 +389,20 @@ public static void checkShadowActivationConsistency(PrismObject shad //throw new IllegalStateException(m); // use only for testing } } + + public static CachingStategyType getCachingStrategy(ProvisioningContext ctx) + throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException { + CachingPolicyType caching = ctx.getResource().getCaching(); + if (caching == null) { + return CachingStategyType.NONE; + } + if (caching.getCachingStategy() == null) { + return CachingStategyType.NONE; + } + return caching.getCachingStategy(); + } + + public static boolean shouldDoRepoSearch(GetOperationOptions rootOptions) { + return GetOperationOptions.isNoFetch(rootOptions) || GetOperationOptions.isMaxStaleness(rootOptions); + } } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java index 21a8b7f220b..7f1482badca 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ProvisioningTestUtil.java @@ -143,6 +143,10 @@ public static void checkRepoEntitlementShadow(PrismObject repoShadow } public static void checkRepoShadow(PrismObject repoShadow, ShadowKindType kind) { + checkRepoShadow(repoShadow, kind, 2); + } + + public static void checkRepoShadow(PrismObject repoShadow, ShadowKindType kind, Integer expectedNumberOfAttributes) { ShadowType repoShadowType = repoShadow.asObjectable(); assertNotNull("No OID in repo shadow "+repoShadow, repoShadowType.getOid()); assertNotNull("No name in repo shadow "+repoShadow, repoShadowType.getName()); @@ -152,7 +156,9 @@ public static void checkRepoShadow(PrismObject repoShadow, ShadowKin assertNotNull("No attributes in repo shadow "+repoShadow, attributesContainer); List> attributes = attributesContainer.getValue().getItems(); assertFalse("Empty attributes in repo shadow "+repoShadow, attributes.isEmpty()); - assertEquals("Unexpected number of attributes in repo shadow "+repoShadow, 2, attributes.size()); + if (expectedNumberOfAttributes != null) { + assertEquals("Unexpected number of attributes in repo shadow "+repoShadow, (int)expectedNumberOfAttributes, attributes.size()); + } } public static QName getDefaultAccountObjectClass(ResourceType resourceType) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java index 5dba0d948af..f8ff82afd48 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java @@ -301,22 +301,18 @@ protected void checkConsistency(PrismObject object) throws } - protected void assertAttribute(ShadowType shadow, String attrName, T... expectedValues) { - ProvisioningTestUtil.assertAttribute(resource, shadow, attrName, expectedValues); + protected void assertAttribute(PrismObject shadow, String attrName, T... expectedValues) { + ProvisioningTestUtil.assertAttribute(resource, shadow.asObjectable(), attrName, expectedValues); } - protected void assertAttribute(ShadowType shadow, QName attrName, T... expectedValues) { - ProvisioningTestUtil.assertAttribute(resource, shadow, attrName, expectedValues); + protected void assertAttribute(PrismObject shadow, QName attrName, T... expectedValues) { + ProvisioningTestUtil.assertAttribute(resource, shadow.asObjectable(), attrName, expectedValues); } - protected void assertAttribute(ShadowType shadow, MatchingRule matchingRule, QName attrName, T... expectedValues) throws SchemaException { - ProvisioningTestUtil.assertAttribute(resource, shadow, matchingRule, attrName, expectedValues); + protected void assertAttribute(PrismObject shadow, MatchingRule matchingRule, QName attrName, T... expectedValues) throws SchemaException { + ProvisioningTestUtil.assertAttribute(resource, shadow.asObjectable(), matchingRule, attrName, expectedValues); } - - protected void assertNoAttribute(ShadowType shadow, String attrName) { - ProvisioningTestUtil.assertNoAttribute(resource, shadow, attrName); - } - + protected void assertNoAttribute(PrismObject shadow, String attrName) { ProvisioningTestUtil.assertNoAttribute(resource, shadow.asObjectable(), attrName); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java index b5677e3347f..80264861736 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java @@ -62,6 +62,7 @@ import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismObject; @@ -144,6 +145,8 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningScriptType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; @@ -192,6 +195,7 @@ public class TestDummy extends AbstractDummyTest { private String drakeIcfUid; private String corsairsIcfUid; private String corsairsShadowOid; + private String meathookAccountOid; protected MatchingRule getUidMatchingRule() { return null; @@ -1080,6 +1084,8 @@ public void test100AddAccount() throws Exception { account.checkConsistence(); display("Adding shadow", account); + + XMLGregorianCalendar start = clock.currentTimeXMLGregorianCalendar(); // WHEN TestUtil.displayWhen(TEST_NAME); @@ -1087,6 +1093,9 @@ public void test100AddAccount() throws Exception { // THEN TestUtil.displayThen(TEST_NAME); + + XMLGregorianCalendar end = clock.currentTimeXMLGregorianCalendar(); + result.computeStatus(); display("add object result", result); TestUtil.assertSuccess("addObject has failed (result)", result); @@ -1095,8 +1104,12 @@ public void test100AddAccount() throws Exception { account.checkConsistence(); PrismObject accountRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); - checkAccountShadowWill(accountRepo); + // Added account is slightly different case. Even not-returned-by-default attributes are stored in the cache. + checkRepoAccountShadowWill(accountRepo, start, end); + willIcfUid = getIcfUid(accountRepo); + display("Will ICF UID", willIcfUid); + assertNotNull("No will ICF UID", willIcfUid); ActivationType activationRepo = accountRepo.asObjectable().getActivation(); if (supportsActivation()) { @@ -1110,13 +1123,16 @@ public void test100AddAccount() throws Exception { PrismObject accountProvisioning = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result); + + XMLGregorianCalendar tsAfterRead = clock.currentTimeXMLGregorianCalendar(); + display("Account provisioning", accountProvisioning); ShadowType accountTypeProvisioning = accountProvisioning.asObjectable(); display("account from provisioning", accountTypeProvisioning); assertShadowName(accountProvisioning, ACCOUNT_WILL_USERNAME); assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, accountTypeProvisioning.getKind()); - assertAttribute(accountTypeProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, transformNameFromResource(ACCOUNT_WILL_USERNAME)); - assertAttribute(accountTypeProvisioning, getUidMatchingRule(), ConnectorFactoryIcfImpl.ICFS_UID, willIcfUid); + assertAttribute(accountProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, transformNameFromResource(ACCOUNT_WILL_USERNAME)); + assertAttribute(accountProvisioning, getUidMatchingRule(), ConnectorFactoryIcfImpl.ICFS_UID, willIcfUid); ActivationType activationProvisioning = accountTypeProvisioning.getActivation(); if (supportsActivation()) { @@ -1147,21 +1163,33 @@ public void test100AddAccount() throws Exception { assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); - ProvisioningTestUtil.checkRepoAccountShadow(shadowFromRepo); + checkRepoAccountShadow(shadowFromRepo); + + checkRepoAccountShadowWill(shadowFromRepo, end, tsAfterRead); checkConsistency(accountProvisioning); assertSteadyResource(); } - protected void checkAccountShadowWill(PrismObject accountRepo) { + protected void checkRepoAccountShadowWillBasic(PrismObject accountRepo, + XMLGregorianCalendar start, XMLGregorianCalendar end, Integer expectedNumberOfAttributes) { display("Will account repo", accountRepo); ShadowType accountTypeRepo = accountRepo.asObjectable(); assertShadowName(accountRepo, ACCOUNT_WILL_USERNAME); assertEquals("Wrong kind (repo)", ShadowKindType.ACCOUNT, accountTypeRepo.getKind()); - assertAttribute(accountTypeRepo, ConnectorFactoryIcfImpl.ICFS_NAME, getWillRepoIcfName()); + assertAttribute(accountRepo, ConnectorFactoryIcfImpl.ICFS_NAME, getWillRepoIcfName()); if (isIcfNameUidSame()) { - assertAttribute(accountTypeRepo, ConnectorFactoryIcfImpl.ICFS_UID, getWillRepoIcfName()); + assertAttribute(accountRepo, ConnectorFactoryIcfImpl.ICFS_UID, getWillRepoIcfName()); } + + assertNumberOfAttributes(accountRepo, expectedNumberOfAttributes); + + assertRepoCachingMetadata(accountRepo, start, end); + } + + protected void checkRepoAccountShadowWill(PrismObject accountRepo, XMLGregorianCalendar start, XMLGregorianCalendar end) { + checkRepoAccountShadowWillBasic(accountRepo, start, end, 2); + assertRepoShadowCacheActivation(accountRepo, null); } @Test @@ -1219,7 +1247,7 @@ public void test101AddAccountWithoutName() throws Exception { assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); - ProvisioningTestUtil.checkRepoAccountShadow(shadowFromRepo); + checkRepoAccountShadow(shadowFromRepo); checkConsistency(account.asPrismObject()); @@ -1238,8 +1266,8 @@ public void test102GetAccount() throws Exception { XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, + result); // THEN result.computeStatus(); @@ -1253,38 +1281,17 @@ public void test102GetAccount() throws Exception { assertNotNull("No dummy account", shadow); - checkAccountWill(shadow, result); + checkAccountWill(shadow, result, startTs, endTs); PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); - checkAccountShadowWill(shadowRepo); + checkRepoAccountShadowWill(shadowRepo, startTs, endTs); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); - checkCachingMetadata(shadow, startTs, endTs); - assertNoCachingMetadata(shadowRepo); + assertCachingMetadata(shadow, false, startTs, endTs); assertSteadyResource(); } - private void assertNoCachingMetadata(PrismObject shadowRepo) { - assertNull("Unexpected caching metadata in "+shadowRepo, shadowRepo.asObjectable().getCachingMetadata()); - } - - private void checkCachingMetadata(ShadowType shadow, XMLGregorianCalendar startTs, - XMLGregorianCalendar endTs) { - CachingMetadataType cachingMetadata = shadow.getCachingMetadata(); - assertNotNull("No caching metadata in "+shadow, cachingMetadata); - TestUtil.assertBetween("Wrong retrievalTimestamp in caching metadata in "+shadow, startTs, endTs, cachingMetadata.getRetrievalTimestamp()); - } - - protected void checkAccountWill(ShadowType shadow, OperationResult result) throws SchemaException, EncryptionException { - checkAccountShadow(shadow, result); - Collection> attributes = ShadowUtil.getAttributes(shadow); - assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); - assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); - assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); - assertEquals("Unexpected number of attributes", 6, attributes.size()); - } - @Test public void test103GetAccountNoFetch() throws Exception { final String TEST_NAME="test103GetAccountNoFetch"; @@ -1297,12 +1304,15 @@ public void test103GetAccountNoFetch() throws Exception { GetOperationOptions rootOptions = new GetOperationOptions(); rootOptions.setNoFetch(true); Collection> options = SelectorOptions.createCollection(rootOptions); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_WILL_OID, options, null, result); // THEN + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); result.computeStatus(); display("getObject result", result); TestUtil.assertSuccess(result); @@ -1312,10 +1322,11 @@ public void test103GetAccountNoFetch() throws Exception { assertNotNull("No dummy account", shadow); - checkAccountShadow(shadow, result, false); - checkAccountShadowWill(shadow.asPrismObject()); + checkAccountShadow(shadow, result, false, startTs, endTs); + // This is noFetch. Therefore the read should NOT update the caching timestamp + checkRepoAccountShadowWill(shadow, null, startTs); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } @@ -1346,6 +1357,277 @@ public void test105ApplyDefinitionModifyDelta() throws Exception { assertSteadyResource(); } + + /** + * Make a native modification to an account and read it again. Make sure that + * fresh data are returned - even though caching may be in effect. + * MID-3481 + */ + @Test + public void test106GetModifiedAccount() throws Exception { + final String TEST_NAME = "test106GetModifiedAccount"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + accountWill.setEnabled(false); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + assertShadowFetchOperationCountIncrement(1); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); + + assertNotNull("No dummy account", shadow); + + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertEquals("Unexpected number of attributes", 7, attributes.size()); + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, startTs, endTs, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.DISABLED); + + checkConsistency(shadow); + + assertCachingMetadata(shadow, false, startTs, endTs); + + assertSteadyResource(); + } + + /** + * Make a native modification to an account and read it with max staleness option. + * As there is no caching enabled this should throw an error. + * + * Note: This test is overridden in TestDummyCaching + * + * MID-3481 + */ + @Test + public void test107AGetModifiedAccountFromCacheMax() throws Exception { + final String TEST_NAME = "test107AGetModifiedAccountFromCacheMax"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Nice Pirate"); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Interceptor"); + accountWill.setEnabled(true); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createMaxStaleness()); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + + try { + + ShadowType shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, + result).asObjectable(); + + AssertJUnit.fail("Unexpected success"); + } catch (ConfigurationException e) { + // Caching is disabled, this is expected. + TestUtil.displayThen(TEST_NAME); + display("Expected exception", e); + result.computeStatus(); + TestUtil.assertFailure(result); + } + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, null, startTs, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.DISABLED); + + assertShadowFetchOperationCountIncrement(0); + + assertSteadyResource(); + } + + /** + * Make a native modification to an account and read it with high staleness option. + * In this test there is no caching enabled, so this should return fresh data. + * + * Note: This test is overridden in TestDummyCaching + * + * MID-3481 + */ + @Test + public void test107BGetModifiedAccountFromCacheHighStaleness() throws Exception { + final String TEST_NAME = "test107BGetModifiedAccountFromCacheHighStaleness"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Very Nice Pirate"); + accountWill.setEnabled(true); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createStaleness(1000000L)); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Very Nice Pirate"); + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, null, startTs, null); + + assertShadowFetchOperationCountIncrement(1); + + assertSteadyResource(); + } + + /** + * Staleness of one millisecond is too small for the cache to work. + * Fresh data should be returned - both in case the cache is enabled and disabled. + * MID-3481 + */ + @Test + public void test108GetAccountLowStaleness() throws Exception { + final String TEST_NAME = "test106GetModifiedAccount"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createStaleness(1L)); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + assertShadowFetchOperationCountIncrement(1); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); + + assertNotNull("No dummy account", shadow); + + checkAccountShadow(shadow, result, true, startTs, endTs); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Very Nice Pirate"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Interceptor"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertEquals("Unexpected number of attributes", 7, attributes.size()); + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, startTs, endTs, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Very Nice Pirate"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Interceptor"); + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + + checkConsistency(shadow); + + assertCachingMetadata(shadow, false, startTs, endTs); + + assertSteadyResource(); + } + + /** + * Clean up after caching tests so we won't break subsequent tests. + * MID-3481 + */ + @Test + public void test109ModifiedAccountCleanup() throws Exception { + final String TEST_NAME = "test109ModifiedAccountCleanup"; + TestUtil.displayTestTile(TEST_NAME); + + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + // Modify this back so won't break subsequent tests + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); + accountWill.replaceAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME); + accountWill.setEnabled(true); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, result); + + // THEN + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + assertShadowFetchOperationCountIncrement(1); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); + + assertNotNull("No dummy account", shadow); + + checkAccountWill(shadow, result, startTs, endTs); + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWill(shadowRepo, startTs, endTs); + + checkConsistency(shadow); + + assertCachingMetadata(shadow, false, startTs, endTs); + + assertSteadyResource(); + } @Test public void test110SeachIterative() throws Exception { @@ -1371,6 +1653,8 @@ public void test110SeachIterative() throws Exception { new QName(ResourceTypeUtil.getResourceNamespace(resourceType), ConnectorFactoryIcfImpl.ACCOUNT_OBJECT_CLASS_LOCAL_NAME), prismContext); + final XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + final Holder seenMeathookHolder = new Holder(false); final List> foundObjects = new ArrayList>(); ResultHandler handler = new ResultHandler() { @@ -1379,17 +1663,20 @@ public void test110SeachIterative() throws Exception { public boolean handle(PrismObject object, OperationResult parentResult) { foundObjects.add(object); display("Found", object); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); - ObjectType objectType = object.asObjectable(); - assertTrue(objectType instanceof ShadowType); - ShadowType shadow = (ShadowType) objectType; + assertTrue(object.canRepresent(ShadowType.class)); try { - checkAccountShadow(shadow, parentResult); + checkAccountShadow(object, parentResult, true, startTs, endTs); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } + assertCachingMetadata(object, false, startTs, endTs); + if (object.asObjectable().getName().getOrig().equals("meathook")) { + meathookAccountOid = object.getOid(); seenMeathookHolder.setValue(true); try { Long loot = ShadowUtil.getAttributeValue(object, dummyResourceCtl.getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME)); @@ -1403,11 +1690,13 @@ public boolean handle(PrismObject object, OperationResult parentResu } }; rememberShadowFetchOperationCount(); - + // WHEN provisioningService.searchObjectsIterative(ShadowType.class, query, null, handler, null, result); // THEN + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); result.computeStatus(); display("searchObjectsIterative result", result); TestUtil.assertSuccess(result); @@ -1418,18 +1707,30 @@ public boolean handle(PrismObject object, OperationResult parentResu assertProtected(foundObjects, 1); PrismObject shadowWillRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); - checkAccountShadowWill(shadowWillRepo); + assertRepoShadowCachedAttributeValue(shadowWillRepo, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); + checkRepoAccountShadowWill(shadowWillRepo, startTs, endTs); + + PrismObject shadowMeathook = repositoryService.getObject(ShadowType.class, meathookAccountOid, null, result); + display("Meathook shadow", shadowMeathook); + assertRepoShadowCachedAttributeValue(shadowMeathook, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "hook"); + assertRepoCachingMetadata(shadowMeathook, startTs, endTs); + // And again ... foundObjects.clear(); rememberShadowFetchOperationCount(); + XMLGregorianCalendar startTs2 = clock.currentTimeXMLGregorianCalendar(); + // WHEN provisioningService.searchObjectsIterative(ShadowType.class, query, null, handler, null, result); // THEN + XMLGregorianCalendar endTs2 = clock.currentTimeXMLGregorianCalendar(); assertShadowFetchOperationCountIncrement(1); display("Found shadows", foundObjects); @@ -1439,7 +1740,12 @@ public boolean handle(PrismObject object, OperationResult parentResu assertProtected(foundObjects, 1); shadowWillRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); - checkAccountShadowWill(shadowWillRepo); + checkRepoAccountShadowWill(shadowWillRepo, startTs2, endTs2); + + shadowMeathook = repositoryService.getObject(ShadowType.class, meathookAccountOid, null, result); + assertRepoShadowCachedAttributeValue(shadowMeathook, + DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "hook"); + assertRepoCachingMetadata(shadowMeathook, startTs2, endTs2); assertSteadyResource(); } @@ -1454,19 +1760,29 @@ public void test111SeachIterativeNoFetch() throws Exception { ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID, new QName(ResourceTypeUtil.getResourceNamespace(resourceType), - ConnectorFactoryIcfImpl.ACCOUNT_OBJECT_CLASS_LOCAL_NAME), prismContext); + ConnectorFactoryIcfImpl.ACCOUNT_OBJECT_CLASS_LOCAL_NAME), prismContext); + + final XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); final List> foundObjects = new ArrayList>(); ResultHandler handler = new ResultHandler() { @Override - public boolean handle(PrismObject object, OperationResult parentResult) { - foundObjects.add(object); + public boolean handle(PrismObject shadow, OperationResult parentResult) { + foundObjects.add(shadow); -// ObjectType objectType = object.asObjectable(); -// assertTrue(objectType instanceof ShadowType); -// ShadowType shadow = (ShadowType) objectType; -// checkAccountShadow(shadow, parentResult, false); + assertTrue(shadow.canRepresent(ShadowType.class)); + try { + checkCachedAccountShadow(shadow, parentResult, false, null, startTs); + } catch (SchemaException e) { + throw new SystemException(e.getMessage(), e); + } + + assertRepoCachingMetadata(shadow, null, startTs); + + if (shadow.asObjectable().getName().getOrig().equals("meathook")) { + assertRepoShadowCachedAttributeValue(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Sea Monkey"); + } return true; } @@ -1536,7 +1852,7 @@ public boolean handle(PrismObject object, OperationResult parentResu assertSteadyResource(); } - private void assertProtected(List> shadows, int expectedNumberOfProtectedShadows) { + protected void assertProtected(List> shadows, int expectedNumberOfProtectedShadows) { int actual = countProtected(shadows); assertEquals("Unexpected number of protected shadows", expectedNumberOfProtectedShadows, actual); } @@ -1579,8 +1895,8 @@ public void test113SearchAllShadowsInRepository() throws Exception { } @Test - public void test114SearchAllShadows() throws Exception { - final String TEST_NAME = "test114SearchAllShadows"; + public void test114SearchAllAccounts() throws Exception { + final String TEST_NAME = "test114SearchAllAccounts"; TestUtil.displayTestTile(TEST_NAME); // GIVEN OperationResult result = new OperationResult(TestDummy.class.getName() @@ -1610,8 +1926,8 @@ public void test114SearchAllShadows() throws Exception { } @Test - public void test115CountAllShadows() throws Exception { - TestUtil.displayTestTile("test115CountAllShadows"); + public void test115CountAllAccounts() throws Exception { + TestUtil.displayTestTile("test115CountAllAccounts"); // GIVEN OperationResult result = new OperationResult(TestDummy.class.getName() + ".test115countAllShadows"); @@ -1681,7 +1997,103 @@ public void test117CountNullQueryResource() throws Exception { assertSteadyResource(); } + /** + * Search for all accounts with long staleness option. This is a search, + * so we cannot evaluate whether our data are fresh enough. Therefore + * search on resource will always be performed. + * MID-3481 + */ + @Test + public void test118SearchAllAccountsLongStaleness() throws Exception { + final String TEST_NAME = "test118SearchAllAccountsLongStaleness"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + + "." + TEST_NAME); + ObjectQuery query = IntegrationTestTools.createAllShadowsQuery(resourceType, + SchemaTestConstants.ICF_ACCOUNT_OBJECT_CLASS_LOCAL_NAME, prismContext); + display("All shadows query", query); + + rememberShadowFetchOperationCount(); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createStaleness(1000000L)); + + // WHEN + List> allShadows = provisioningService.searchObjects(ShadowType.class, + query, options, null, result); + + // THEN + result.computeStatus(); + display("searchObjects result", result); + TestUtil.assertSuccess(result); + + display("Found " + allShadows.size() + " shadows"); + + assertFalse("No shadows found", allShadows.isEmpty()); + assertEquals("Wrong number of results", 4, allShadows.size()); + + assertShadowFetchOperationCountIncrement(1); + + checkConsistency(allShadows); + assertProtected(allShadows, 1); + + assertSteadyResource(); + } + /** + * Search for all accounts with maximum staleness option. + * This is supposed to return only cached data. Therefore + * repo search is performed. But as caching is + * not enabled in this test only errors will be returned. + * + * Note: This test is overridden in TestDummyCaching + * + * MID-3481 + */ + @Test + public void test119SearchAllAccountsMaxStaleness() throws Exception { + final String TEST_NAME = "test119SearchAllAccountsMaxStaleness"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + + "." + TEST_NAME); + ObjectQuery query = IntegrationTestTools.createAllShadowsQuery(resourceType, + SchemaTestConstants.ICF_ACCOUNT_OBJECT_CLASS_LOCAL_NAME, prismContext); + display("All shadows query", query); + + rememberShadowFetchOperationCount(); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createMaxStaleness()); + + // WHEN + List> allShadows = provisioningService.searchObjects(ShadowType.class, + query, options, null, result); + + // THEN + result.computeStatus(); + display("searchObjects result", result); + TestUtil.assertFailure(result); + + display("Found " + allShadows.size() + " shadows"); + + assertFalse("No shadows found", allShadows.isEmpty()); + assertEquals("Wrong number of results", 4, allShadows.size()); + + for (PrismObject shadow: allShadows) { + display("Found shadow (error expected)", shadow); + OperationResultType fetchResult = shadow.asObjectable().getFetchResult(); + assertNotNull("No fetch result status in "+shadow, fetchResult); + assertEquals("Wrong fetch result status in "+shadow, OperationResultStatusType.FATAL_ERROR, fetchResult.getStatus()); + } + + assertShadowFetchOperationCountIncrement(0); + + assertProtected(allShadows, 1); + + assertSteadyResource(); + } @@ -2466,19 +2878,22 @@ public void test159GetLockedoutAccount() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); dummyAccount.setLockout(true); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, result); - ShadowType shadowType = shadow.asObjectable(); // THEN result.computeStatus(); display("getObject result", result); TestUtil.assertSuccess(result); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); - display("Retrieved account shadow", shadowType); + display("Retrieved account shadow", shadow); - assertNotNull("No dummy account", shadowType); + assertNotNull("No dummy account", shadow); if (supportsActivation()) { PrismAsserts.assertPropertyValue(shadow, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS, @@ -2487,9 +2902,9 @@ public void test159GetLockedoutAccount() throws Exception { PrismAsserts.assertNoItem(shadow, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS); } - checkAccountWill(shadowType, result); + checkAccountWill(shadow, result, startTs, endTs); - checkConsistency(shadowType.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } @@ -2578,19 +2993,22 @@ public void test163GetAccount() throws Exception { // GIVEN OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); // WHEN PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, result); - ShadowType shadowType = shadow.asObjectable(); // THEN result.computeStatus(); display("getObject result", result); TestUtil.assertSuccess(result); - display("Retrieved account shadow", shadowType); + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); - assertNotNull("No dummy account", shadowType); + assertNotNull("No dummy account", shadow); if (supportsActivation()) { PrismAsserts.assertPropertyValue(shadow, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, @@ -2602,9 +3020,9 @@ public void test163GetAccount() throws Exception { PrismAsserts.assertNoItem(shadow, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS); } - checkAccountWill(shadowType, result); + checkAccountWill(shadow, result, startTs, endTs); - checkConsistency(shadowType.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } @@ -2924,20 +3342,22 @@ private void testSeachIterative(final String TEST_NAME, ObjectFilter attrFilter, display("Query", query); + + final XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); final List> foundObjects = new ArrayList>(); ResultHandler handler = new ResultHandler() { @Override - public boolean handle(PrismObject object, OperationResult parentResult) { - foundObjects.add(object); + public boolean handle(PrismObject shadow, OperationResult parentResult) { + foundObjects.add(shadow); - ObjectType objectType = object.asObjectable(); - assertTrue(objectType instanceof ShadowType); + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + assertTrue(shadow.canRepresent(ShadowType.class)); if (!useRepo) { - ShadowType shadow = (ShadowType) objectType; try { - checkAccountShadow(shadow, parentResult, fullShadow); + checkAccountShadow(shadow, parentResult, fullShadow, startTs, endTs); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); } @@ -2948,6 +3368,7 @@ public boolean handle(PrismObject object, OperationResult parentResu Collection> options = SelectorOptions.createCollection(rootOptions); + // WHEN if (useRepo) { repositoryService.searchObjectsIterative(ShadowType.class, query, handler, null, false, result); @@ -3019,10 +3440,9 @@ public void test200AddGroup() throws Exception { syncServiceMock.assertNotifySuccessOnly(); assertDummyResourceGroupMembersReadCountIncrement(null, 0); - ShadowType groupProvisioningType = provisioningService.getObject(ShadowType.class, - GROUP_PIRATES_OID, null, task, result).asObjectable(); - display("group from provisioning", groupProvisioningType); - checkGroupPirates(groupProvisioningType, result); + PrismObject groupProvisioning = provisioningService.getObject(ShadowType.class, GROUP_PIRATES_OID, null, task, result); + display("group from provisioning", groupProvisioning); + checkGroupPirates(groupProvisioning, result); piratesIcfUid = getIcfUid(groupRepoType); assertDummyResourceGroupMembersReadCountIncrement(null, 0); @@ -3040,7 +3460,7 @@ public void test200AddGroup() throws Exception { assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); - ProvisioningTestUtil.checkRepoEntitlementShadow(shadowFromRepo); + checkRepoEntitlementShadow(shadowFromRepo); assertDummyResourceGroupMembersReadCountIncrement(null, 0); checkConsistency(group); @@ -3059,8 +3479,7 @@ public void test202GetGroup() throws Exception { rememberDummyResourceGroupMembersReadCount(null); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, GROUP_PIRATES_OID, null, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, GROUP_PIRATES_OID, null, null, result); // THEN result.computeStatus(); @@ -3075,15 +3494,15 @@ public void test202GetGroup() throws Exception { checkGroupPirates(shadow, result); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } - private void checkGroupPirates(ShadowType shadow, OperationResult result) throws SchemaException { + private void checkGroupPirates(PrismObject shadow, OperationResult result) throws SchemaException { checkGroupShadow(shadow, result); PrismAsserts.assertEqualsPolyString("Name not equal.", transformNameFromResource(GROUP_PIRATES_NAME), shadow.getName()); - assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.getKind()); + assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.asObjectable().getKind()); assertAttribute(shadow, DummyResourceContoller.DUMMY_GROUP_ATTRIBUTE_DESCRIPTION, "Scurvy pirates"); Collection> attributes = ShadowUtil.getAttributes(shadow); assertEquals("Unexpected number of attributes", 3, attributes.size()); @@ -3107,8 +3526,7 @@ public void test203GetGroupNoFetch() throws Exception { rememberDummyResourceGroupMembersReadCount(null); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, GROUP_PIRATES_OID, options, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, GROUP_PIRATES_OID, options, null, result); // THEN result.computeStatus(); @@ -3123,7 +3541,7 @@ public void test203GetGroupNoFetch() throws Exception { checkGroupShadow(shadow, result, false); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } @@ -3202,11 +3620,11 @@ public void test210AddPrivilege() throws Exception { syncServiceMock.assertNotifySuccessOnly(); - ShadowType privProvisioningType = provisioningService.getObject(ShadowType.class, - PRIVILEGE_PILLAGE_OID, null, task, result).asObjectable(); - display("priv from provisioning", privProvisioningType); - checkPrivPillage(privProvisioningType, result); - pillageIcfUid = getIcfUid(privProvisioningType); + PrismObject privProvisioning = provisioningService.getObject(ShadowType.class, + PRIVILEGE_PILLAGE_OID, null, task, result); + display("priv from provisioning", privProvisioning); + checkPrivPillage(privProvisioning, result); + pillageIcfUid = getIcfUid(privProvisioning); // Check if the priv was created in the dummy resource @@ -3220,7 +3638,7 @@ public void test210AddPrivilege() throws Exception { assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); - ProvisioningTestUtil.checkRepoEntitlementShadow(shadowFromRepo); + checkRepoEntitlementShadow(shadowFromRepo); checkConsistency(priv); assertSteadyResource(); @@ -3235,8 +3653,7 @@ public void test212GetPriv() throws Exception { + "." + TEST_NAME); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, PRIVILEGE_PILLAGE_OID, null, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, PRIVILEGE_PILLAGE_OID, null, null, result); // THEN result.computeStatus(); @@ -3249,15 +3666,15 @@ public void test212GetPriv() throws Exception { checkPrivPillage(shadow, result); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); assertSteadyResource(); } - private void checkPrivPillage(ShadowType shadow, OperationResult result) throws SchemaException { + private void checkPrivPillage(PrismObject shadow, OperationResult result) throws SchemaException { checkEntitlementShadow(shadow, result, OBJECTCLAS_PRIVILEGE_LOCAL_NAME, true); assertShadowName(shadow, PRIVILEGE_PILLAGE_NAME); - assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.getKind()); + assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.asObjectable().getKind()); Collection> attributes = ShadowUtil.getAttributes(shadow); assertEquals("Unexpected number of attributes", 3, attributes.size()); assertAttribute(shadow, DummyResourceContoller.DUMMY_PRIVILEGE_ATTRIBUTE_POWER, 100); @@ -3302,8 +3719,8 @@ public void test214AddPrivilegeBargain() throws Exception { syncServiceMock.assertNotifySuccessOnly(); assertDummyResourceGroupMembersReadCountIncrement(null, 0); - ShadowType privProvisioningType = provisioningService.getObject(ShadowType.class, - PRIVILEGE_BARGAIN_OID, null, task, result).asObjectable(); + PrismObject privProvisioningType = provisioningService.getObject(ShadowType.class, + PRIVILEGE_BARGAIN_OID, null, task, result); display("priv from provisioning", privProvisioningType); checkPrivBargain(privProvisioningType, result); bargainIcfUid = getIcfUid(privProvisioningType); @@ -3321,17 +3738,17 @@ public void test214AddPrivilegeBargain() throws Exception { assertNotNull("Shadow was not created in the repository", shadowFromRepo); display("Repository shadow", shadowFromRepo.debugDump()); - ProvisioningTestUtil.checkRepoEntitlementShadow(shadowFromRepo); + checkRepoEntitlementShadow(shadowFromRepo); checkConsistency(priv); assertDummyResourceGroupMembersReadCountIncrement(null, 0); assertSteadyResource(); } - private void checkPrivBargain(ShadowType shadow, OperationResult result) throws SchemaException { + private void checkPrivBargain(PrismObject shadow, OperationResult result) throws SchemaException { checkEntitlementShadow(shadow, result, OBJECTCLAS_PRIVILEGE_LOCAL_NAME, true); assertShadowName(shadow, PRIVILEGE_BARGAIN_NAME); - assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.getKind()); + assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.asObjectable().getKind()); Collection> attributes = ShadowUtil.getAttributes(shadow); assertEquals("Unexpected number of attributes", 2, attributes.size()); @@ -3891,13 +4308,13 @@ public void test260AddAccountLeChuck() throws Exception { OperationResult result = task.getResult(); syncServiceMock.reset(); - PrismObject account = prismContext.parseObject(new File(ACCOUNT_LECHUCK_FILENAME)); - account.checkConsistence(); + PrismObject accountBefore = prismContext.parseObject(new File(ACCOUNT_LECHUCK_FILENAME)); + accountBefore.checkConsistence(); - display("Adding shadow", account); + display("Adding shadow", accountBefore); // WHEN - String addedObjectOid = provisioningService.addObject(account, null, null, task, result); + String addedObjectOid = provisioningService.addObject(accountBefore, null, null, task, result); // THEN result.computeStatus(); @@ -3905,7 +4322,7 @@ public void test260AddAccountLeChuck() throws Exception { TestUtil.assertSuccess("addObject has failed (result)", result); assertEquals(ACCOUNT_LECHUCK_OID, addedObjectOid); - account.checkConsistence(); + accountBefore.checkConsistence(); PrismObject shadow = provisioningService.getObject(ShadowType.class, addedObjectOid, null, task, result); leChuckIcfUid = getIcfUid(shadow); @@ -3928,39 +4345,37 @@ public void test260AddAccountLeChuck() throws Exception { DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); assertMember(group, transformNameFromResource(ACCOUNT_LECHUCK_NAME)); - ShadowType accountType = repositoryService.getObject(ShadowType.class, ACCOUNT_LECHUCK_OID, null, result) - .asObjectable(); - assertShadowName(accountType, ACCOUNT_LECHUCK_NAME); - assertEquals("Wrong kind (repo)", ShadowKindType.ACCOUNT, accountType.getKind()); - assertAttribute(accountType, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_LECHUCK_NAME); + PrismObject repoAccount = repositoryService.getObject(ShadowType.class, ACCOUNT_LECHUCK_OID, null, result); + assertShadowName(repoAccount, ACCOUNT_LECHUCK_NAME); + assertEquals("Wrong kind (repo)", ShadowKindType.ACCOUNT, repoAccount.asObjectable().getKind()); + assertAttribute(repoAccount, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_LECHUCK_NAME); if (isIcfNameUidSame()) { - assertAttribute(accountType, ConnectorFactoryIcfImpl.ICFS_UID, ACCOUNT_LECHUCK_NAME); + assertAttribute(repoAccount, ConnectorFactoryIcfImpl.ICFS_UID, ACCOUNT_LECHUCK_NAME); } else { - assertAttribute(accountType, ConnectorFactoryIcfImpl.ICFS_UID, dummyAccount.getId()); + assertAttribute(repoAccount, ConnectorFactoryIcfImpl.ICFS_UID, dummyAccount.getId()); } syncServiceMock.assertNotifySuccessOnly(); PrismObject provisioningAccount = provisioningService.getObject(ShadowType.class, ACCOUNT_LECHUCK_OID, null, task, result); - ShadowType provisioningAccountType = provisioningAccount.asObjectable(); - display("account from provisioning", provisioningAccountType); - assertShadowName(provisioningAccountType, ACCOUNT_LECHUCK_NAME); - assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, provisioningAccountType.getKind()); - assertAttribute(provisioningAccountType, ConnectorFactoryIcfImpl.ICFS_NAME, transformNameFromResource(ACCOUNT_LECHUCK_NAME)); + display("account from provisioning", provisioningAccount); + assertShadowName(provisioningAccount, ACCOUNT_LECHUCK_NAME); + assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, provisioningAccount.asObjectable().getKind()); + assertAttribute(provisioningAccount, ConnectorFactoryIcfImpl.ICFS_NAME, transformNameFromResource(ACCOUNT_LECHUCK_NAME)); if (isIcfNameUidSame()) { - assertAttribute(provisioningAccountType, ConnectorFactoryIcfImpl.ICFS_UID, transformNameFromResource(ACCOUNT_LECHUCK_NAME)); + assertAttribute(provisioningAccount, ConnectorFactoryIcfImpl.ICFS_UID, transformNameFromResource(ACCOUNT_LECHUCK_NAME)); } else { - assertAttribute(provisioningAccountType, ConnectorFactoryIcfImpl.ICFS_UID, dummyAccount.getId()); + assertAttribute(provisioningAccount, ConnectorFactoryIcfImpl.ICFS_UID, dummyAccount.getId()); } - assertEntitlementGroup(account, GROUP_PIRATES_OID); - assertEntitlementPriv(account, PRIVILEGE_PILLAGE_OID); + assertEntitlementGroup(provisioningAccount, GROUP_PIRATES_OID); + assertEntitlementPriv(provisioningAccount, PRIVILEGE_PILLAGE_OID); assertNull("The _PASSSWORD_ attribute sneaked into shadow", ShadowUtil.getAttributeValues( - provisioningAccountType, new QName(ConnectorFactoryIcfImpl.NS_ICF_SCHEMA, "password"))); + provisioningAccount, new QName(ConnectorFactoryIcfImpl.NS_ICF_SCHEMA, "password"))); - checkConsistency(account); + checkConsistency(provisioningAccount); assertSteadyResource(); } @@ -4410,7 +4825,7 @@ public void test600AddAccountAlreadyExist() throws Exception { PrismObject accountRepo = findAccountShadowByUsername(getMurrayRepoIcfName(), resource, result); assertNotNull("Shadow was not created in the repository", accountRepo); display("Repository shadow", accountRepo); - ProvisioningTestUtil.checkRepoAccountShadow(accountRepo); + checkRepoAccountShadow(accountRepo); assertEquals("Wrong ICF NAME in murray (repo) shadow", getMurrayRepoIcfName(), getIcfName(accountRepo)); @@ -4497,26 +4912,26 @@ public void test801LiveSyncAddBlackbeard() throws Exception { assertNotNull("Old shadow does not have an OID", oldShadow.getOid()); assertNull("Delta present when not expecting it", lastChange.getObjectDelta()); - ShadowType currentShadowType = lastChange.getCurrentShadow().asObjectable(); + PrismObject currentShadow = lastChange.getCurrentShadow(); assertNotNull("Current shadow missing", lastChange.getCurrentShadow()); - assertTrue("Wrong type of current shadow: " + currentShadowType.getClass().getName(), - currentShadowType instanceof ShadowType); + assertTrue("Wrong type of current shadow: " + currentShadow.getClass().getName(), + currentShadow.canRepresent(ShadowType.class)); ResourceAttributeContainer attributesContainer = ShadowUtil - .getAttributesContainer(currentShadowType); + .getAttributesContainer(currentShadow); assertNotNull("No attributes container in current shadow", attributesContainer); Collection> attributes = attributesContainer.getAttributes(); assertFalse("Attributes container is empty", attributes.isEmpty()); - assertAttribute(currentShadowType, + assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Edward Teach"); - assertAttribute(currentShadowType, + assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 66666L); assertEquals("Unexpected number of attributes", 4, attributes.size()); PrismObject accountRepo = findAccountShadowByUsername(getBlackbeardRepoIcfName(), resource, result); assertNotNull("Shadow was not created in the repository", accountRepo); display("Repository shadow", accountRepo); - ProvisioningTestUtil.checkRepoAccountShadow(accountRepo); + checkRepoAccountShadow(accountRepo); checkAllShadows(); @@ -4556,48 +4971,35 @@ public void test802LiveSyncModifyBlackbeard() throws Exception { display("The change", lastChange); PrismObject oldShadow = lastChange.getOldShadow(); - assertNotNull("Old shadow missing", oldShadow); - assertNotNull("Old shadow does not have an OID", oldShadow.getOid()); - PrismAsserts.assertClass("old shadow", ShadowType.class, oldShadow); - ShadowType oldShadowType = oldShadow.asObjectable(); - ResourceAttributeContainer attributesContainer = ShadowUtil - .getAttributesContainer(oldShadowType); - assertNotNull("No attributes container in old shadow", attributesContainer); - Collection> attributes = attributesContainer.getAttributes(); - assertFalse("Attributes container is empty", attributes.isEmpty()); - assertEquals("Unexpected number of attributes", 2, attributes.size()); - ResourceAttribute icfsNameAttribute = attributesContainer.findAttribute(ConnectorFactoryIcfImpl.ICFS_NAME); - assertNotNull("No ICF name attribute in old shadow", icfsNameAttribute); - assertEquals("Wrong value of ICF name attribute in old shadow", getBlackbeardRepoIcfName(), - icfsNameAttribute.getRealValue()); + assertSyncOldShadow(oldShadow, getBlackbeardRepoIcfName()); assertNull("Delta present when not expecting it", lastChange.getObjectDelta()); - ShadowType currentShadowType = lastChange.getCurrentShadow().asObjectable(); + PrismObject currentShadow = lastChange.getCurrentShadow(); assertNotNull("Current shadow missing", lastChange.getCurrentShadow()); - assertTrue("Wrong type of current shadow: " + currentShadowType.getClass().getName(), - currentShadowType instanceof ShadowType); + assertTrue("Wrong type of current shadow: " + currentShadow.getClass().getName(), + currentShadow.canRepresent(ShadowType.class)); - attributesContainer = ShadowUtil - .getAttributesContainer(currentShadowType); + ResourceAttributeContainer attributesContainer = ShadowUtil + .getAttributesContainer(currentShadow); assertNotNull("No attributes container in current shadow", attributesContainer); - attributes = attributesContainer.getAttributes(); + Collection> attributes = attributesContainer.getAttributes(); assertFalse("Attributes container is empty", attributes.isEmpty()); - assertAttribute(currentShadowType, + assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Captain Blackbeard"); - assertAttribute(currentShadowType, + assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 66666L); assertEquals("Unexpected number of attributes", 4, attributes.size()); PrismObject accountRepo = findAccountShadowByUsername(getBlackbeardRepoIcfName(), resource, result); assertNotNull("Shadow was not created in the repository", accountRepo); display("Repository shadow", accountRepo); - ProvisioningTestUtil.checkRepoAccountShadow(accountRepo); + checkRepoAccountShadow(accountRepo); checkAllShadows(); assertSteadyResource(); } - + @Test public void test810LiveSyncAddDrakeDumbObjectClass() throws Exception { testLiveSyncAddDrake("test810LiveSyncAddDrakeDumbObjectClass", DummySyncStyle.DUMB, ProvisioningTestUtil.getDefaultAccountObjectClass(resourceType)); @@ -4768,7 +5170,7 @@ public void testLiveSyncAddDrake(final String TEST_NAME, DummySyncStyle syncStyl PrismObject accountRepo = findAccountShadowByUsername(getDrakeRepoIcfName(), resource, result); assertNotNull("Shadow was not created in the repository", accountRepo); display("Repository shadow", accountRepo); - ProvisioningTestUtil.checkRepoAccountShadow(accountRepo); + checkRepoAccountShadow(accountRepo); checkAllShadows(); @@ -4806,40 +5208,27 @@ public void testLiveSyncModifyDrake(final String TEST_NAME, DummySyncStyle syncS display("The change", lastChange); PrismObject oldShadow = lastChange.getOldShadow(); - assertNotNull("Old shadow missing", oldShadow); - assertNotNull("Old shadow does not have an OID", oldShadow.getOid()); - PrismAsserts.assertClass("old shadow", ShadowType.class, oldShadow); - ShadowType oldShadowType = oldShadow.asObjectable(); - ResourceAttributeContainer attributesContainer = ShadowUtil - .getAttributesContainer(oldShadowType); - assertNotNull("No attributes container in old shadow", attributesContainer); - Collection> attributes = attributesContainer.getAttributes(); - assertFalse("Attributes container is empty", attributes.isEmpty()); - assertEquals("Unexpected number of attributes", 2, attributes.size()); - ResourceAttribute icfsNameAttribute = attributesContainer.findAttribute(ConnectorFactoryIcfImpl.ICFS_NAME); - assertNotNull("No ICF name attribute in old shadow", icfsNameAttribute); - assertEquals("Wrong value of ICF name attribute in old shadow", getDrakeRepoIcfName(), - icfsNameAttribute.getRealValue()); + assertSyncOldShadow(oldShadow, getDrakeRepoIcfName()); assertNull("Delta present when not expecting it", lastChange.getObjectDelta()); - ShadowType currentShadowType = lastChange.getCurrentShadow().asObjectable(); + PrismObject currentShadow = lastChange.getCurrentShadow(); assertNotNull("Current shadow missing", lastChange.getCurrentShadow()); - assertTrue("Wrong type of current shadow: " + currentShadowType.getClass().getName(), - currentShadowType instanceof ShadowType); + assertTrue("Wrong type of current shadow: " + currentShadow.getClass().getName(), + currentShadow.canRepresent(ShadowType.class)); - attributesContainer = ShadowUtil - .getAttributesContainer(currentShadowType); + ResourceAttributeContainer attributesContainer = ShadowUtil + .getAttributesContainer(currentShadow); assertNotNull("No attributes container in current shadow", attributesContainer); - attributes = attributesContainer.getAttributes(); + Collection> attributes = attributesContainer.getAttributes(); assertFalse("Attributes container is empty", attributes.isEmpty()); - assertAttribute(currentShadowType, + assertAttribute(currentShadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Captain Drake"); assertEquals("Unexpected number of attributes", 3, attributes.size()); PrismObject accountRepo = findAccountShadowByUsername(getDrakeRepoIcfName(), resource, result); assertNotNull("Shadow was not created in the repository", accountRepo); display("Repository shadow", accountRepo); - ProvisioningTestUtil.checkRepoAccountShadow(accountRepo); + checkRepoAccountShadow(accountRepo); checkAllShadows(); @@ -5036,20 +5425,7 @@ public void testLiveSyncDeleteDrake(final String TEST_NAME, DummySyncStyle syncS display("The change", lastChange); PrismObject oldShadow = lastChange.getOldShadow(); - assertNotNull("Old shadow missing", oldShadow); - assertNotNull("Old shadow does not have an OID", oldShadow.getOid()); - PrismAsserts.assertClass("old shadow", ShadowType.class, oldShadow); - ShadowType oldShadowType = oldShadow.asObjectable(); - ResourceAttributeContainer attributesContainer = ShadowUtil - .getAttributesContainer(oldShadowType); - assertNotNull("No attributes container in old shadow", attributesContainer); - Collection> attributes = attributesContainer.getAttributes(); - assertFalse("Attributes container is empty", attributes.isEmpty()); - assertEquals("Unexpected number of attributes", 2, attributes.size()); - ResourceAttribute icfsNameAttribute = attributesContainer.findAttribute(ConnectorFactoryIcfImpl.ICFS_NAME); - assertNotNull("No ICF name attribute in old shadow", icfsNameAttribute); - assertEquals("Wrong value of ICF name attribute in old shadow", getDrakeRepoIcfName(), - icfsNameAttribute.getRealValue()); + assertSyncOldShadow(oldShadow, getDrakeRepoIcfName()); ObjectDelta objectDelta = lastChange.getObjectDelta(); assertNotNull("Delta missing", objectDelta); @@ -5147,28 +5523,30 @@ public void test999Shutdown() throws Exception { dummyResource.assertNoConnections(); } - private void checkAccountShadow(ShadowType shadow, OperationResult parentResult) throws SchemaException { - checkAccountShadow(shadow, parentResult, true); - } - - private void checkAccountShadow(ShadowType shadowType, OperationResult parentResult, boolean fullShadow) throws SchemaException { + protected void checkAccountShadow(PrismObject shadowType, OperationResult parentResult, boolean fullShadow, XMLGregorianCalendar startTs, + XMLGregorianCalendar endTs) throws SchemaException { ObjectChecker checker = createShadowChecker(fullShadow); - ShadowUtil.checkConsistence(shadowType.asPrismObject(), parentResult.getOperation()); - IntegrationTestTools.checkAccountShadow(shadowType, resourceType, repositoryService, checker, getUidMatchingRule(), prismContext, parentResult); + ShadowUtil.checkConsistence(shadowType, parentResult.getOperation()); + IntegrationTestTools.checkAccountShadow(shadowType.asObjectable(), resourceType, repositoryService, checker, getUidMatchingRule(), prismContext, parentResult); + } + + protected void checkCachedAccountShadow(PrismObject shadowType, OperationResult parentResult, boolean fullShadow, XMLGregorianCalendar startTs, + XMLGregorianCalendar endTs) throws SchemaException { + checkAccountShadow(shadowType, parentResult, fullShadow, startTs, endTs); } - private void checkGroupShadow(ShadowType shadow, OperationResult parentResult) throws SchemaException { + private void checkGroupShadow(PrismObject shadow, OperationResult parentResult) throws SchemaException { checkEntitlementShadow(shadow, parentResult, SchemaTestConstants.ICF_GROUP_OBJECT_CLASS_LOCAL_NAME, true); } - private void checkGroupShadow(ShadowType shadow, OperationResult parentResult, boolean fullShadow) throws SchemaException { + private void checkGroupShadow(PrismObject shadow, OperationResult parentResult, boolean fullShadow) throws SchemaException { checkEntitlementShadow(shadow, parentResult, SchemaTestConstants.ICF_GROUP_OBJECT_CLASS_LOCAL_NAME, fullShadow); } - private void checkEntitlementShadow(ShadowType shadowType, OperationResult parentResult, String objectClassLocalName, boolean fullShadow) throws SchemaException { + private void checkEntitlementShadow(PrismObject shadow, OperationResult parentResult, String objectClassLocalName, boolean fullShadow) throws SchemaException { ObjectChecker checker = createShadowChecker(fullShadow); - ShadowUtil.checkConsistence(shadowType.asPrismObject(), parentResult.getOperation()); - IntegrationTestTools.checkEntitlementShadow(shadowType, resourceType, repositoryService, checker, objectClassLocalName, getUidMatchingRule(), prismContext, parentResult); + ShadowUtil.checkConsistence(shadow, parentResult.getOperation()); + IntegrationTestTools.checkEntitlementShadow(shadow.asObjectable(), resourceType, repositoryService, checker, objectClassLocalName, getUidMatchingRule(), prismContext, parentResult); } private void checkAllShadows() throws SchemaException, ObjectNotFoundException, CommunicationException, @@ -5206,4 +5584,75 @@ public void check(ShadowType shadow) { }; } + + protected void checkRepoAccountShadow(PrismObject shadowFromRepo) { + ProvisioningTestUtil.checkRepoAccountShadow(shadowFromRepo); + } + + protected void checkRepoEntitlementShadow(PrismObject repoShadow) { + ProvisioningTestUtil.checkRepoEntitlementShadow(repoShadow); + } + + protected void assertSyncOldShadow(PrismObject oldShadow, String repoName) { + assertSyncOldShadow(oldShadow, repoName, 2); + } + + protected void assertSyncOldShadow(PrismObject oldShadow, String repoName, Integer expectedNumberOfAttributes) { + assertNotNull("Old shadow missing", oldShadow); + assertNotNull("Old shadow does not have an OID", oldShadow.getOid()); + PrismAsserts.assertClass("old shadow", ShadowType.class, oldShadow); + ShadowType oldShadowType = oldShadow.asObjectable(); + ResourceAttributeContainer attributesContainer = ShadowUtil + .getAttributesContainer(oldShadowType); + assertNotNull("No attributes container in old shadow", attributesContainer); + Collection> attributes = attributesContainer.getAttributes(); + assertFalse("Attributes container is empty", attributes.isEmpty()); + if (expectedNumberOfAttributes != null) { + assertEquals("Unexpected number of attributes", (int)expectedNumberOfAttributes, attributes.size()); + } + ResourceAttribute icfsNameAttribute = attributesContainer.findAttribute(ConnectorFactoryIcfImpl.ICFS_NAME); + assertNotNull("No ICF name attribute in old shadow", icfsNameAttribute); + assertEquals("Wrong value of ICF name attribute in old shadow", repoName, + icfsNameAttribute.getRealValue()); + } + + protected void assertRepoShadowCachedAttributeValue(PrismObject shadowRepo, String attrName, T... attrValues) { + PrismAsserts.assertNoItem(shadowRepo, new ItemPath(ShadowType.F_ATTRIBUTES, + new QName(ResourceTypeUtil.getResourceNamespace(resource), attrName))); + } + + protected void assertRepoShadowCacheActivation(PrismObject shadowRepo, ActivationStatusType expectedAdministrativeStatus) { + ActivationType activationType = shadowRepo.asObjectable().getActivation(); + if (activationType == null) { + return; + } + ActivationStatusType administrativeStatus = activationType.getAdministrativeStatus(); + assertNull("Unexpected activation administrativeStatus in repo shadow "+shadowRepo+": "+administrativeStatus, administrativeStatus); + } + + /** + * We do not know what the timestamp should be + */ + protected void assertRepoCachingMetadata(PrismObject shadowRepo) { + assertNull("Unexpected caching metadata in "+shadowRepo, shadowRepo.asObjectable().getCachingMetadata()); + } + + protected void assertRepoCachingMetadata(PrismObject shadowRepo, XMLGregorianCalendar start, XMLGregorianCalendar end) { + assertNull("Unexpected caching metadata in "+shadowRepo, shadowRepo.asObjectable().getCachingMetadata()); + } + + protected void assertCachingMetadata(PrismObject shadow, boolean expectedCached, XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) { + assertNull("Unexpected caching metadata in "+shadow, shadow.asObjectable().getCachingMetadata()); + } + + protected void checkAccountWill(PrismObject shadow, OperationResult result, + XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) throws SchemaException, EncryptionException { + checkAccountShadow(shadow, result, true, startTs, endTs); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + assertEquals("Unexpected number of attributes", 6, attributes.size()); + } + } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyCaching.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyCaching.java new file mode 100644 index 00000000000..4ed2c9fa97a --- /dev/null +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyCaching.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2016 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.evolveum.midpoint.provisioning.impl.dummy; + +import static org.testng.AssertJUnit.assertTrue; +import static com.evolveum.midpoint.test.IntegrationTestTools.display; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; + +import java.io.File; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.lang.StringUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +import com.evolveum.icf.dummy.resource.DummyAccount; +import com.evolveum.icf.dummy.resource.DummyGroup; +import com.evolveum.icf.dummy.resource.DummyPrivilege; +import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.match.MatchingRule; +import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; +import com.evolveum.midpoint.prism.match.StringIgnoreCaseMatchingRule; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.provisioning.impl.ProvisioningTestUtil; +import com.evolveum.midpoint.provisioning.ucf.impl.ConnectorFactoryIcfImpl; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.processor.ResourceAttribute; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.SchemaTestConstants; +import com.evolveum.midpoint.schema.util.ShadowUtil; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; + +/** + * Almost the same as TestDummy but this is using a caching configuration. + * + * @author Radovan Semancik + * + */ +@ContextConfiguration(locations = "classpath:ctx-provisioning-test-main.xml") +@DirtiesContext +public class TestDummyCaching extends TestDummy { + + public static final File TEST_DIR = new File("src/test/resources/impl/dummy-caching/"); + public static final File RESOURCE_DUMMY_FILE = new File(TEST_DIR, "resource-dummy.xml"); + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + } + + @Override + protected File getResourceDummyFilename() { + return RESOURCE_DUMMY_FILE; + } + + /** + * Make a native modification to an account and read it from the cache. Make sure that + * cached data are returned and there is no read from the resource. + * MID-3481 + */ + @Test + @Override + public void test107AGetModifiedAccountFromCacheMax() throws Exception { + final String TEST_NAME = "test107AGetModifiedAccountFromCacheMax"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Nice Pirate"); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Interceptor"); + accountWill.setEnabled(true); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createMaxStaleness()); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + + assertShadowFetchOperationCountIncrement(0); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); + + assertNotNull("No dummy account", shadow); + + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertEquals("Unexpected number of attributes", 7, attributes.size()); + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, null, startTs, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.DISABLED); + + checkConsistency(shadow); + + assertCachingMetadata(shadow, true, null, startTs); + + assertShadowFetchOperationCountIncrement(0); + + assertSteadyResource(); + } + + /** + * Make a native modification to an account and read it with high staleness option. + * This should return cached data. + * MID-3481 + */ + @Test + @Override + public void test107BGetModifiedAccountFromCacheHighStaleness() throws Exception { + final String TEST_NAME = "test107BGetModifiedAccountFromCacheHighStaleness"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + "." + TEST_NAME); + rememberShadowFetchOperationCount(); + + DummyAccount accountWill = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + accountWill.replaceAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Very Nice Pirate"); + accountWill.setEnabled(true); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createStaleness(1000000L)); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, options, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + display("getObject result", result); + TestUtil.assertSuccess(result); + + assertShadowFetchOperationCountIncrement(0); + + XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); + + display("Retrieved account shadow", shadow); + + assertNotNull("No dummy account", shadow); + + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertEquals("Unexpected number of attributes", 7, attributes.size()); + + PrismObject shadowRepo = repositoryService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, result); + checkRepoAccountShadowWillBasic(shadowRepo, null, startTs, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, "Pirate"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Black Pearl"); + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.DISABLED); + + checkConsistency(shadow); + + assertCachingMetadata(shadow, true, null, startTs); + + assertShadowFetchOperationCountIncrement(0); + + assertSteadyResource(); + } + + /** + * Search for all accounts with maximum staleness option. + * This is supposed to return only cached data. Therefore + * repo search is performed. + * MID-3481 + */ + @Test + @Override + public void test119SearchAllAccountsMaxStaleness() throws Exception { + final String TEST_NAME = "test119SearchAllAccountsMaxStaleness"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + OperationResult result = new OperationResult(TestDummy.class.getName() + + "." + TEST_NAME); + ObjectQuery query = IntegrationTestTools.createAllShadowsQuery(resourceType, + SchemaTestConstants.ICF_ACCOUNT_OBJECT_CLASS_LOCAL_NAME, prismContext); + display("All shadows query", query); + + XMLGregorianCalendar startTs = clock.currentTimeXMLGregorianCalendar(); + + rememberShadowFetchOperationCount(); + + Collection> options = + SelectorOptions.createCollection(GetOperationOptions.createMaxStaleness()); + + // WHEN + List> allShadows = provisioningService.searchObjects(ShadowType.class, + query, options, null, result); + + // THEN + result.computeStatus(); + display("searchObjects result", result); + TestUtil.assertSuccess(result); + + display("Found " + allShadows.size() + " shadows"); + + assertFalse("No shadows found", allShadows.isEmpty()); + assertEquals("Wrong number of results", 4, allShadows.size()); + + for (PrismObject shadow: allShadows) { + display("Found shadow", shadow); + ShadowType shadowType = shadow.asObjectable(); + OperationResultType fetchResult = shadowType.getFetchResult(); + if (fetchResult != null) { + assertEquals("Wrong fetch result status in "+shadow, OperationResultStatusType.SUCCESS, fetchResult.getStatus()); + } + assertCachingMetadata(shadow, true, null, startTs); + + if (shadow.asObjectable().getName().getOrig().equals("meathook")) { + assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Sea Monkey"); + } + } + + assertShadowFetchOperationCountIncrement(0); + + assertProtected(allShadows, 1); + + assertSteadyResource(); + } + + @Override + protected void checkRepoAccountShadowWill(PrismObject shadowRepo, XMLGregorianCalendar start, XMLGregorianCalendar end) { + // Sometimes there are 6 and sometimes 7 attributes. Treasure is not returned by default. It is not normally in the cache. + // So do not check for number of attributes here. Check for individual values. + checkRepoAccountShadowWillBasic(shadowRepo, start, end, null); + + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); + // this is shadow, values are normalized + // MID-3484 +// assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "sword", "love"); + assertRepoShadowCachedAttributeValue(shadowRepo, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 42); + + assertRepoShadowCacheActivation(shadowRepo, ActivationStatusType.ENABLED); + } + + @Override + protected void assertRepoShadowCacheActivation(PrismObject shadowRepo, ActivationStatusType expectedAdministrativeStatus) { + ActivationType activationType = shadowRepo.asObjectable().getActivation(); + assertNotNull("No activation in repo shadow "+shadowRepo, activationType); + ActivationStatusType administrativeStatus = activationType.getAdministrativeStatus(); + assertEquals("Wrong activation administrativeStatus in repo shadow "+shadowRepo, expectedAdministrativeStatus, administrativeStatus); + } + + /** + * We do not know what the timestamp should be. But some timestamp should be there. + */ + @Override + protected void assertRepoCachingMetadata(PrismObject shadowFromRepo) { + CachingMetadataType cachingMetadata = shadowFromRepo.asObjectable().getCachingMetadata(); + assertNotNull("No caching metadata in "+shadowFromRepo, cachingMetadata); + + assertNotNull("Missing retrieval timestamp in caching metadata in "+shadowFromRepo, + cachingMetadata.getRetrievalTimestamp()); + } + + @Override + protected void assertRepoCachingMetadata(PrismObject shadowFromRepo, XMLGregorianCalendar start, XMLGregorianCalendar end) { + CachingMetadataType cachingMetadata = shadowFromRepo.asObjectable().getCachingMetadata(); + assertNotNull("No caching metadata in "+shadowFromRepo, cachingMetadata); + + TestUtil.assertBetween("Wrong retrieval timestamp in caching metadata in "+shadowFromRepo, + start, end, cachingMetadata.getRetrievalTimestamp()); + } + + @Override + protected void assertCachingMetadata(PrismObject shadow, boolean expectedCached, XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) { + CachingMetadataType cachingMetadata = shadow.asObjectable().getCachingMetadata(); + if (expectedCached) { + assertNotNull("No caching metadata in "+shadow, cachingMetadata); + TestUtil.assertBetween("Wrong retrievalTimestamp in caching metadata in "+shadow, startTs, endTs, cachingMetadata.getRetrievalTimestamp()); + } else { + super.assertCachingMetadata(shadow, expectedCached, startTs, endTs); + } + } + + + @Override + protected void checkRepoAccountShadow(PrismObject repoShadow) { + ProvisioningTestUtil.checkRepoShadow(repoShadow, ShadowKindType.ACCOUNT, null); + } + + @Override + protected void checkRepoEntitlementShadow(PrismObject repoShadow) { + ProvisioningTestUtil.checkRepoShadow(repoShadow, ShadowKindType.ENTITLEMENT, null); + } + + @Override + protected void assertRepoShadowAttributes(List> attributes, int expectedNumberOfIdentifiers) { + // We can only assert that there are at least the identifiers. But we do not know how many attributes should be there + assertTrue("Unexpected number of attributes in repo shadow, expected at least "+ + expectedNumberOfIdentifiers+", but was "+attributes.size(), attributes.size() >= expectedNumberOfIdentifiers); + } + + @Override + protected void assertSyncOldShadow(PrismObject oldShadow, String repoName) { + assertSyncOldShadow(oldShadow, repoName, null); + } + + @Override + protected void assertRepoShadowCachedAttributeValue(PrismObject shadowRepo, String attrName, T... attrValues) { + assertAttribute(shadowRepo, attrName, attrValues); + } + + @Override + protected void checkCachedAccountShadow(PrismObject shadow, OperationResult parentResult, boolean fullShadow, XMLGregorianCalendar startTs, + XMLGregorianCalendar endTs) throws SchemaException { + super.checkAccountShadow(shadow, parentResult, fullShadow, startTs, endTs); + if (fullShadow) { + assertCachingMetadata(shadow, true, startTs, endTs); + } + } +} diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyExtra.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyExtra.java index b8a89cbac34..a019b84eb0f 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyExtra.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyExtra.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Evolveum + * Copyright (c) 2015-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import java.io.File; +import javax.xml.datatype.XMLGregorianCalendar; + import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -56,9 +58,9 @@ protected File getResourceDummyFilename() { } @Override - protected void checkAccountWill(ShadowType shadow, OperationResult result) throws SchemaException, EncryptionException { - super.checkAccountWill(shadow, result); - assertPassword(shadow, "3lizab3th"); + protected void checkAccountWill(PrismObject shadow, OperationResult result, XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) throws SchemaException, EncryptionException { + super.checkAccountWill(shadow, result, startTs, endTs); + assertPassword(shadow.asObjectable(), "3lizab3th"); } @Test diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyPrioritiesAndReadReplace.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyPrioritiesAndReadReplace.java index 2d1add60c59..5c6555e49cf 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyPrioritiesAndReadReplace.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyPrioritiesAndReadReplace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -152,8 +152,8 @@ public void test100AddAccount() throws Exception { display("account from provisioning", accountTypeProvisioning); PrismAsserts.assertEqualsPolyString("Name not equal", ACCOUNT_WILL_USERNAME, accountTypeProvisioning.getName()); assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, accountTypeProvisioning.getKind()); - assertAttribute(accountTypeProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_WILL_USERNAME); - assertAttribute(accountTypeProvisioning, getUidMatchingRule(), ConnectorFactoryIcfImpl.ICFS_UID, willIcfUid); + assertAttribute(accountProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_WILL_USERNAME); + assertAttribute(accountProvisioning, getUidMatchingRule(), ConnectorFactoryIcfImpl.ICFS_UID, willIcfUid); ActivationType activationProvisioning = accountTypeProvisioning.getActivation(); if (supportsActivation()) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySecurity.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySecurity.java index e6f3872752d..b358d3f2201 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySecurity.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummySecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,10 @@ */ package com.evolveum.midpoint.provisioning.impl.dummy; -import static com.evolveum.midpoint.test.util.TestUtil.assertFailure; -import static com.evolveum.midpoint.test.util.TestUtil.assertSuccess; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertTrue; import java.io.File; import java.util.Collection; @@ -44,8 +40,8 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.schema.util.SchemaTestConstants; +import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.IntegrationTestTools; @@ -248,8 +244,7 @@ public void test300GetAccount() throws Exception { + "." + TEST_NAME); // WHEN - ShadowType shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, - result).asObjectable(); + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, null, result); // THEN result.computeStatus(); @@ -262,7 +257,7 @@ public void test300GetAccount() throws Exception { checkAccountWill(shadow, result); - checkConsistency(shadow.asPrismObject()); + checkConsistency(shadow); } @Test @@ -301,7 +296,7 @@ public void test310SearchAllShadows() throws Exception { // TODO: search - private void checkAccountWill(ShadowType shadow, OperationResult result) { + private void checkAccountWill(PrismObject shadow, OperationResult result) { Collection> attributes = ShadowUtil.getAttributes(shadow); assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME, "Flying Dutchman"); assertAttribute(shadow, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME, "Sword", "LOVE"); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java index ff8b937d1c1..6e77bf93c90 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java @@ -153,7 +153,7 @@ private String addFettucini(final String TEST_NAME, File file, String oid, Strin ShadowType accountTypeRepo = accountRepo.asObjectable(); PrismAsserts.assertEqualsPolyString("Name not equal", ACCOUNT_FETTUCINI_NAME, accountTypeRepo.getName()); assertEquals("Wrong kind (repo)", ShadowKindType.ACCOUNT, accountTypeRepo.getKind()); - assertAttribute(accountTypeRepo, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); + assertAttribute(accountRepo, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); String icfUid = getIcfUid(accountRepo); syncServiceMock.assertNotifySuccessOnly(); @@ -165,8 +165,8 @@ private String addFettucini(final String TEST_NAME, File file, String oid, Strin display("account from provisioning", accountTypeProvisioning); PrismAsserts.assertEqualsPolyString("Name not equal", ACCOUNT_FETTUCINI_NAME, accountTypeProvisioning.getName()); assertEquals("Wrong kind (provisioning)", ShadowKindType.ACCOUNT, accountTypeProvisioning.getKind()); - assertAttribute(accountTypeProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); - assertAttribute(accountTypeProvisioning, ConnectorFactoryIcfImpl.ICFS_UID, icfUid); + assertAttribute(accountProvisioning, ConnectorFactoryIcfImpl.ICFS_NAME, ACCOUNT_FETTUCINI_NAME); + assertAttribute(accountProvisioning, ConnectorFactoryIcfImpl.ICFS_UID, icfUid); // Check if the account was created in the dummy resource DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_FETTUCINI_NAME, icfUid); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java index 76353b78f65..1fdfee4b108 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfDummy.java @@ -434,7 +434,7 @@ public void test100FetchEmptyChanges() throws Exception { assertTrue("Last sync token definition is NOT dynamic", lastTokenDef.isDynamic()); // WHEN - List> changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); + List changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); AssertJUnit.assertEquals(0, changes.size()); } @@ -459,12 +459,12 @@ public void test101FetchAddChange() throws Exception { dummyResource.addAccount(newAccount); // WHEN - List> changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); + List changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); AssertJUnit.assertEquals(1, changes.size()); - Change change = changes.get(0); + Change change = changes.get(0); assertNotNull("null change", change); - PrismObject currentShadow = change.getCurrentShadow(); + PrismObject currentShadow = change.getCurrentShadow(); assertNotNull("null current shadow", currentShadow); PrismAsserts.assertParentConsistency(currentShadow); Collection> identifiers = change.getIdentifiers(); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java index d471fd9c567..82f2545c3fb 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/ucf/TestUcfOpenDj.java @@ -406,12 +406,12 @@ public void test200FetchChanges() throws Exception { assertNotNull("No last token", lastToken); assertNotNull("No last token value", lastToken.getRealValue()); - List> changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); + List changes = cc.fetchChanges(accountDefinition, lastToken, null, null, result); display("Changes", changes); // Just one pseudo-change that updates the token AssertJUnit.assertEquals(1, changes.size()); - Change change = changes.get(0); + Change change = changes.get(0); assertNull(change.getCurrentShadow()); assertNull(change.getIdentifiers()); assertNull(change.getObjectDelta()); diff --git a/provisioning/provisioning-impl/src/test/resources/impl/dummy-caching/resource-dummy.xml b/provisioning/provisioning-impl/src/test/resources/impl/dummy-caching/resource-dummy.xml new file mode 100644 index 00000000000..71d0a69eafc --- /dev/null +++ b/provisioning/provisioning-impl/src/test/resources/impl/dummy-caching/resource-dummy.xml @@ -0,0 +1,201 @@ + + + + + + Dummy Resource + + + + + + Shiver me timbers! + + Dead men tell no tales + + true + + + + false + false + false + + + + http://midpoint.evolveum.com/xml/ns/public/resource/instance/ef2bc95b-76e0-59e2-86d6-9999dddddddd + + + + account + default + Default Account + true + ri:AccountObjectClass + + icfs:name + Username + + + ri:weapon + mr:stringIgnoreCase + + + ri:loot + explicit + + + ri:ship + + + true + true + true + + + + + ri:drink + + + true + false + true + + + + + ri:quote + + + true + true + false + + + + + ri:gossip + + + false + true + true + + + + + ri:water + + + false + false + false + + + + + ri:group + entitlement + group + objectToSubject + ri:members + icfs:name + + + ri:priv + entitlement + privilege + subjectToObject + ri:privileges + icfs:name + + + root + + + daemon + + + + + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + attributes/icfs:name + + daviejones + + + + + + + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + attributes/icfs:name + + X + true + + + + + + + + declare namespace icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"; + attributes/icfs:name + + -adm + true + + + + + + entitlement + group + true + ri:GroupObjectClass + + ri:members + minimal + + + + entitlement + privilege + false + ri:CustomprivilegeObjectClass + + + + + passive + + + diff --git a/provisioning/provisioning-impl/testng-integration.xml b/provisioning/provisioning-impl/testng-integration.xml index 26d56cf2703..6c8d988db82 100644 --- a/provisioning/provisioning-impl/testng-integration.xml +++ b/provisioning/provisioning-impl/testng-integration.xml @@ -57,6 +57,7 @@ + diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java index ebd90f987f1..a99123ec691 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ModifyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.evolveum.midpoint.repo.sql; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; import com.evolveum.midpoint.common.SynchronizationUtils; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.delta.ItemDelta; @@ -25,6 +27,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.query.LessFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepoModifyOptions; @@ -32,7 +35,12 @@ import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.constants.MidPointConstants; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.test.util.MidPointTestConstants; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; @@ -41,6 +49,7 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -66,21 +75,28 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class ModifyTest extends BaseSQLRepoTest { + private static final File TEST_DIR = new File("src/test/resources/modify"); + private static final File ACCOUNT_FILE = new File(TEST_DIR, "account.xml"); + private static final File MODIFY_USER_ADD_LINK = new File(TEST_DIR, "change-add.xml"); + + private static final Trace LOGGER = TraceManager.getTrace(ModifyTest.class); + @BeforeSuite public void setup() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); + InternalsConfig.encryptionChecks = false; } protected RepoModifyOptions getModifyOptions() { return null; } - private static final Trace LOGGER = TraceManager.getTrace(ModifyTest.class); - private static final File TEST_DIR = new File("src/test/resources/modify"); - @Test(expectedExceptions = SystemException.class, enabled = false) public void test010ModifyWithExistingName() throws Exception { + final String TEST_NAME = "test010ModifyWithExistingName"; + TestUtil.displayTestTile(TEST_NAME); + OperationResult result = new OperationResult("MODIFY"); File userFile = new File(TEST_DIR, "modify-user.xml"); @@ -109,6 +125,9 @@ public void test010ModifyWithExistingName() throws Exception { @Test(expectedExceptions = ObjectNotFoundException.class, enabled = false) public void test020ModifyNotExistingUser() throws Exception { + final String TEST_NAME = "test020ModifyNotExistingUser"; + TestUtil.displayTestTile(TEST_NAME); + ObjectModificationType modification = PrismTestUtil.parseAtomicValue( new File(TEST_DIR, "change-add.xml"), ObjectModificationType.COMPLEX_TYPE); @@ -120,8 +139,11 @@ public void test020ModifyNotExistingUser() throws Exception { repositoryService.modifyObject(UserType.class, "1234", deltas, getModifyOptions(), result); } - @Test(enabled = false) + @Test(enabled = false) // MID-3483 public void test030ModifyUserOnNonExistingAccountTest() throws Exception { + final String TEST_NAME = "test030ModifyUserOnNonExistingAccountTest"; + TestUtil.displayTestTile(TEST_NAME); + OperationResult result = new OperationResult("MODIFY"); //add user @@ -153,13 +175,16 @@ public void test030ModifyUserOnNonExistingAccountTest() throws Exception { AssertJUnit.assertTrue("User is not equivalent.", userOld.equivalent(userNew)); } - @Test(enabled = false) + @Test(enabled=false) // MID-3483 public void test031ModifyUserOnExistingAccountTest() throws Exception { - OperationResult result = new OperationResult("MODIFY"); + final String TEST_NAME = "test031ModifyUserOnExistingAccountTest"; + TestUtil.displayTestTile(TEST_NAME); + + // GIVEN + OperationResult result = new OperationResult(TEST_NAME); //add account - File accountFile = new File(TEST_DIR, "account.xml"); - PrismObject account = prismContext.parseObject(accountFile); + PrismObject account = prismContext.parseObject(ACCOUNT_FILE); repositoryService.addObject(account, null, result); //add user @@ -172,13 +197,11 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { PrismObject userOld = repositoryService.getObject(UserType.class, oid, null, result); - ObjectModificationType modification = PrismTestUtil.parseAtomicValue( - new File(TEST_DIR, "change-add.xml"), - ObjectModificationType.COMPLEX_TYPE); - - Collection deltas = DeltaConvertor.toModifications(modification, - UserType.class, prismContext); + ObjectDeltaType objectDeltaType = PrismTestUtil.parseAnyValue(MODIFY_USER_ADD_LINK); + ObjectDelta objectDelta = DeltaConvertor.createObjectDelta(objectDeltaType, prismContext); + Collection> deltas = objectDelta.getModifications(); + // WHEN repositoryService.modifyObject(UserType.class, oid, deltas, getModifyOptions(), result); PropertyDelta.applyTo(deltas, userOld); @@ -193,7 +216,10 @@ public void test031ModifyUserOnExistingAccountTest() throws Exception { @Test public void test032ModifyTaskObjectRef() throws Exception { - OperationResult result = new OperationResult("MODIFY"); + final String TEST_NAME = "test032ModifyTaskObjectRef"; + TestUtil.displayTestTile(TEST_NAME); + + OperationResult result = new OperationResult(TEST_NAME); File taskFile = new File(TEST_DIR, "task.xml"); System.out.println("ADD"); PrismObject task = prismContext.parseObject(taskFile); @@ -282,7 +308,10 @@ private void checkReference(String taskOid) { } @Test - public void testModifyUserAddRole() throws Exception { + public void test100ModifyUserAddRole() throws Exception { + final String TEST_NAME = "test100ModifyUserAddRole"; + TestUtil.displayTestTile(TEST_NAME); + OperationResult parentResult = new OperationResult("Modify user -> add roles"); String userToModifyOid = "f65963e3-9d47-4b18-aaf3-bfc98bdfa000"; @@ -321,7 +350,10 @@ public void testModifyUserAddRole() throws Exception { } @Test - public void testModifyDeleteObjectChangeFromAccount() throws Exception { + public void test110ModifyDeleteObjectChangeFromAccount() throws Exception { + final String TEST_NAME = "test110ModifyDeleteObjectChangeFromAccount"; + TestUtil.displayTestTile(TEST_NAME); + OperationResult parentResult = new OperationResult("testModifyDeleteObjectChnageFromAccount"); PrismObject accShadow = prismContext.parseObject(new File(TEST_DIR + "/account-delete-object-change.xml")); String oid = repositoryService.addObject(accShadow, null, parentResult); @@ -347,68 +379,93 @@ public void testModifyDeleteObjectChangeFromAccount() throws Exception { AssertJUnit.assertNull(afterModify.asObjectable().getObjectChange()); } - @Test(enabled = false) - public void testModifyAccountMetadata() throws Exception { - OperationResult parentResult = new OperationResult("testModifyAccountMetadata"); + /** + * Modify account metadata. Make sure that no unrelated item has changed. + */ + @Test(enabled = false) // MID-3484 + public void test120ModifyAccountMetadata() throws Exception { + final String TEST_NAME = "test120ModifyAccountMetadata"; + TestUtil.displayTestTile(TEST_NAME); + + // GIVEN + OperationResult parentResult = new OperationResult(TEST_NAME); - PrismObject user = prismContext.parseObject(new File(TEST_DIR + "/user-modify-link-account.xml")); - - - PrismObject accShadow = prismContext.parseObject(new File(TEST_DIR + "/account-modify-metadata.xml")); + PrismObject shadowBefore = prismContext.parseObject(ACCOUNT_FILE); MetadataType metaData = new MetadataType(); metaData.setCreateChannel("channel"); metaData.setCreateTimestamp(XmlTypeConverter.createXMLGregorianCalendar(System.currentTimeMillis())); - accShadow.asObjectable().setMetadata(metaData); - + shadowBefore.asObjectable().setMetadata(metaData); + + // The parsed shadow has attributes that have xsi:type specification. Add another one that has + // fully dynamic definition + + QName attrBazQName = new QName(MidPointConstants.NS_RI, "baz"); + PrismContainer attributesContainerBefore = shadowBefore.findContainer(ShadowType.F_ATTRIBUTES); + PrismProperty attrBazBefore = new PrismProperty<>(new QName(MidPointConstants.NS_RI, "baz"), prismContext); + PrismPropertyDefinition attrBazDefBefore = new PrismPropertyDefinition<>(attrBazQName, DOMUtil.XSD_STRING, prismContext); + attrBazDefBefore.setMaxOccurs(-1); + attrBazBefore.setDefinition(attrBazDefBefore); + attrBazBefore.addRealValue("BaZ1"); + attrBazBefore.addRealValue("BaZ2"); + attrBazBefore.addRealValue("BaZ3"); + attributesContainerBefore.add(attrBazBefore); + System.out.println("\nAcc shadow"); - System.out.println(accShadow.debugDump()); + System.out.println(shadowBefore.debugDump()); - String oid = repositoryService.addObject(accShadow, null, parentResult); - System.out.println("\nAcc shadow"); - System.out.println(accShadow.debugDump()); + String oid = repositoryService.addObject(shadowBefore, null, parentResult); - accShadow.asObjectable().setObjectChange(null); + // WHEN + TestUtil.displayWhen(TEST_NAME); + PrismObject repoShadow = repositoryService.getObject(ShadowType.class, oid, null, parentResult); + + // THEN + TestUtil.displayThen(TEST_NAME); System.out.println("\nRepo shadow"); System.out.println(repoShadow.debugDump()); - ObjectDelta d = repoShadow.diff(accShadow); + ObjectDelta d = repoShadow.diff(shadowBefore); System.out.println("\nDelta"); System.out.println(d.debugDump()); + assertTrue("Delta after add is not empty", d.isEmpty()); - PrismObjectDefinition accountDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); - PrismReferenceValue accountRef = new PrismReferenceValue(); - accountRef.setOid(oid); - accountRef.setTargetType(ShadowType.COMPLEX_TYPE); - - Collection accountRefDeltas = ReferenceDelta.createModificationAddCollection( - UserType.F_LINK_REF, user.getDefinition(), accountRef); - - repositoryService.modifyObject(ShadowType.class, oid, accountRefDeltas, getModifyOptions(), parentResult); - - PrismObject afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); - System.out.println("\nAfter modify"); - System.out.println(afterModify.debugDump()); + PrismObjectDefinition accountDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); Collection modifications = new ArrayList(); - PropertyDelta pdelta = PropertyDelta.createModificationReplaceProperty((new ItemPath(ObjectType.F_METADATA, MetadataType.F_MODIFY_CHANNEL)), accountDefinition, "channel"); + PropertyDelta pdelta = PropertyDelta.createModificationReplaceProperty( + (new ItemPath(ObjectType.F_METADATA, MetadataType.F_MODIFY_CHANNEL)), accountDefinition, "channel"); modifications.add(pdelta); - pdelta = PropertyDelta.createModificationReplaceProperty((new ItemPath(ObjectType.F_METADATA, - MetadataType.F_MODIFY_TIMESTAMP)), accountDefinition, XmlTypeConverter - .createXMLGregorianCalendar(System.currentTimeMillis())); + XMLGregorianCalendar modifyTimestampBefore = XmlTypeConverter + .createXMLGregorianCalendar(System.currentTimeMillis()); + pdelta = PropertyDelta.createModificationReplaceProperty((new ItemPath(ObjectType.F_METADATA, + MetadataType.F_MODIFY_TIMESTAMP)), accountDefinition, modifyTimestampBefore); modifications.add(pdelta); + // WHEN + TestUtil.displayWhen(TEST_NAME); repositoryService.modifyObject(ShadowType.class, oid, modifications, getModifyOptions(), parentResult); - afterModify = repositoryService.getObject(ShadowType.class, + // THEN + TestUtil.displayThen(TEST_NAME); + PrismObject afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); - System.out.println("\nAfter modify"); + System.out.println("\nAfter modify 1"); System.out.println(afterModify.debugDump()); - - + + MetadataType metadataAfter = afterModify.asObjectable().getMetadata(); + assertEquals("Wrong modifyTimestamp", modifyTimestampBefore, metadataAfter.getModifyTimestamp()); + + PrismAsserts.assertEqualsPolyString("Wrong shadow name", "1234", afterModify.asObjectable().getName()); + assertAttribute(afterModify, new QName(SchemaConstants.NS_ICF_SCHEMA, "uid"), "8daaeeae-f0c7-41c9-b258-2a3351aa8876"); + assertAttribute(afterModify, "foo", "FOO"); + assertAttribute(afterModify, "bar", "Bar1", "Bar2"); + assertAttribute(afterModify, "baz", "BaZ1", "BaZ2", "BaZ3"); + + // GIVEN XMLGregorianCalendar timestamp = XmlTypeConverter.createXMLGregorianCalendar(System.currentTimeMillis()); List> syncSituationDeltas = SynchronizationUtils. createSynchronizationSituationDescriptionDelta(repoShadow, SynchronizationSituationType.LINKED, timestamp, null, false); @@ -416,16 +473,24 @@ public void testModifyAccountMetadata() throws Exception { createSynchronizationSituationDelta(repoShadow, SynchronizationSituationType.LINKED); syncSituationDeltas.add(syncSituationDelta); + // WHEN + TestUtil.displayWhen(TEST_NAME); repositoryService.modifyObject(ShadowType.class, oid, syncSituationDeltas, getModifyOptions(), parentResult); // AssertJUnit.assertNull(afterModify.asObjectable().getObjectChange()); + + // THEN + TestUtil.displayThen(TEST_NAME); afterModify = repositoryService.getObject(ShadowType.class, oid, null, parentResult); - System.out.println("\nAfter modify"); + System.out.println("\nAfter modify 2"); System.out.println(afterModify.debugDump()); } - @Test - public void testExtensionModify() throws Exception { + @Test + public void test130ExtensionModify() throws Exception { + final String TEST_NAME = "test130ExtensionModify"; + TestUtil.displayTestTile(TEST_NAME); + final QName QNAME_LOOT = new QName("http://example.com/p", "loot"); File userFile = new File(TEST_DIR, "user-with-extension.xml"); @@ -461,7 +526,10 @@ public void testExtensionModify() throws Exception { } @Test - public void testModifyAccountSynchronizationSituation() throws Exception { + public void test140ModifyAccountSynchronizationSituation() throws Exception { + final String TEST_NAME = "test140ModifyAccountSynchronizationSituation"; + TestUtil.displayTestTile(TEST_NAME); + OperationResult result = new OperationResult("testModifyAccountSynchronizationSituation"); //add account @@ -521,8 +589,11 @@ public void testModifyAccountSynchronizationSituation() throws Exception { } @Test - public void modifyRoleAddInducements() throws Exception { - OperationResult result = new OperationResult("MODIFY"); + public void test150ModifyRoleAddInducements() throws Exception { + final String TEST_NAME = "test150ModifyRoleAddInducements"; + TestUtil.displayTestTile(TEST_NAME); + + OperationResult result = new OperationResult(TEST_NAME); File roleFile = new File(TEST_DIR, "role-modify.xml"); //add first user @@ -566,4 +637,18 @@ public void modifyRoleAddInducements() throws Exception { assertEquals("Version has changed", version, role.getVersion()); } } + + private void assertAttribute(PrismObject shadow, String attrName, T... expectedValues) { + assertAttribute(shadow, new QName(MidPointConstants.NS_RI, attrName), expectedValues); + } + + private void assertAttribute(PrismObject shadow, QName attrQName, T... expectedValues) { + PrismProperty attr = shadow.findProperty(new ItemPath(ShadowType.F_ATTRIBUTES, attrQName)); + if (expectedValues.length == 0) { + assertTrue("Expected no value for attribute "+attrQName+" in "+shadow+", but it has "+attr, attr == null); + } else { + assertNotNull("No attribute "+attrQName+" in "+shadow, attr); + PrismAsserts.assertPropertyValue(attr, expectedValues); + } + } } diff --git a/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml b/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml index c65a51fbd6d..9c6a31eeb73 100644 --- a/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml +++ b/repo/repo-sql-impl-test/src/test/resources/basic/objects.xml @@ -30,7 +30,9 @@ atestuserX00002 - + + testLifecycleStatus + http://triggerUri 2013-05-07T10:38:21.350+02:00 diff --git a/repo/repo-sql-impl-test/src/test/resources/modify/account.xml b/repo/repo-sql-impl-test/src/test/resources/modify/account.xml index 5288f0c7612..bc38a473728 100644 --- a/repo/repo-sql-impl-test/src/test/resources/modify/account.xml +++ b/repo/repo-sql-impl-test/src/test/resources/modify/account.xml @@ -1,7 +1,7 @@ - + xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3" + xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" + xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"> 1234 ri:AccountObjectClass - 8daaeeae-f0c7-41c9-b258-2a3351aa8876 + 8daaeeae-f0c7-41c9-b258-2a3351aa8876 + FOO + Bar1 + Bar2 enabled diff --git a/repo/repo-sql-impl-test/src/test/resources/modify/change-add.xml b/repo/repo-sql-impl-test/src/test/resources/modify/change-add.xml index d3076b9dcad..b34259d8127 100644 --- a/repo/repo-sql-impl-test/src/test/resources/modify/change-add.xml +++ b/repo/repo-sql-impl-test/src/test/resources/modify/change-add.xml @@ -15,17 +15,19 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + modify + UserType f65963e3-9d47-4b18-aaf3-bfc98bdfa000 - + add c:linkRef 1234567890 - - + + diff --git a/repo/repo-sql-impl-test/src/test/resources/modify/modify-user.xml b/repo/repo-sql-impl-test/src/test/resources/modify/modify-user.xml index 81b72de79d9..b7e6ad795a3 100644 --- a/repo/repo-sql-impl-test/src/test/resources/modify/modify-user.xml +++ b/repo/repo-sql-impl-test/src/test/resources/modify/modify-user.xml @@ -1,5 +1,5 @@