/* * Lokomo OneCMDB - An Open Source Software for Configuration * Management of Datacenter Resources * * Copyright (C) 2006 Lokomo Systems AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via * paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33 * Danderyd, Sweden. * */ package org.onecmdb.ui.gwt.desktop.server.service.model.mdr; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Properties; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.codehaus.xfire.service.ServiceFactory; import org.dom4j.DocumentException; import org.onecmdb.core.utils.IBeanProvider; import org.onecmdb.core.utils.ParentBeanProvider; import org.onecmdb.core.utils.bean.CiBean; import org.onecmdb.core.utils.transform.DataSet; import org.onecmdb.core.utils.transform.IDataSource; import org.onecmdb.core.utils.transform.IInstance; import org.onecmdb.core.utils.transform.SimpleTransformProvider; import org.onecmdb.core.utils.transform.TransformBeanProvider; import org.onecmdb.core.utils.transform.csv.CSVDataSource; import org.onecmdb.core.utils.transform.csv.CSVInstanceSelector; import org.onecmdb.core.utils.transform.csv.CSVRow; import org.onecmdb.core.utils.transform.excel.ExcelDataSource; import org.onecmdb.core.utils.transform.jdbc.JDBCDataSourceWrapper; import org.onecmdb.core.utils.transform.jdbc.JDBCInstanceSelector; import org.onecmdb.core.utils.transform.jdbc.JDBCRow; import org.onecmdb.core.utils.wsdl.IOneCMDBWebService; import org.onecmdb.core.utils.wsdl.WSDLBeanProvider; import org.onecmdb.ui.gwt.desktop.client.service.CMDBRPCException; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentData; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFile; import org.onecmdb.ui.gwt.desktop.client.service.content.ContentFolder; import org.onecmdb.ui.gwt.desktop.client.service.content.IContentService; import org.onecmdb.ui.gwt.desktop.client.service.model.CIModel; import org.onecmdb.ui.gwt.desktop.client.service.model.grid.AttributeColumnConfig; import org.onecmdb.ui.gwt.desktop.client.service.model.grid.GridModelConfig; import org.onecmdb.ui.gwt.desktop.client.service.model.mdr.TransformConfig; import org.onecmdb.ui.gwt.desktop.client.service.model.mdr.transform.DataSetModel; import org.onecmdb.ui.gwt.desktop.client.service.model.mdr.transform.TransformModel; import org.onecmdb.ui.gwt.desktop.server.service.CMDBRPCHandler; import org.onecmdb.ui.gwt.desktop.server.service.ServiceLocator; import org.onecmdb.ui.gwt.desktop.server.service.change.ICIMDR; import org.onecmdb.ui.gwt.desktop.server.service.content.ContentParserFactory; import org.onecmdb.ui.gwt.desktop.server.service.content.ContentServiceImpl; import org.onecmdb.ui.gwt.desktop.server.service.model.CMDBWebServiceFactory; import org.onecmdb.utils.wsdl.OneCMDBTransform; import com.extjs.gxt.ui.client.data.BaseModel; import com.extjs.gxt.ui.client.data.BasePagingLoadConfig; import com.extjs.gxt.ui.client.data.BasePagingLoadResult; public class MDRSetupService { private Log log = LogFactory.getLog(this.getClass()); public TransformConfig loadTransformConfig(String token, ContentData ciMDRData, CIModel mdr, CIModel mdrCfg) throws CMDBRPCException, DocumentException { String mdrName = mdr.getValue("name").getValue(); String mdrConfigName = mdrCfg.getValue("name").getValue(); TransformConfig config = new TransformConfig(); config.setMDRName(mdrName); config.setMDRConfigName(mdrConfigName); ContentFolder sourceMdrFolder = new ContentFolder("MDR_Template/source-templates"); IContentService svc = (IContentService) ServiceLocator.getService(IContentService.class); if (svc == null) { svc = new ContentServiceImpl(); } ICIMDR ciMDR = (ICIMDR) ContentParserFactory.get().getCachedAdaptor(ciMDRData, ICIMDR.class); // Get datasources. List<? extends ContentData> sourceTemplates = svc.list(token, sourceMdrFolder); for (ContentData data : sourceTemplates) { updateDataSource(svc, token, data, config); } // Set defaul to excel... config.setDataSourceType("excel"); ContentFile defTransform = new ContentFile("MDR_Template/transform-template.xml"); updateDataTransform(token, svc, ciMDR, defTransform, config); // Try to find datasource. ContentFile configurable = new ContentFile("MDR/" + mdrName + "/" + "conf/configurable"); svc.stat(configurable); config.setConfigurabe(configurable.isExists()); ContentFile dataSource = new ContentFile("MDR/" + mdrName + "/" + "conf/" + mdrConfigName +"/source.xml"); updateDataSource(svc, token, dataSource, config); ContentFile dataTransform = new ContentFile("MDR/" + mdrName + "/" + "conf/" + mdrConfigName +"/transform.xml"); updateDataTransform(token, svc, ciMDR, dataTransform, config); if (config.getTransformModel().getName() == null) { config.getTransformModel().setName(mdrConfigName); } return(config); } private void updateDataTransform(String token, IContentService svc, ICIMDR mdr, ContentData data, TransformConfig config) throws DocumentException { svc.stat(data); if (!data.isExists() || data.isDirectory()) { return; } String content = svc.get(token, data, "UTF-8"); TransformModel model = TransformConverter.fromXML(token, mdr, content); config.setTransformModel(model); } private void updateDataSource(IContentService svc, String token, ContentData data, TransformConfig config) { svc.stat(data); if (!data.isExists() || data.isDirectory()) { return; } String content = svc.get(token, data); Properties p = new Properties(); try { ByteArrayInputStream array = new ByteArrayInputStream(content.getBytes()); p.loadFromXML(array); } catch (Exception e) { log.error("Can't read '" + data.getPath() + "'", e); // Ignore this. return; } Enumeration<?> keys = p.propertyNames(); BaseModel dataSource = new BaseModel(); String type = (String) p.get("type"); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = p.getProperty(key); if (key.startsWith(type + ".")) { key = key.substring((type + ".").length()); } dataSource.set(key, value); } config.setDataSourceType(type); config.setDataSource(type, dataSource); } public boolean storeTransformConfig(String token, ContentData ciMDRData, CIModel mdr, CIModel mdrCfg, TransformConfig cfg) throws Exception { IContentService svc = (IContentService) ServiceLocator.getService(IContentService.class); if (svc == null) { svc = new ContentServiceImpl(); } String mdrPath = "MDR/" + mdr.getValueAsString("name") + "/conf/" + mdrCfg.getValueAsString("name"); ContentFolder mdrFolder = new ContentFolder(mdrPath); svc.stat(mdrFolder); if (!mdrFolder.isExists()) { svc.mkdir(token, mdrFolder); } // Store data source. Properties p = getDataSourceProperties(cfg, false); String sPath = mdrPath + "/source.xml"; ByteArrayOutputStream out = new ByteArrayOutputStream(); p.storeToXML(out, "", "UTF-8"); svc.put(token, new ContentFile(sPath), out.toString("UTF-8")); // Store transform data. TransformModel transform = cfg.getTransformModel(); String tPath = mdrPath + "/transform.xml"; ContentFile f = new ContentFile(tPath); String transformXML = TransformConverter.toXML(cfg.getDataSourceType(), transform); svc.put(token, f, "UTF-8", transformXML); return(true); } public GridModelConfig loadDataSourceColumns(String token, TransformConfig config) throws IOException { GridModelConfig gridCfg = new GridModelConfig(); gridCfg.setColumnConfig(getDataSourceColumns(config)); return(gridCfg); } public BasePagingLoadResult<BaseModel> loadDataSourceData(String token, BasePagingLoadConfig config) throws IOException { TransformConfig tCfg = config.get("transformConfig"); List<IInstance> rows = loadData(tCfg); int total = rows.size(); List<BaseModel> data = new ArrayList<BaseModel>(); int maxIndex = config.getOffset() + config.getLimit(); if (maxIndex > total) { maxIndex = total; } for (int i = config.getOffset(); i < maxIndex; i++) { IInstance ins = rows.get(i); BaseModel rowData = new BaseModel(); if (ins instanceof CSVRow) { CSVRow row = (CSVRow)ins; List<String> cols = row.getColumnNames(); for (String key : cols) { Object value = row.getCol(key); String v = (value == null ? null : value.toString()); rowData.set(key, v); } /* String cols[] = ((CSVRow)ins).getColumns(); for (int col = 0; col < cols.length; col++) { String value = ((CSVRow)ins).getCol(col+1); rowData.set("" + (col+1), value); } */ } if (ins instanceof JDBCRow) { JDBCRow row = (JDBCRow)ins; List<String> cols = row.getColumnNames(); for (String key : cols) { Object value = row.getCol(key); String v = (value == null ? null : value.toString()); rowData.set(key, v); } } data.add(rowData); } BasePagingLoadResult<BaseModel> result = new BasePagingLoadResult<BaseModel>(data, config.getOffset(), total); return(result); } public List<AttributeColumnConfig> getDataSourceColumns(TransformConfig config) throws IOException { List<AttributeColumnConfig> list = new ArrayList<AttributeColumnConfig>(); List<IInstance> data = loadData(config); if (data.size() > 0) { IInstance ins = data.get(0); if (ins instanceof CSVRow) { CSVRow row = (CSVRow)ins; //String cols[] = row.getColumns(); List<String> cols = row.getColumnNames(); for (int i = 0; i < cols.size(); i++) { String name = cols.get(i); if (name == null || name.length() == 0) { name = "EMPTY-" + i; } AttributeColumnConfig aCfg = new AttributeColumnConfig(); aCfg.setId(name); aCfg.setName(name); aCfg.setType("xs:string"); list.add(aCfg); } } if (ins instanceof JDBCRow) { JDBCRow row = (JDBCRow)ins; List<String> cols = row.getColumnNames(); for (int i = 0; i < cols.size(); i++) { String name = cols.get(i); AttributeColumnConfig aCfg = new AttributeColumnConfig(); aCfg.setId(name); aCfg.setName(name); aCfg.setType("xs:string"); list.add(aCfg); } } } return(list); } protected List<IInstance> loadData(TransformConfig config) throws IOException { OneCMDBTransform trans = new OneCMDBTransform(); Properties p = getDataSourceProperties(config, true); IDataSource source = trans.getDataSource(p); DataSet dataSet = new DataSet(); dataSet.setDataSource(source); if (source instanceof ExcelDataSource || source instanceof CSVDataSource) { CSVInstanceSelector isel = new CSVInstanceSelector(); List<IInstance> instances = isel.getInstances(dataSet); return(instances); } if (source instanceof JDBCDataSourceWrapper) { JDBCInstanceSelector isel = new JDBCInstanceSelector(); List<IInstance> instances = isel.getInstances(dataSet); return(instances); } return(new ArrayList<IInstance>()); } private Properties getDataSourceProperties(TransformConfig config, boolean appendRoot) { String type = config.getDataSourceType(); Properties p = new Properties(); p.setProperty("type", type); // Need to set the root path. if (appendRoot) { p.setProperty(type + ".rootPath", ContentParserFactory.get().getRootPath().getPath() + "/MDR/" + config.getMDRName()); } BaseModel base = config.get(type); for (String key : base.getPropertyNames()) { Object o = base.get(key); if (key.equals("rootPath")) { continue; } if (o instanceof String) { p.setProperty(type + "." + key, (String)base.get(key)); } } return(p); } public List<BaseModel> calcInstances(String token, TransformConfig config) throws CMDBRPCException { IOneCMDBWebService service = null; try { service = CMDBWebServiceFactory.get().getOneCMDBWebService(); } catch (Exception e1) { throw new CMDBRPCException("Internal Error", "Can't contact OneCMDB Core WebService", null); } OneCMDBTransform trans = new OneCMDBTransform(); Properties p = getDataSourceProperties(config, true); IDataSource dataSource = null; try { dataSource = trans.getDataSource(p); } catch (IOException e) { throw new CMDBRPCException("Internal Error", "Can't resolve data source", CMDBRPCHandler.getStackTrace(e)); } //IDataSource dataSource = getDataSource(); TransformBeanProvider transformWorker = new TransformBeanProvider(); //transformWorker.setValueMap(valueMap); ParentBeanProvider transformProvider = new ParentBeanProvider(); // Create reader String transformXML = TransformConverter.toXML(config.getDataSourceType(), config.getTransformModel()); // Create transform provider. SimpleTransformProvider simpleProvider = new SimpleTransformProvider(); simpleProvider.setInputReader(new StringReader(transformXML)); simpleProvider.setType(config.getDataSourceType()); // Create template provider. IBeanProvider templateProvider = new WSDLBeanProvider(service, token); transformProvider.setInstanceProvider(simpleProvider); transformProvider.setTemplateProvider(templateProvider); transformWorker.setDataSource(dataSource); transformWorker.setTransformProvider(transformProvider); //transformWorker.setName(config.getMDRConfigName()); // TODO: Handle if. transformWorker.setWebService(service); transformWorker.setToken(token); transformWorker.setValidate(true); List<CiBean> allBeans = transformWorker.getBeans(); // Caclulate # instances of each template. List<BaseModel> result = new ArrayList<BaseModel>(); for (DataSetModel ds : config.getTransformModel().getDataSets()) { Set<CiBean> beans = transformWorker.getBeansForDataSet(ds.getName()); if (beans == null) { continue; } BaseModel m = new BaseModel(); m.set("ds", ds.getName()); m.set("count", beans.size()); int foundCount = 0; for (CiBean bean: beans) { if (bean.getId() != null) { foundCount++; } } m.set("foundCount", foundCount); result.add(m); } return(result); } }