package rocks.inspectit.server.service; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import rocks.inspectit.shared.all.communication.data.cmr.ApplicationData; import rocks.inspectit.shared.all.communication.data.cmr.BusinessTransactionData; import rocks.inspectit.shared.all.spring.logger.Log; import rocks.inspectit.shared.all.util.Pair; import rocks.inspectit.shared.cs.ci.business.impl.ApplicationDefinition; import rocks.inspectit.shared.cs.ci.business.impl.BusinessTransactionDefinition; import rocks.inspectit.shared.cs.cmr.service.IBusinessContextManagementService; import rocks.inspectit.shared.cs.cmr.service.IBusinessContextRegistryService; /** * Cached access and management service to the business context definition. * * @author Alexander Wert * */ @Service public class BusinessContextManagementService implements IBusinessContextManagementService, IBusinessContextRegistryService, InitializingBean { /** The logger of this class. */ @Log Logger log; /** * Map of {@link ApplicationData} instances representing identified applications. */ private final ConcurrentHashMap<Integer, ApplicationData> applications = new ConcurrentHashMap<Integer, ApplicationData>(); /** * Map of {@link BusinessTransactionData} instances representing identified business * transactions. */ private final ConcurrentHashMap<Pair<Integer, Integer>, BusinessTransactionData> businessTransactions = new ConcurrentHashMap<Pair<Integer, Integer>, BusinessTransactionData>(); /** * {@inheritDoc} */ @Override public Collection<ApplicationData> getApplications() { return new ArrayList<>(applications.values()); } /** * {@inheritDoc} */ @Override public Collection<BusinessTransactionData> getBusinessTransactions() { return new ArrayList<>(businessTransactions.values()); } /** * {@inheritDoc} */ @Override public Collection<BusinessTransactionData> getBusinessTransactions(int applicationId) { Set<BusinessTransactionData> resultSet = new HashSet<>(); for (BusinessTransactionData businessTx : businessTransactions.values()) { if (businessTx.getApplication().getId() == applicationId) { resultSet.add(businessTx); } } return resultSet; } /** * {@inheritDoc} */ @Override public ApplicationData registerApplication(ApplicationDefinition applicationDefinition) { int applicationId = deriveInstanceId(applicationDefinition.getApplicationName(), applicationDefinition.getId()); ApplicationData application = getApplicationForId(applicationId); if (null == application) { application = new ApplicationData(applicationId, applicationDefinition.getId(), applicationDefinition.getApplicationName()); ApplicationData existingApplication = applications.putIfAbsent(applicationId, application); if (null != existingApplication) { application = existingApplication; } } return application; } /** * {@inheritDoc} */ @Override public BusinessTransactionData registerBusinessTransaction(ApplicationData application, BusinessTransactionDefinition businessTransactionDefinition, String businessTransactionName) { int businessTxId = deriveInstanceId(businessTransactionName, businessTransactionDefinition.getId()); BusinessTransactionData businessTransaction = getBusinessTransactionForId(application.getId(), businessTxId); if (null == businessTransaction) { businessTransaction = new BusinessTransactionData(businessTxId, businessTransactionDefinition.getId(), application, businessTransactionName); Pair<Integer, Integer> key = new Pair<Integer, Integer>(application.getId(), businessTransaction.getId()); BusinessTransactionData existingBusinessTx = businessTransactions.putIfAbsent(key, businessTransaction); if (null != existingBusinessTx) { businessTransaction = existingBusinessTx; } } return businessTransaction; } /** * {@inheritDoc} */ @Override public ApplicationData getApplicationForId(int id) { return applications.get(id); } /** * {@inheritDoc} */ @Override public BusinessTransactionData getBusinessTransactionForId(int appId, int businessTxId) { return businessTransactions.get(new Pair<Integer, Integer>(appId, businessTxId)); } /** * Calculates an instance id from a pair of a name and a definition id. * * @param name * The name of the business transaction or application * @param id * The id of the business transaction definition or application definition. * @return The derived instance id for the application or business transaction. */ private int deriveInstanceId(String name, int id) { if (id == 0) { return 0; } else { final int prime = 31; int result = 1; result = (prime * result) + name.hashCode(); result = (prime * result) + id; return result; } } /** * {@inheritDoc} */ @Override public void afterPropertiesSet() throws Exception { if (log.isInfoEnabled()) { log.info("|-Business Context Management Service active..."); } } }