package com.perforce.maven.scm.provider.p4.manager; import java.net.URISyntaxException; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.scm.ScmException; import org.codehaus.plexus.logging.AbstractLogEnabled; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable; import org.codehaus.plexus.util.StringUtils; import com.perforce.maven.scm.provider.p4.repository.P4ScmProviderRepository; import com.perforce.maven.scm.provider.p4.util.P4Utils; import com.perforce.p4java.exception.MessageSeverityCode; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.impl.mapbased.rpc.sys.helper.RpcSystemFileCommandsHelper; import com.perforce.p4java.option.UsageOptions; import com.perforce.p4java.option.server.LoginOptions; import com.perforce.p4java.option.server.TrustOptions; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.IServer; import com.perforce.p4java.server.ServerFactory; import com.perforce.p4java.server.callback.ICommandCallback; /** * Manage IServer cache * * @plexus.component role="com.perforce.maven.scm.provider.p4.manager.P4ServerManager" */ public class DefaultP4ServerManager extends AbstractLogEnabled implements P4ServerManager, Disposable { private Map<String, IServer> servers = new ConcurrentHashMap<String, IServer>(); public void dispose() { for ( IServer server : servers.values() ) { try { server.disconnect(); } catch ( P4JavaException e ) { this.getLogger().error( e.getLocalizedMessage() ); } } servers.clear(); } public IServer getServer( P4ScmProviderRepository repo ) throws ScmException { IServer server = servers.get( repo.getP4Port() ); if ( server != null ) { { if ( !isValidServer( server ) ) { this.getLogger().warn( "Cached server instance is invalid, will try a new one" ); disconnectQuietly( server ); servers.remove( repo.getP4Port() ); server = null; } } } if ( server == null ) { server = this.createServer( repo ); servers.put( repo.getP4Port(), server ); } return server; } public static boolean isValidServer( IServer server ) { if ( !server.isConnected() ) { return false; } try { server.getUser( server.getUserName() ); } catch ( P4JavaException e ) { // lost connection return false; } return true; } /** * Initialize an instance of the Perforce server from the factory using the specified protocol, server port, * protocol specific properties and usage options. Register callback on the server. Connect to server; set the user * (if present) to server and login to the server with the user's password (if present). * * @throws ScmException the scm exception */ public IOptionsServer createServer( P4ScmProviderRepository repo ) throws ScmException { IOptionsServer server = null; try { // Set default system file helper ServerFactory.setRpcFileSystemHelper( new RpcSystemFileCommandsHelper() ); // Get an instance of the P4J server. Properties p4ServerProperties = null; // FIXME UsageOptions p4ServerOptions = null; server = ServerFactory.getOptionsServer( getUrl( repo.getP4Port() ), p4ServerProperties, p4ServerOptions ); if ( P4Utils.getSettings().getCharset() != null ) { server.setCharsetName( P4Utils.getSettings().getCharset() ); } if ( isSsl( repo.getP4Port() ) ) { // assume a new first time connection server.addTrust( new TrustOptions().setAutoAccept( true ) ); } // Register server callback. server.registerCallback( new ICommandCallback() { public void receivedServerMessage( int key, int genericCode, int severityCode, String message ) { // Log warning messages from server, since it's not included // in the other callback methods. if ( severityCode == MessageSeverityCode.E_WARN ) { getLogger().warn( message ); } } public void receivedServerInfoLine( int key, String infoLine ) { if ( getLogger().isDebugEnabled() ) { getLogger().info( infoLine ); } } public void receivedServerErrorLine( int key, String errorLine ) { if ( getLogger().isErrorEnabled() ) { getLogger().error( errorLine ); } } public void issuingServerCommand( int key, String command ) { if ( getLogger().isInfoEnabled() ) { getLogger().info( command ); } } public void completedServerCommand( int key, long millisecsTaken ) { if ( getLogger().isDebugEnabled() ) { getLogger().debug( "Command completed in " + millisecsTaken + "ms" ); } } } ); server.connect(); String p4Charset = P4Utils.getSettings().getCharset(); if ( !StringUtils.isBlank( p4Charset ) ) { if ( server.isConnected() ) { if ( server.supportsUnicode() ) { server.setCharsetName( p4Charset ); } } } if ( !StringUtils.isBlank( repo.getUser() ) ) { server.setUserName( repo.getUser() ); // Login to the server with a password. // Password can be null if it is not needed (i.e. SSO logins). server.login( repo.getPassword(), new LoginOptions() ); } } catch ( URISyntaxException e ) { if ( getLogger().isErrorEnabled() ) { getLogger().error( e.getLocalizedMessage(), e ); } throw new ScmException( e.getLocalizedMessage(), e ); } catch ( P4JavaException e ) { if ( getLogger().isErrorEnabled() ) { getLogger().error( e.getLocalizedMessage(), e ); } throw new ScmException( e.getLocalizedMessage(), e ); } return server; } private static String getUrl( String p4Port ) { String protocol = "p4java"; String hostPort = p4Port; if ( isSsl( p4Port ) ) { protocol += "ssl"; hostPort = p4Port.substring( 4 ); } return protocol + "://" + hostPort; } private static boolean isSsl( String p4Port ) { return p4Port.startsWith( "ssl:" ); } private void disconnectQuietly( IServer server ) { try { if ( server != null ) { server.disconnect(); } } catch ( P4JavaException e ) { this.getLogger().warn( "Unable to disconnect", e ); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#10 | 11505 | dantran | Allow option to enable P4 server log at command line via P4VERBOSE system property and p4maven-settings | ||
#9 | 11424 | dantran |
- P4Java logs are no under debug mode to reduce verbosity. To enable, pass in -X into mvn command - Info command now supports tag - Add p4java into export extension - Use BSD for license name - Update doc |
||
#8 | 10044 | dantran | work around for https://jira.codehaus.org/browse/MRELEASE-884 | ||
#7 | 10043 | dantran | work around for https://jira.codehaus.org/browse/MRELEASE-884 | ||
#6 | 10035 | dantran | Support p4tickets authentication | ||
#5 | 9705 | dantran |
- add apache snapshot repo for maven-scm-test-1.10-SNAPSHOT - add settings'checkStaledConnection for optimization purpose |
||
#4 | 9590 | dantran |
- add option to fail tag when it already exist - add P4ScmUrl parser test - cleanup |
||
#3 | 9566 | dantran |
- pickup charset from external config - Use repo's path during branch, if is not value use the basedir. This means it assumes maven user likely to name artifactId and module the same - Less verbose on server info |
||
#2 | 9533 | dantran | source format | ||
#1 | 9519 | dantran | folder rename to match with its artifactId | ||
//guest/dantran/p4maven/com.perforce.maven/src/main/java/com/perforce/maven/scm/provider/p4/manager/DefaultP4ServerManager.java | |||||
#5 | 9513 | dantran | add provider doc, deploy site:jar, support external charset config | ||
#4 | 9477 | dantran | add logger, prepare the next release | ||
#3 | 9476 | dantran |
- Each managed client now has its own server to prevent concurrency - Validate managed client and server instances |
||
#2 | 9423 | dantran | get all test to use the same setup, handle checkout with tag, need to revisit how we handle ScmVersion | ||
#1 | 9233 | dantran | initial implementation of all the needed manager to cache Iclient and Iserver instances |