-
Notifications
You must be signed in to change notification settings - Fork 2
Open Infinity Core Documentation V2.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. |
The package includes the following functionality.
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() {...}
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() {...}
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() {...}
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() {...}
Field validator for validating XSS attacks.
@NotScript
private String someField;
@NotScript(allowedInputPattern=Person.SSN_XSS)
private String someField;
The package includes the following functionality.
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" />
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” />
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>
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" />
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" />
The package includes the following functionality for parallel processing and CRUD integrations.
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" />
The package includes the following functionality.
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>
The package includes the following functionality.
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);
}
}
}
The package includes the following functionality.
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;
}
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;
}
The package includes the following functionality.
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);
}
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
);
}
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
);
}
The package includes the following functionality.
Utility for handling aspect specific features.
Log logAnnotation = AspectUtil.getAnnotation(joinPoint, Log.class);
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);
}
});
Exception utility class which offers basic methods for exception throwing and stack trace resolving.
String stackTrace = ExceptionUtil.getStackTraceString(throwable);
or:
ExceptionUtil.throwBusinessViolationException(cause);
Utility for handling stream, reader and writer objects.
IOUtil.copyStream(inputStream, outputStream);
IOUtil.getBytes(object);
IOUtil.closeReader(reader);
IOUtil.closeWriter(writer);
IOUtil.closeStream(stream);
Helper class for handling Strings.
@Override
Public String toString() {
StringUtil.toString(this);
}
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" />
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>