Skip to content
This repository has been archived by the owner on May 31, 2022. It is now read-only.

Commit

Permalink
Added audit assertion failures diagnostic facility: AuditPointRuntime…
Browse files Browse the repository at this point in the history
…Info and co.
  • Loading branch information
dima767 committed Nov 14, 2011
1 parent 8c46a66 commit a7c9187
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 87 deletions.
@@ -0,0 +1,23 @@
package com.github.inspektr.audit;

import org.aspectj.lang.JoinPoint;

/**
* Wrapper around AspectJ's JoinPoint containing the runtime execution info for current audit points
*
* @author Dmitriy Kopylenko
*
* @since 1.0.6
*/
public class AspectJAuditPointRuntimeInfo implements AuditPointRuntimeInfo {

private JoinPoint currentJoinPoint;

public AspectJAuditPointRuntimeInfo(JoinPoint currentJoinPoint) {
this.currentJoinPoint = currentJoinPoint;
}

public String asString() {
return this.currentJoinPoint.toLongString();
}
}
Expand Up @@ -59,14 +59,14 @@ public final class AuditActionContext implements Serializable {
private final String serverIpAddress;

public AuditActionContext(final String principal, final String resourceOperatedUpon, final String actionPerformed, final String applicationCode,
final Date whenActionWasPerformed, final String clientIpAddress, final String serverIpAddress) {
assertNotNull(principal, "principal cannot be null");
assertNotNull(resourceOperatedUpon, "resourceOperatedUpon cannot be null");
assertNotNull(actionPerformed, "actionPerformed cannot be null.");
assertNotNull(applicationCode, "applicationCode cannot be null.");
assertNotNull(whenActionWasPerformed, "whenActionPerformed cannot be null.");
assertNotNull(clientIpAddress, "clientIpAddress cannot be null.");
assertNotNull(serverIpAddress, "serverIpAddress cannot be null.");
final Date whenActionWasPerformed, final String clientIpAddress, final String serverIpAddress, AuditPointRuntimeInfo runtimeInfo) {
assertNotNull(principal, "'principal' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(resourceOperatedUpon, "'resourceOperatedUpon' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(actionPerformed, "'actionPerformed' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(applicationCode, "'applicationCode' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(whenActionWasPerformed, "'whenActionPerformed' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(clientIpAddress, "'clientIpAddress' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
assertNotNull(serverIpAddress, "'serverIpAddress' cannot be null.\n" + getDiagnosticInfo(runtimeInfo));
this.principal = principal;
this.resourceOperatedUpon = resourceOperatedUpon;
this.actionPerformed = actionPerformed;
Expand Down Expand Up @@ -109,4 +109,8 @@ public String getClientIpAddress() {
public String getServerIpAddress() {
return this.serverIpAddress;
}

private String getDiagnosticInfo(AuditPointRuntimeInfo runtimeInfo) {
return "Check the correctness of @Audit annotation at the following audit point: " + runtimeInfo.asString();
}
}
@@ -0,0 +1,19 @@
package com.github.inspektr.audit;

import java.io.Serializable;

/**
* Encapsulates a runtime execution context at advised audit points. Used for diagnostic purposes
* to provide clear contextual information about any given audit point in case of runtime failures
* during audit capturing operation, e.g. any assert failures, etc.
*
* @author Dmitriy Kopylenko
* @since 1.0.6
*/
public interface AuditPointRuntimeInfo extends Serializable {

/**
* @return String representation of this audit point runtime execution context
*/
String asString();
}
Expand Up @@ -37,123 +37,126 @@

/**
* A POJO style aspect modularizing management of an audit trail data concern.
*
*
* @author Dmitriy Kopylenko
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 1.0
*/
@Aspect
public final class AuditTrailManagementAspect {

private final PrincipalResolver auditPrincipalResolver;

private final Map<String, AuditActionResolver> auditActionResolvers;

private final Map<String, AuditResourceResolver> auditResourceResolvers;
private final Map<String, AuditResourceResolver> auditResourceResolvers;

private final List<AuditTrailManager> auditTrailManagers;
private final String applicationCode;

private ClientInfoResolver clientInfoResolver = new DefaultClientInfoResolver();
/**
* Constructs an AuditTrailManagementAspect with the following parameters. Also, registers some default AuditActionResolvers including the
* {@link com.github.inspektr.audit.spi.support.DefaultAuditActionResolver}, the {@link com.github.inspektr.audit.spi.support.BooleanAuditActionResolver} and the {@link com.github.inspektr.audit.spi.support.ObjectCreationAuditActionResolver}.
*
* @param applicationCode the overall code that identifies this application.
* @param auditablePrincipalResolver the resolver which will locate principals.
* @param auditTrailManagers the list of managers to write the audit trail out to.
* @param auditActionResolverMap the map of resolvers by name provided in the annotation on the method.
* @param auditResourceResolverMap the map of resolvers by the name provided in the annotation on the method.
*/
public AuditTrailManagementAspect(final String applicationCode, final PrincipalResolver auditablePrincipalResolver, final List<AuditTrailManager> auditTrailManagers, final Map<String,AuditActionResolver> auditActionResolverMap, final Map<String,AuditResourceResolver> auditResourceResolverMap) {
this.auditPrincipalResolver = auditablePrincipalResolver;
this.auditTrailManagers = auditTrailManagers;
this.applicationCode = applicationCode;

private final String applicationCode;

private ClientInfoResolver clientInfoResolver = new DefaultClientInfoResolver();

/**
* Constructs an AuditTrailManagementAspect with the following parameters. Also, registers some default AuditActionResolvers including the
* {@link com.github.inspektr.audit.spi.support.DefaultAuditActionResolver}, the {@link com.github.inspektr.audit.spi.support.BooleanAuditActionResolver} and the {@link com.github.inspektr.audit.spi.support.ObjectCreationAuditActionResolver}.
*
* @param applicationCode the overall code that identifies this application.
* @param auditablePrincipalResolver the resolver which will locate principals.
* @param auditTrailManagers the list of managers to write the audit trail out to.
* @param auditActionResolverMap the map of resolvers by name provided in the annotation on the method.
* @param auditResourceResolverMap the map of resolvers by the name provided in the annotation on the method.
*/
public AuditTrailManagementAspect(final String applicationCode, final PrincipalResolver auditablePrincipalResolver, final List<AuditTrailManager> auditTrailManagers, final Map<String, AuditActionResolver> auditActionResolverMap, final Map<String, AuditResourceResolver> auditResourceResolverMap) {
this.auditPrincipalResolver = auditablePrincipalResolver;
this.auditTrailManagers = auditTrailManagers;
this.applicationCode = applicationCode;
this.auditActionResolvers = auditActionResolverMap;
this.auditResourceResolvers = auditResourceResolverMap;

}
@Around(value="@annotation(audits)", argNames="audits")

@Around(value = "@annotation(audits)", argNames = "audits")
public Object handleAuditTrail(final ProceedingJoinPoint joinPoint, final Audits audits) throws Throwable {
Object retVal = null;
String currentPrincipal = null;
final String[] actions = new String[audits.value().length];
final String[][] auditableResources = new String[audits.value().length][];
try {
retVal = joinPoint.proceed();
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, retVal);
if (currentPrincipal != null) {
for (int i = 0; i < audits.value().length; i++) {
Object retVal = null;
String currentPrincipal = null;
final String[] actions = new String[audits.value().length];
final String[][] auditableResources = new String[audits.value().length][];
try {
retVal = joinPoint.proceed();
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, retVal);

if (currentPrincipal != null) {
for (int i = 0; i < audits.value().length; i++) {
final AuditActionResolver auditActionResolver = this.auditActionResolvers.get(audits.value()[i].actionResolverName());
final AuditResourceResolver auditResourceResolver = this.auditResourceResolvers.get(audits.value()[i].resourceResolverName());
auditableResources[i] = auditResourceResolver.resolveFrom(joinPoint, retVal);
actions[i] = auditActionResolver.resolveFrom(joinPoint, retVal, audits.value()[i]);
}
}
return retVal;
} catch (final Exception e) {
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, e);
if (currentPrincipal != null) {
for (int i = 0; i < audits.value().length; i++) {
auditableResources[i] = this.auditResourceResolvers.get(audits.value()[i].resourceResolverName()).resolveFrom(joinPoint, e);
actions[i] = auditActionResolvers.get(audits.value()[i].actionResolverName()).resolveFrom(joinPoint, e, audits.value()[i]);
}
}
throw e;
} finally {
for (int i = 0; i < audits.value().length; i++) {
executeAuditCode(currentPrincipal, auditableResources[i], joinPoint, retVal, actions[i], audits.value()[i]);
}
}
auditableResources[i] = auditResourceResolver.resolveFrom(joinPoint, retVal);
actions[i] = auditActionResolver.resolveFrom(joinPoint, retVal, audits.value()[i]);
}
}
return retVal;
} catch (final Exception e) {
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, e);

if (currentPrincipal != null) {
for (int i = 0; i < audits.value().length; i++) {
auditableResources[i] = this.auditResourceResolvers.get(audits.value()[i].resourceResolverName()).resolveFrom(joinPoint, e);
actions[i] = auditActionResolvers.get(audits.value()[i].actionResolverName()).resolveFrom(joinPoint, e, audits.value()[i]);
}
}
throw e;
} finally {
for (int i = 0; i < audits.value().length; i++) {
executeAuditCode(currentPrincipal, auditableResources[i], joinPoint, retVal, actions[i], audits.value()[i]);
}
}
}
@Around(value="@annotation(audit)", argNames="audit")

@Around(value = "@annotation(audit)", argNames = "audit")
public Object handleAuditTrail(final ProceedingJoinPoint joinPoint, final Audit audit) throws Throwable {
final AuditActionResolver auditActionResolver = this.auditActionResolvers.get(audit.actionResolverName());
final AuditResourceResolver auditResourceResolver = this.auditResourceResolvers.get(audit.resourceResolverName());
String currentPrincipal = null;
String[] auditResource = null;
String action = null;
Object retVal = null;
try {
retVal = joinPoint.proceed();
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, retVal);

String currentPrincipal = null;
String[] auditResource = new String[]{null};
String action = null;
Object retVal = null;
try {
retVal = joinPoint.proceed();

currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, retVal);
auditResource = auditResourceResolver.resolveFrom(joinPoint, retVal);
action = auditActionResolver.resolveFrom(joinPoint, retVal, audit);

return retVal;
} catch (final Exception e) {
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, e);
return retVal;
} catch (final Exception e) {
currentPrincipal = this.auditPrincipalResolver.resolveFrom(joinPoint, e);
auditResource = auditResourceResolver.resolveFrom(joinPoint, e);
action = auditActionResolver.resolveFrom(joinPoint, e, audit);
throw e;
} finally {
executeAuditCode(currentPrincipal, auditResource, joinPoint, retVal, action, audit);
}
throw e;
} finally {
executeAuditCode(currentPrincipal, auditResource, joinPoint, retVal, action, audit);
}
}

private void executeAuditCode(final String currentPrincipal, final String[] auditableResources, final ProceedingJoinPoint joinPoint, final Object retVal, final String action, final Audit audit) {
final String applicationCode = (audit.applicationCode() != null && audit.applicationCode().length() > 0) ? audit.applicationCode() : this.applicationCode;
final ClientInfo clientInfo = this.clientInfoResolver.resolveFrom(joinPoint, retVal);
final Date actionDate = new Date();
final AuditPointRuntimeInfo runtimeInfo = new AspectJAuditPointRuntimeInfo(joinPoint);
for (final String auditableResource : auditableResources) {
final AuditActionContext auditContext = new AuditActionContext(currentPrincipal, auditableResource, action, applicationCode, actionDate, clientInfo.getClientIpAddress(), clientInfo.getServerIpAddress());
final AuditActionContext auditContext =
new AuditActionContext(currentPrincipal, auditableResource, action, applicationCode,
actionDate, clientInfo.getClientIpAddress(), clientInfo.getServerIpAddress(), runtimeInfo);
// Finally record the audit trail info
for(AuditTrailManager manager : auditTrailManagers) {
for (AuditTrailManager manager : auditTrailManagers) {
manager.record(auditContext);
}
}
}

public void setClientInfoResolver(final ClientInfoResolver factory) {
this.clientInfoResolver = factory;
}
public void setClientInfoResolver(final ClientInfoResolver factory) {
this.clientInfoResolver = factory;
}
}

0 comments on commit a7c9187

Please sign in to comment.