001/* 002 * (C) Copyright 2006-2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * tdelprat, jcarsique 019 */ 020package org.nuxeo.ecm.admin.runtime; 021 022import java.io.File; 023import java.io.IOException; 024import java.io.InputStream; 025import java.util.ArrayList; 026import java.util.Collection; 027import java.util.Collections; 028import java.util.Enumeration; 029import java.util.List; 030import java.util.PropertyResourceBundle; 031import java.util.zip.ZipEntry; 032import java.util.zip.ZipFile; 033 034import org.apache.commons.logging.Log; 035import org.apache.commons.logging.LogFactory; 036import org.nuxeo.connect.update.Version; 037import org.nuxeo.osgi.BundleFile; 038import org.nuxeo.osgi.BundleImpl; 039import org.nuxeo.osgi.JarBundleFile; 040import org.nuxeo.runtime.RuntimeMessageHandler; 041import org.nuxeo.runtime.RuntimeService; 042import org.nuxeo.runtime.api.Framework; 043import org.nuxeo.runtime.model.RegistrationInfo; 044import org.osgi.framework.Bundle; 045 046/** 047 * Extracts information about the Bundles currently deployed in Nuxeo Runtime 048 * 049 * @author tiry 050 */ 051public class RuntimeInstrospection { 052 053 protected static final Log log = LogFactory.getLog(RuntimeInstrospection.class); 054 055 protected static SimplifiedServerInfo info; 056 057 protected static List<String> bundleIds; 058 059 public static synchronized SimplifiedServerInfo getInfo() { 060 if (info == null) { 061 RuntimeService runtime = Framework.getRuntime(); 062 Collection<RegistrationInfo> registrations = runtime.getComponentManager().getRegistrations(); 063 bundleIds = new ArrayList<>(); 064 List<SimplifiedBundleInfo> bundles = new ArrayList<>(); 065 for (RegistrationInfo ri : registrations) { 066 Bundle bundle = ri.getContext().getBundle(); 067 if (bundle != null && !bundleIds.contains(bundle.getSymbolicName())) { 068 SimplifiedBundleInfo bi = getBundleSimplifiedInfo(bundle); 069 bundleIds.add(bundle.getSymbolicName()); 070 if (bi != null) { 071 bundles.add(bi); 072 } 073 } 074 } 075 Collections.sort(bundles); 076 info = new SimplifiedServerInfo(); 077 info.setBundleInfos(bundles); 078 info.setRuntimeVersion(runtime.getVersion().toString()); 079 RuntimeMessageHandler runtimeMessageHandler = runtime.getMessageHandler(); 080 info.setWarnings(runtimeMessageHandler.getWarnings()); 081 info.setErrors(runtimeMessageHandler.getErrors()); 082 } 083 return info; 084 } 085 086 public static List<String> getBundleIds() { 087 if (bundleIds == null) { 088 getInfo(); 089 } 090 return bundleIds; 091 } 092 093 protected static SimplifiedBundleInfo getBundleSimplifiedInfo(Bundle bundle) { 094 if (!(bundle instanceof BundleImpl)) { 095 return null; 096 } 097 BundleImpl nxBundle = (BundleImpl) bundle; 098 BundleFile file = nxBundle.getBundleFile(); 099 File jarFile = null; 100 if (file instanceof JarBundleFile) { 101 JarBundleFile jar = (JarBundleFile) file; 102 jarFile = jar.getFile(); 103 } 104 if (jarFile == null || jarFile.isDirectory()) { 105 return null; 106 } 107 SimplifiedBundleInfo result = null; 108 try (ZipFile zFile = new ZipFile(jarFile)) { 109 // Look for a pom.properties to extract its Maven version 110 Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zFile.entries(); 111 while (entries.hasMoreElements()) { 112 ZipEntry entry = entries.nextElement(); 113 if (entry.getName().endsWith("pom.properties")) { 114 try (InputStream pomStream = zFile.getInputStream(entry)) { 115 PropertyResourceBundle prb = new PropertyResourceBundle(pomStream); 116 String version = prb.getString("version"); 117 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version); 118 } 119 break; 120 } 121 } 122 } catch (IOException e) { 123 log.debug(e.getMessage(), e); 124 } 125 if (result == null) { 126 // Fall back on the filename to extract a version 127 try { 128 Version version = new Version(jarFile.getName()); 129 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version.toString()); 130 } catch (NumberFormatException e) { 131 log.debug(e.getMessage()); 132 } 133 } 134 if (result == null) { 135 // Fall back on the MANIFEST Bundle-Version 136 try { 137 org.osgi.framework.Version version = bundle.getVersion(); 138 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version.toString()); 139 } catch (RuntimeException e) { 140 log.debug(e.getMessage()); 141 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), "unknown"); 142 } 143 } 144 return result; 145 } 146}