View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.deployment.service;
35  
36  import fr.paris.lutece.plugins.deployment.service.vcs.IVCSService;
37  import java.io.FileNotFoundException;
38  import java.util.HashMap;
39  import java.util.Locale;
40  
41  import javax.inject.Inject;
42  import javax.servlet.http.HttpServletRequest;
43  import javax.xml.bind.JAXBException;
44  
45  import org.apache.commons.lang.StringUtils;
46  
47  import fr.paris.lutece.plugins.deployment.business.Application;
48  import fr.paris.lutece.plugins.deployment.business.CommandResult;
49  import fr.paris.lutece.plugins.deployment.business.IAction;
50  import fr.paris.lutece.plugins.deployment.business.ServerApplicationInstance;
51  import fr.paris.lutece.plugins.deployment.business.WorkflowDeploySiteContext;
52  import fr.paris.lutece.plugins.deployment.util.ConstanteUtils;
53  import fr.paris.lutece.plugins.deployment.util.DeploymentUtils;
54  import fr.paris.lutece.plugins.deployment.util.ReleaseUtils;
55  import fr.paris.lutece.portal.service.datastore.DatastoreService;
56  import fr.paris.lutece.portal.service.plugin.Plugin;
57  import fr.paris.lutece.portal.service.plugin.PluginService;
58  import fr.paris.lutece.portal.service.util.AppException;
59  import fr.paris.lutece.portal.service.util.AppLogService;
60  import fr.paris.lutece.portal.service.util.AppPropertiesService;
61  import java.io.File;
62  import java.io.IOException;
63  import java.nio.file.Files;
64  import java.nio.file.Path;
65  import java.nio.file.Paths;
66  import org.apache.commons.io.FileUtils;
67  
68  public class WorkflowDeploySiteService implements IWorkflowDeploySiteService
69  {
70      HashMap<Integer, WorkflowDeploySiteContext> _mapWorkflowDeploySiteContext = new HashMap<Integer, WorkflowDeploySiteContext>( );
71  
72      @Inject
73      IEnvironmentService _environmentService;
74      @Inject
75      IServerApplicationService _serverApplicationService;
76      @Inject
77      IFtpService _ftpService;
78      @Inject
79      IApplicationService _applicationService;
80      @Inject
81      private IActionService _actionService;
82  
83      public synchronized int addWorkflowDeploySiteContext( WorkflowDeploySiteContext context )
84      {
85          int nIdKey = Integer.parseInt( DatastoreService.getDataValue( ConstanteUtils.CONSTANTE_MAX_DEPLOY_SITE_CONTEXT_KEY, "0" ) ) + 1;
86          // stored key in database
87          DatastoreService.setDataValue( ConstanteUtils.CONSTANTE_MAX_DEPLOY_SITE_CONTEXT_KEY, Integer.toString( nIdKey ) );
88          context.setId( nIdKey );
89          _mapWorkflowDeploySiteContext.put( nIdKey, context );
90  
91          return nIdKey;
92      }
93  
94      public WorkflowDeploySiteContext getWorkflowDeploySiteContext( int nIdContext )
95      {
96          return _mapWorkflowDeploySiteContext.get( nIdContext );
97      }
98  
99      public String checkoutSite( WorkflowDeploySiteContext context, Locale locale )
100     {
101         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
102         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
103         IVCSService vcsService = DeploymentUtils.getVCSService( application.getRepoType( ) );
104         context.getCommandResult( ).getLog( ).append( "Starting Action Checkout  Site...\n" );
105 
106         vcsService.checkAuthentication( context.getSvnBaseSiteUrl( ), context.getVcsUser( ) );
107 
108         vcsService.doCheckoutSite( application.getArtifactId( ), application.getUrlRepo( ), context.getVcsUser( ), context.getCommandResult( ), null,
109                 context.getTagToDeploy( ) );
110 
111         // throw RuntimeException for stopping Workflow
112 
113         stopWorkflowIfTechnicalError( "Error Chekout Site", context.getCommandResult( ) );
114 
115         context.getCommandResult( ).getLog( ).append( "End Action Checkout   Site...\n" );
116 
117         return null;
118     }
119 
120     public void initTagInformations( WorkflowDeploySiteContext context )
121     {
122         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
123         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
124 
125         String strVersion = null;
126         String strNextVersion = null;
127         String strTagName = null;
128 
129         // release version and next version
130         try
131         {
132             strVersion = ReleaseUtils.getReleaseVersion( DeploymentUtils.getPathCheckoutSite( application.getUrlRepo( ) ) );
133             strNextVersion = ReleaseUtils.getNextVersion( strVersion );
134             strTagName = ReleaseUtils.getReleaseName( application.getName( ), strVersion );
135         }
136         catch( FileNotFoundException e )
137         {
138             // TODO Auto-generated catch block
139             AppLogService.error( e );
140         }
141         catch( JAXBException e )
142         {
143             // TODO Auto-generated catch block
144             e.printStackTrace( );
145         }
146 
147         context.setTagName( strTagName );
148         context.setTagVersion( strVersion );
149         context.setNextVersion( strNextVersion );
150     }
151 
152     public String assemblySite( WorkflowDeploySiteContext context, Locale locale )
153     {
154         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
155         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
156 
157         ServerApplicationInstance serverApplicationInstance = _serverApplicationService.getServerApplicationInstance( application,
158                 context.getCodeServerInstance( ConstanteUtils.CONSTANTE_SERVER_TOMCAT ), context.getCodeEnvironement( ),
159                 ConstanteUtils.CONSTANTE_SERVER_TOMCAT, locale, false, false );
160         context.getCommandResult( ).getLog( ).append( "Starting Action Assembly  Site...\n" );
161         MavenService.getService( ).mvnSiteAssembly( application.getArtifactId( ), context.getTagName( ),
162                 serverApplicationInstance.getMavenProfile( application.getIdApplication( ) ), context.getVcsUser( ), context.getCommandResult( ) );
163         // throw RuntimeException for stopping Workflow
164         stopWorkflowIfTechnicalError( "Error During assembly Site", context.getCommandResult( ) );
165         context.getCommandResult( ).getLog( ).append( "End Action Assembly  Site...\n" );
166 
167         return null;
168     }
169 
170     public String deploySite( WorkflowDeploySiteContext context, Locale locale )
171     {
172         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
173         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
174         ServerApplicationInstance serverApplicationInstance = _serverApplicationService.getServerApplicationInstance( application,
175                 context.getCodeServerInstance( ConstanteUtils.CONSTANTE_SERVER_TOMCAT ), context.getCodeEnvironement( ),
176                 ConstanteUtils.CONSTANTE_SERVER_TOMCAT, locale, false, false );
177         context.getCommandResult( ).getLog( ).append( "Starting Action Deploy  Site...\n" );
178 
179         String strWarGeneratedName = MavenService.getService( ).getSiteWarName( application.getArtifactId( ) );
180 
181         _ftpService.uploadFile( application.getWebAppName( ) + ConstanteUtils.ARCHIVE_WAR_EXTENSION, DeploymentUtils.getPathArchiveGenerated(
182                 DeploymentUtils.getPathCheckoutSite( application.getArtifactId( ) ), strWarGeneratedName, ConstanteUtils.ARCHIVE_WAR_EXTENSION ),
183                 serverApplicationInstance.getFtpInfo( ), DeploymentUtils.getDeployDirectoryTarget( application.getCode( ), serverApplicationInstance ), context
184                         .getCommandResult( ), true );
185         // throw RuntimeException for stopping Workflow
186         stopWorkflowIfTechnicalError( "Error During Deploy Site", context.getCommandResult( ) );
187 
188         context.getCommandResult( ).getLog( ).append( "End Action Deploy  Site...\n" );
189 
190         return null;
191     }
192 
193     public String deployScript( WorkflowDeploySiteContext context, Locale locale )
194     {
195         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
196         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
197 
198         String strServerType = !StringUtils.isEmpty( context.getCodeServerInstance( ConstanteUtils.CONSTANTE_SERVER_MYSQL ) ) ? ConstanteUtils.CONSTANTE_SERVER_MYSQL
199                 : ConstanteUtils.CONSTANTE_SERVER_PSQ;
200         ServerApplicationInstance serverApplicationInstance = _serverApplicationService.getServerApplicationInstance( application,
201                 context.getCodeServerInstance( strServerType ), context.getCodeEnvironement( ), strServerType, locale, false, false );
202 
203         context.getCommandResult( ).getLog( ).append( "Starting Action Deploy  Script...\n" );
204 
205         _ftpService.uploadFile( context.getScriptFileItemName( ), context.getScriptFileItem( ), serverApplicationInstance.getFtpInfo( ),
206                 DeploymentUtils.getDeployDirectoryTarget( application.getCode( ), serverApplicationInstance ), context.getCommandResult( ), false );
207         // throw RuntimeException for stopping Workflow
208         stopWorkflowIfTechnicalError( "Error During Deploy Script", context.getCommandResult( ) );
209 
210         context.getCommandResult( ).getLog( ).append( "End Action Deploy  Script...\n" );
211 
212         return null;
213     }
214 
215     public String executeServerAction( String strActionKey, HttpServletRequest request, WorkflowDeploySiteContext context, Locale locale )
216     {
217         Plugin plugin = PluginService.getPlugin( DeploymentPlugin.PLUGIN_NAME );
218         Application application = _applicationService.getApplication( context.getIdApplication( ), plugin );
219         IAction action = _actionService.getAction( strActionKey, locale );
220         // test if the server instance is in the deployment context
221         if ( context.getCodeServerInstance( action.getServerType( ) ) != null )
222         {
223 
224             ServerApplicationInstance serverApplicationInstance = _serverApplicationService.getServerApplicationInstance( application,
225                     context.getCodeServerInstance( action.getServerType( ) ), context.getCodeEnvironement( ), action.getServerType( ), locale, false, false );
226             boolean bResult;
227             if ( action != null
228                     && _actionService.canExecuteAction( application, action, serverApplicationInstance, context.getCommandResult( ),
229                             DeploymentUtils.getActionParameters( context ) ) )
230             {
231                 context.getCommandResult( ).getLog( ).append( "Starting Action " + action.getName( ) + " \n" );
232                 bResult = _actionService.executeAction( application, action, serverApplicationInstance, context.getCommandResult( ),
233                         DeploymentUtils.getActionParameters( context ) );
234                 if ( !bResult && action.isStopWorkflowIfExecutionError( ) )
235                 {
236                     context.getCommandResult( ).setErrorType( CommandResult.ERROR_TYPE_STOP );
237                     // throw RuntimeException for stopping Workflow
238                     throw new RuntimeException( "Error During Server Action Execution" );
239 
240                 }
241                 context.getCommandResult( ).getLog( ).append( "End Action " + action.getName( ) + " \n" );
242 
243             }
244         }
245 
246         return null;
247     }
248 
249     private void stopWorkflowIfTechnicalError( String strProcess, CommandResult commandResult ) throws RuntimeException
250     {
251 
252         if ( commandResult != null && commandResult.getStatus( ) == CommandResult.STATUS_ERROR
253                 && commandResult.getErrorType( ) == CommandResult.ERROR_TYPE_STOP )
254         {
255             throw new RuntimeException( strProcess );
256         }
257     }
258     
259 }