/*
* 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.beans.publish;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avanza.astrix.beans.config.AstrixConfig;
import com.avanza.astrix.beans.core.AstrixBeanKey;
import com.avanza.astrix.beans.core.AstrixBeanSettings.BeanSetting;
import com.avanza.astrix.beans.factory.AstrixBeans;
import com.avanza.astrix.beans.factory.BeanFactory;
import com.avanza.astrix.beans.factory.DynamicFactoryBean;
import com.avanza.astrix.beans.factory.FactoryBean;
import com.avanza.astrix.beans.factory.StandardFactoryBean;
import com.avanza.astrix.beans.service.ServiceDiscoveryDefinition;
import com.avanza.astrix.beans.service.ServiceDiscoveryFactory;
import com.avanza.astrix.beans.service.ServiceDiscoveryMetaFactory;
import com.avanza.astrix.beans.service.ServiceFactory;
import com.avanza.astrix.beans.service.ServiceMetaFactory;
/**
*
* @author Elias Lindholm (elilin)
*
*/
public class BeanPublisherImpl implements BeanPublisher {
private static final Logger log = LoggerFactory.getLogger(BeanPublisherImpl.class);
private final ApiProviderPluginsImpl apiProviderPluginsImpl;
private final BeanFactory beanFactory;
private final ServiceMetaFactory serviceMetaFactory;
private final ServiceDiscoveryMetaFactory serviceDiscoveryMetaFactory;
private final AstrixConfig config;
public BeanPublisherImpl(ApiProviderPluginsImpl apiProviderPluginsImpl, BeanFactory beanFactory,
ServiceMetaFactory serviceMetaFactory, ServiceDiscoveryMetaFactory serviceDiscoveryMetaFactory,
AstrixConfig config) {
this.apiProviderPluginsImpl = apiProviderPluginsImpl;
this.beanFactory = beanFactory;
this.serviceMetaFactory = serviceMetaFactory;
this.serviceDiscoveryMetaFactory = serviceDiscoveryMetaFactory;
this.config = config;
}
@Override
public void publish(ApiProviderClass apiProvider) {
log.debug("Registering apiProvider={}", apiProvider.getName());
apiProviderPluginsImpl.getProviderPlugin(apiProvider).publishBeans(new BeanPublisherPlugin.BeanPublisher() {
@Override
public <T> void publishService(ServiceBeanDefinition<T> serviceBeanDefinition) {
ServiceDiscoveryFactory<?> serviceDiscoveryFactory = createServiceDiscoveryFactory(serviceBeanDefinition.getServiceDiscoveryDefinition());
ServiceFactory<T> serviceFactory = serviceMetaFactory.createServiceFactory(serviceBeanDefinition.getServiceDefinition(), serviceDiscoveryFactory);
if (serviceBeanDefinition.getServiceDefinition().isDynamicQualified()) {
log.debug("Registering dynamic service factory. beanType={} apiProvider={}", serviceBeanDefinition.getBeanKey().getBeanType(), apiProvider.getName());
registerBean(serviceFactory, serviceBeanDefinition.getDefaultBeanSettingsOverride());
} else {
log.debug("Registering factory for service-bean. beanKey={} apiProvider={}", serviceBeanDefinition.getBeanKey(), apiProvider.getName());
registerBean(new FactoryBeanAdapter<>(serviceFactory, serviceBeanDefinition.getBeanKey()), serviceBeanDefinition.getDefaultBeanSettingsOverride());
}
}
@Override
public <T> void publishLibrary(LibraryBeanDefinition<T> libraryBeanDefinition) {
log.debug("Registering factory for library-bean. beanKey={} apiProvider={}",
libraryBeanDefinition.getBeanKey(),
apiProvider.getName());
registerBean(libraryBeanDefinition.getFactory(), libraryBeanDefinition.getDefaultBeanSettingsOverride());
}
}, apiProvider);
}
private void registerBean(FactoryBean<?> factory, Map<BeanSetting<?>, Object> defaultBeanSettingsOverride) {
this.beanFactory.registerFactory(factory);
this.config.setDefaultBeanConfig(getBeanKey(factory), defaultBeanSettingsOverride);
}
@SuppressWarnings("unchecked")
private AstrixBeanKey<?> getBeanKey(FactoryBean<?> factory) {
if (factory instanceof StandardFactoryBean) {
return StandardFactoryBean.class.cast(factory).getBeanKey();
}
if (factory instanceof DynamicFactoryBean) {
return AstrixBeanKey.create(DynamicFactoryBean.class.cast(factory).getType(), "*");
}
throw new RuntimeException("Unknown factory type: " + factory.getClass().getName());
}
private <T> ServiceDiscoveryFactory<?> createServiceDiscoveryFactory(ServiceDiscoveryDefinition serviceDiscoveryDefinition) {
return serviceDiscoveryMetaFactory.createServiceDiscoveryFactory(serviceDiscoveryDefinition.getDiscoveryBeanKey().getBeanType(),
serviceDiscoveryDefinition.getServiceDiscoveryProperties());
}
private static class FactoryBeanAdapter<T> implements StandardFactoryBean<T> {
private ServiceFactory<T> serviceFactory;
private AstrixBeanKey<T> beanKey;
public FactoryBeanAdapter(ServiceFactory<T> serviceFactory,
AstrixBeanKey<T> beanKey) {
this.serviceFactory = serviceFactory;
this.beanKey = beanKey;
}
@Override
public T create(AstrixBeans beans) {
return serviceFactory.create(beanKey);
}
@Override
public AstrixBeanKey<T> getBeanKey() {
return beanKey;
}
}
}