Resource Monitoring

Provides monitoring of a resource and notifying resource observers when the resource is available. Resource can be a DataSource, directory, third party service or REST resource. Resource monitoring helps robust application startup in case when resource is not available and notifies registered observers when resource becomes available. This avoids application failures during application startup.

For example: When a service with afterPropertiesSet() method needs to initialize the service using information from database, if database is not available during application startup, it will fail the application startup. Resource monitoring approach helps to robust application startup, avoids failures and notifies the services which needs to be initialized when the database is available, so that service can be initialized using information from database.

Service which is implemented using resource monitoring approach, if the resource is not available and service is not initialized, until it is initialized properly, any calls made to the service methods leads to an exception through AOP.

Resource Observer Priority - Initialization Order

Since the initialization order of spring beans is unspecified, the order in which ResourceObservers register with a ResourceObserverRegistry is also unspecified, but the order in which they will be initialized (with onResourceAvailable) must be deterministic at least in situations where some ResourceObserver may invoke methods on others during the initialization - the latter ones must be initialized first. (This applies mostly to the product level, since the actual implementation on the product level determines the correct initialization order).

For this purpose the ResourceObserver interface extends the PriorityOrdered spring interface, and the implementation of the ResourceObserverRegistry makes sure the notifications are applied in the order of the priorities of the ResourceObservers (by storing them in a PriorityQueue and returning its entries in priority order).

For correct initialization you should stick to the following policy for assigning/implementing the priority of each observer:

  • ResourceObservers that do not invoke methods on other ResourceObservers during their initialization should override the ResourceObserver.getOrder() method returning PriorityOrdered.HIGHEST_PRECEDENCE.
  • ResourceObservers that do invoke methods on other ResourceObservers during their initialization phase should either override ResourceObserver.getOrder()by returning a higher value than all the ResourceObservers they interact with during that phase, or simply rely on the default implementation which returns the highest value possible (PriorityOrdered.LOWEST_PRECEDENCE)

Database Resource Monitoring

Provides resource monitoring implementation by monitoring the DataSource connection.  Notifies all the registered database resource observers, when database connection is available. If your service needs to be initialized using information from database, you can write resource observing servicing in the following way:

Define Resource Observer

Services which needs to be initialized during application startup using information from database should implement interface DbResourceObserver and override the method onDbResourceAvailable(), in this method you can provide the service initialization logic  using the information from database.

Register Resource Observer in Registry

Register the service which implemented the interface DbResourceObserver in the database resource monitor registry, so that it will be notified when the database is available. For example, you can implement Spring’s InitializingBean interface and override afterPropertiesSet() method, where you can register the service to database resource monitor registry.

You can see com.trimplement.wallet.server.payment.impl.PaymentSessionServiceImpl for sample configuration.

Example Resource Observer

public class SampleServiceImpl extends PaymentBaseServiceImpl implements DbResourceObserver, InitializingBean {
    private ResourceObserverRegistry<DbResourceObserver> dbResourceObserverRegistry;
    @Override
    public void afterPropertiesSet() throws Exception {
    dbResourceObserverRegistry.register(this);
    }
    @Override
    public void onDbResourceAvailable() throws WalletException {
     // Initialization from database
    }
    @Override
    public int getOrder() {
      return PriorityOrdered.HIGHEST_PRECEDENCE; // see the policy described above
    }
}

Spring configuration (non job beans)

<bean id="sampleService" class="SampleServiceImpl">
     <property name="dbResourceObserverRegistry" ref="common.monitoring.resource.db.ResourceObserverRegistry" />
</bean>

If you want to initialize anything related to Quartz jobs, then you have to register the service with a different resource observer registry, as the monitoring data source for Quartz jobs is different:

Spring configuration (job beans)

<bean id="sampleService" class="SampleServiceImpl">
     <property name="dbResourceObserverRegistry" ref="common.monitoring.resource.db.QuartzDbResourceObserverRegistry" />
</bean>

Quartz Scheduler configuration

DataSource monitoring is also applied to Quartz scheduler factory bean using com.trimplement.wallet.server.common.scheduling.CommonQuartzSchedulerFactoryBean. This implementation will register jobs and triggers when the Quartz’ jobs DataSource is available. So Quartz job schedulers must be registered using CommonQuartzSchedulerFactoryBean in the following way:

<bean id="payment.impl.PersistentJobScheduler" class="com.trimplement.wallet.server.common.scheduling.CommonQuartzSchedulerFactoryBean" depends-on="payment.impl.CreateQuartzTables" parent="common.scheduling.CommonQuartzSchedulerFactoryBean">
</bean>

You can see payment module job scheduler configuration for sample configuration.

Providing Different Resource Monitoring

If you want to develop monitoring for a different resource, for example files or third party service, and initialize the service when it is available, you can develop it with help of the following implementations.

Resource Monitor

Monitors the resource and notifies the resource observers when the resource is available. You can see com.trimplement.wallet.server.common.monitoring.resource.db.DbResourceMonitor

implementation and write your own monitor in a similar way. A resource monitor must be registered in resource monitor registry, so that it will start the monitoring of the resource when the application context is initialized.

Resource Observer

A resource observer is notified when the corresponding resource monitor reports the resource to be available. An observer must be registered with the corresponding resource observer registry. You can see com.trimplement.wallet.server.common.monitoring.resource.db.DbResourceObserver implementation and write your own resource observer in similar way.

See Spring configuration for how to configure beans in com.trimplement.wallet.server.common.monitoring.resource.xml file.