All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avanza.astrix.context.AstrixContextImpl Maven / Gradle / Ivy

There is a newer version: 2.0.6
Show newest version
/*
 * Copyright 2014 Avanza Bank AB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.avanza.astrix.context;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.avanza.astrix.beans.config.AstrixConfig;
import com.avanza.astrix.beans.config.BeanConfiguration;
import com.avanza.astrix.beans.core.AstrixBeanKey;
import com.avanza.astrix.beans.core.AstrixSettings;
import com.avanza.astrix.beans.factory.BeanFactory;
import com.avanza.astrix.beans.factory.StandardFactoryBean;
import com.avanza.astrix.beans.publish.ApiProviderClass;
import com.avanza.astrix.beans.publish.BeanPublisher;
import com.avanza.astrix.beans.service.ServiceDefinition;
import com.avanza.astrix.beans.service.ServiceDefinitionSource;
import com.avanza.astrix.beans.service.StatefulAstrixBean;
import com.avanza.astrix.modules.Modules;
import com.avanza.astrix.serviceunit.AstrixApplicationDescriptor;
import com.avanza.astrix.serviceunit.ExportedServiceBeanDefinition;
import com.avanza.astrix.serviceunit.ServiceAdministrator;
import com.avanza.astrix.serviceunit.ServiceAdministratorVersioningConfigurer;
import com.avanza.astrix.serviceunit.ServiceExporter;
import com.avanza.astrix.versioning.core.ObjectSerializerDefinition;
/**
 * An AstrixContextImpl is the runtime-environment for the astrix-framework. It is used
 * both by consuming applications as well as server applications. AstrixContextImpl providers access
 * to different Astrix-plugins at runtime and is used as a factory to create Astrix-beans.
 * 
 * @author Elias Lindholm (elilin)
 */
final class AstrixContextImpl implements Astrix, AstrixApplicationContext {
	
	private final Logger log = LoggerFactory.getLogger(AstrixContextImpl.class);
	private final BeanFactory beanFactory;
	private final BeanPublisher beanPublisher;
	private final Modules modules;
	private final AstrixApplicationDescriptor applicationDescriptor;
	private final AstrixConfig config;
	
	public AstrixContextImpl(Modules modules, AstrixApplicationDescriptor applicationDescriptor) {
		this.modules = modules;
		this.applicationDescriptor = applicationDescriptor;
		this.config = modules.getInstance(AstrixConfig.class);
		this.beanPublisher = modules.getInstance(BeanPublisher.class);
		this.beanFactory = modules.getInstance(BeanFactory.class);
	}
	

	void register(ApiProviderClass apiProvider) {
		this.beanPublisher.publish(apiProvider);		
	}

	 void registerBeanFactory(StandardFactoryBean beanFactory) {
		this.beanFactory.registerFactory(beanFactory);
	}
	
	@Override
	public void destroy() {
		this.modules.destroy();
	}

	@Override
	public void close() throws Exception {
		destroy();
	}
	
	public BeanConfiguration getBeanConfiguration(AstrixBeanKey beanKey) {
		return this.config.getBeanConfiguration(beanKey);
	}
	
	@Override
	public  T getBean(Class beanType) {
		return getBean(beanType, null);
	}
	
	@Override
	public  T getBean(Class beanType, String qualifier) {
		return beanFactory.getBean(AstrixBeanKey.create(beanType, qualifier));
	}
	
	public  T getBean(AstrixBeanKey beanKey) {
		return beanFactory.getBean(beanKey);
	}
	

	@Override
	public  T waitForBean(Class beanType, long timeoutMillis) throws InterruptedException {
		return waitForBean(beanType, null, timeoutMillis);
	}
	
	@Override
	public  T waitForBean(Class beanType, String qualifier, long timeoutMillis) throws InterruptedException {
		AstrixBeanKey beanKey = AstrixBeanKey.create(beanType, qualifier);
		T bean = beanFactory.getBean(beanKey);
		for (AstrixBeanKey dependencyKey : beanFactory.getDependencies(beanKey)) {
			Object dependency = beanFactory.getBean(dependencyKey);
			waitForBeanToBeBound(dependency, timeoutMillis);
		}
		waitForBeanToBeBound(bean, timeoutMillis);
		return bean;
	}
	private void waitForBeanToBeBound(Object bean, long timeoutMillis) throws InterruptedException {
		if (bean instanceof StatefulAstrixBean) {
			StatefulAstrixBean.class.cast(bean).waitUntilBound(timeoutMillis);
		}
	}

	/**
	 * Returns an instance of an internal framework class.
	 * @param classType
	 * @return
	 */
	public final  T getInstance(final Class classType) {
		return this.modules.getInstance(classType);
	}
	
	@Override
	public void startServicePublisher() {
		if (!isServer()) {
			throw new IllegalStateException("Server part not configured. Set AstrixConfigurer.setApplicationDescriptor to load server part of framework");
		}
		ServiceExporter serviceExporter = getInstance(ServiceExporter.class);
		
		if (config.get(AstrixSettings.SERVICE_ADMINISTRATOR_EXPORTED).get()) {
			exportServiceAdministrator(serviceExporter);
		} else {
			log.info("Export of ServiceAdministrator service explicitly disabled. Won't export ServiceAdministrator service.");
		}
		
		serviceExporter.startPublishServices();
	}


	private void exportServiceAdministrator(ServiceExporter serviceExporter) {
		String applicationInstanceId = config.get(AstrixSettings.APPLICATION_INSTANCE_ID).get();
		serviceExporter.addServiceProvider(getInstance(ServiceAdministrator.class));
		ObjectSerializerDefinition serializer = ObjectSerializerDefinition.versionedService(1, ServiceAdministratorVersioningConfigurer.class);
		AstrixBeanKey serviceAdministratorQualifier = AstrixBeanKey.create(ServiceAdministrator.class, applicationInstanceId);
		ServiceDefinition serviceDefinition = new ServiceDefinition<>(ServiceDefinitionSource.create("FrameworkServices"),
				serviceAdministratorQualifier, 
				serializer, 
				true); // isDynamicQualified
		String serviceAdministratorComponent = config.get(AstrixSettings.SERVICE_ADMINISTRATOR_COMPONENT).get();
		ExportedServiceBeanDefinition serviceAdminDefintion = new ExportedServiceBeanDefinition<>(serviceAdministratorQualifier, 
				serviceDefinition, 
				true, // isVersioned  
				true, // alwaysActive
				serviceAdministratorComponent);
		serviceExporter.exportService(serviceAdminDefintion);
		log.info("Exported ServiceAdministrator service. component={} qualifier={}", serviceAdministratorComponent, serviceAdministratorQualifier);
	}


	private boolean isServer() {
		return this.applicationDescriptor != null;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy