001package org.apache.maven.scm.provider.integrity;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import com.mks.api.CmdRunner;
023import com.mks.api.Command;
024import com.mks.api.IntegrationPoint;
025import com.mks.api.IntegrationPointFactory;
026import com.mks.api.Session;
027import com.mks.api.response.APIException;
028import com.mks.api.response.Response;
029import org.apache.maven.scm.log.ScmLogger;
030import org.codehaus.plexus.util.StringUtils;
031
032import java.io.IOException;
033
034/**
035 * The APISession provides a wrapper for the MKS JAVA API
036 *
037 * @author <a href="mailto:cletus@mks.com">Cletus D'Souza</a>
038 * @since 1.6
039 */
040public class APISession
041{
042    // Store the API Version
043    public static final String VERSION =
044        IntegrationPointFactory.getAPIVersion().substring( 0, IntegrationPointFactory.getAPIVersion().indexOf( ' ' ) );
045
046    public static final int MAJOR_VERSION = Integer.parseInt( VERSION.substring( 0, VERSION.indexOf( '.' ) ) );
047
048    public static final int MINOR_VERSION =
049        Integer.parseInt( VERSION.substring( VERSION.indexOf( '.' ) + 1, VERSION.length() ) );
050
051    // Logs all API work...
052    private ScmLogger logger;
053
054    // Class variables used to create an API Session
055    private String hostName;
056
057    private int port = 0;
058
059    private String userName;
060
061    private String password;
062
063    // API Specific Objects
064    private IntegrationPoint ip;
065
066    private Session session;
067
068    private boolean terminated;
069
070    /**
071     * Constructor for the API Session Object
072     * Needs an ScmLogger to log all API operations
073     *
074     * @param logger
075     */
076    public APISession( ScmLogger logger )
077    {
078        logger.info( "MKS Integrity API Version: " + VERSION );
079        this.logger = logger;
080    }
081
082    /**
083     * Establishes a connection with the MKS Integrity Server
084     *
085     * @param host    Hostname or IP address for the MKS Integrity Server
086     * @param portNum Port number for the MKS Integrity Server
087     * @param user    Username to connect to the MKS Integrity Server
088     * @param paswd   Password for the User connecting to the server
089     * @throws APIException
090     */
091    public Response connect( String host, int portNum, String user, String paswd )
092        throws APIException
093    {
094        // Initialize our termination flag...
095        terminated = false;
096        // Create a local integration point
097        ip = IntegrationPointFactory.getInstance().createLocalIntegrationPoint( MAJOR_VERSION, MINOR_VERSION );
098        // Set the flag to automatically start the MKS Integrity Client, if not running
099        ip.setAutoStartIntegrityClient( true );
100        // Use a common session, which means we don't have to manage the password
101        if ( null != paswd && paswd.length() > 0 )
102        {
103            logger.info( "Creating session for " + user + "/" + StringUtils.repeat( "*", paswd.length() ) );
104            session = ip.createSession( user, paswd );
105            logger.info( "Attempting to establish connection using " + user + "@" + host + ":" + portNum );
106        }
107        else
108        {
109            logger.info( "Using a common session.  Connection information is obtained from client preferences" );
110            session = ip.getCommonSession();
111        }
112        // Test the connection to the MKS Integrity Server
113        Command ping = new Command( Command.SI, "connect" );
114        CmdRunner cmdRunner = session.createCmdRunner();
115        // Initialize the command runner with valid connection information
116        if ( null != host && host.length() > 0 )
117        {
118            cmdRunner.setDefaultHostname( host );
119        }
120        if ( portNum > 0 )
121        {
122            cmdRunner.setDefaultPort( portNum );
123        }
124        if ( null != user && user.length() > 0 )
125        {
126            cmdRunner.setDefaultUsername( user );
127        }
128        if ( null != paswd && paswd.length() > 0 )
129        {
130            cmdRunner.setDefaultPassword( paswd );
131        }
132        // Execute the connection
133        Response res = cmdRunner.execute( ping );
134        logger.debug( res.getCommandString() + " returned exit code " + res.getExitCode() );
135        // Initialize class variables based on the connection information
136        hostName = res.getConnectionHostname();
137        port = res.getConnectionPort();
138        userName = res.getConnectionUsername();
139        password = paswd;
140        cmdRunner.release();
141        logger.info( "Successfully established connection " + userName + "@" + hostName + ":" + port );
142        return res;
143    }
144
145    /**
146     * This function executes a generic API Command
147     *
148     * @param cmd MKS API Command Object representing an API command
149     * @return MKS API Response Object
150     * @throws APIException
151     */
152    public Response runCommand( Command cmd )
153        throws APIException
154    {
155        CmdRunner cmdRunner = session.createCmdRunner();
156        cmdRunner.setDefaultHostname( hostName );
157        cmdRunner.setDefaultPort( port );
158        cmdRunner.setDefaultUsername( userName );
159        if ( null != password && password.length() > 0 )
160        {
161            cmdRunner.setDefaultPassword( password );
162        }
163        Response res = cmdRunner.execute( cmd );
164        logger.debug( res.getCommandString() + " returned exit code " + res.getExitCode() );
165        cmdRunner.release();
166        return res;
167    }
168
169    /**
170     * This function executes a generic API Command impersonating another user
171     *
172     * @param cmd             MKS API Command Object representing a API command
173     * @param impersonateUser The user to impersonate
174     * @return MKS API Response Object
175     * @throws APIException
176     */
177    public Response runCommandAs( Command cmd, String impersonateUser )
178        throws APIException
179    {
180        CmdRunner cmdRunner = session.createCmdRunner();
181        cmdRunner.setDefaultHostname( hostName );
182        cmdRunner.setDefaultPort( port );
183        cmdRunner.setDefaultUsername( userName );
184        if ( null != password && password.length() > 0 )
185        {
186            cmdRunner.setDefaultPassword( password );
187        }
188        cmdRunner.setDefaultImpersonationUser( impersonateUser );
189        Response res = cmdRunner.execute( cmd );
190        logger.debug( res.getCommandString() + " returned exit code " + res.getExitCode() );
191        cmdRunner.release();
192        return res;
193    }
194
195    /**
196     * Terminate the API Session and Integration Point
197     */
198    public void terminate()
199    {
200        // Terminate only if not already terminated!
201        if ( !terminated )
202        {
203            try
204            {
205                if ( null != session )
206                {
207                    session.release();
208                }
209
210                if ( null != ip )
211                {
212                    ip.release();
213                }
214                terminated = true;
215                logger.info( "Successfully disconnected connection " + userName + "@" + hostName + ":" + port );
216            }
217            catch ( APIException aex )
218            {
219                logger.debug( "Caught API Exception when releasing session!" );
220                aex.printStackTrace();
221            }
222            catch ( IOException ioe )
223            {
224                logger.debug( "Caught IO Exception when releasing session!" );
225                ioe.printStackTrace();
226            }
227        }
228    }
229
230    /**
231     * Returns the MKS Integrity Hostname for this APISession
232     *
233     * @return
234     */
235    public String getHostName()
236    {
237        return hostName;
238    }
239
240    /**
241     * Returns the MKS Integrity Port for this APISession
242     *
243     * @return
244     */
245    public int getPort()
246    {
247        return port;
248    }
249
250    /**
251     * Returns the MKS Integrity User for this APISession
252     *
253     * @return
254     */
255    public String getUserName()
256    {
257        return userName;
258    }
259
260    /**
261     * Returns the MKS Integrity Password for this APISession
262     *
263     * @return
264     */
265    public String getPassword()
266    {
267        if ( null != password && password.length() > 0 )
268        {
269            return password;
270        }
271        else
272        {
273            return "";
274        }
275    }
276
277    /**
278     * Returns the ScmLogger for this APISession
279     */
280    public ScmLogger getLogger()
281    {
282        return logger;
283    }
284}