/* * 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.core.utils.wsdl; import java.io.File; import java.util.ArrayList; import java.util.List; import org.acegisecurity.userdetails.UserDetails; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.onecmdb.core.ICcb; import org.onecmdb.core.ICi; import org.onecmdb.core.ICmdbTransaction; import org.onecmdb.core.IJobService; import org.onecmdb.core.IJobStartResult; import org.onecmdb.core.IModelService; import org.onecmdb.core.IOneCmdbContext; import org.onecmdb.core.IRFC; import org.onecmdb.core.IRfcResult; import org.onecmdb.core.ISession; import org.onecmdb.core.IUpdateService; import org.onecmdb.core.internal.authentication.OneCMDBUser; import org.onecmdb.core.internal.authorization.RBACSession; import org.onecmdb.core.internal.ccb.RFCSummaryDecorator; import org.onecmdb.core.internal.ccb.RfcQueryCriteria; import org.onecmdb.core.internal.ccb.workers.RfcResult; import org.onecmdb.core.internal.model.ItemId; import org.onecmdb.core.internal.model.Path; import org.onecmdb.core.internal.model.QueryCriteria; import org.onecmdb.core.internal.model.QueryResult; import org.onecmdb.core.utils.ImportBeanProvider; import org.onecmdb.core.utils.MemoryBeanProvider; import org.onecmdb.core.utils.OnecmdbUtils; import org.onecmdb.core.utils.bean.CiBean; import org.onecmdb.core.utils.graph.handler.QueryHandler; import org.onecmdb.core.utils.graph.query.GraphQuery; import org.onecmdb.core.utils.graph.result.Graph; import org.onecmdb.core.utils.xml.BeanCache; import org.onecmdb.core.utils.xml.OneCmdbBeanProvider; import org.onecmdb.core.utils.xpath.commands.AuthCommand; import org.onecmdb.core.utils.xpath.commands.QueryCommand; import org.onecmdb.core.utils.xpath.generator.XMLContentGenerator; public class OneCMDBWebServiceImpl implements IOneCMDBWebService { private static final String DATA_PATH = "data/instance"; private IOneCmdbContext onecmdb; private Log log = LogFactory.getLog(this.getClass()); /** * Spring injections. * @param onecmdb */ public void setOneCmdb(IOneCmdbContext onecmdb) { this.onecmdb = onecmdb; } public IOneCmdbContext getOneCmdb() { return this.onecmdb; } /** * Authenticate a user with password. * * @return a sesion token, used for all operations. * @throws IllegalAccessException */ public String auth(String username, String pwd) throws IllegalAccessException { //ServiceInvocationHandler log.info("WSDL: auth(" + username + ", ******)"); AuthCommand cmd = new AuthCommand(this.onecmdb); if (pwd == null) { pwd = ""; } cmd.setUser(username); cmd.setPwd(pwd); String token = cmd.getToken(); log.info("WSDL: user " + username +" granted token " + token); return(token); } /** * Query OneCMDB with a valid auth token. */ public CiBean[] query(String authToken, String path, String attributes) { long start = System.currentTimeMillis(); log.info("WSDL: query(" + authToken + ", " + path + ", " + attributes + ")"); // Create command. QueryCommand cmd = new QueryCommand(this.onecmdb); cmd.setAuth(authToken); cmd.setPath(path); cmd.setOutputAttributes(attributes); // Create parser. XMLContentGenerator generator = new XMLContentGenerator(); generator.setCommand(cmd); // Generate beans according to command. List<CiBean> beans = generator.getBeans(); long stop = System.currentTimeMillis(); log.info("WSDL: query completed in " + (stop-start) + "ms returned + " + beans.size() + " objects"); return(beans.toArray(new CiBean[0])); } public int searchCount(String auth, QueryCriteria criteria) { long start = System.currentTimeMillis(); log.info("WSDL: searchCount(" + auth + ", " + criteria + ")"); ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } IModelService mService = (IModelService)session.getService(IModelService.class); int count = mService.queryCount(criteria); long stop = System.currentTimeMillis(); log.info("WSDL: searchCount completed in " + (stop-start) + "ms returned + " + count); return(count); } public CiBean[] search(String auth, QueryCriteria criteria) { long start = System.currentTimeMillis(); log.info("WSDL: search(" + auth + ", " + criteria + ")"); ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } IModelService mService = (IModelService)session.getService(IModelService.class); QueryResult<ICi> result = mService.query(criteria); ArrayList<CiBean> resultList = new ArrayList<CiBean>(); OneCmdbBeanProvider converter = new OneCmdbBeanProvider(); long stop = System.currentTimeMillis(); log.info("WSDL: search completed in " + (stop-start) + "ms returned + " + result.size() + " objects"); start = stop; for (ICi ci : result) { // Convert ci to cibean. CiBean bean = converter.convertCiToBean(ci); resultList.add(bean); } stop = System.currentTimeMillis(); log.info("WSDL: search convert completed in " + (stop-start) + "ms returned + " + result.size() + " beans"); log.info("WSDL: " + BeanCache.getInstance().getStatistics()); return(resultList.toArray(new CiBean[0])); } public int historyCount(String auth, CiBean bean, RfcQueryCriteria criteria) { long start = System.currentTimeMillis(); log.info("WSDL: history(" + auth + ", " + criteria + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } // Find the ci if provided. IModelService modelSvc = (IModelService) session.getService(IModelService.class); ICi ci = null; if (bean != null) { if (bean.getId() != null) { ci = modelSvc.find(new ItemId(bean.getId())); if (ci == null) { throw new IllegalArgumentException("CI with id <" + bean.getId() + "> not found"); } } else if (bean.getAlias() != null) { ci = modelSvc.findCi(new Path<String>(bean.getAlias())); if (ci == null) { throw new IllegalArgumentException("CI with alias <" + bean.getAlias() + "> not found"); } } } ICcb ccbSvc = (ICcb) session.getService(ICcb.class); int count = ccbSvc.queryRFCForCiCount(ci, criteria); long stop = System.currentTimeMillis(); log.info("WSDL: historyCount completed in " + (stop-start) + "ms returned + " + count); return(count); } public RFCBean[] history(String auth, CiBean bean, RfcQueryCriteria criteria) { long start = System.currentTimeMillis(); log.info("WSDL: history(" + auth + ", " + criteria + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } // Find the ci if provided. IModelService modelSvc = (IModelService) session.getService(IModelService.class); ICi ci = null; if (bean != null) { if (bean.getId() != null) { ci = modelSvc.find(new ItemId(bean.getId())); if (ci == null) { throw new IllegalArgumentException("CI with id <" + bean.getId() + "> not found"); } } else if (bean.getAlias() != null) { ci = modelSvc.findCi(new Path<String>(bean.getAlias())); if (ci == null) { throw new IllegalArgumentException("CI with alias <" + bean.getAlias() + "> not found"); } } } ICcb ccbSvc = (ICcb) session.getService(ICcb.class); List<IRFC> rfcs = ccbSvc.queryRFCForCi(ci, criteria); long stop = System.currentTimeMillis(); log.info("WSDL: history completed in " + (stop-start) + "ms returned + " + rfcs.size() + " objects"); start = stop; stop = System.currentTimeMillis(); log.info("WSDL: history convert completed in " + (stop-start) + "ms returned + " + rfcs.size() + " beans"); List<RFCBean> rfcBeans = convert(session, rfcs); return(rfcBeans.toArray(new RFCBean[0])); } public RfcResult update(String auth, CiBean[] local, CiBean[] base) { long start = System.currentTimeMillis(); log.info("WSDL: update(" + auth + ", " + local + ", " + base + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ImportBeanProvider importBeans = new ImportBeanProvider(); importBeans.setValidation(false); importBeans.setSession(session); importBeans.setProvider(new MemoryBeanProvider(local)); if (base != null) { importBeans.setBaseProvider(new MemoryBeanProvider(base)); } IRfcResult result = importBeans.processProvider(); long stop = System.currentTimeMillis(); log.info("WSDL: update completed in " + (stop - start) + "ms result = " + result); return((RfcResult)result); } public void logout(String authToken) { log.info("WSDL: logout(" + authToken + ")"); this.onecmdb.removeSession(authToken); } public CiBean[] evalRelation(String auth, CiBean source, String relationPath, QueryCriteria crit) { long start = System.currentTimeMillis(); log.info("WSDL: evalRelation(" + auth + ", " + relationPath + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } if (source == null) { throw new IllegalArgumentException("Source can not be null!"); } IModelService modelSvc = (IModelService) session.getService(IModelService.class); ICi ci = null; if (source.getId() != null) { ci = modelSvc.find(new ItemId(source.getId())); if (ci == null) { throw new IllegalArgumentException("CI with id <" + source.getId() + "> not found"); } } else if (source.getAlias() != null) { ci = modelSvc.findCi(new Path<String>(source.getAlias())); if (ci == null) { throw new IllegalArgumentException("CI with alias <" + source.getAlias() + "> not found"); } } if (ci == null) { throw new IllegalArgumentException("Source CI have no id or alias specified!"); } // Lookup the source OnecmdbUtils utils = new OnecmdbUtils(session); //Set<IValue> set = utils.evaluate(ci, relationPath); QueryResult result = utils.evaluate(ci, relationPath, crit, false); // Convert Values to Beans. long stop = System.currentTimeMillis(); log.info("WSDL: evalRelation completed in " + (stop-start) + "ms returned + " + result.size() + " objects"); start = stop; ArrayList<CiBean> resultList = new ArrayList<CiBean>(); OneCmdbBeanProvider converter = new OneCmdbBeanProvider(); for (Object resCI : result) { if (resCI instanceof ICi) { // Convert ci to cibean. CiBean bean = converter.convertCiToBean((ICi)resCI); resultList.add(bean); } } stop = System.currentTimeMillis(); log.info("WSDL: evalRelation convert completed in " + (stop-start) + "ms returned + " + resultList.size() + " beans"); return(resultList.toArray(new CiBean[0])); } public int evalRelationCount(String auth, CiBean source, String relationPath, QueryCriteria crit) { long start = System.currentTimeMillis(); log.info("WSDL: evalRelationCount(" + auth + ", " + relationPath + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } if (source == null) { throw new IllegalArgumentException("Source can not be null!"); } ICi ci = getICI(session, source); // Lookup the source OnecmdbUtils utils = new OnecmdbUtils(session); //Set<IValue> set = utils.evaluate(ci, relationPath); QueryResult result = utils.evaluate(ci, relationPath, crit, true); // Convert Values to Beans. long stop = System.currentTimeMillis(); log.info("WSDL: evalRelationCount completed in " + (stop-start) + "ms returned + " + result.size() + " objects"); return(result.getTotalHits()); } private ICi getICI(ISession session, CiBean bean) { IModelService modelSvc = (IModelService) session.getService(IModelService.class); ICi ci = null; if (bean.getId() != null) { ci = modelSvc.find(new ItemId(bean.getId())); if (ci == null) { throw new IllegalArgumentException("CI with id <" + bean.getId() + "> not found"); } } else if (bean.getAlias() != null) { ci = modelSvc.findCi(new Path<String>(bean.getAlias())); if (ci == null) { throw new IllegalArgumentException("CI with alias <" + bean.getAlias() + "> not found"); } } if (ci == null) { throw new IllegalArgumentException("Source CI have no id or alias specified!"); } return(ci); } public String[] findRelation(String auth, CiBean source, CiBean target) { throw new IllegalArgumentException("Not implemented yet!"); } public String newInstanceAlias(String auth, String templateAlias) { // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } // For now use the file system. File file = new File(DATA_PATH + "/" + templateAlias + "/"); if (!file.exists()) { file.mkdirs(); } // Make sure we are alone. synchronized(this) { String files[] = file.list(); int offset = 0; if (files.length == 0) { // Validate offset... offset = 1; } else { offset = Integer.parseInt(files[0]); } offset = validateInstanceOffset(session, offset, templateAlias); if (files.length == 0) { // Create new offset. File index = new File(file, "" + offset); try { if (!index.createNewFile()) { } } catch (Exception e) { throw new IllegalArgumentException("Can't create index file path " + file.getPath()); } } else { File newIndex = new File(file, "" + offset); File oldFile = new File(file, files[0]); oldFile.renameTo(newIndex); } return(templateAlias + "-" + offset); } } /** * Run under synchronization * @param session * @param offset * @param templateAlias * @return */ private int validateInstanceOffset(ISession session, int offset, String templateAlias) { IModelService service = (IModelService) session.getService(IModelService.class); QueryCriteria crit = new QueryCriteria(); crit.setCiAlias(templateAlias + "-" + offset); if (service.queryCount(crit) == 0) { return(offset); } return(validateInstanceOffset(session, (offset+1), templateAlias)); } public RBACSession getRBACSession(String token) { ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } return(session.getRBACSession()); } public CiBean getAuthAccount(String token) { ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } UserDetails user = session.getPrincipal(); if (user instanceof OneCMDBUser) { OneCMDBUser cmdbUser = (OneCMDBUser)user; ICi account = cmdbUser.getAccount(); if (account != null) { CiBean bean = (new OneCmdbBeanProvider()).convertCiToBean(account); return(bean); } } return(null); //throw new SecurityException("Token is not a OneCMDB Account!"); } public RFCBean[] compare(String auth, CiBean[] local, CiBean[] base, String[] keys) { long start = System.currentTimeMillis(); log.info("WSDL: compare(" + auth + ", " + local + ", " + base + ")"); // Update all beans. ISession session = onecmdb.getSession(auth); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ImportBeanProvider importBeans = new ImportBeanProvider(); importBeans.setValidation(false); importBeans.setSession(session); importBeans.setProvider(new MemoryBeanProvider(local)); if (base != null) { importBeans.setBaseProvider(new MemoryBeanProvider(base)); } List<IRFC> rfcs = importBeans.compare(); List<RFCBean> rfcBeans = convert(session, rfcs); long stop = System.currentTimeMillis(); log.info("WSDL: compare completed in " + (stop - start) + "ms result = " + rfcBeans.size()); return(rfcBeans.toArray(new RFCBean[0])); } private List<RFCBean> convert(ISession session, List<IRFC> rfcs) { ICcb ccbSvc = (ICcb) session.getService(ICcb.class); IModelService mSvc = (IModelService) session.getService(IModelService.class); // Return this list. List<RFCBean> rfcBeans = new ArrayList<RFCBean>(); for (IRFC rfc : rfcs) { RFCBean rfcBean = new RFCBean(); rfcBean.setId(rfc.getId()); rfcBean.setSummary(RFCSummaryDecorator.decorateSummary(mSvc, rfc)); rfcBean.setTransactionId(rfc.getTxId()); rfcBean.setTs(rfc.getTs()); if (ccbSvc != null) { // Retrive the Transaction to get the issuer. ICmdbTransaction tx = ccbSvc.findTxForRfc(rfc); rfcBean.setIssuer(tx.getIssuer()); } rfcBeans.add(rfcBean); } return(rfcBeans); } public Graph queryGraph(String token, GraphQuery q) { long start = System.currentTimeMillis(); log.info("WSDL: QueryGraph(" + token + ", " + q.toString() + ")"); Graph result = new Graph(); try { // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } long t1 = System.currentTimeMillis(); QueryHandler handler = new QueryHandler(session); result = handler.execute3(q); long t2 = System.currentTimeMillis(); log.info("\tWSDL: GraphQuery: result=" + result.toString() + (t2-t1) + "ms"); } catch (Throwable t) { long stop = System.currentTimeMillis(); log.error("WSDL{" + (stop-start) + "}: ERROR QueryGraph(" + token + ", " + q.toString() + ")", t); t.printStackTrace(); throw new IllegalArgumentException(t.getMessage(), t); } long stop = System.currentTimeMillis(); log.info("WSDL{" + (stop-start) + "}: QueryGraph(" + token + ", " + q.toString() + ") : " + result.toString()); return(result); } public IJobStartResult cancelJob(String token, CiBean job) { long start = System.currentTimeMillis(); log.info("WSDL: cancelJob(" + token + ", " + job.getAlias() + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ICi ci = getICI(session, job); IJobService jobSvc = (IJobService)session.getService(IJobService.class); IJobStartResult result = jobSvc.cancelJob(session, ci); long stop = System.currentTimeMillis(); log.info("WSDL: {" + (stop-start) + "} cancelJob(" + token + ", " + job.getAlias() + ")=" + result); return(result); } public void cancelTrigger(String token, CiBean trigger) { long start = System.currentTimeMillis(); log.info("WSDL: cancelTrigger(" + token + ", " + trigger.getAlias() + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ICi ci = getICI(session, trigger); IJobService jobSvc = (IJobService)session.getService(IJobService.class); jobSvc.cancelTrigger(session, ci); long stop = System.currentTimeMillis(); log.info("WSDL: {" + (stop-start) + "} cancelTrigger(" + token + ", " + trigger.getAlias() + ")"); } public void reschedualeTrigger(String token, CiBean trigger) { long start = System.currentTimeMillis(); log.info("WSDL: reschedualeTrigger(" + token + ", " + trigger.getAlias() + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ICi ci = getICI(session, trigger); IJobService jobSvc = (IJobService)session.getService(IJobService.class); jobSvc.reschedualeTrigger(session, ci); long stop = System.currentTimeMillis(); log.info("WSDL: {" + (stop-start) + "} reschedualeTrigger(" + token + ", " + trigger.getAlias() + ")"); } public IJobStartResult startJob(String token, CiBean job) { long start = System.currentTimeMillis(); log.info("WSDL: startJob(" + token + ", " + job.getAlias() + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } ICi ci = getICI(session, job); IJobService jobSvc = (IJobService)session.getService(IJobService.class); IJobStartResult result = jobSvc.startJob(session, ci); long stop = System.currentTimeMillis(); log.info("WSDL: {" + (stop-start) + "} startJob(" + token + ", " + job.getAlias() + ")=" + result); return(result); } public String getUpdateInfo(String token, boolean force) { long start = System.currentTimeMillis(); log.info("WSDL: getUpdateInfo(" + token + ", " + force + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } IUpdateService updSvc = (IUpdateService)session.getService(IUpdateService.class); if (updSvc == null) { log.info("WSDL: getUpdateInfo(" + token + ","+ force +") - Service not available!"); return(null); } if (force) { updSvc.checkForUpdate(); } String result = updSvc.getLatestUpdateInfo(); log.info("WSDL: getUpdateInfo(" + token + ","+ force +")=" + result); return(result); } public boolean isUpdateAvailable(String token, boolean force) { long start = System.currentTimeMillis(); log.info("WSDL: isUpdateAvailable(" + token + ", " + force + ")"); // Update all beans. ISession session = onecmdb.getSession(token); if (session == null) { throw new SecurityException("No Session found! Try to do auth() first!"); } IUpdateService updSvc = (IUpdateService)session.getService(IUpdateService.class); if (updSvc == null) { log.info("WSDL: isUpdateAvailable(" + token + ","+ force +") - Service not available!"); return(false); } if (force) { updSvc.checkForUpdate(); } boolean result = updSvc.isUpdateAvaliable(); log.info("WSDL: getUpdateInfo(" + token + ","+ force +")=" + result); return(result); } }