Skip to content

Open Infinity Core Documentation V2.0.X.RELEASE

ileinone edited this page Dec 7, 2014 · 4 revisions

Open Infinity Core - 2.0.X.RELEASE

Open Infinity Core framework is a solution accelerator providing best practices patterns and tactics to overcome cross-cutting concerns like audit trail, logging, standardized and localized exception hierarchy, validation, security and quality.

Package Explanation
org.openinfinity.core.annotation Package includes platform specific annotations. Annotations are used as an metadata for aspects.
org.openinfinity.core.aspect Package includes platform specific aspects removing boilerplate code and providing better quality through reusability.
org.openinfinity.core.exception Package includes platform specific exception mechanism. Exceptions have three layerd mechanism to provide information about the application state. Exception level has also been defined.
org.openinfinity.core.util Package includes platform specific utilities and helper classes.
org.openinfinity.core.validation Package includes platform specific security validation modules.
org.openinfinity.core.spring Package includes Spring framework specific helper classes.

org.openinfinity.core.annotation

The package includes the following functionality.

AuditTrail

This annotation represents the metadata added to the runtime method. The metadata executes the org.openinfinity.core.aspect.AuditTrailAspect -aspect when defined. Annotation can be defined in the method level.

@AudiTrail
public SomeObject someMethod(AnotherObject anotherObject() {...}

@AuditTrail(
    isUsernameEnabled=true,
    isRolesEnabled=false,
    isTimeStampEnabled=true, 
    value={"auto/tire/screw","personId"}, 
    argumentStrategy=CUSTOM
)
public SomeObject someMethod(AnotherObject anotherObject() {...}

Encrypt

This annotation represents the metadata added to the runtime method. The metadata executes the org.openinfinity.core.aspect.CryptoAspect -aspect when defined. Annotation can be defined in the method level. Annotation can be utilized to encrypt data graphs attributes.

@Encrypt
public SomeObject someMethod(AnotherObject anotherObject() {...}

@Encrypt(
    value={"auto/tire/screw","personId"}, 
    argumentStrategy=CUSTOM
)
public SomeObject someMethod(AnotherObject anotherObject() {...}

Decrypt

This annotation represents the metadata added to the runtime method. The metadata executes the org.openinfinity.core.aspect.CryptoAspect -aspect when defined. Annotation can be defined in the method level. Annotation can be utilized to decrypt data graphs attributes.

@Decrypt
public SomeObject someMethod(AnotherObject anotherObject() {...}

@Decrypt(
    value={"auto/tire/screw","personId"}, 
    argumentStrategy=CUSTOM
)
public SomeObject someMethod(AnotherObject anotherObject() {...}

Log

This annotation represents the metadata added to the runtime method. The metadata executes the org.openinfinity.core.aspect.LogAspect-aspect when defined. Annotation can be defined in the method level.

@Log
public SomeObject someMethod(AnotherObject anotherObject() {...}

@Log(level=LogLevel.INFO)
public SomeObject someMethod(AnotherObject anotherObject() {...}

@Log(
    value={"auto/tire/screw","personId"}, 
    argumentStrategy=CUSTOM
    level=LogLevel.INFO
)
public SomeObject someMethod(AnotherObject anotherObject() {...}
  

NotScript

Field validator for validating XSS attacks.

@NotScript
private String someField;

@NotScript(allowedInputPattern=Person.SSN_XSS)
private String someField;

org.openinfinity.core.aspect

The package includes the following functionality.

AuditTrailAspect

Class is responsible for creating audit trail information. Audit trail storage system can be defined through Log4j property files (JDBCAppender, FileAppender, JMSAppender etc).

<context:component-scan base-package=“org.openinfinity.core"> 

<aop:aspectj-autoproxy>
      <aop:include name="auditTrailAspect“ />
</aop:aspectj-autoproxy>

<bean 
    id="auditTrailAspect" 
    class=“org.openinfinity.core.aspect.AuditTrailAspect" />

ExceptionTranslationAspect

Aspect for handling controller and service level exception translation. Service level exceptions should always be instance of org.openinfinity.core.exception.ApplicationException,org.openinfinity.core.exception.SystemException or org.openinfinity.core.exception.BusinessViolationException. Unknown exceptions will be translated to org.openinfinity.core.exception.SystemException.

<context:component-scan base-package=“org.openinfinity.core"> 

<aop:aspectj-autoproxy>
      <aop:include name=“exceptionTranslatorAspect"/>
</aop:aspectj-autoproxy>

<bean 
    id="exceptionTranslatorAspect"    
    class="org.openinfinity.core.aspect.ExceptionTranslatorAspect” />

CryptoAspect

This class is responsible of the encrypting and decrypting data entity's fields. All the incoming parameters will be encrypted or decrypted based on the defined annotation (@Encrypt or @Decrypt).

<context:component-scan base-package=“org.openinfinity.core"> 

<aop:aspectj-autoproxy>
      <aop:include name=“cryptoAspect"/>
</aop:aspectj-autoproxy>

<bean id="cryptoAspect" class="org.openinfinity.core.aspect.CryptoAspect">
	<property name="cryptoSupport" ref="cryptoSupport" />
	<property name="encoding" value="${crypto.character.encoding}"/>
</bean>

<bean id ="cryptoSupport" class="org.openinfinity.core.crypto.CryptoSupport">
	<constructor-arg name="asymmetricPublicKeyPath" value="${asymmetric.public.key.path}"/>
	<constructor-arg name="asymmetricPrivateKeyPath" value="${asymmetric.private.key.path}"/>
</bean>

LogAspect

This class is responsible of the logging. All the incoming parameters will be logged (based on toString() method). Logging storage system can be defined through Log4j property files (JDBCAppender, FileAppender, JMSAppender etc).

<context:component-scan base-package=“org.openinfinity.core"> 

<aop:aspectj-autoproxy>
      <aop:include name=“logAspect"/>
</aop:aspectj-autoproxy>

<bean 
    id="logAspect" 
    class="org.openinfinity.core.aspect.LogAspect" />

MultiTenantAspect

This class is responsible of the tenant id injection into the domain entity which extends org.openinfinity.core.domain.entity.MultiTenantBaseEntity. org.openinfinity.core.security.principal.Identity implements org.springframework.security.core.Authentication interface and is therefore available through Spring security's code>org.springframework.security.core.context.SecurityContext.

<context:component-scan base-package=“org.openinfinity.core"> 

<aop:aspectj-autoproxy>
      <aop:include name=“multiTenantAspect"/>
</aop:aspectj-autoproxy>

<bean 
    id="multiTenantAspect" 
    class="org.openinfinity.core.aspect.MultiTenantAspect" />

org.openinfinity.core.async

The package includes the following functionality for parallel processing and CRUD integrations.

ParallelServiceActivator

Class is responsible for parallel computing regarding CRUD (Create, Read, Update, Delete) like operations.

    @Autowired
	private IntegrationTest integrationTestService;
	
	@Autowired
	private IntegrationTest integrationTestService2;
	
	@Autowired
	private ExecutorServiceAdapter executorServiceAdapter;
	
	public void activateServiceCallsInParallel() {
		ParallelServiceActivator parallelServiceActivator = new ParallelServiceActivator();
		parallelServiceActivator.setExecutorServiceAdapter(executorServiceAdapter);
		
		String id = "testname";
		parallelServiceActivator.
			prepareToQueryAllById(integrationTestService, id, "accounts1").
			prepareToQueryAllById(integrationTestService2, id, "accounts2").
			activate();
	
		Collection<Account> accounts1 = parallelServiceActivator.loadResult("accounts1");
		Collection<Account> accounts2 = parallelServiceActivator.loadResult("accounts2");
		// manage account informations
	}

or

        ParallelServiceActivator parallelServiceActivator = new ParallelServiceActivator();
		parallelServiceActivator.setExecutorServiceAdapter(executorServiceAdapter);
		
		String id = "testname";
		final Collection<Account> allAccounts = new ArrayList<Account>();
		
		parallelServiceActivator.
		prepareToQueryAllById(integrationTestService, id).
		prepareToQueryAllById(integrationTestService2, id).
		activate().
		onResult(new AsyncResultCallback<Collection<Account>>() {
			@Override
			public void onResult(Collection<Account> accounts) {	
				allAccounts.addAll(accounts);
			}
		}).
		onResult(new AsyncResultCallback<Collection<Account>>() {
			@Override
			public void onResult(Collection<Account> accounts) {	
				allAccounts.addAll(accounts);
			}
		});

Configure Spring context with following Bean definition:

    <bean id="taskExecutor"
		class="org.springframework.scheduling.config.TaskExecutorFactoryBean">
		<property name="poolSize" value="90" />
		<property name="queueCapacity" value="100" />
	</bean>

	<bean id="executorServiceAdapter"
		class="org.springframework.core.task.support.ExecutorServiceAdapter">
		<constructor-arg ref="taskExecutor" />
	</bean>

	<task:annotation-driven executor="taskExecutor" />

org.openinfinity.core.crypto

The package includes the following functionality.

CryptoSupport

This object supports encryption and decryption of the entity fields. It handles the base 64 encoding and decoding of java.util.String fields.

CryptoSupport example usage for encryption:

@Autowired 
CryptoSupport cryptoSupport;

public SomeObject someMethod(Object plainArgument) {
      byte[] plainBytes = IOUtil.getBytes(plainArgument);
      byte[] encryptedBytes = cryptoSupport.encrypt(plainBytes);
}

public SomeObject someMethod(Object argument) {
      byte[] plainBytes = IOUtil.getBytes(field.get(object));
      String encryptedBase64Presentation = cryptoSupport.encryptAndReturnBase64Presentation(plainBytes, "ISO-8859-1");
}

CryptoSupport example usage for decryption:

@Autowired 
CryptoSupport cryptoSupport;

public SomeObject someMethod(Object encryptedArgument) {
      byte[] plainBytes = IOUtil.getBytes(argument);
      byte[] encryptedBytes = cryptoSupport.encrypt(plainBytes);
}

public SomeObject someMethod(Object encryptedArgument) {
     	byte[] encryptedBytes = IOUtil.getBytes(field.get(encryptedArgument));
	String decryptedBase64Presentation = cryptoSupport.decryptAndReturnBase64Presentation(encryptedBytes, "ISO-8859-1");
}

Context configuration:

<context:component-scan base-package=“org.openinfinity.core"> 

# Asymmetric algorithm configuration
<bean id ="cryptoSupport" class="org.openinfinity.core.crypto.CryptoSupport">
	<constructor-arg name="asymmetricPublicKeyPath" value="${asymmetric.public.key.path}"/>
	<constructor-arg name="asymmetricPrivateKeyPath" value="${asymmetric.private.key.path}"/>
</bean>

# Symmetric algorithm configuration
<bean id ="cryptoSupport" class="org.openinfinity.core.crypto.CryptoSupport">
	<constructor-arg name="symmetricKeyPath" value="${symmetric.key.path}"/>
</bean>

org.openinfinity.core.security.principal

The package includes the following functionality.

Identity

Class for maintaining the state of the federated identity. Implements org.springframework.security.core.Authentication interface.

Identity object example usage for storing relevant user information:

String username = (String) (request.getAttribute(USER_NAME) != null ? request.getAttribute(USER_NAME) : null);
String tenantId = (String) (request.getAttribute(TENANT_ID) != null ? request.getAttribute(TENANT_ID) : null);
String userRoles = ((String) (request.getAttribute(USER_ROLES) != null ? request.getAttribute(USER_ROLES) : null));
String[] splittedUserRoles = userRoles!=null ? userRoles.split(ROLE_DELIMITER) : null;
Identity identity = new Identity();
populatePrincipals(username, tenantId, splittedUserRoles, identity);
populateUserAttributes(request, identity);
identity.setAuthenticated(true);

private void populatePrincipals(String username, String tenantId, String[] userRoles, Identity identity) {
        if (username != null) {
	        UserPrincipal userPrincipal = new UserPrincipal(username);
	        identity.setUserPrincipal(userPrincipal);
        }
	if (tenantId != null) {
		TenantPrincipal<?> tenantPrincipal = new TenantPrincipal<Object>(tenantId);
		identity.setTenantPrincipal(tenantPrincipal);
	}
	if (userRoles != null) {
		Collection<RolePrincipal> rolePrincipals = new ArrayList<RolePrincipal>();
		for (String role : userRoles) {
			RolePrincipal rolePrincipal = new RolePrincipal(ROLE_PREFIX + role);
			rolePrincipals.add(rolePrincipal);
		}
		identity.setRolePrincipals(rolePrincipals);
	}
}

private void populateUserAttributes(Request request, Identity identity) {
	String[] splittedAttributesKeys = USER_ATTRIBUTE_KEYS.split(USER_ATTRIBUTE_DELIMITER);
	for (String attributeKey : splittedAttributesKeys) {
		String attributeValue = (String) request.getAttribute(attributeKey);
		if (attributeValue != null) {
			identity.addAttribute(attributeKey, attributeValue);
		}
	}
}

org.openinfinity.core.entity

The package includes the following functionality.

BaseEntity

Represents a base entity class to be utilized with domain entities. Following Attributes are provided:

  • id, which represents the unique id of the entity
  • creationDate, which represents the starting point of the entity lifecycle
  • updateInformations, which represents the collection of the lifecycle events for the domain entity
  • terminationDate, which represents the termination date of the domain entity's lifecycle

BaseEntity example usage for defining lifecycle events:


public Account extends BaseEntity<BigInteger> {}

@Autowired
MongoTemplate mongoTemplate; // Notice, that not part of core dependency.

public SomeObject storeAccount(Account account) {
    DateTime dateTime = new DateTime();
    Date date = dateTime.toDate();
    Collection<UpdateInformation<String>> updateInformations = createUpdateInformation(date);
    account.setCreationDate(date);
    account.setUpdateInformations(updateInformations);
    mongoTemplate.save(account);
}

private Collection<UpdateInformation<String>> createUpdateInformation(Date updateDate) {
    SecurityContext context = SecurityContextHolder.getSecurityContext();
    Authentication authentication = context.getAuthentication;
    String username = authentication.getName();
    UpdateInformation<String> updateInformation = new UpdateInformation<String>();
    updateInformation.setUpdateById(username);
    updateInformation.setUpdateDate(updateDate);
    Collection<UpdateInformation<String>> updateInformations = new Collection<UpdateInformation<String>>();
    updateInformations.add(updateInformation);
    return updateInformations;
}

MultiTenantBaseEntity

Represents the domain entity for multitenant Software as a Service applications with shared schema model and extends org.openinfinity.core.domain.entity.BaseEntity.

MultiTenantBaseEntity example usage for defining lifecycle events:


public Account extends MultiTenantBaseEntity<BigInteger, BigInteger> {}

@Autowired
MongoTemplate mongoTemplate; // Notice, that not part of core dependency.

@MultiTenant //Populates id of the tenant to the domain object itself. 
public SomeObject storeAccount(Account account) {
    DateTime dateTime = new DateTime();
    Date date = dateTime.toDate();
    Collection<UpdateInformation<String>> updateInformations = createUpdateInformation(date);
    account.setCreationDate(date);
    account.setUpdateInformations(updateInformations);
    mongoTemplate.save(account);
}

private Collection<UpdateInformation<String>> createUpdateInformation(Date updateDate) {
    SecurityContext context = SecurityContextHolder.getSecurityContext();
    Authentication authentication = context.getAuthentication;
    String username = authentication.getName();
    UpdateInformation<String> updateInformation = new UpdateInformation<String>();
    updateInformation.setUpdateById(username);
    updateInformation.setUpdateDate(updateDate);
    Collection<UpdateInformation<String>> updateInformations = new Collection<UpdateInformation<String>>();
    updateInformations.add(updateInformation);
    return updateInformations;
}

org.openinfinity.core.exception

The package includes the following functionality.

BusinessViolationException

Business violation exception is thrown when business rule fails. This kind of behaviour has a fatal impact for the business. Exception is derived from org.openinfinity.core.exception.AbstractCoreException.

Service interface mapped to error properties:

private static final UNIQUE_EXCEPTION = ”bve.exception.not.found”;

Service implementation using localized properties:

if (product.isNotFound()) {
    BusinessViolationException bve = new BusinessViolationException
    (
        ”Product not found”,      
        ExceptionLevel.ERROR,
        UNIQUE_EXCEPTION
    ); 
    throw bve;
} 

or simply using core utilities:

if (product.isNotFound()) { 
    ExceptionUtil.throwBusinessViolationException(
        ”Product not found”, 
        ExceptionLevel.ERROR, 
    UNIQUE_EXCEPTION);
}

SystemException

This class holds information about the system errors.This exception will be thrown when system level exception occurs (connection failure etc). Exception is derived from org.openinfinity.core.exception.AbstractCoreException.

private static final UNIQUE_EXCEPTION = ”se.exception.cf”;
if (connection.isInFailureState()) {
   SystemException se = new SystemException
   (
       ”Connection failure occurred”,
       ExceptionLevel.WARNING,
       UNIQUE_EXCEPTION
   ); 
   throw se;
}

or:

if (product.isNotFound()) { 
       ExceptionUtil.throwSystemException
       (
           ”Connection failure occurred”,
            ExceptionLevel.WARNING,
            UNIQUE_EXCEPTION
       );
}

ApplicationException

This class holds information about application error. This exception should be thrown when application (use cases) specific problems occurs. Exception is derived from org.openinfinity.core.exception.AbstractCoreException.

if (product.ifContainsIllegalInformation()) {    
   ExceptionUtil.throwApplicationException
   (
      ”Product contains illegal information”,   
      ExceptionLevel.INFORMATIVE, 
      UNIQUE_EXCEPTION
   );
}

org.openinfinity.core.util

The package includes the following functionality.

AspectUtil

Utility for handling aspect specific features.

Log logAnnotation = AspectUtil.getAnnotation(joinPoint, Log.class);

CollectionUtil

CollectionUtil enables element callbacks on java.util.Collection and java.util.Map interfaces unifying their API usage.

Collection<String> expected = new ArrayList<String>();
expected.add("foo");
expected.add("bar");

CollectionElementUtil.iterate(expected, new CollectionElementCallback<String>() {
	public void callback(String callbackObject) {
		System.out.println(callbackObject);	
	}			
});

Map<String, String> expected = new HashMap<String, String>();	
expected.put("foo","me1");
expected.put("bar", "me2");

CollectionElementUtil.iterate(expected, new MapElementCallback<String, String>() {
        public void callback(String key, String value) {
	         System.out.println(key + ":" + value);	
	}			
});

or adding traverse object

	Map<String, String> expected = new HashMap<String, String>();
	expected.put("foo","me1");
	expected.put("bar", "me2");
	Collection<String> traverseCollection = new ArrayList<String>();
	CollectionElementUtil.iterate(expected, traverseCollection, new TraverseObjectMapElementCallback<String, String, Collection<String>>() {
		public void callback(String key, String value, Collection<String> traverseCollection) {
			<!--validate entry-->	
			traverseCollection.add(value);
		}			
	});

ExceptionUtil

Exception utility class which offers basic methods for exception throwing and stack trace resolving.

String stackTrace = ExceptionUtil.getStackTraceString(throwable);

or:

ExceptionUtil.throwBusinessViolationException(cause);

IOUtil

Utility for handling stream, reader and writer objects.

IOUtil.copyStream(inputStream, outputStream);
IOUtil.getBytes(object);
IOUtil.closeReader(reader);
IOUtil.closeWriter(writer);
IOUtil.closeStream(stream);

StringUtil

Helper class for handling Strings.

@Override
Public String toString() {
    StringUtil.toString(this);
}

ValidationUtil

Helper class for handling Java Beans Validation (JSR 303) and core provided exceptions (business violation exception, application exception, and system exception), and their exception levels (informative, warning, error). Below examples show usage for validation util.

        @Autowired
        ValidationUtil validationUtil;	

        public void doBeanValidationChallenge() {
            Account account = new Account(SCRIPT_FUNCTION,SCRIPT_FUNCTION);
	    account.setAddress(SCRIPT_FUNCTION);
	    account.setCreationDate(new Date());
	    account.setTerminationDate(new Date());
	    validationUtil.throwBusinessViolationExceptionOnFailure(account);
        }

or

        @Autowired
        ValidationUtil validationUtil;	

        public void doBeanValidationChallenge() {
            Account account = new Account(SCRIPT_FUNCTION,SCRIPT_FUNCTION);
	    account.setAddress(SCRIPT_FUNCTION);
	    account.setCreationDate(new Date());
	    account.setTerminationDate(new Date());
	    validationUtil.throwApplicationExceptionOnFailure(account, ExceptionLevel.WARNING);
        }

or

        @Autowired
        ValidationUtil validationUtil;	

        public void doBeanValidationChallenge() {
            Account account = new Account(SCRIPT_FUNCTION,SCRIPT_FUNCTION);
	    account.setAddress(SCRIPT_FUNCTION);
	    account.setCreationDate(new Date());
	    account.setTerminationDate(new Date());
	    validationUtil.throwSystemExceptionOnFailure(account, ExceptionLevel.WARNING, "Scripting is not allowed");
        }

Configure Spring Bean context with following content:

<bean id="validator"
		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> 
 
 <context:component-scan base-package="org.openinfinity" />

JdbcPropertyPlaceholderConfigurer

Utility for key-value properties from JDBC datasource.

<import resource=“classpath:datasource-definitions.xml"/>

<bean class=” org.openinfinity.core.aspect.JdbcPropertyPlaceholderConfigurer">
    <constructor-arg ref=”dataSource” />
    <property name="locations">
        <list>
            <value>
               classpath:/META-INF/properties/logging.properties
            </value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>