/******************************************************************************* * Copyright (c) 2008 Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source$ * Created by: Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com </a>) * Created on: Jul 15, 2008 * Revision: $Id$ * * Contributors: * Cambridge Semantics Incorporated - initial API and implementation *******************************************************************************/ package org.openanzo.servlet.status; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.servlet.ServletException; import org.eclipse.jetty.server.Request; import org.openanzo.exceptions.AnzoException; import org.openanzo.exceptions.AnzoRuntimeException; import org.openanzo.exceptions.LogUtils; import org.openanzo.osgi.AnzoAttributeDefinition; import org.openanzo.osgi.ConfiguredServiceActivator; import org.openanzo.osgi.GenericObjectClassDef; import org.openanzo.osgi.attributes.ServicesAttributes; import org.openanzo.rdf.Constants; import org.openanzo.rdf.URI; import org.openanzo.services.AnzoPrincipal; import org.openanzo.services.ServicesDictionary; import org.openanzo.servlet.BasicAuthenticator; import org.openanzo.servlet.IAuthenticatorRealm; import org.openanzo.servlet.PathSpec; import org.openanzo.servlet.SecurityConstraint; import org.openanzo.servlet.WebcontainerTracker; import org.ops4j.pax.web.service.WebContainer; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.http.HttpContext; import org.osgi.service.metatype.AttributeDefinition; import org.osgi.service.metatype.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Activator for status servlet * * @author Matthew Roy ( <a href="mailto:mroy@cambridgesemantics.com">mroy@cambridgesemantics.com</a>) * */ public class Activator extends ConfiguredServiceActivator { private static final Logger log = LoggerFactory.getLogger(Activator.class); StatusServlet servlet = null; static final String SERVICE_PID = "org.openanzo.servlet.Status"; GenericObjectClassDef classDef; WebContainer webContainer; WebcontainerTracker wcTracker; public static final AnzoAttributeDefinition Secure = new AnzoAttributeDefinition() { public String getName() { return "secure"; } public boolean isRestartRequired() { return false; } public String getID() { return "org.openanzo.servlet.status.secure"; } public String getDescription() { return "" + "Is encryption required for accessing this servlet"; } public String validate(String value) { return ""; } public int getType() { return AnzoAttributeDefinition.BOOLEAN; } public String[] getOptionValues() { return null; } public String[] getOptionLabels() { return null; } public String[] getDefaultValue() { return new String[] { Boolean.toString(true) }; } public int getCardinality() { return 0; } }; public ObjectClassDefinition getObjectClassDefinition(String id, String locale) { return classDef != null ? classDef : (classDef = new GenericObjectClassDef(SERVICE_PID, getBundleName(), getBundleDescription(), new AttributeDefinition[] { ServicesAttributes.Enabled }, new AttributeDefinition[] { Secure })); } @Override public String[] getDependencies() { return new String[] {}; } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ @Override public void start(BundleContext context) throws Exception { super.start(context); } /** * @return the SERVICE_PID */ @Override public String getServicePid() { return SERVICE_PID; } @Override public boolean isInitialized() { return super.isInitialized() && webContainer != null; } @Override public void configurationPropertiesSet(Set<String> changedProps) throws ConfigurationException { if (configProperties != null && wcTracker == null) { String instanceIds = (String) configProperties.get("org.ops4j.pax.web.instanceId"); try { wcTracker = new WebcontainerTracker(context, instanceIds, new WebcontainerTracker.WebcontainerTrackerListener() { public void webcontainerUnAvailable(String instanceId, WebContainer wc) { Activator.this.webContainer = null; stopLocked(false); } public void webcontainerAvailable(String instanceId, WebContainer wc) { Activator.this.webContainer = wc; if (isInitialized()) { startLocked(); } } }); wcTracker.open(); } catch (InvalidSyntaxException ise) { throw new ConfigurationException("org.ops4j.pax.web.instanceId", ise.getMessage()); } } } @Override public void start() { try { final String serviceUserName = ServicesDictionary.getUser(configProperties, null); final String servicePassword = ServicesDictionary.getPassword(configProperties, null); servlet = new StatusServlet(context); PathSpec ps = new PathSpec("*"); Boolean requireSSL = ServicesDictionary.getRequireSSL(configProperties); final boolean reqSSL = (requireSSL != null) ? requireSSL.booleanValue() : false; HttpContext httpContext = null; String secure = (String) configProperties.get("org.openanzo.servlet.status.secure"); if (secure == null || Boolean.parseBoolean(secure)) { httpContext = new BasicAuthenticator(context, reqSSL ? SecurityConstraint.INTEGRAL : SecurityConstraint.NONE, new IAuthenticatorRealm() { public AnzoPrincipal authenticate(String userId, Object credentials, Request request) { if (userId != null && serviceUserName.equals(userId) && credentials != null && credentials.equals(servicePassword)) { HashSet<URI> rolesSet = new HashSet<URI>(); URI userURI = Constants.valueFactory.createURI("http://openanzo.org/system/internal/sysadmin"); rolesSet.add(userURI); rolesSet.add(Constants.AUTHENTICATED_USERS_ROLE); rolesSet.add(Constants.EVERYONE_ROLE); AnzoPrincipal principal = new AnzoPrincipal(userId, userURI, rolesSet, true, false); return principal; } else { return null; } } }, null, Collections.<PathSpec> emptySet(), Collections.<PathSpec> singleton(ps)); } webContainer.registerServlet(servlet, new String[] { "/status/*" }, null, httpContext); } catch (ServletException se) { log.error(LogUtils.LIFECYCLE_MARKER, "Error starting status servlet", se); throw new RuntimeException(se); } catch (AnzoException ae) { log.error(LogUtils.LIFECYCLE_MARKER, "Error starting status servlet", ae); throw new AnzoRuntimeException(ae); } } @Override public void stop(boolean bundleStopping) { if (webContainer != null) webContainer.unregisterServlet(servlet); if (wcTracker != null && bundleStopping) { wcTracker.close(); wcTracker = null; } } }