View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of 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.releaser.service;
35  
36  import java.util.Collection;
37  import java.util.Locale;
38  
39  import javax.servlet.http.HttpServletRequest;
40  
41  import org.apache.commons.collections.CollectionUtils;
42  
43  import fr.paris.lutece.plugins.releaser.business.Component;
44  import fr.paris.lutece.plugins.releaser.business.Site;
45  import fr.paris.lutece.plugins.releaser.business.WorkflowReleaseContext;
46  import fr.paris.lutece.plugins.releaser.util.ConstanteUtils;
47  import fr.paris.lutece.plugins.releaser.util.ReleaserUtils;
48  import fr.paris.lutece.plugins.workflowcore.business.action.Action;
49  import fr.paris.lutece.plugins.workflowcore.business.state.State;
50  import fr.paris.lutece.portal.business.user.AdminUser;
51  import fr.paris.lutece.portal.service.util.AppException;
52  import fr.paris.lutece.portal.service.util.AppLogService;
53  import fr.paris.lutece.portal.service.workflow.WorkflowService;
54  
55  // TODO: Auto-generated Javadoc
56  /**
57   * NotificationClientTask.
58   */
59  public class ReleaseComponentTask implements Runnable
60  {
61  
62      /** The Constant WAIT_TIME. */
63      private static final long WAIT_TIME = 1000;
64  
65      /** The n id workflow. */
66      private int _nIdWorkflow;
67  
68      /** The wf context. */
69      private WorkflowReleaseContext _wfContext;
70  
71      /** The request. */
72      private HttpServletRequest _request;
73  
74      /** The user. */
75      private AdminUser _user;
76  
77      /** The locale. */
78      private Locale _locale;
79  
80      /**
81       * Instantiates a new release component task.
82       *
83       * @param nIdWf
84       *            the n id wf
85       * @param context
86       *            the context
87       * @param request
88       *            the request
89       * @param user
90       *            the user
91       * @param locale
92       *            the locale
93       */
94      public ReleaseComponentTask( int nIdWf, WorkflowReleaseContext context, HttpServletRequest request, AdminUser user, Locale locale )
95      {
96  
97          _nIdWorkflow = nIdWf;
98          _wfContext = context;
99          _request = request;
100         _user = user;
101         _locale = locale;
102     }
103 
104     /**
105      * runWorkflowRelease.
106      */
107     public void run( )
108     {
109 
110         State state = WorkflowService.getInstance( ).getState( _wfContext.getId( ), WorkflowReleaseContext.WORKFLOW_RESOURCE_TYPE, _nIdWorkflow,
111                 ConstanteUtils.CONSTANTE_ID_NULL );
112         ReleaserUtils.startCommandResult( _wfContext );
113 
114         try
115         {
116 
117             // Wait all component released before releasing site
118             if ( _wfContext.getSite( ) != null )
119             {
120                 while ( !testAllComponentReleased( _wfContext.getSite( ) ) )
121                 {
122 
123                     try
124                     {
125                         Thread.sleep( WAIT_TIME );
126                     }
127                     catch( InterruptedException e )
128                     {
129                         AppLogService.error( e );
130                     }
131                 }
132 
133                 if ( hasErrorDuringReleaseComponent( _wfContext.getSite( ) ) )
134                 {
135                     ReleaserUtils.addTechnicalError( _wfContext.getCommandResult( ),
136                             "The site can not be retrieved because one  of component of the site is in error" );
137                 }
138             }
139 
140             Collection<Action> listActions = WorkflowService.getInstance( ).getActions( _wfContext.getId( ), WorkflowReleaseContext.WORKFLOW_RESOURCE_TYPE,
141                     _nIdWorkflow, _user );
142 
143             for ( Action action : listActions )
144             {
145                 WorkflowService.getInstance( ).doProcessAction( _wfContext.getId( ), WorkflowReleaseContext.WORKFLOW_RESOURCE_TYPE, action.getId( ), -1,
146                         _request, _locale, true );
147                 if ( _wfContext.getComponent( ) != null )
148                 {
149 
150                     // Save in database the release and the next snapshot version
151                     ComponentService.getService( ).setLastReleaseVersion( _wfContext.getComponent( ).getArtifactId( ),
152                             _wfContext.getComponent( ).getTargetVersion( ) );
153                     _wfContext.getComponent( ).setLastAvailableVersion( _wfContext.getComponent( ).getTargetVersion( ) );
154                     ComponentService.getService( ).setLastReleaseNextSnapshotVersion( _wfContext.getComponent( ).getArtifactId( ),
155                             _wfContext.getComponent( ).getNextSnapshotVersion( ) );
156                     _wfContext.getComponent( ).setLastAvailableSnapshotVersion( _wfContext.getComponent( ).getNextSnapshotVersion( ) );
157 
158                 }
159 
160                 break;
161             }
162 
163         }
164         catch( AppException appe )
165         {
166             if ( _wfContext.getComponent( ) != null )
167             {
168 
169                 _wfContext.getComponent( ).setErrorLastRelease( true );
170             }
171             AppLogService.error( appe );
172         }
173         finally
174         {
175             ReleaserUtils.stopCommandResult( _wfContext );
176             WorkflowReleaseContextService.getService( ).saveWorkflowReleaseContext( _wfContext );
177         }
178     }
179 
180     /**
181      * Test all component released.
182      *
183      * @param site
184      *            the site
185      * @return true, if successful
186      */
187     private boolean testAllComponentReleased( Site site )
188     {
189         if ( !CollectionUtils.isEmpty( site.getComponents( ) ) )
190         {
191 
192             for ( Component component : site.getComponents( ) )
193             {
194                 // Test if the release is finished
195                 if ( !component.isErrorLastRelease( ) && component.shouldBeReleased( ) )
196                 {
197                     return false;
198 
199                 }
200             }
201         }
202 
203         return true;
204 
205     }
206 
207     /**
208      * Checks for error during release component.
209      *
210      * @param site
211      *            the site
212      * @return true, if successful
213      */
214     private boolean hasErrorDuringReleaseComponent( Site site )
215     {
216         if ( !CollectionUtils.isEmpty( site.getComponents( ) ) )
217         {
218 
219             for ( Component component : site.getComponents( ) )
220             {
221                 // Test if the release is finished
222                 if ( component.isErrorLastRelease( ) )
223                 {
224                     return true;
225 
226                 }
227             }
228         }
229 
230         return false;
231 
232     }
233 
234 }