/*
* Copyright (c) 2010-2013 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.repo.sql;
import com.evolveum.midpoint.audit.api.AuditEventRecord;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.repo.sql.data.audit.RAuditEventRecord;
import com.evolveum.midpoint.repo.sql.util.SimpleTaskAdapter;
import com.evolveum.midpoint.schema.ObjectDeltaOperation;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* @author lazyman
*/
@ContextConfiguration(locations = {"../../../../../ctx-test.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class CleanupTest extends BaseSQLRepoTest {
private static final Trace LOGGER = TraceManager.getTrace(CleanupTest.class);
private Calendar create_2013_07_12_12_00_Calendar() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2013);
calendar.set(Calendar.MONTH, Calendar.MAY);
calendar.set(Calendar.DAY_OF_MONTH, 7);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
private Duration createDuration(Calendar when, long now) throws Exception {
long seconds = (now - when.getTimeInMillis()) / 1000;
return DatatypeFactory.newInstance().newDuration("PT" + seconds + "S").negate();
}
private CleanupPolicyType createPolicy(Calendar when, long now) throws Exception {
CleanupPolicyType policy = new CleanupPolicyType();
Duration duration = createDuration(when, now);
policy.setMaxAge(duration);
return policy;
}
private CleanupPolicyType createPolicy(int maxRecords) throws Exception {
CleanupPolicyType policy = new CleanupPolicyType();
policy.setMaxRecords(Integer.valueOf(maxRecords));
return policy;
}
@AfterMethod
public void cleanup() {
Session session = getFactory().openSession();
try {
session.beginTransaction();
session.createQuery("delete from RObjectDeltaOperation").executeUpdate();
session.createQuery("delete from RAuditPropertyValue").executeUpdate();
session.createQuery("delete from RAuditReferenceValue").executeUpdate();
session.createQuery("delete from RAuditEventRecord").executeUpdate();
Query query = session.createQuery("select count(*) from " + RAuditEventRecord.class.getSimpleName());
Long count = (Long) query.uniqueResult();
AssertJUnit.assertEquals(0L, (long) count);
session.getTransaction().commit();
} finally {
session.close();
}
}
@Test
public void testAuditCleanupMaxAge() throws Exception {
//GIVEN
prepareAuditEventRecords();
//WHEN
Calendar calendar = create_2013_07_12_12_00_Calendar();
calendar.add(Calendar.HOUR_OF_DAY, 1);
calendar.add(Calendar.MINUTE, 1);
final long NOW = System.currentTimeMillis();
CleanupPolicyType policy = createPolicy(calendar, NOW);
OperationResult result = new OperationResult("Cleanup audit");
auditService.cleanupAudit(policy, result);
result.recomputeStatus();
//THEN
RAuditEventRecord record = assertAndReturnAuditEventRecord(result);
Date finished = new Date(record.getTimestamp().getTime());
Date mark = new Date(NOW);
Duration duration = policy.getMaxAge();
duration.addTo(mark);
AssertJUnit.assertTrue("finished: " + finished + ", mark: " + mark, finished.after(mark));
}
@Test
public void testAuditCleanupMaxRecords() throws Exception {
//GIVEN
prepareAuditEventRecords();
//WHEN
Calendar calendar = create_2013_07_12_12_00_Calendar();
calendar.add(Calendar.HOUR_OF_DAY, 1);
calendar.add(Calendar.MINUTE, 1);
final long NOW = System.currentTimeMillis();
CleanupPolicyType policy = createPolicy(1);
OperationResult result = new OperationResult("Cleanup audit");
auditService.cleanupAudit(policy, result);
result.recomputeStatus();
//THEN
RAuditEventRecord record = assertAndReturnAuditEventRecord(result);
}
private RAuditEventRecord assertAndReturnAuditEventRecord(OperationResult result) {
AssertJUnit.assertTrue(result.isSuccess());
Session session = getFactory().openSession();
try {
session.beginTransaction();
Query query = session.createQuery("from " + RAuditEventRecord.class.getSimpleName());
List<RAuditEventRecord> records = query.list();
AssertJUnit.assertEquals(1, records.size());
session.getTransaction().commit();
return records.get(0);
} finally {
session.close();
}
}
private void prepareAuditEventRecords() throws Exception {
Calendar calendar = create_2013_07_12_12_00_Calendar();
for (int i = 0; i < 3; i++) {
long timestamp = calendar.getTimeInMillis();
AuditEventRecord record = new AuditEventRecord();
record.addDelta(createObjectDeltaOperation(i));
record.setTimestamp(timestamp);
record.addPropertyValue("prop1", "val1");
record.addReferenceValue("ref1", ObjectTypeUtil.createObjectRef("oid1", ObjectTypes.USER).asReferenceValue());
LOGGER.info("Adding audit record with timestamp {}", new Object[]{new Date(timestamp)});
auditService.audit(record, new SimpleTaskAdapter());
calendar.add(Calendar.HOUR_OF_DAY, 1);
}
Session session = getFactory().openSession();
try {
session.beginTransaction();
Query query = session.createQuery("select count(*) from " + RAuditEventRecord.class.getSimpleName());
Long count = (Long) query.uniqueResult();
AssertJUnit.assertEquals(3L, (long) count);
session.getTransaction().commit();
} finally {
session.close();
}
}
private ObjectDeltaOperation createObjectDeltaOperation(int i) throws Exception {
ObjectDeltaOperation delta = new ObjectDeltaOperation();
delta.setExecutionResult(new OperationResult("asdf"));
UserType user = new UserType();
prismContext.adopt(user);
PolyStringType name = new PolyStringType();
name.setOrig("a" + i);
name.setNorm("a" + i);
user.setName(name);
delta.setObjectDelta(ObjectDelta.createAddDelta(user.asPrismObject()));
return delta;
}
}