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.RuntimeMessage.Level; 041import org.nuxeo.runtime.RuntimeMessageHandler; 042import org.nuxeo.runtime.RuntimeService; 043import org.nuxeo.runtime.api.Framework; 044import org.nuxeo.runtime.model.RegistrationInfo; 045import org.osgi.framework.Bundle; 046 047/** 048 * Extracts information about the Bundles currently deployed in Nuxeo Runtime 049 * 050 * @author tiry 051 */ 052public class RuntimeInstrospection { 053 054 protected static final Log log = LogFactory.getLog(RuntimeInstrospection.class); 055 056 protected static SimplifiedServerInfo info; 057 058 protected static List<String> bundleIds; 059 060 public static synchronized SimplifiedServerInfo getInfo() { 061 if (info == null) { 062 RuntimeService runtime = Framework.getRuntime(); 063 Collection<RegistrationInfo> registrations = runtime.getComponentManager().getRegistrations(); 064 bundleIds = new ArrayList<>(); 065 List<SimplifiedBundleInfo> bundles = new ArrayList<>(); 066 for (RegistrationInfo ri : registrations) { 067 Bundle bundle = ri.getContext().getBundle(); 068 if (bundle != null && !bundleIds.contains(bundle.getSymbolicName())) { 069 SimplifiedBundleInfo bi = getBundleSimplifiedInfo(bundle); 070 bundleIds.add(bundle.getSymbolicName()); 071 if (bi != null) { 072 bundles.add(bi); 073 } 074 } 075 } 076 Collections.sort(bundles); 077 info = new SimplifiedServerInfo(); 078 info.setBundleInfos(bundles); 079 info.setRuntimeVersion(runtime.getVersion().toString()); 080 RuntimeMessageHandler runtimeMessageHandler = runtime.getMessageHandler(); 081 info.setWarnings(runtimeMessageHandler.getMessages(Level.WARNING)); 082 info.setErrors(runtimeMessageHandler.getMessages(Level.ERROR)); 083 } 084 return info; 085 } 086 087 public static List<String> getBundleIds() { 088 if (bundleIds == null) { 089 getInfo(); 090 } 091 return bundleIds; 092 } 093 094 protected static SimplifiedBundleInfo getBundleSimplifiedInfo(Bundle bundle) { 095 if (!(bundle instanceof BundleImpl)) { 096 return null; 097 } 098 BundleImpl nxBundle = (BundleImpl) bundle; 099 BundleFile file = nxBundle.getBundleFile(); 100 File jarFile = null; 101 if (file instanceof JarBundleFile) { 102 JarBundleFile jar = (JarBundleFile) file; 103 jarFile = jar.getFile(); 104 } 105 if (jarFile == null || jarFile.isDirectory()) { 106 return null; 107 } 108 SimplifiedBundleInfo result = null; 109 try (ZipFile zFile = new ZipFile(jarFile)) { 110 // Look for a pom.properties to extract its Maven version 111 Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zFile.entries(); 112 while (entries.hasMoreElements()) { 113 ZipEntry entry = entries.nextElement(); 114 if (entry.getName().endsWith("pom.properties")) { 115 try (InputStream pomStream = zFile.getInputStream(entry)) { 116 PropertyResourceBundle prb = new PropertyResourceBundle(pomStream); 117 String version = prb.getString("version"); 118 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version); 119 } 120 break; 121 } 122 } 123 } catch (IOException e) { 124 log.debug(e.getMessage(), e); 125 } 126 if (result == null) { 127 // Fall back on the filename to extract a version 128 try { 129 Version version = new Version(jarFile.getName()); 130 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version.toString()); 131 } catch (NumberFormatException e) { 132 log.debug(e.getMessage()); 133 } 134 } 135 if (result == null) { 136 // Fall back on the MANIFEST Bundle-Version 137 try { 138 org.osgi.framework.Version version = bundle.getVersion(); 139 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), version.toString()); 140 } catch (RuntimeException e) { 141 log.debug(e.getMessage()); 142 result = new SimplifiedBundleInfo(bundle.getSymbolicName(), "unknown"); 143 } 144 } 145 return result; 146 } 147}