org.glassfish.appclient.client.acc.AppClientContainerBuilder Maven / Gradle / Ivy
Show all versions of payara-client Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package org.glassfish.appclient.client.acc;
import com.sun.enterprise.container.common.spi.util.InjectionException;
import com.sun.enterprise.module.bootstrap.BootException;
import com.sun.enterprise.util.LocalStringManager;
import com.sun.enterprise.util.LocalStringManagerImpl;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.callback.CallbackHandler;
import org.glassfish.api.naming.ClientNamingConfigurator;
import org.glassfish.appclient.client.acc.config.AuthRealm;
import org.glassfish.appclient.client.acc.config.ClientCredential;
import org.glassfish.appclient.client.acc.config.MessageSecurityConfig;
import org.glassfish.appclient.client.acc.config.Property;
import org.glassfish.appclient.client.acc.config.TargetServer;
import org.glassfish.appclient.client.acc.config.util.XML;
import org.glassfish.enterprise.iiop.api.GlassFishORBHelper;
import org.xml.sax.SAXParseException;
/**
* Implements a builder for accumulating configuration information for the
* app client container and then starting the ACC.
*
* The interface for the ACC builder is defined as AppClientContainer.Builder so the
* relevant JavaDoc is concentrated in that one class.
*
* The AppClientContainerBuilder class records the
* information the container itself needs in order to operate.
*
* @author tjquinn
*/
public class AppClientContainerBuilder implements AppClientContainer.Builder {
private final static String ENDPOINTS_PROPERTY_NAME = "com.sun.appserv.iiop.endpoints";
private static final LocalStringManager localStrings = new LocalStringManagerImpl(AppClientContainerBuilder.class);
/** caller-specified target servers */
private TargetServer[] targetServers;
/** caller-optional logger - initialized to logger name from the class; caller can override with logger method */
private Logger logger = Logger.getLogger(getClass().getName());
private AuthRealm authRealm = null;
private URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
/**
* The caller can pre-set the client credentials using the
* clientCredentials
method. The ACC will use the
* username and realm values in intializing a callback handler if one is
* needed.
*/
private ClientCredential clientCredential = null;
private boolean sendPassword = true;
private GlassFishORBHelper orbHelper;
/** caller-provided message security configurations */
private final List messageSecurityConfigs = new ArrayList();
// private Class extends CallbackHandler> callbackHandlerClass = null;
/**
* optional caller-specified properties governing the ACC's behavior.
* Correspond to the property elements available in the client-container
* element from sun-application-client-containerxxx.dtd.
*/
private Properties containerProperties = null;
AppClientContainerBuilder() {
}
/**
* Creates a new builder with the specified target servers and client URI.
*
* @param targetServers the TargetServer
s to use
* @param clientURI the URI of the client archive to launch
*/
AppClientContainerBuilder(final TargetServer[] targetServers) {
this.targetServers = targetServers;
}
public AppClientContainer newContainer(final Class mainClass,
final CallbackHandler callerSpecifiedCallbackHandler) throws Exception {
prepareHabitat();
Launchable client = Launchable.LaunchableUtil.newLaunchable(
ACCModulesManager.getHabitat(), mainClass);
AppClientContainer container = createContainer(client,
callerSpecifiedCallbackHandler, false /* istextAuth */);
return container;
}
public AppClientContainer newContainer(final Class mainClass) throws Exception {
return newContainer(mainClass, null);
}
public AppClientContainer newContainer(final URI clientURI,
final CallbackHandler callerSpecifiedCallbackHandler,
final String callerSpecifiedMainClassName,
final String callerSpecifiedAppClientName) throws Exception, UserError {
return newContainer(clientURI, callerSpecifiedCallbackHandler,
callerSpecifiedMainClassName,
callerSpecifiedAppClientName,
false /* isTextAuth */);
}
public AppClientContainer newContainer(final URI clientURI,
final CallbackHandler callerSpecifiedCallbackHandler,
final String callerSpecifiedMainClassName,
final String callerSpecifiedAppClientName,
final boolean isTextAuth) throws Exception, UserError {
prepareHabitat();
prepareIIOP(targetServers, containerProperties);
Launchable client = Launchable.LaunchableUtil.newLaunchable(
clientURI,
callerSpecifiedMainClassName,
callerSpecifiedAppClientName,
ACCModulesManager.getHabitat());
AppClientContainer container = createContainer(client,
callerSpecifiedCallbackHandler, isTextAuth);
return container;
}
public AppClientContainer newContainer(final URI clientURI) throws Exception, UserError {
return newContainer(clientURI, null, null, null);
}
private AppClientContainer createContainer(final Launchable client,
final CallbackHandler callerSuppliedCallbackHandler,
final boolean isTextAuth) throws BootException, BootException, URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException, InjectionException, IOException, SAXParseException {
AppClientContainer container = ACCModulesManager.getService(AppClientContainer.class);
//process the packaged permissions.xml
container.processPermissions();
container.setClient(client);
container.setBuilder(this);
CallbackHandler callbackHandler =
(callerSuppliedCallbackHandler != null ?
callerSuppliedCallbackHandler : getCallbackHandlerFromDescriptor(client.getDescriptor(classLoader).getCallbackHandler()));
container.prepareSecurity(targetServers, messageSecurityConfigs, containerProperties,
clientCredential, callbackHandler, classLoader, isTextAuth);
return container;
}
private CallbackHandler getCallbackHandlerFromDescriptor(final String callbackHandlerName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (callbackHandlerName != null && ! callbackHandlerName.equals("")) {
Class callbackHandlerClass =
(Class) Class.forName(callbackHandlerName, true, classLoader);
return callbackHandlerClass.newInstance();
}
return null;
}
private void prepareHabitat() throws URISyntaxException {
ACCModulesManager.initialize(Thread.currentThread().getContextClassLoader());
orbHelper = ACCModulesManager.getService(GlassFishORBHelper.class);
}
/**
* Prepares the client ORB to bootstrap into the server ORB(s) specified
* by the TargetServer objects.
* @param targetServers the TargetServer endpoints to which the client ORB can try to connect
* @param containerProperties Properties, if specified, which might indicate that SSL is to be used
* @return ORB-related properties to define host and port for bootstrapping
*/
private void prepareIIOP(final TargetServer[] targetServers, Properties containerProperties) {
if (targetServers.length == 0) {
throw new IllegalArgumentException();
}
final StringBuilder sb = new StringBuilder();
for (TargetServer ts : targetServers) {
if (sb.length() > 0) {
sb.append(",");
}
sb.append(ts.getAddress()).append(":").append(ts.getPort());
}
/*
* If the user has explicitly defined the ORB-related properties, do
* not override those settings.
*/
if (targetServers.length == 1) {
defineIfNotDefined(GlassFishORBHelper.OMG_ORB_INIT_HOST_PROPERTY,
targetServers[0].getAddress());
defineIfNotDefined(GlassFishORBHelper.OMG_ORB_INIT_PORT_PROPERTY,
Integer.toString(targetServers[0].getPort()));
} else {
/*
* Currently, set a system property to specify multiple endpoints.
*/
defineIfNotDefined(ENDPOINTS_PROPERTY_NAME, sb.toString());
}
if (isSSLRequired(targetServers, containerProperties)) {
orbHelper.setCSIv2Prop(GlassFishORBHelper.ORB_SSL_CLIENT_REQUIRED, "true");
}
logger.log(Level.CONFIG, "Using endpoint address(es): {0}", sb.toString());
}
/**
* Define the specified system property using the new value unless the
* property is already set.
* @param propName name of the property to check and, possibly, set
* @param newPropValue value to set if the property is not already set
*/
private void defineIfNotDefined(final String propName, final String newPropValue) {
if (System.getProperty(propName) == null) {
if (newPropValue == null) {
throw new RuntimeException(localStrings.getLocalString(
AppClientContainerBuilder.class,
"appclient.missingValue",
"Value for {0} expected but was not configured or assigned",
new Object[] {propName}
));
}
System.setProperty(propName, newPropValue);
}
}
/**
* Reports whether the ORB should be requested to use SSL.
*
* If any TargetServer specifies SSL or the container-level properties
* specify SSL then report "true."
* @param targetServers configured TargetServer(s)
* @param containerProperties configured container-level properties
* @return whether the target servers or the properties implies the use of SSL
*/
private boolean isSSLRequired(final TargetServer[] targetServers, final Properties containerProperties) {
if (containerProperties != null) {
String sslPropertyValue = containerProperties.getProperty("ssl");
if ("required".equals(sslPropertyValue)) {
return true;
}
}
for (TargetServer ts : targetServers) {
/*
* If this target server has the optional security sub-item then
* the security sub-item must have an ssl sub-item. So we can just
* look for the security sub-item.
*/
if (ts.getSecurity() != null) {
return true;
}
}
return false;
}
// /**
// * Returns an AppClientContainer prepared to execute the app client implied
// * by the launch info and the app client args.
// * @param launchInfo info about the launch (type, name)
// * @param appclientArgs appclient command line arguments
// * @return
// */
// AppClientContainer newContainer(final CommandLaunchInfo launchInfo, final AppclientCommandArguments appclientArgs) {
// AppClientContainer acc = null;
//// switch (launchInfo.getClientLaunchType()) {
//// case JAR:
//// /*
//// * The user will have used local file path syntax, so create a
//// * file first and then get its URI.
//// */
//// File f = new File(launchInfo.getClientName());
//// acc = newContainer(f.toURI());
////
//// StandAloneAppClientInfo acInfo = new StandAloneAppClientInfo(
//// false /* isJWS */,
//// logger,
//// f, archivist, mainClassFromCommandLine)
//// }
// return acc;
// }
public AppClientContainerBuilder addMessageSecurityConfig(final MessageSecurityConfig msConfig) {
messageSecurityConfigs.add(msConfig);
return this;
}
public List getMessageSecurityConfig() {
return this.messageSecurityConfigs;
}
public AppClientContainerBuilder logger(final Logger logger) {
this.logger = logger;
return this;
}
public Logger getLogger() {
return logger;
}
public AppClientContainerBuilder authRealm(final String className) {
authRealm = new AuthRealm(className);
return this;
}
public AuthRealm getAuthRealm() {
return authRealm;
}
public AppClientContainerBuilder clientCredentials(final String user, final char[] password) {
return clientCredentials(user, password, null);
}
public AppClientContainerBuilder clientCredentials(final String user, final char[] password, final String realm) {
// this.clientCredential = new ClientCredential()
// this.user = user;
// this.password = password;
// this.realmName = realm;
ClientCredential cc = new ClientCredential(user, new XML.Password(password), realm);
return clientCredentials(cc);
}
public AppClientContainerBuilder clientCredentials(final ClientCredential cc) {
clientCredential = cc;
return this;
}
public ClientCredential getClientCredential() {
return clientCredential;
}
public AppClientContainerBuilder containerProperties(final Properties props) {
this.containerProperties = props;
return this;
}
public AppClientContainerBuilder containerProperties(final List props) {
containerProperties = XML.toProperties(props);
return this;
}
public Properties getContainerProperties() {
return containerProperties;
}
public AppClientContainerBuilder sendPassword(final boolean sendPassword){
this.sendPassword = sendPassword;
return this;
}
public boolean getSendPassword() {
return sendPassword;
}
// public AppClientContainerBuilder callbackHandler(final Class extends CallbackHandler> callbackHandlerClass) {
// this.callbackHandlerClass = callbackHandlerClass;
// return this;
// }
// public Class extends CallbackHandler> getCallbackHandler() {
// return callbackHandlerClass;
// }
public TargetServer[] getTargetServers() {
return targetServers;
}
// public AppClientContainerBuilder mainClass(Class mainClass) {
// this.mainClass = mainClass;
// return this;
// }
// public Class getMainClass() {
// return mainClass;
// }
//
// public AppClientContainerBuilder mainClassName(String mainClassName) {
// if (isMainClassFromCaller) {
// throw new IllegalStateException();
// }
// this.mainClassName = mainClassName;
// return this;
// }
//
// public String getMainClassName() {
// return mainClassName;
// }
//
// public AppClientContainerBuilder mainClass(final Class mainClass) {
// this.mainClass = mainClass;
// mainClassName = mainClass.getName();
// return this;
// }
//
// public Method getMainMethod() {
// return mainMethod;
// }
//
// private void completeConfig() throws NoSuchMethodException {
// mainMethod = initMainMethod();
// }
//
}