/*
* Copyright 2008-2009 MOPAS(Ministry of Public Administration and Security).
*
* 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 egovframework.rte.itl.webservice;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import egovframework.rte.itl.integration.EgovIntegrationContext;
import egovframework.rte.itl.integration.EgovIntegrationNoSuchServiceException;
import egovframework.rte.itl.integration.EgovIntegrationService;
import egovframework.rte.itl.integration.EgovIntegrationServiceProvider;
import egovframework.rte.itl.integration.metadata.IntegrationDefinition;
import egovframework.rte.itl.integration.metadata.dao.IntegrationDefinitionDao;
import egovframework.rte.itl.integration.monitor.EgovIntegrationServiceMonitor;
import egovframework.rte.itl.integration.type.CircularInheritanceException;
import egovframework.rte.itl.integration.type.NoSuchTypeException;
import egovframework.rte.itl.integration.type.RecordType;
import egovframework.rte.itl.integration.type.TypeLoader;
import egovframework.rte.itl.webservice.data.WebServiceClientDefinition;
import egovframework.rte.itl.webservice.data.WebServiceServerDefinition;
import egovframework.rte.itl.webservice.data.dao.WebServiceClientDefinitionDao;
import egovframework.rte.itl.webservice.data.dao.WebServiceServerDefinitionDao;
import egovframework.rte.itl.webservice.service.EgovWebServiceClassLoader;
import egovframework.rte.itl.webservice.service.EgovWebServiceClient;
import egovframework.rte.itl.webservice.service.MessageConverter;
import egovframework.rte.itl.webservice.service.ServiceBridge;
import egovframework.rte.itl.webservice.service.ServiceEndpointInfo;
import egovframework.rte.itl.webservice.service.ServiceEndpointInterfaceInfo;
import egovframework.rte.itl.webservice.service.impl.EgovWebServiceClientImpl;
import egovframework.rte.itl.webservice.service.impl.MessageConverterImpl;
import egovframework.rte.itl.webservice.service.impl.ServiceBridgeImpl;
import egovframework.rte.itl.webservice.service.impl.ServiceEndpointInfoImpl;
import egovframework.rte.itl.webservice.service.impl.ServiceEndpointInterfaceInfoImpl;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;
/**
* 전자정부 웹서비스 Context 구현 클래스
* <p>
* <b>NOTE:</b> 전자정부 웹서비스 Context Class이다. </p>
*
* @author 실행환경 개발팀 심상호
* @since 2009.06.01
* @version 1.0
* @see <pre>
* == 개정이력(Modification Information) ==
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.06.01 심상호 최초 생성
*
* </pre>
*/
public class EgovWebServiceContext implements EgovIntegrationContext,
ApplicationContextAware {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovWebServiceContext.class);
// //////////////////////////////////////////////////////////////////////////
// set method를 이용하여 설정되는 attributes
//
/** 기관 Id */
protected String organizationId;
/** 시스템 Id */
protected String systemId;
/** Default Timeout (millisecond) */
protected long defaultTimeout;
/** 연계 정의 DAO */
protected IntegrationDefinitionDao integrationDefinitionDao;
/** 웹서비스 클라이언트 정의 DAO */
protected WebServiceClientDefinitionDao webServiceClientDefinitionDao;
/** 웹서비스 서버 정의 DAO */
protected WebServiceServerDefinitionDao webServiceServerDefinitionDao;
/** Type Loader */
protected TypeLoader typeLoader;
/** ClassLoader */
protected EgovWebServiceClassLoader classLoader;
//
// //////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
// ApplicationContextAware interface에 의해 자동으로 설정되는
// attribute
//
/** ApplicationContext */
protected ApplicationContext applicationContext;
//
// //////////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
// init method에서 생성되는 attributes
//
/** MessageConverter */
protected MessageConverter messageConverter;
/** ServiceMap */
protected Map<String, EgovWebService> serviceMap;
/** ServerList */
protected List<ServerInfo> serverList;
/** Bus */
protected Bus bus;
//
// //////////////////////////////////////////////////////////////////////////
/**
* Default Constructor
*/
public EgovWebServiceContext() {
super();
}
/**
* organizationId
*
* @param organizationId
* the organizationId to set
*/
public void setOrganizationId(String organizationId) {
this.organizationId = organizationId;
}
/**
* systemId
*
* @param systemId
* the systemId to set
*/
public void setSystemId(String systemId) {
this.systemId = systemId;
}
/**
* defaultTimeout
*
* @return the defaultTimeout
*/
public long getDefaultTimeout() {
return defaultTimeout;
}
/**
* defaultTimeout
*
* @param defaultTimeout
* the defaultTimeout to set
*/
public void setDefaultTimeout(long defaultTimeout) {
this.defaultTimeout = defaultTimeout;
}
/**
* integrationDefinitionDao
*
* @param integrationDefinitionDao
* the integrationDefinitionDao to set
*/
public void setIntegrationDefinitionDao(
IntegrationDefinitionDao integrationDefinitionDao) {
this.integrationDefinitionDao = integrationDefinitionDao;
}
/**
* webServiceClientDefinitionDao
*
* @param webServiceClientDefinitionDao
* the webServiceClientDefinitionDao to set
*/
public void setWebServiceClientDefinitionDao(
WebServiceClientDefinitionDao webServiceClientDefinitionDao) {
this.webServiceClientDefinitionDao = webServiceClientDefinitionDao;
}
/**
* webServiceServerDefinitionDao
*
* @param webServiceServerDefinitionDao
* the webServiceServerDefinitionDao to set
*/
public void setWebServiceServerDefinitionDao(
WebServiceServerDefinitionDao webServiceServerDefinitionDao) {
this.webServiceServerDefinitionDao = webServiceServerDefinitionDao;
}
/**
* typeLoader
*
* @param typeLoader
* the typeLoader to set
*/
public void setTypeLoader(TypeLoader typeLoader) {
this.typeLoader = typeLoader;
}
/**
* classLoader
*
* @param classLoader
* the classLoader to set
*/
public void setClassLoader(EgovWebServiceClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* applicationContext
*
* @param applicationContext
* the applicationContext to set
*/
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* EgovWebServiceContext를 초기화한다.
*
* @throws IllegalArgumentException
* 필요한 attribute가 설정되어 있지 않을 경우
*/
public void init() throws IllegalArgumentException {
LOGGER.debug("Initilaize EgovWebServiceContext");
if (StringUtils.hasText(organizationId) == false) {
LOGGER.error("Argument 'organizationId' is null or has no text "
+ "(organizationId = "
+ (organizationId == null ? "\"" : "") + organizationId
+ (organizationId == null ? "\"" : "") + ")");
throw new IllegalArgumentException();
} else if (StringUtils.hasText(systemId) == false) {
LOGGER.error("Argument 'systemId' is null or has no text "
+ "(systemId = " + (systemId == null ? "\"" : "")
+ systemId + (systemId == null ? "\"" : "") + ")");
throw new IllegalArgumentException();
} else if (integrationDefinitionDao == null) {
LOGGER.error("Argument 'integrationDefinitionDao' is null");
throw new IllegalArgumentException();
} else if (webServiceClientDefinitionDao == null) {
LOGGER.error("Argument 'webServiceClientDefinitionDao' is null");
throw new IllegalArgumentException();
} else if (webServiceServerDefinitionDao == null) {
LOGGER.error("Argument 'webServiceServerDefinitionDao' is null");
throw new IllegalArgumentException();
} else if (typeLoader == null) {
LOGGER.error("Argument 'typeLoader' is null");
throw new IllegalArgumentException();
} else if (classLoader == null) {
LOGGER.error("Argument 'classLoader' is null");
throw new IllegalArgumentException();
}
LOGGER.debug("Create MessageConverter");
messageConverter = new MessageConverterImpl(classLoader);
initServerInfo();
initClient();
}
/**
* 웹서비스 서버 정보를 생성한다.
*/
protected void initServerInfo() {
LOGGER.debug("Initialzise Server Info");
List<WebServiceServerDefinition> webServiceServerDefinitions = new ArrayList<WebServiceServerDefinition>();
List<IntegrationDefinition> integrationDefinitions = integrationDefinitionDao
.getIntegrationDefinitionOfProvider(organizationId, systemId);
LOGGER.debug("Scan IntegrationDefinitions");
for (IntegrationDefinition integrationDefinition : integrationDefinitions) {
LOGGER.debug("Create Service Info of IntegrationDefinition({})",
integrationDefinition);
if (integrationDefinition == null) {
LOGGER.error("IntegrationDefinition is null");
continue;
} else if (integrationDefinition.isValid() == false) {
LOGGER.error("IntegrationDefinition is invalid");
continue;
} else if (integrationDefinition.isUsing() == false) {
LOGGER.info("IntegrationDefinition({}) is not usable",
integrationDefinition);
continue;
} else if (integrationDefinition.getProvider().isUsing() == false) {
LOGGER.info(
"IntegrationDefinition({})'s provider service is not usable",
integrationDefinition);
continue;
}
WebServiceServerDefinition webServiceServerDefinition = webServiceServerDefinitionDao
.getWebServiceServerDefinition(integrationDefinition
.getProvider());
if (webServiceServerDefinition == null) {
LOGGER.error(
"WebServiceServerDefinition of IntegrationDefinition({}) does not exist.",
integrationDefinition);
continue;
} else if (webServiceServerDefinition.isValid() == false) {
LOGGER.error(
"WebServiceServerDefinition of IntegrationDefinition({}) is invalid",
integrationDefinition);
continue;
}
if (webServiceServerDefinitions
.contains(webServiceServerDefinition) == false) {
webServiceServerDefinitions.add(webServiceServerDefinition);
}
}
// Method Refactoring
createWebServiceServerModule(webServiceServerDefinitions);
}
private void createWebServiceServerModule(
List<WebServiceServerDefinition> webServiceServerDefinitions) {
LOGGER.debug("Create WebService Server Module");
serverList = new ArrayList<ServerInfo>();
for (WebServiceServerDefinition webServiceServerDefinition : webServiceServerDefinitions) {
LOGGER.debug("webServiceServerDefinition = {}",
webServiceServerDefinition);
RecordType requestType = null;
try {
// CHECKSTYLE:OFF
requestType = (RecordType) typeLoader
.getType(webServiceServerDefinition
.getServiceDefinition()
.getRequestMessageTypeId());
// CHECKSTYLE:ON
} catch (NoSuchTypeException e) {
LOGGER.error(
"RequestMessageType RecordType(id = \"{}\")'s definition does not exist. {}",
webServiceServerDefinition.getServiceDefinition().getRequestMessageTypeId(), e);
continue;
} catch (CircularInheritanceException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"RequestMessageType RecordType(id = \"{}\") has circular inheritance. {}",
webServiceServerDefinition.getServiceDefinition()
.getRequestMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
}
LOGGER.debug("RequestMesageType = {}", requestType);
RecordType responseType = null;
try {
// CHECKSTYLE:OFF
responseType = (RecordType) typeLoader
.getType(webServiceServerDefinition
.getServiceDefinition()
.getResponseMessageTypeId());
// CHECKSTYLE:ON
} catch (NoSuchTypeException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"ResponseMessageType RecordType(id = \"{}\")'s definition does not exist. {}",
webServiceServerDefinition.getServiceDefinition()
.getResponseMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
} catch (CircularInheritanceException e) {
LOGGER.error(
"ResponseMessageType RecordType(id = \"{}\") has circular inheritance. {}",
webServiceServerDefinition.getServiceDefinition().getResponseMessageTypeId(), e);
continue;
}
LOGGER.debug("ResponseMessageType = {}", responseType);
ServiceEndpointInfo serviceEndpointInfo = null;
try {
serviceEndpointInfo = new ServiceEndpointInfoImpl(
webServiceServerDefinition, requestType, responseType);
} catch (IllegalArgumentException e) {
LOGGER.error("Cannot create ServiceEndpointInfoImpl {}", e);
continue;
}
LOGGER.debug("ServiceEndpointInfo = {}", serviceEndpointInfo);
Class<?> serviceImplClass = null;
try {
serviceImplClass = classLoader.loadClass(serviceEndpointInfo);
} catch (ClassNotFoundException e) {
LOGGER.error("Cannot load ServerEndpoint Class {}", e);
continue;
}
LOGGER.debug("ServiceEndpoint Class = {}", serviceImplClass);
Object serviceImpl = null;
try {
serviceImpl = serviceImplClass.newInstance();
} catch (IllegalAccessException e) {
LOGGER.error("Cannot instantiate ServiceEndpoint {}", e);
continue;
} catch (InstantiationException e) {
LOGGER.error("Cannot instantiate ServiceEndpoint {}", e);
continue;
}
LOGGER.debug("ServiceEndpoint instance = {}", serviceImpl);
EgovIntegrationServiceProvider provider = null;
try {
// CHECKSTYLE:OFF
provider = (EgovIntegrationServiceProvider) applicationContext
.getBean(webServiceServerDefinition
.getServiceDefinition()
.getServiceProviderBeanId());
// CHECKSTYLE:ON
} catch (BeansException e) {
LOGGER.error("Cannot get providerBean(id = \"{}\") {}",
webServiceServerDefinition.getServiceDefinition().getServiceProviderBeanId(), e);
continue;
}
LOGGER.debug("EgovIntegrationServiceProvider = {}", provider);
ServiceBridge serviceBridge = null;
try {
serviceBridge = new ServiceBridgeImpl(provider,
serviceEndpointInfo, messageConverter);
} catch (IllegalArgumentException e) {
LOGGER.error("Cannot create ServiceBridge {}", e);
continue;
}
LOGGER.debug("ServiceBridge = {}", serviceBridge);
Field fieldServiceBridge = null;
String fieldName = classLoader.getFieldNameOfServiceBridge();
try {
fieldServiceBridge = serviceImplClass.getField(fieldName);
} catch (NoSuchFieldException e) {
LOGGER.error(
"ServiceEndpoint does not have the field(name = \"{}\") {}",
fieldName, e);
continue;
}
try {
fieldServiceBridge.set(serviceImpl, serviceBridge);
} catch (IllegalAccessException e) {
LOGGER.error("Cannot set ServiceBridge to provider {}", e);
continue;
} catch (IllegalArgumentException e) {
LOGGER.error("Cannot set ServiceBridge to provider {}", e);
continue;
} catch (SecurityException e) {
LOGGER.error("Cannot set ServiceBridge to provider {}", e);
continue;
}
LOGGER.debug("Add new ServiceInfo");
serverList.add(new ServerInfo(webServiceServerDefinition.getAddress(), serviceImpl));
}
LOGGER.debug("Finished Initializing Server Info");
}
protected void initClient() {
LOGGER.debug("Initialize Client Info");
serviceMap = new HashMap<String, EgovWebService>();
// CHECKSTYLE:OFF
List<IntegrationDefinition> integrationDefinitions = integrationDefinitionDao
.getIntegrationDefinitionOfConsumer(organizationId, systemId);
// CHECKSTYLE:ON
for (IntegrationDefinition integrationDefinition : integrationDefinitions) {
LOGGER.debug("Create Client Info of IntegrationDefinition({})",
integrationDefinition);
if (integrationDefinition == null) {
LOGGER.error("IntegrationDefinition is null");
continue;
} else if (integrationDefinition.isValid() == false) {
LOGGER.error("IntegrationDefinition is invalid");
continue;
} else if (integrationDefinition.isUsing() == false) {
LOGGER.info("IntegrationDefinition({}) is not usagble",
integrationDefinition);
continue;
} else if (integrationDefinition.getProvider().isUsing() == false) {
LOGGER.info(
"IntegrationDefinition({})'s provider service is not usable",
integrationDefinition);
continue;
}
// CHECKSTYLE:OFF
WebServiceClientDefinition webServiceClientDefinition = webServiceClientDefinitionDao
.getWebServiceClientDefinition(integrationDefinition.getProvider());
// CHECKSTYLE:ON
if (webServiceClientDefinition == null) {
LOGGER.error(
"WebServiceClientDefinition of IntegrationDefinition({}) does not exist.",
integrationDefinition);
continue;
} else if (webServiceClientDefinition.isValid() == false) {
LOGGER.error(
"WebServiceClientDefinition of IntegrationDefinition({}) is invalid",
integrationDefinition);
continue;
}
LOGGER.debug("WebServiceClientDefinition = "
+ webServiceClientDefinition);
RecordType requestType = null;
try {
// CHECKSTYLE:OFF
requestType = (RecordType) typeLoader
.getType(webServiceClientDefinition
.getServiceDefinition()
.getRequestMessageTypeId());
// CHECKSTYLE:ON
} catch (NoSuchTypeException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"RequestMessageType RecordType(id = \"{}\")'s definition does not exist. {}",
webServiceClientDefinition.getServiceDefinition()
.getRequestMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
} catch (CircularInheritanceException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"RequestMessageType RecordType(id = \"{}\") has circular inheritance. {}",
webServiceClientDefinition.getServiceDefinition()
.getRequestMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
}
LOGGER.debug("RequestMesageType = {}", requestType);
RecordType responseType = null;
try {
// CHECKSTYLE:OFF
responseType = (RecordType) typeLoader
.getType(webServiceClientDefinition
.getServiceDefinition()
.getResponseMessageTypeId());
// CHECKSTYLE:ON
} catch (NoSuchTypeException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"ResponseMessageType RecordType(id = \"{}\")'s definition does not exist. {}",
webServiceClientDefinition.getServiceDefinition()
.getResponseMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
} catch (CircularInheritanceException e) {
// CHECKSTYLE:OFF
LOGGER.error(
"ResponseMessageType RecordType(id = \"{}\") has circular inheritance. {}",
webServiceClientDefinition.getServiceDefinition()
.getResponseMessageTypeId(), e);
// CHECKSTYLE:ON
continue;
}
LOGGER.debug("ResponseMessageType = {}", responseType);
// ServiceEndpointInterface 정보를 생성한다.
ServiceEndpointInterfaceInfo serviceEndpointInterfaceInfo = null;
try {
serviceEndpointInterfaceInfo = new ServiceEndpointInterfaceInfoImpl(
webServiceClientDefinition, requestType, responseType);
} catch (IllegalArgumentException e) {
LOGGER.error("Cannot create ServiceEndpointInterfaceInfo {}", e);
continue;
}
LOGGER.debug("ServiceEndpointInterfaceInfo = {}",
serviceEndpointInterfaceInfo);
EgovWebServiceClient client = null;
try {
client = new EgovWebServiceClientImpl(classLoader,
serviceEndpointInterfaceInfo, messageConverter);
} catch (ClassNotFoundException e) {
LOGGER.error("Cannot create EgovWebServiceClient {}", e);
continue;
} catch (MalformedURLException e) {
LOGGER.error("Cannot create EgovWebServiceClient {}", e);
continue;
} catch (NoSuchMethodException e) {
LOGGER.error("Cannot create EgovWebServiceClient {}", e);
continue;
} catch (SecurityException e) {
LOGGER.error("Cannot create EgovWebServiceClient {}", e);
continue;
}
LOGGER.debug("EgovWebServiceClient = {}", client);
EgovWebService service = null;
try {
service = new EgovWebService(integrationDefinition.getId(),
defaultTimeout, integrationDefinition, client);
} catch (IllegalArgumentException e) {
LOGGER.error("Cannot create EgovWebService {}", e);
continue;
}
LOGGER.debug("EgovWebService = {}", service);
LOGGER.debug("Add Client Info");
serviceMap.put(integrationDefinition.getId(), service);
}
LOGGER.debug("Finish initializing Client Info");
}
public void publishServer(Bus bus) {
LOGGER.debug("Publish Server");
this.bus = bus;
BusFactory.setDefaultBus(bus);
for (ServerInfo serverInfo : serverList) {
LOGGER.debug("Publish Server (address = \"{}\")",
serverInfo.address);
try {
Endpoint.publish(serverInfo.address, serverInfo.serviceImpl);
} catch (Throwable e) {
LOGGER.error("Fail in publishing Server (address = \"{}\") {}",
serverInfo.address, e);
}
}
LOGGER.debug("Finish publish Server");
}
public void attachMonitor(EgovIntegrationServiceMonitor monitor) {
}
public void detachMonitor(EgovIntegrationServiceMonitor monitor) {
}
public EgovIntegrationService getService(String id) {
if (serviceMap.containsKey(id) == false) {
throw new EgovIntegrationNoSuchServiceException();
}
return serviceMap.get(id);
}
protected static class ServerInfo {
private String address;
private Object serviceImpl;
public ServerInfo(String address, Object serviceImpl) {
super();
this.address = address;
this.serviceImpl = serviceImpl;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Object getServiceImpl() {
return serviceImpl;
}
public void setServiceImpl(Object serviceImpl) {
this.serviceImpl = serviceImpl;
}
}
}